[C# Helper]
Index Books FAQ Contact About Rod
[Essential Algorithms, Second Edition]

[The Modern C# Challenge]

[WPF 3d, Three-Dimensional Graphics with WPF and C#]

[The C# Helper Top 100]

[Interview Puzzles Dissected]

[C# 24-Hour Trainer]

[Beginning Software Engineering]

[C# 5.0 Programmer's Reference]

[MCSD Certification Toolkit (Exam 70-483): Programming in C#]

Title: Use WPF 3d techniques to draw a snowman with WPF and C#

[Use WPF 3d techniques to draw a snowman with WPF and C#]

This example shows how to use the tools and techniques described in my book WPF 3d, Three-Dimensional Graphics with WPF and C# to draw a three-dimensional snowman. I won't go into all of the details because there are a whole book's worth, but here's the code that builds the snowman model.

// Define the model. private void DefineModel() { // Show the axes. // MeshExtensions.AddAxes(MainGroup); // Make the snowman's body. const double bodyR = 2; const double headR = 1.25; MeshGeometry3D bodyMesh = new MeshGeometry3D(); double headY = 0.8 * (headR + bodyR) - 1; MeshExtensions.AddSphere(bodyMesh, new Point3D(0, headY, 0), headR, 40, 20, true); MeshExtensions.AddSphere(bodyMesh, new Point3D(0, -1, 0), bodyR, 40, 20, true); MainGroup.Children.Add(bodyMesh.MakeModel(Brushes.White)); // Nose. const double noseR = 0.2; MeshGeometry3D noseMesh = new MeshGeometry3D(); MeshExtensions.AddSphere(noseMesh, new Point3D(0, headY, 0), noseR, 20, 10, true); MainGroup.Children.Add(noseMesh.MakeModel(Brushes.Orange)); noseMesh.ApplyTransformation(new ScaleTransform3D(1, 1, 3)); noseMesh.ApplyTransformation(new TranslateTransform3D(0, 0, headR)); // Eyes. const double eyeR = 0.15; MeshGeometry3D eyeMesh = new MeshGeometry3D(); MeshExtensions.AddSphere(eyeMesh, new Point3D(0.4, 0.4, -0.15), eyeR, 7, 3, false); MeshExtensions.AddSphere(eyeMesh, new Point3D(-0.4, 0.4, -0.15), eyeR, 6, 3, false); MainGroup.Children.Add(eyeMesh.MakeModel(Brushes.Black)); eyeMesh.ApplyTransformation( new TranslateTransform3D(0, headY, headR)); // Buttons. const double buttonR = 0.17; MeshGeometry3D button1Mesh = new MeshGeometry3D(); MeshExtensions.AddSphere(button1Mesh, new Point3D(0, 0, bodyR), buttonR, 7, 3, false); button1Mesh.ApplyTransformation(new TranslateTransform3D(0, -1, 0)); MainGroup.Children.Add(button1Mesh.MakeModel(Brushes.DarkBlue)); MeshGeometry3D button2Mesh = new MeshGeometry3D(); MeshExtensions.AddSphere(button2Mesh, new Point3D(0, 0, bodyR), buttonR, 6, 3, false); Rotation3D rotation2 = new AxisAngleRotation3D(new Vector3D(1, 0, 0), -23); button2Mesh.ApplyTransformation( new RotateTransform3D(rotation2, new Point3D())); button2Mesh.ApplyTransformation(new TranslateTransform3D(0, -1, 0)); MainGroup.Children.Add(button2Mesh.MakeModel(Brushes.DarkBlue)); MeshGeometry3D button3Mesh = new MeshGeometry3D(); MeshExtensions.AddSphere(button3Mesh, new Point3D(0, 0, bodyR), buttonR, 7, 3, false); Rotation3D rotation3 = new AxisAngleRotation3D(new Vector3D(1, 0, 0), -46); button3Mesh.ApplyTransformation( new RotateTransform3D(rotation3, new Point3D())); button3Mesh.ApplyTransformation(new TranslateTransform3D(0, -1, 0)); MainGroup.Children.Add(button3Mesh.MakeModel(Brushes.DarkBlue)); // Hat. MeshGeometry3D hatMesh = new MeshGeometry3D(); const double hatR = 0.8; const double hatL = 1.65; Point3D[] polygon = G3.MakePolygonPoints(20, new Point3D(), new Vector3D(hatR, 0, 0), new Vector3D(0, 0, hatR)); MeshExtensions.AddConeFrustum(hatMesh, new Point3D(0, headY, 0), polygon, new Vector3D(0, -3 * hatL, 0), hatL); // Brim. const double brimR = 1.5 * hatR; Point3D[] brimPolygon = G3.MakePolygonPoints(20, new Point3D(0, -hatL / 2, 0), new Vector3D(brimR, 0, 0), new Vector3D(0, 0, brimR)); MeshExtensions.AddCylinder(hatMesh, brimPolygon, new Vector3D(0, -0.2, 0), true); Rotation3D hatRotation = new AxisAngleRotation3D(new Vector3D(0, 0, 1), -10); hatMesh.ApplyTransformation( new RotateTransform3D(hatRotation, new Point3D())); hatMesh.ApplyTransformation(new TranslateTransform3D(0.5, headY + 2, 0)); MainGroup.Children.Add(hatMesh.MakeModel(Brushes.Green)); }

The basic steps for creating a WPF 3d object are:

  1. Create a mesh to hold a shape's geometry.
  2. Use methods defined by the MeshExtensions and G3 classes to create objects such as spheres, cubes, boxes, polygons, tori, frustums, parametric surfaces, and other shapes and add them to the mesh.
  3. Transform the mesh if desired to translate, rotate, or scale the objects.
  4. Add the mesh to the main object group specifying the color that you want to give the mesh.

This example uses those techniques to create the snowman's two body parts, nose, eyes, buttons, and hat.

[Use WPF 3d techniques to draw a snowman with WPF and C#]

My book WPF 3d includes many other options for working with 3D scenes. For example, it lets you determine whether objects are smoothed. This example makes the snowman's body, nose, and hat smooth, but it makes its eyes and buttons not smooth (so they look a little bit more like coal).

Other techniques described in the book include:

  • The lights, cameras, materials, texture coordinates, and other details that you need to create a 3D scene
  • Orthographic, perspective, and other projections that emphasize different aspects of a scene
  • Special material treatments such as specular reflection, wireframes, and solid and translucent materials
  • Examples of many shapes including flat polygons, boxes, Platonic solids, spheres, tori, cones, and more
  • Advanced objects such as parametric surfaces, surfaces of transformation, fractal surfaces, and 2D and 3D text
  • Higher-level scene management to let users select and move objects
  • Advanced techniques such as loading models created in other applications and using skeletons

Download the example to experiment with it and to see additional details.

© 2009-2022 Rocky Mountain Computer Consulting, Inc. All rights reserved.