Make a truncated cube in WPF and C#

[truncated cube]

Sorry but this is a pretty long post with a lot of details. If you don’t want to read about how the example program does its tricks, you can just read the first section and look at the pretty pictures.

Archimedean Solids

A platonic solid is a polyhedron where every face is congruent and each vertex is shared by the same number of faces. (See posts such as Easily draw platonic solids in WPF and C# for information about drawing them in WPF and C#.)

An archimedean solid has two or more types of faces, every edge has the same length, and each vertex has the same arrangement of faces. For more information on archimedean solids, see Wolfram Mathworld and Wikipedia.

[truncated cube]
One way to create some of the archimedean solids is to truncate a platonic solid. In other words, take a platonic solid and slice its corners off.

To see how you can do this for a cube, take a look at Figure 1. When you slice a corner off, two things happen. First, you get the new face shown in blue in Figure 1. That face’s shape depends on the arrangement of the original faces at the vertex. For a cube, the vertex is shared by 3 faces so the resulting new (blue) face has 3 sides and thus is a triangle.



[truncated cube]
The second thing that happens when you chop off a vertex is you replace a corner with a new segment in the vertex’s faces. Figure 2 shows a cube face after you slice off all four of its vertices. The result is shown in green in Figure 2.

Cutting the vertices off of a face adds one new side per vertex. Because a polygon has the same number of vertices as sides, that doubles the number of the polygon’s sides, in this case from 4 to 8.



[truncated cube]
The exception to that rule is if you chop off so much of the face that new edges touch and remove the existing edges as shown in Figure 3.



[truncated cube]
I decided to make this program specify the amount of the edge that is chopped off as a fraction of the initial edge length. In Figure 4 the value frac is the fraction of the side length that should be removed. If frac is 0, the solid is unchanged. If frac is 0.5, the new edges remove the old ones as shown in Figure 3. If frac is between 0 and 0.5, you get faces with double their original number of edges.

The Example

The example program uses a lot of new code, much of it contained in the ArchimedeanSolids class. The code is pretty long so here I’m only going to describe the main pieces at a high level.

The two results you get from chopping off the vertices give you two kinds of new faces: faces that replace the vertices (blue in Figure 1) and modified original faces (green in Figure 2). The ArchimedeanSolids class defines two methods to create meshes holding those faces: MakeTruncatedSolidCornerMesh and MakeTruncatedSolidFaceMesh.

MakeTruncatedSolidCornerMesh

This method makes the new faces created by chopping off the vertices (blue in Figure 1). To do that, the method follows these steps:

[truncated cube]

  • For each vertex, follow these steps to make the new face for the vertex:
    1. Loop through all of the solid’s faces and find those that contain the vertex. For each of those faces:
      1. Find the vertex in the face’s polygon.
      2. Find the two corners that are adjacent to the vertex in the polygon. In Figure 5, the target vertex is V and the adjacent corners are A and B.
      3. Multiply the vectors VA and VB by the fraction frac to find the points a and b.
      4. Create an Edge object to represent the new edge ab and add it to a point list.
    2. After you finish looping through the faces, you have a list of edges for the new vertex face. These are the dashed segments shown in Figure 1. Unfortunately they may not be in the correct order. To put the new edges in the correct order:
      1. Take the first edge and:
        1. Save its second end point in variable last_point
        2. Add last_point to a point list.
        3. Remove the edge from the edge list.
      2. Repeat until the edge list is empty:
        1. Find the edge in the edge list where either end point matches last_point.
        2. Set last_point equal to the edge’s other end point.
        3. Add last_point to a point list.
        4. Remove the edge from the edge list.
      3. At this point the point list contains the points that define the new vertex face (blue in Figure 1) in a valid order. Unfortunately the points may be ordered so the polygon they define is not outwardly oriented. To fix that:
        1. Let v01 be the vector from point 0 to point 1 in the point list.
        2. Let v12 be the vector from point 1 to point 2 in the point list.
        3. Take the cross product v01×v12 and save the result in vector cross.
        4. Let vOutside be the vector from the point list’s first point to the vertex V we just removed from the original solid (vertex V in Figure 5).
        5. If the polygon is outwardly oriented, then cross and vOutside should point in the same general direction. To see if that is true, take their dot product. If the result is less than 0, then the polygon is inwardly oriented. To fix that, simply reverse the order of the polygon’s points. (Yes, this is a fairly long test but at least the fix is easy.)

When you’re done, you have a polygon representing each of the new vertex faces so you can add them to a 3D mesh.

MakeTruncatedSolidFaceMesh

This method makes new faces representing the original faces modified by chopping off the vertices (green in Figure 2). To do that, the method follows these steps:

  • For each of the original solid’s faces:
    1. Loop through the face’s edges. For each edge:
      1. Find the points frac and 1 - frac of the way through the edge.
      2. Add those points to an output point list. (If frac is 0.5, those will be the same point so only add one copy to the list.)
    2. After you finish looping through the face’s edges, the point list contains the new face’s corners.

This is a lot simpler than the MakeTruncatedSolidCornerMesh method.

Picking frac

[truncated cube]
Any value for frac where 0.0 < frac ≤ 0.5 will give you a truncated cube. To be an archimedean solid, all of the result’s edges should have the same length.

If frac is 0.5, you get the solid shown in Figure 6. The green square faces are the remnants of the original cube’s sides and the green triangles have replaced the original cube’s corners.

By symmetry it’s pretty easy to see that all of the green faces are squares and that they are congruent. Because the blue triangles share edges with the squares, all of the solid’s edges must have the same lengths so this is an archimedean solid.



[truncated cube]
Other values of frac produce solids that are not archimedean. For example, the solid shown in Figure 7 was built with frac = 0.2. You can easily see the remnants of the original cube in the green faces. You can also easily see that the edges of the blue triangles are shorter than the longer edges of the green octagons.

If you make frac bigger, the edges of the triangles grow longer and the other octagon edges grow shorter. At some point, they will have the same length.



[truncated cube]
To see what magic value of frac makes all of the edge lengths the same, take a look at Figure 8. Assume the original cube’s side length is S and the amount A is removed from each side of the edges. In that case, the remaining octagon has sides with two lengths: A - 2A and [truncated cube]. If all of the edges are going to have the same length, then those two values must be equal so:


[truncated cube]

The value A equals S·frac. If you substitute S·frac for A and rearrange a bit, you can solve for frac to get:


[truncated cube]



[truncated cube]
Figure 9 shows the resulting solid. If you look closely, you can see that the green octagons look like their side lengths are all the same. (If you run the program and rotate so you’re looking squarely at an octagon, you can measure the side lengths and see that they are really the same. The example program also contains code that checks this mathematically.)

Conclusion

So there are two values for frac that give an archimedean solid:


[truncated cube]

In later posts I’ll show how you can truncate the other platonic solids to create archimedean solids.


Download Example   Follow me on Twitter   RSS feed   Donate




About RodStephens

Rod Stephens is a software consultant and author who has written more than 30 books and 250 magazine articles covering C#, Visual Basic, Visual Basic for Applications, Delphi, and Java.

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

One Response to Make a truncated cube in WPF and C#

  1. Pingback: Make truncated tetrahedrons, octahedrons, and icosahedrons in WPF and C# - C# HelperC# Helper

Leave a Reply

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