Windows Phone开发(18):变形金刚第九季——变换

简介: 原文: Windows Phone开发(18):变形金刚第九季——变换 变换不是一个好理解的概念,不是吓你,它涉及很多有关代数,几何,以及线性代数的知识。怎么?被我的话吓怕了?不用怕,尽管我们未必能够理解这些概念,只要我们知道怎么使用它们就是了。
原文: Windows Phone开发(18):变形金刚第九季——变换

变换不是一个好理解的概念,不是吓你,它涉及很多有关代数,几何,以及线性代数的知识。怎么?被我的话吓怕了?不用怕,尽管我们未必能够理解这些概念,只要我们知道怎么使用它们就是了。
其实,变换就是平面上一种坐标变化,听起来很抽象,但,只要我把它说具体了,你就会觉得不抽象了。
相信各位如果玩过Photoshop,或者其它的绘图软件,应该知道什么叫做旋转,什么叫做倾斜,什么叫做平移……
是的,这些就是我们今天要聊的变换,好了,现在你是不是可以坐下来喝一杯珍珠奶茶来放松一下呢?哦,对了,珍珠奶茶尽量少喝哦。

好,闲话少吹,开始今天的表演。

 

一、TranslateTransform。


这个应该算是最好理解了,就是平移嘛,相信大家不会陌生的,学习解析几何的时候是不是经常玩啊?它无非就两个参数——X和Y,分别是平面上两个方向的位移。

上图中的三个矩形,它们的位置是一样的,但经过平移后,看起来它们好像不在同一个位置了。

    <Canvas>
        <!-- 三个矩形在Canvas中的位置是相同的,但经过平移变换后,
             看起来,好像并不在同一个位置了。    
        -->
        <Rectangle Width="120" Height="120"
                   Fill="DarkGreen"
                   Canvas.ZIndex="0"
                   Canvas.Top="15"
                   Canvas.Left="15">
            <Rectangle.RenderTransform>
                <TranslateTransform X="20" Y="20"/>
            </Rectangle.RenderTransform>
        </Rectangle>
        <Rectangle Width="120" Height="120"
                   Fill="Yellow"
                   Canvas.ZIndex="1"
                   Canvas.Top="15"
                   Canvas.Left="15">
            <Rectangle.RenderTransform>
                <TranslateTransform X="80" Y="80"/>
            </Rectangle.RenderTransform>
        </Rectangle>
        <Rectangle Width="120" Height="120"
                   Fill="Blue"
                   Canvas.ZIndex="2"
                   Canvas.Top="15"
                   Canvas.Left="15">
            <Rectangle.RenderTransform>
                <TranslateTransform X="140" Y="140"/>
            </Rectangle.RenderTransform>
        </Rectangle>
    </Canvas>


 

二、RotateTransform。


这个家伙就是用来旋转元素的,Angle属性就是旋转的角度,不用我解释了吧,小学生的知识。另外,有两个属性要注意一下:
CenterX:旋转中心的X坐标,这个坐标是相对于目标的左上角的,例如,你要让一个矩形转旋转,默认的情况,旋转中心就是0,就是矩形的左上角;
CenterY:和上面一样了,只是Y坐标的点。

这两个旋转点不太好把握,如果我们希望比较的相对定位,可以通过UIElement的RenderTransformOrigin属性来改动旋转原点,这个点坐标是相对于元素可视化的边界的,即0到1之间的值,如:
1、左上角:(0,0)
2、左下角:(1,1)
3、顶部居中:(0.5,0)
4、底部居中:(0.5,1)


上图中的三个图象,旋转中心都在底部居中,只是旋转的角度不同而已。

    <Grid>
        <Image Margin="289,42,241,143" Source="/TransFormSample;component/1.jpg" Stretch="Uniform" Opacity="0.3"
               RenderTransformOrigin="0.5,1">
            <Image.RenderTransform>
                <RotateTransform Angle="-60"/>
            </Image.RenderTransform>
        </Image>
        <Image Margin="289,42,241,143" Source="/TransFormSample;component/1.jpg" Stretch="Uniform" Opacity="0.6"
               RenderTransformOrigin="0.5,1">
            <Image.RenderTransform>
                <RotateTransform Angle="0"/>
            </Image.RenderTransform>
        </Image>
        <Image Margin="289,42,241,143" Source="/TransFormSample;component/1.jpg" Stretch="Uniform"
               RenderTransformOrigin="0.5,1">
            <Image.RenderTransform>
                <RotateTransform  Angle="60"/>
            </Image.RenderTransform>
        </Image>
    </Grid>


 

 

