This example extends the example Draw interlocked tetrahedrons in a cage of “line segments” using WPF and C# by using improved 3D line segments. The previous example draws skinny rectangular prisms to represent line segments. If you make the prisms thick enough, you can see that they don’t line up well at their corners. (See the picture on the left side.)

This example uses the following `AddSegment` method to extend the prisms slightly so segments that share an end point overlap by the size of their thickness. That makes them line up nicely. (At least when their prism sides are parallel. See the picture on the right side.) The new code is shown in blue.

private void AddSegment(MeshGeometry3D mesh, Point3D point1, Point3D point2, Vector3D up, bool extend) { const double thickness = 0.25; // Get the segment's vector. Vector3D v = point2 - point1; if (extend) { // Increase the segment's length on both ends // by thickness / 2. Vector3D n = ScaleVector(v, thickness / 2.0); point1 -= n; point2 += n; } // Get the scaled up vector. Vector3D n1 = ScaleVector(up, thickness / 2.0); // Get another scaled perpendicular vector. Vector3D n2 = Vector3D.CrossProduct(v, n1); n2 = ScaleVector(n2, thickness / 2.0); // Make a skinny box. // p1pm means point1 PLUS n1 MINUS n2. Point3D p1pp = point1 + n1 + n2; Point3D p1mp = point1 - n1 + n2; Point3D p1pm = point1 + n1 - n2; Point3D p1mm = point1 - n1 - n2; Point3D p2pp = point2 + n1 + n2; Point3D p2mp = point2 - n1 + n2; Point3D p2pm = point2 + n1 - n2; Point3D p2mm = point2 - n1 - n2; // Sides. AddTriangle(mesh, p1pp, p1mp, p2mp); AddTriangle(mesh, p1pp, p2mp, p2pp); AddTriangle(mesh, p1pp, p2pp, p2pm); AddTriangle(mesh, p1pp, p2pm, p1pm); AddTriangle(mesh, p1pm, p2pm, p2mm); AddTriangle(mesh, p1pm, p2mm, p1mm); AddTriangle(mesh, p1mm, p2mm, p2mp); AddTriangle(mesh, p1mm, p2mp, p1mp); // Ends. AddTriangle(mesh, p1pp, p1pm, p1mm); AddTriangle(mesh, p1pp, p1mm, p1mp); AddTriangle(mesh, p2pp, p2mp, p2mm); AddTriangle(mesh, p2pp, p2mm, p2pm); }

If the extend parameter is `true`, the program creates a vector in the direction of the line segment that has length equal to half of the prism’s width. It then moves the segment’s end points that distance away from each other to extend the segment the correct amount.

The rest of the method is similar to the code used in the previous example.

Use segments to draw arrows in a 3D model using WPF and XAMLThe example Draw improved 3D “line segments” using WPF and XAML showed how to draw thin rectangular boxes to represent three-dimensional line segments. This example uses that technique to draw 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); …

Nice series of WPF 3D articles. You may also consider using EmissiveMaterial for 3D lines – it looks more like a line if the box is not shaded. Note that you need to use MaterialGroup with DiffuseMaterial when you are using EmissiveMaterial to prevent drawing back objects on top of line. For example:

var lineMaterial = new MaterialGroup();

lineMaterial.Children.Add(new DiffuseMaterial(Brushes.Black));

lineMaterial.Children.Add(new EmissiveMaterial(new SolidColorBrush(lineColor)));

Good suggestion!

Pingback: Draw a 3D wireframe using WPF and C# -

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