Matrix Transformation of two-dimensional graphics (iii) -- applying matrix transformation in WPF

Source: Internet
Author: User

Uielement and rendertransform

First, let's see what types of objects can be transformed. In WPF, the base class of the object to be presented to the user is a visual class, but the visual object does not have the transformation function. What has the transformation function is its subclass uielement. This class is also a very underlying class. Almost all of our common controls are inherited from it. That is to say, basically all UI objects can be transformed by applications.

Then, let's take a look at the transformation types in uielement. Uielement supports two types of transformations: rendertransform and layouttransform. layouttransform changes the layout and affects the adjacent space size and location, as shown in.

Since we often use rendertransfrom, and the usage of the Two Transformations is very similar, the following article mainly introduces rendertransfrom. The following example demonstrates its usage:

<Stackpanel orientation = "vertical">
<Button content = "A button" opacity = "1"/>
<Button content = "rotated button">
<Button. rendertransform>
<Rotatetransform angle = "45"/>
</Button. rendertransform>
</Button>
<Button content = "A button" opacity = "1"/>
</Stackpanel>

 

Matrix Transformation matrixtransform

The previous example demonstrates the rotatetransform usage of Rotation Transformations. Other basic transformations also have the following Transformation classes: scaletransform, translatetransform, and skewtransform. We can also put multiple transformations into one transformation group to achieve the effect of superposition.

These basic transformations are relatively simple to use, so we will not introduce them here. The following describes the focus of this article: matrix transformation matrixtransform. Its usage is similar to rotatetransform:

<Button content = "rotated button">
<Button. rendertransform>
<Matrixtransform X: Name = "mymatrixtransform">
<Matrixtransform. Matrix>
<Matrix offsetx = "10" offline sety = "100"/>
</Matrixtransform. Matrix>
</Matrixtransform>
</Button. rendertransform>
</Button>

From the code above, we can see that since matrix transformation requires six values, and these values are not readable, It is very intuitive to use them in XAML, most of the time we set it in the code.

From this example alone, we cannot see the superiority of matrix transformation. This is because the transformation we use is relatively simple. We have introduced in the matrix transformation of the previous two-dimensional graph (I)-basic concepts that any sequence of two-dimensional transformations can be stored in a single matrix object, therefore, it is very easy to implement the transformation superposition effect. The following describes how to use WPF to implement a simple image viewer using matrix transformation as an example.

The main function of this example is to implement an image Viewer that supports mouse dragging and scroll wheel scaling. In the original article, the image Viewer is implemented by the combination of translation transformation and zoom transformation. Here, the matrix transformation is used for implementation. First, let's take a look at the XAML section.

<Grid>
<Image Source = "source.jpg" mousewheel = "image_mousewheel" previewmouseleftbuttondown = "image_mouseleftbuttondown"
Previewmousemove = "image_mousemove">
<Image. rendertransform>
<Matrixtransform X: Name = "transform"/>
</Image. rendertransform>
</Image>
</GRID>

Then the event is implemented:

Privatevoid image_mousewheel (Object sender, mousewheeleventargs E)
{
VaR center = getposition (sender, e );
VaR scale = (E. Delta> 0? 1.2: 1/1.2 );

VaR matrix = transform. matrix;
Matrix. scaleat (scale, scale, Center. X, Center. y );

Transform. Matrix = matrix;
}

Point dragstart;
Privatevoid image_mouseleftbuttondown (Object sender, mousebuttoneventargs E)
{
Dragstart = getposition (sender, e );
}

Privatevoid image_mousemove (Object sender, mouseeventargs E)
{
If (E. leftbutton! = Mousebuttonstate. Pressed ))
{
Return;
}

VaR current = getposition (sender, e );
VaR offset = Current-dragstart;

VaR matrix = transform. matrix;
Matrix. Translate (offset. X, offset. y );

Transform. Matrix = matrix;

Dragstart = current;
}

Point getposition (Object sender, mouseeventargs E)
{
Return e. getposition (sender asuielement) * transform. matrix;
}

This example is not complex and does not reflect the superiority of matrix transformation, but it is evident. In the original text, the translation and scaling transformations are used for superposition. Therefore, these two transformations affect each other. The offset must be considered during translation, adjust the corresponding parameters for correction. Matrix transformation is much simpler. You only need to multiply the transformation matrix and the original transformation matrix to obtain the superposition effect.

In addition, matrix transformation can also be applied to point, so it is very convenient to implement some additional functions. For example, when we want to obtain the enlarged image at the position of the original image, you only need to take the four points around the screen and multiply the inverse matrix of the period transformation matrix. The rest will not be listed one by one. To implement a complete image viewer, matrix transformation is much more convenient than the combination of translation transformation and zoom transformation.

 

Matrix Transformation Animation

In WPF, the transformation process can be easily changed to the cool animation effect, but the system does not provide the built-in implementation of matrix transformation of the animation effect. However, this is not difficult to solve. After Google finds that someone has implemented it on Stack Overflow, the original article address is as follows: smooth animation using matrixtransform ?, In order to prevent the headmaster from spreading his love to others, I will repeat it here.

using System.Windows;using System.Windows.Media;using System.Windows.Media.Animation;namespace MapControl{    public class LinearMatrixAnimation : AnimationTimeline    {        public Matrix? From        {            set { SetValue(FromProperty, value);}            get { return (Matrix)GetValue(FromProperty); }        }        public static DependencyProperty FromProperty = DependencyProperty.Register("From", typeof(Matrix?), typeof(LinearMatrixAnimation), new PropertyMetadata(null));        public Matrix? To        {            set { SetValue(ToProperty, value); }            get { return (Matrix)GetValue(ToProperty); }        }        public static DependencyProperty ToProperty = DependencyProperty.Register("To", typeof(Matrix?), typeof(LinearMatrixAnimation), new PropertyMetadata(null));        public LinearMatrixAnimation()        {                    }        public LinearMatrixAnimation(Matrix from, Matrix to, Duration duration)        {            Duration = duration;            From = from;            To = to;        }        public override object GetCurrentValue(object defaultOriginValue, object defaultDestinationValue, AnimationClock animationClock)        {            if (animationClock.CurrentProgress == null)            {                return null;            }            double progress = animationClock.CurrentProgress.Value;            Matrix from = From ?? (Matrix)defaultOriginValue;            if (To.HasValue)            {                Matrix to = To.Value;                Matrix newMatrix = new Matrix(((to.M11 - from.M11) * progress)+from.M11, 0, 0, ((to.M22 - from.M22) * progress)+from.M22,                                              ((to.OffsetX - from.OffsetX) * progress) + from.OffsetX, ((to.OffsetY - from.OffsetY) * progress)+ from.OffsetY);                return newMatrix;            }            return Matrix.Identity;        }        protected override System.Windows.Freezable CreateInstanceCore()        {            return new LinearMatrixAnimation();        }        public override System.Type  TargetPropertyType        {            get { return typeof(Matrix); }        }    }}
View code

 

Matrix Transformation of two-dimensional graphics (iii) -- applying matrix transformation in WPF

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.