三、ScaleTransform。


与上面的旋转变换相似,但这个是用于放大和缩小的,它也有一个中心点,就是缩放中心,同样,它的默认值是目标元素的左上角,至于以哪个点为缩放中心,你就自己调整中心坐标了。


 

上图中为了能清楚看到缩放的效果,后面两个图象都设置透明度。

    <Grid>
        <Image Source="/TransFormSample;component/1.jpg" Stretch="Uniform" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="130"
               Canvas.ZIndex="0" Opacity="0.09">
            <Image.RenderTransform>
                <ScaleTransform CenterX="110" CenterY="180" ScaleX="2" ScaleY="2"/>
            </Image.RenderTransform>
        </Image>

        <Image Source="/TransFormSample;component/1.jpg" Stretch="Uniform" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="130"
               Canvas.ZIndex="1" Opacity="0.2">
            <Image.RenderTransform>
                <ScaleTransform CenterX="120" CenterY="150" ScaleX="1.6" ScaleY="1.6"/>
            </Image.RenderTransform>
        </Image>

        <Image Source="/TransFormSample;component/1.jpg" Stretch="Uniform" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="130"
               Canvas.ZIndex="2"/>
    </Grid>


 

 

四、SkewTransform。


扭曲变换,可以说是倾斜,它的确实现了倾斜的效果。
同样它也有一个中心点,与上面的相似,AngleX是沿X轴扭曲的角度,AngleY就是沿Y轴扭曲。

 

    <Grid>
        <Image Source="/TransFormSample;component/1.jpg" HorizontalAlignment="Center"
               VerticalAlignment="Center"
               Margin="100"/>
        <Image Source="/TransFormSample;component/1.jpg" HorizontalAlignment="Center"
               VerticalAlignment="Center"
               Margin="100" Opacity="0.3">
            <Image.RenderTransform>
                <SkewTransform CenterX="0" CenterY="-200" AngleX="30" AngleY="0"/>
            </Image.RenderTransform>
        </Image>
        <Image Source="/TransFormSample;component/1.jpg" HorizontalAlignment="Center"
               VerticalAlignment="Center"
               Margin="100" Opacity="0.3">
            <Image.RenderTransform>
                <SkewTransform CenterX="0" CenterY="-550" AngleX="-15" AngleY="0"/>
            </Image.RenderTransform>
        </Image>

    </Grid>


 

 

五、TransformGroup。


严格上说,这个不算是一种变换,但它可以实现把N个变换叠加在一起。

 

    <Grid>
        <Image Source="/TransFormSample;component/1.jpg"
               Stretch="Uniform" Margin="65,98,472,92" />
        <Image Source="/TransFormSample;component/1.jpg"
               Stretch="Uniform" Margin="65,98,472,92" >
            <Image.RenderTransform>
                <TransformGroup>
                    <TranslateTransform X="270" Y="30"/>
                    <ScaleTransform ScaleX="1.5" ScaleY="1.5" CenterX="185" CenterY="280"/>
                    <RotateTransform CenterX="400" CenterY="60" Angle="18"/>
                </TransformGroup>
            </Image.RenderTransform>
        </Image>

    </Grid>


 

 

 

 

六、CompositeTransform。


这与上面的TransformGroup有点像,但你也看到,它不是把多个变换叠加,而是同时应用多种变换方式,但它是有顺序的。
缩放 ->扭曲->旋转->位移

 

 

    <Grid>
        <Image Source="/TransFormSample;component/1.jpg" Stretch="Uniform" Margin="48,68,492,131" />
        <Image Source="/TransFormSample;component/1.jpg" Stretch="Uniform" Margin="48,68,492,131"
               Opacity="0.5">
            <Image.RenderTransform>
                <CompositeTransform
                    CenterX="250" CenterY="185"
                    Rotation="45"
                    SkewX="15" SkewY="15"
                    ScaleX="1.2" ScaleY="1.2"
                    TranslateX="230" TranslateY="200"/>
            </Image.RenderTransform>
        </Image>

    </Grid>


 

 

 

七、MatrixTrasform。


这是最复杂的一种变换,它是一个3乘3的矩阵,但是,由于它第3列为0,0,1,所以,其实我们只需设置6个值就够了。它们分别是:
 m11       m12     0
 m21       m22     0
 offsetX  offsetY  1
