• WPF中的平移缩放和矩阵变换(TranslateTransform、ScaleTransform、MatrixTransform)


    在WPF中的平移缩放都是通过RenderTransform这个类来实现这些效果的,在这个类中,除了平移和缩放还有旋转、扭曲变换、矩阵变换。这些都差不多的,都是坐标的变换。

    这里我就先简单弄个平移和缩放吧:

    平移呢就是以原来的对象为坐标原点(0,0),然后向X轴、Y轴进行平移变换。缩放呢有几个属性,ScaleX、ScaleY属性表示对象在X、Y轴进行缩放的倍数,CenterX 和 CenterY属性指定一个中心点。

    下面有一个平移和缩放的简单的demo,用鼠标拖图片放进行平移,点击按钮来进行缩放,同时在缩放时让图片回到窗口的中央:

    <Grid Name="grid">
            <Grid.Resources>
                <TransformGroup x:Key="trasformView">
                    <ScaleTransform />
                    <TranslateTransform />
                </TransformGroup>
            </Grid.Resources>
            <ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Disabled" Focusable="False">
                <ContentControl MouseLeftButtonDown="OnMouseLeftButtonDown"
                                MouseLeftButtonUp="OnMouseLeftButtonUp"
                                MouseMove="OnMouseMove">
                    <Image Name="Image1" Source="Images/Picture.jpg" Stretch="Uniform"
                           RenderTransform="{StaticResource trasformView}" />
                </ContentControl>
            </ScrollViewer>
            <StackPanel HorizontalAlignment="Right" VerticalAlignment="Bottom">
                <Button Content="放大" Click="Button_Click_1" />
                <Button Content="缩小" Click="Button_Click_2" />
            </StackPanel>
        </Grid>
    View Code

    分别处理MouseDown/Move/Up来达到移动,通过点击按钮然后控制ScaleX、ScaleY,CenterX 和 CenterY来放大缩小倍数和控制中心点

    private void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
                var image = sender as ContentControl;
                if (image == null) {
                    return;
                }
                image.CaptureMouse();
                ismouseLeftButtonDown = true;
                this.mousePoint = e.GetPosition(image);
            }
    
            private void OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e) {
                var image = sender as ContentControl;
                if (image == null) {
                    return;
                }
                image.ReleaseMouseCapture();
                ismouseLeftButtonDown = false;
            }
    
            private void OnMouseMove(object sender, MouseEventArgs e) {
                var image = sender as ContentControl;
                if (image == null) {
                    return;
                }
                if (ismouseLeftButtonDown) {
                    ImageMove(image, e.GetPosition(image));
                }
            }
    
            private void ImageMove(ContentControl image, Point point) {
                var group = grid.FindResource("trasformView") as TransformGroup;
                var translateTransform = group.Children[1] as TranslateTransform;
                translateTransform.X += point.X - mousePoint.X;
                translateTransform.Y += point.Y - mousePoint.Y;
                mousePoint = point;
    
                sumx = translateTransform.X;
                sumy = translateTransform.Y;
            }
    View Code
    private void ScalingAndtranslation(string str) {
                var group = grid.FindResource("trasformView") as TransformGroup;
                var scaleTransform = group.Children[0] as ScaleTransform;
                var translateTransform = group.Children[1] as TranslateTransform;
    
                var mainWindowPoint = new Point(window.ActualWidth / 2, window.ActualHeight / 2);
                var imagePoint = new Point(Image1.ActualWidth / 2, Image1.ActualHeight / 2);
    
                scaleTransform.CenterX = imagePoint.X;
                scaleTransform.CenterY = imagePoint.Y;
    
                if (str == "amplify") {
                    scaleTransform.ScaleX += 0.2;
                    scaleTransform.ScaleY += 0.2;
                } else if (str == "reduce" && scaleTransform.ScaleX > 0.1) {
                    scaleTransform.ScaleX -= 0.2;
                    scaleTransform.ScaleY -= 0.2;
                }
    
                if (translateTransform.X != 0 || translateTransform.Y != 0) {
                    translateTransform.X = translateTransform.X - sumx;
                    translateTransform.Y = translateTransform.Y - sumy;
                }
            }
    View Code

    上面是用了TranslateTransform、ScaleTransform,还有一个MatrixTransform,这个是其他变换的底层的实现,是通过矩阵的运算来得到的。可以更加灵活的运动变换。

    这个可以仔细的学习一下:

    <MatrixTransform Matrix="M11 M12 M21 M22 OffsetX OffsetY"></MatrixTransform>

    可以看到上面这个,Matrix里面的是什么意思呢,首先看简单的[OffsetX OffsetY]这两个。这两个是跟平移有关,很简单,就是一个简单的矩阵的加减法,比如[1,1]+[1,0]=[2,1]。这个就表示(1,1)这个点在X轴上平移一个单位可以到(2,1)。同理:[1,1]+[0,1]=[1,2]。这个就是在Y轴上平移一个单位。

    然后来看缩放:

    这个矩阵的乘法表示(1,2)这个点通过乘一个矩阵后变为(3,8),X轴变为原来3倍,Y轴变为4倍。

    然后呢这个中间乘的矩阵就是上面M11和M22。就可以控制缩放的倍数。

    同样的,剩下的两个就是用来控制旋转的啦。

    所以,就可以通过几个矩阵的结合来一次性的旋转、平移、缩放等等操作。上面都是2*2的矩阵,其实有3*3的矩阵的,就是本人数学较烂。就找个图贴贴总结下吧。

    最终坐标:即是说最终坐标 (x1,y1) : x1 =  x0 * M11 + x0 * M21 + OffsetX , y1 = y0 * M12 + y0 * M22 + OffsetY.

    好了,这样MatrixTransform 就可以进行使用了。例子还没写=-= 以后补充吧。

    先把上面那个简单的平移缩放的DEMO放着:NO1

  • 相关阅读:
    [NLP] 语义网络与知识图谱入门(二)
    [NLP] 语义网络与知识图谱入门(一)
    [论文理解] LFFD: A Light and Fast Face Detector for Edge Devices
    [学习笔记] 匈牙利匹配
    [NLP] nlp-lstm-cos -> sin
    [ros] ros入门记录
    [推荐系统] 两种协同过滤
    [NN] Guided Backpropgation 可视化
    [torch] pytorch hook学习
    python高级编程和算法
  • 原文地址:https://www.cnblogs.com/socialdk/p/3348036.html
Copyright © 2020-2023  润新知