Draw surface normals on a 3D model using WPF and XAML

surface normals

This example shows how to draw surface normals. It uses the following code to create a MeshGeometry3D object holding segments showing surface normals for an existing MeshGeometry3D object.

// Return a MeshGeometry3D for 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 Draw improved 3D line segments using WPF and C# 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.


Download Example   Follow me on Twitter   RSS feed   Donate




This entry was posted in algorithms, drawing, geometry, graphics, mathematics, wpf, XAML and tagged , , , , , , , , , , , , , , , , , , , , , , , , , . Bookmark the permalink.

4 Responses to Draw surface normals on a 3D model using WPF and XAML

  1. Draw triangle vertex normals on a 3D model using WPF and XAML

    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]; …

  2. Pingback: Draw triangle vertex normals on a 3D model

  3. Ramesh says:

    scale vector, add segment does not occur in the current context? this is the error iam getting help me out

    • RodStephens says:

      I’m not sure exactly what you mean.

      Did you download the example program? If you just try to copy and paste the code shown on this page, there will be pieces missing so it probably won’t work.

      Try downloading the example by clicking the Download button and see if that works.

Leave a Reply

Your email address will not be published. Required fields are marked *