You are here

Constructing Mathlets Quickly using LiveGraphics3D - Intersectiong Objects

Jonathan Rogness and Martin Kraus

As discussed in the previous section, LiveGraphics3D employs the very simple "painter's algorithm" to render primitives. Unfortunately, this algorithm will often fail to produce correct occlusions, especially for intersecting objects. In this section we discuss some typical problems and common solutions.

In order to illustrate the problem for a line intersecting a polygon, consider a line segment between two user-specified points {x0,y0,z0} and {x1,y1,z1} and a polygon in the plane z = 0defined by the points {0,0,0}, {1,0,0}, {1,1,0}, and {0,1,0}. Here is a mathlet that visualizes the scene:

Resulting Applet:

By rotating the scene and/or dragging the points defining the line, you can convince yourself that either the polygon will occlude the line or the line will occlude the polygon. If the line intersects the polygon, this will result in an incorrect image.

One very simple solution to this kind of problem is to only render the outline of the polygon. By using four Line primitives (instead of one) and also coloring them in the same way as the user-specified line, almost all incorrect occlusions are avoided:

Resulting Applet:

While this approach is often suitable, a better solution is required in many cases. In general, most other solutions are based on avoiding intersections by splitting primitives at intersection points. In our example, the line segment from {x0,y0,z0} to {x1,y1,z1} should be split into two parts, say from {x0,y0,z0} to {x2,y2,z2} and from {x2,y2,z2} to {x1,y1,z1}. All we need to do is to compute the intersection point {x2,y2,z2} of the line with the plane z=0. This is rather straightforward and implemented with the help of dependent variables in the example below. But wait a moment! What if the line segment does not intersect the plane z=0 at all, i.e., if z0 and z1 are both either smaller than 0 or greater than 0? In this case we should actually not split the original line. There are multiple ways to handle this case. In the example below, we simply set the coordinates of the intersection point to {x0,y0,z0} in case the line does not intersect the plane at z=0. Thus, the line segment between {x0,y0,z0} to {x2,y2,z2} will collapse to the single point {x0,y0,z0} and we don't need to worry about it.

Resulting Applet:

This approach effectively avoids intersecting objects; however, it does not guarantee correct occlusions: By placing one of the points close to the polygon, you can easily generate an incorrect rendering. However, for many applications this way of splitting lines generates acceptable results.

If you have a closer look at the code above, you might realize that the computation of x2 and y2 includes a division by the difference between two user-specified coordinates, which might result in a division by zero. Do we have to take care of this problem? And what about square roots of potentially negative numbers?

In general, you don't need to care about these cases: whenever a division by zero occurs or the result of any function is not defined in the real domain, LiveGraphics3D will reject the last user input and revert to the last valid configuration. The only exception is the configuration defined by the initial values of the independent variables: if any expression cannot be evaluated for these values, LiveGraphics3D will reject the input and abort the execution. Note that no user action is involved in this case; thus, it is usually easily checked by starting a mathlet.

If it is not possible (or not worth the effort) to compute the intersection between a line and a surface, you can still try to split the line primitive into a set of smaller line primitives. These are more likely to be sorted correctly. Moreover, if an occlusion error does occur, it will be with smaller primitives, and the error will not be as noticeable.

Apart from the intersection of lines with polygons, polygons intersecting other polygons will also cause occlusion errors. For an example, consider the following mathlet:

Resulting Applet:

In order to avoid these unpleasant occlusion errors, you will usually have to split the polygons at the line of intersection:

Resulting Applet:

Unfortunately, the computation of intersections between polygons tends to be rather complicated. Thus, we can only recommend this approach for static objects, and not parametrized graphics. Moreover, you should consider computing these intersections with the help of other programming tools. If you have access to Mathematica, you could use the free package LiveGraphics3D.mwhich is linked from the documentation of LiveGraphics3D (Kraus). This package was employed to split intersecting polygons for many of the mathlets that are part of the online encyclopedia MathWorld (Weisstein).

Jonathan Rogness and Martin Kraus, "Constructing Mathlets Quickly using LiveGraphics3D - Intersectiong Objects," Loci (May 2006)


Journal of Online Mathematics and its Applications