可能是offsetX和offsetY比较容易看出来就是位移,那前面几呢?我们可以猜,默认值为1的就是缩放,因为不可能为0倍,剩下两个就是X轴和Y轴方向的倾斜值了。

其实,我也是通过写代码来找规律的,保持其实参数不变单独改变一个参数来观察图形的变化就能找到答案了。

        m11 ——X轴缩放
        m12 ——Y轴上倾斜
        m21 ——X轴上倾斜
        m22——Y轴缩放
        offsetX ——X轴上的位移
        offsetY ——Y轴上的位移

 

 

    <Grid>
        <Image Height="206" HorizontalAlignment="Left" Margin="73,104,0,0" Name="image1" Stretch="Uniform" VerticalAlignment="Top" Width="139" Source="/TransFormSample;component/1.jpg">
            <Image.RenderTransform>
                <MatrixTransform Matrix="2,0,0,1,12,6"/>
            </Image.RenderTransform>
        </Image>
        <Image Height="206" HorizontalAlignment="Left" Margin="122,424,0,0" Name="image2" Source="/TransFormSample;component/1.jpg" Stretch="Uniform" VerticalAlignment="Top" Width="136" >
            <Image.RenderTransform>
                <MatrixTransform Matrix="1,-1,0,1,0,137"/>
            </Image.RenderTransform>
        </Image>
        <Image Height="206" HorizontalAlignment="Left" Margin="293,12,0,0" Name="image3" Source="/TransFormSample;component/1.jpg" Stretch="Uniform" VerticalAlignment="Top" Width="139" >
            <Image.RenderTransform>
                <MatrixTransform Matrix="1,0.6,0,1,0,0"/>
            </Image.RenderTransform>
        </Image>
        <Image Height="206" HorizontalAlignment="Left" Margin="269,424,0,0" Name="image4" Source="/TransFormSample;component/1.jpg" Stretch="Uniform" VerticalAlignment="Top" Width="139" >
            <Image.RenderTransform>
                <MatrixTransform Matrix="1,1,0,1,0,0"/>
            </Image.RenderTransform>
        </Image>
    </Grid>


 

如何学习有关变换的知识呢?个人推荐一种方法,很有效,那就是——乱来。
真的,乱来的学习效果很好的,呵呵。

你可以写好代码,然后不断地改变数值,看看有什么变化,多试几次你就会找到规律。

 

 

