This example uses the techniques described in the post Draw improved 3D line segments using WPF and C# to draw 3D arrows.

The following code shows the `AddArrow` extension method that adds an arrow to a `MeshGeometry3D` object.

// Make an arrow. public static void AddArrow(this MeshGeometry3D mesh, Point3D point1, Point3D point2, Vector3D up, double barb_length) { // Make the shaft. AddSegment(mesh, point1, point2, 0.05, true); // Get a unit vector in the direction of the segment. Vector3D v = point2 - point1; v.Normalize(); // Get a perpendicular unit vector in the arrowhead's plane. Vector3D perp = Vector3D.CrossProduct(v, up); perp.Normalize(); // Calculate the arrowhead end points. Vector3D v1 = ScaleVector(-v + perp, barb_length); Vector3D v2 = ScaleVector(-v - perp, barb_length); // Draw the arrowhead. AddSegment(mesh, point2, point2 + v1, up, 0.05); AddSegment(mesh, point2, point2 + v2, up, 0.05); }

The method first calls `AddSegment` to create the arrow’s shaft.

The “up” vector indicates a direction perpendicular to the plane in which the arrow’s head should lie. The method uses `Vector3D.CrossProduct` to get a vector in that plane. It then adds and subtracts combinations of the vector in that plane and the shaft direction’s unit vector to find new vectors pointing in the directions of the arrowhead’s sides.

The picture on the right shows the vector math that builds the arrowhead’s sides. The red segment on the top shows the arrow’s shaft. The black vector `v` is a unit vector in the direction of the shaft. The black vector `perp` is the vector perpendicular to the shaft and the “up” vector.

On the lower left, the blue arrow shows the result of the vector equation `-v + perp`. On the lower right, the green arrow shows the result of the vector equation `-v - perp`. The program scales those vectors to the desired length and then adds them to the shaft’s end point to create the arrowhead’s barb segments.

The following code shows how the main program makes its X axis arrow. It makes the other axis arrows similarly.

// X = Red. MeshGeometry3D x_arrow_mesh = new MeshGeometry3D(); x_arrow_mesh.AddArrow(origin, new Point3D(arrow_length, 0, 0), new Vector3D(0, 1, 0), arrowhead_length); DiffuseMaterial x_arrow_material = new DiffuseMaterial(Brushes.Red); XArrowModel = new GeometryModel3D(x_arrow_mesh, x_arrow_material); model_group.Children.Add(XArrowModel);

This code creates a new `MeshGeometry3D` object. It calls the mesh’s `AddArrow` extension method, creates a red material for it, and uses the mesh and material to create a `GeometryModel3D` object. Finally it adds the model to the main model group’s `Children` collection.

Download the example to see additional details.