📜 ⬆️ ⬇️

Building a torus with WPF

Good evening, Habr.
This article is for beginners, I will talk about drawing simple rotation bodies in the Windows Presentation Foundation. After the semester of graphics programming on OpenGL, or rather glut.h, I decided to spend the evening on getting to know WPF. In this article we will build a torus.

WPF Basics


The main building block in WPF is mesh , I haven’t found a translation of the term into Russian, but I think it can be translated as a triangle segment or just a triangle. The question arises: why a triangle, and not a line?
Suppose we need to build a basic representation of the surface - a plane. As is known from school geometry, a plane is built at at least three points and it is quite logical to make surfaces of triangles.
For example, I removed a few building blocks from the cylinder.
image

With each triangular segment associated characteristics such as the position of its vertices and the normal. Vertices are listed clockwise or against, depending on which of the planes of the triangle (of which there are two) should be visible. Determining the desired order is very simple, just use
right hand rule
Raise the thumb of your right hand, it indicates the side to which you are looking. Put your finger down, you will see the opposite, the position of the other fingers will show the order of the walk.
image

The normal is a vector perpendicular to the plane of the triangle is defined as
vector product of two sides of a triangle
image

Normals are added in the same sequence as vertices.

As a result, each triangular segment has

The origin of the coordinate system when working with 3D graphics is in the center of the scene, in contrast to 2D, where the beginning is in the upper left corner. Displays the graphic contents of the scene class Viewport3D
')
image

Since the representation of 3D objects on the screen is actually two-dimensional projections, you should select the observation point, from which the appearance of the object will depend. In WPF, this point helps to indicate the camera class.

Thor


A torus is a surface of revolution obtained by rotating a circle that forms a circle around an axis lying in the plane of this circle.
image
The torus equations can be represented in parametric and algebraic form, in this case it is more convenient to use
parametric.

x = (R + r * cos (a)) * cos (b)
y = r * sin (a)
z = - (R + r * cos (a)) sin (b)
Thor
image


Encode the torus equation.
This method simply returns a point for given radii and angles:
public Point3D getPositionTor(double R, double r, double a, double v){ double sinB = Math.Sin(B * Math.PI / 180); double cosB = Math.Cos(B * Math.PI / 180); double sinA = Math.Sin(A * Math.PI / 180); double cosA = Math.Cos(A * Math.PI / 180); Point3D point = new Point3D(); point.X = (R + r * cosA) * cosB; point.Y = r * sinA; point.Z = -(R + r * cosA) * sinB; return point; } 


Create a method for constructing a triangular segment
 public static void drawTriangle( Point3D p0, Point3D p1, Point3D p2, Color color, Viewport3D viewport) { MeshGeometry3D mesh = new MeshGeometry3D(); mesh.Positions.Add(p0); mesh.Positions.Add(p1); mesh.Positions.Add(p2); mesh.TriangleIndices.Add(0); mesh.TriangleIndices.Add(1); mesh.TriangleIndices.Add(2); SolidColorBrush brush = new SolidColorBrush(); brush.Color = color; Material material = new DiffuseMaterial(brush); GeometryModel3D geometry = new GeometryModel3D(mesh, material); ModelUIElement3D model = new ModelUIElement3D(); model.Model = geometry; viewport.Children.Add(model); } 


Everything is ready for drawing a torus.
Torus segment
image

We build the segments presented in the figure above, each of which is the union of two triangles built on four vertices.

  public void drawTor(Point3D center, double R, double r, int N, int n, Color color){ if (n < 2 || N < 2){ return; } Model3DGroup tor = new Model3DGroup(); Point3D[,] points = new Point3D[N, n]; for (int i = 0; i < N; i++){ for (int j = 0; j < n; j++){ points[i, j] = getPositionTor(R, r, i * 360/(N - 1), j * 360/(n - 1)); points[i, j] += (Vector3D)center; } } Point3D[] p = new Point3D[4]; for (int i = 0; i < N - 1; i++){ for (int j = 0; j < n - 1; j++){ p[0] = points[i, j]; p[1] = points[i + 1, j]; p[2] = points[i + 1, j + 1]; p[3] = points[i, j + 1]; drawTriangle(p[0], p[1], p[2], color, mainViewport); drawTriangle(p[2], p[3], p[0], color, mainViewport); } } } 


It remains to call the method of drawing a torus
  drawTor(new Point3D(0, 0, 0), 1.0, 0.3, 20, 15, Colors.Tomato, false); 


The graphical user interface is done with XAML very quickly; I’ll only add ViewPort3D
  <Viewport3D Name="mainViewport" ClipToBounds="True" Height="374"> <Viewport3D.Camera> <PerspectiveCamera FarPlaneDistance="100" LookDirection="-11,-10,-9" UpDirection="0,1,0" NearPlaneDistance="1" Position="11,10,9" FieldOfView="70"/> </Viewport3D.Camera> <ModelVisual3D> <ModelVisual3D.Content> <DirectionalLight Color="White" Direction="-2,-3,-1"/> </ModelVisual3D.Content> </ModelVisual3D> </Viewport3D> 


That's what happened in the end:
image
And remove some segments
image

Thanks for attention.

Source: https://habr.com/ru/post/164857/


All Articles