BLOG.CSHARPHELPER.COM: Draw triangle surface normals on a 3D model using WPF and XAML
Draw triangle surface normals on a 3D model using WPF and XAML
The example Draw a 3D wireframe model for a MeshGeometry3D using WPF and XAML shows how to draw a surface and a wireframe. This example adds surface normals to that program. It uses the following code to create a MeshGeometry3D object holding segments showing surface normals for an existing MeshGeometry3D object.
// Return a MeshGeometry3D representing this mesh's triangle normals.
public static MeshGeometry3D ToTriangleNormals(this MeshGeometry3D mesh,
double length, double thickness)
{
// Make a mesh to hold the normals.
MeshGeometry3D normals = new MeshGeometry3D();
// Loop through the mesh's triangles.
for (int triangle = 0; triangle < mesh.TriangleIndices.Count; triangle += 3)
{
// Get the triangle's vertices.
Point3D point1 = mesh.Positions[mesh.TriangleIndices[triangle]];
Point3D point2 = mesh.Positions[mesh.TriangleIndices[triangle + 1]];
Point3D point3 = mesh.Positions[mesh.TriangleIndices[triangle + 2]];
// Make the triangle's normal
AddTriangleNormal(mesh, normals,
point1, point2, point3, length, thickness);
}
return normals;
}
The method simply creates a MeshGeometry3D object and then loops through the original mesh's triangles calling the following AddTriangleNormal method for each.
// Add a segment representing the triangle's normal to the normals mesh.
private static void AddTriangleNormal(MeshGeometry3D mesh,
MeshGeometry3D normals, Point3D point1, Point3D point2, Point3D point3,
double length, double thickness)
{
// Get the triangle's normal.
Vector3D n = FindTriangleNormal(point1, point2, point3);
// Set the length.
n = ScaleVector(n, length);
// Find the center of the triangle.
Point3D endpoint1 = new Point3D(
(point1.X + point2.X + point3.X) / 3.0,
(point1.Y + point2.Y + point3.Y) / 3.0,
(point1.Z + point2.Z + point3.Z) / 3.0);
// Find the segment's other end point.
Point3D endpoint2 = endpoint1 + n;
// Create the segment.
AddSegment(normals, endpoint1, endpoint2, thickness);
}
This method calls the FindTriangleNormal method described shortly to find a vector normal to the triangle's surface. It averages the triangle's corners to find its "center." (There are other definitions of a triangle's center, but this is easy and probably good enough.) It then adds the normal vector to the "center" to get the other end point for the normal segment. Finally it calls AddSegment to add a segment showing the normal. (See earlier posts for information about the AddSegment method.)
The following code shows the FindTriangleNormal method.
// Calculate a triangle's normal vector.
public static Vector3D FindTriangleNormal(Point3D point1, Point3D point2, Point3D point3)
{
// Get two edge vectors.
Vector3D v1 = point2 - point1;
Vector3D v2 = point3 - point2;
// Get the cross product.
Vector3D n = Vector3D.CrossProduct(v1, v2);
// Normalize.
n.Normalize();
return n;
}
This method creates vectors representing the triangle's first and second edges. It then uses Vector3D.CrossProduct to find a vector perpendicular to the two edge vectors. If the triangle is outwardly oriented, then the vector points in the outward direction.
Download the example for additional details.
4/14/2014 4:24 PM
BLOG.CSHARPHELPER.COM wrote:
The example Draw triangle surface normals on a 3D model using WPF and XAML shows how to draw a surface, wireframe, and triangle surface normals. This example adds vertex normals to that program. It uses the following code to create a MeshGeometry3D object holding segments showing vertex normals for an existing MeshGeometry3D object. // Return a MeshGeometry3D representing this mesh's triangle normals. public static MeshGeometry3D ToVertexNormals(this MeshGeometry3D mesh, double length, double thickness) { // Copy existing vertex normals. Vector3D[] vertex_normals = new Vector3D[mesh.Positions.Count]; ...
Comments