当前位置:首页 > Windows程序 > 正文

Flipping elements with WPF

2021-03-28 Windows程序

Have you already seen ForgottenTime’s new flip animation eye candy? If not, it’s about time! It took me several days to figure out how to do it…

My first thought was to find out how to do a 4-point-tranformation of a given image. (See figure on the left.) It’s no problem to create an “screenshot” of a UI element and I could easily calculate the four vertices of the transformed image (with given angle and a little bit trigonometry) and transform the original screenshot via the function to achieve a 3D effect. Unfortunately, there’s no (easy and fast) way to do that in C# and Windows Presentation Framework, so I had to think of something else.

After my research on the Internet I came across some official demo WPF applications, also using advanced UI techniques such as flipping. So I dug into the code to find out how they did it. As it turned out, they were using 3D graphics.

WELCOME TO THE 3RD DIMENSION

Strictly speaking a computer screen cannot display real 3D graphics of course, only projections of a 3D space onto a plane… the screen. It’s also called a “viewport”, a 2D window, that allows the user to gaze into the imaginary 3D space behind. Just like we have eyes, a viewport needs a “camera” (to be really precise, a PerspectiveCamera).

Let’s assume the image we want to flip is a square with the dimensions 129×129.

<!-- XAML code --> <Viewport3D x:Name="viewport3D"> <Viewport3D.Resources> </Viewport3D.Resources> <Viewport3D.Camera> <PerspectiveCamera x:Name="cam3D" FieldOfView="45" LookDirection="0,0,-1 " UpDirection="0,1,0" /> </Viewport3D.Camera> </Viewport3D>

After the window is loaded, we create a two-dimensional object, a square, which represents our image in 3D space and calculate where our camera should be. If all that is done, we can literally rotate the object around the y-axis and thus flip the image around.

THE TWO-DIMENSIONAL OBJECT

Every object in our 3D space is made of triangles. The triangle surface of such an object is called a mesh. It’s relatively easy to build a square out of two triangles as the sketch below shows.

We center the image around the origin, so that the camera can be easily positioned on the z-axis. To create such a simple object (notice this is two-dimensional!) you have to write tons of code:

// C# code GeometryModel3D model3D; private void BuildModel() { // Customize the brushes // Can be any brush (ImageBrush, DrawingBrush, VisualBrush, ...) ImageBrush front = new ImageBrush(this.frontImageSource); ImageBrush back = new ImageBrush(this.backImageSource); back.Transform = new ScaleTransform(-1, 1, .5, 0); // Flip back image // Create mesh MeshGeometry3D mesh = new MeshGeometry3D(); double radius = 129 / 2.0; // 64.5 mesh.Positions.Add(new Point3D(-radius, -radius, 0)); mesh.Positions.Add(new Point3D(radius, -radius, 0)); mesh.Positions.Add(new Point3D(radius, radius, 0)); mesh.Positions.Add(new Point3D(-radius, radius, 0)); mesh.TriangleIndices.Add(0); mesh.TriangleIndices.Add(1); mesh.TriangleIndices.Add(2); mesh.TriangleIndices.Add(0); mesh.TriangleIndices.Add(2); mesh.TriangleIndices.Add(3); mesh.TextureCoordinates.Add(new Point(0, 1)); mesh.TextureCoordinates.Add(new Point(1, 1)); mesh.TextureCoordinates.Add(new Point(1, 0)); mesh.TextureCoordinates.Add(new Point(0, 0)); // Add texture DiffuseMaterial frontMat = new DiffuseMaterial(front); DiffuseMaterial backMat = new DiffuseMaterial(back); frontMat.AmbientColor = backMat.AmbientColor = Colors.White; model3D = new GeometryModel3D(); model3D.Geometry = mesh; model3D.Material = frontMat; model3D.BackMaterial = backMat; Model3DGroup group = new Model3DGroup(); group.Children.Add(model3D); group.Children.Add(new AmbientLight(Colors.White)); ModelVisual3D visual = new ModelVisual3D(); visual.Content = group; viewport3D.Children.Add(visual); } THE CAMERA POSITION

The camera has to be some distance away from the square, so that everything is within the camera’s field of view. Especially when the image is rotated by 90? around the y-axis, where it’s nearest to the camera. So how do we calculate the distance?

The sketch above shows the image which has already been rotated by 90?. Let’s first look at the left side of the sketch. As we can see the camera is positioned 

技术分享

. We’re going to calculate x using tangent.

温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/68838.html