目录
相关文章
|
3小时前
|
IDE 关系型数据库 开发工具
使用Visual Basic进行Windows窗体开发
【4月更文挑战第27天】本文介绍了使用Visual Basic进行Windows窗体(WinForms)开发的步骤,从搭建开发环境到创建、设计用户界面,再到编写事件驱动的代码和数据绑定。Visual Basic结合WinForms提供了一种易学易用的桌面应用开发方案。通过调试、优化、部署和维护,开发者可以构建专业应用程序。随着技术发展,掌握最新UI设计和开发工具对于保持竞争力至关重要。本文为初学者提供了基础指导,鼓励进一步探索和学习。
|
3小时前
|
算法 Linux Windows
FFmpeg开发笔记(十七)Windows环境给FFmpeg集成字幕库libass
在Windows环境下为FFmpeg集成字幕渲染库libass涉及多个步骤,包括安装freetype、libxml2、gperf、fontconfig、fribidi、harfbuzz和libass。每个库的安装都需要下载源码、配置、编译和安装,并更新PKG_CONFIG_PATH环境变量。最后,重新配置并编译FFmpeg以启用libass及相关依赖。完成上述步骤后,通过`ffmpeg -version`确认libass已成功集成。
19 1
FFmpeg开发笔记(十七)Windows环境给FFmpeg集成字幕库libass
|
3小时前
|
前端开发 Linux iOS开发
【Flutter前端技术开发专栏】Flutter在桌面应用(Windows/macOS/Linux)的开发实践
【4月更文挑战第30天】Flutter扩展至桌面应用开发,允许开发者用同一代码库构建Windows、macOS和Linux应用,提高效率并保持平台一致性。创建桌面应用需指定目标平台,如`flutter create -t windows my_desktop_app`。开发中注意UI适配、性能优化、系统交互及测试部署。UI适配利用布局组件和`MediaQuery`,性能优化借助`PerformanceLogging`、`Isolate`和`compute`。
【Flutter前端技术开发专栏】Flutter在桌面应用(Windows/macOS/Linux)的开发实践
|
3小时前
|
编解码 Linux Windows
FFmpeg开发笔记(十三)Windows环境给FFmpeg集成libopus和libvpx
本文档介绍了在Windows环境下如何为FFmpeg集成libopus和libvpx库。首先,详细阐述了安装libopus的步骤,包括下载源码、配置、编译和安装,并更新环境变量。接着,同样详细说明了libvpx的安装过程,注意需启用--enable-pic选项以避免编译错误。最后,介绍了重新配置并编译FFmpeg以启用这两个库,通过`ffmpeg -version`检查是否成功集成。整个过程参照了《FFmpeg开发实战:从零基础到短视频上线》一书的相关章节。
27 0
FFmpeg开发笔记(十三)Windows环境给FFmpeg集成libopus和libvpx
|
3小时前
|
编解码 Linux Windows
FFmpeg开发笔记(十一)Windows环境给FFmpeg集成vorbis和amr
在Windows环境下,为FFmpeg集成音频编解码库,包括libogg、libvorbis和opencore-amr,涉及下载源码、配置、编译和安装步骤。首先,安装libogg,通过配置、make和make install命令完成,并更新PKG_CONFIG_PATH。接着,安装libvorbis,同样配置、编译和安装,并修改pkgconfig文件。之后,安装opencore-amr。最后,重新配置并编译FFmpeg,启用ogg和amr支持,通过ffmpeg -version检查是否成功。整个过程需确保环境变量设置正确,并根据路径添加相应库。
31 1
FFmpeg开发笔记(十一)Windows环境给FFmpeg集成vorbis和amr
|
3小时前
|
Linux 编译器 C语言
FFmpeg开发笔记(二)搭建Windows系统的开发环境
在Windows上学习FFmpeg通常较困难,但通过安装预编译的FFmpeg开发包可以简化流程。首先需要安装MSYS2来模拟Linux环境。下载并执行MSYS2安装包,然后修改msys2_shell.cmd以继承Windows的Path变量。使用pacman安装必要的编译工具。接着,下载预编译的FFmpeg Windows包,解压并配置系统Path。最后,在MSYS2环境中运行`ffmpeg -version`确认安装成功。欲深入学习FFmpeg开发,推荐阅读《FFmpeg开发实战:从零基础到短视频上线》。
37 4
FFmpeg开发笔记(二)搭建Windows系统的开发环境
|
3小时前
|
数据可视化 数据库 C++
Qt 5.14.2揭秘高效开发:如何用VS2022快速部署Qt 5.14.2,打造无与伦比的Windows应用
Qt 5.14.2揭秘高效开发:如何用VS2022快速部署Qt 5.14.2,打造无与伦比的Windows应用
110 0
|
3小时前
|
移动开发 API 开发者
windows开发技术 mfc浅谈
windows开发技术 mfc浅谈
|
3小时前
|
监控 安全 API
5.9 Windows驱动开发:内核InlineHook挂钩技术
在上一章`《内核LDE64引擎计算汇编长度》`中,`LyShark`教大家如何通过`LDE64`引擎实现计算反汇编指令长度,本章将在此基础之上实现内联函数挂钩,内核中的`InlineHook`函数挂钩其实与应用层一致,都是使用`劫持执行流`并跳转到我们自己的函数上来做处理,唯一的不同的是内核`Hook`只针对`内核API`函数,但由于其身处在`最底层`所以一旦被挂钩其整个应用层都将会受到影响,这就直接决定了在内核层挂钩的效果是应用层无法比拟的,对于安全从业者来说学会使用内核挂钩也是很重要。
45 1
5.9 Windows驱动开发:内核InlineHook挂钩技术
|
3小时前
|
监控 API C++
8.4 Windows驱动开发:文件微过滤驱动入门
MiniFilter 微过滤驱动是相对于`SFilter`传统过滤驱动而言的,传统文件过滤驱动相对来说较为复杂,且接口不清晰并不符合快速开发的需求,为了解决复杂的开发问题,微过滤驱动就此诞生,微过滤驱动在编写时更简单,多数`IRP`操作都由过滤管理器`(FilterManager或Fltmgr)`所接管,因为有了兼容层,所以在开发中不需要考虑底层`IRP`如何派发,更无需要考虑兼容性问题,用户只需要编写对应的回调函数处理请求即可,这极大的提高了文件过滤驱动的开发效率。
45 0