Cubit The original goal of this project was to visually represent a four-dimensional surface simultaneously in three dimensions (not just a slice at a time). Also, the first application envisioned for such an engine was the representation of a solution of the three-dimensional wave equation. The project has gone in several different directions since then, but in the end it came back to exactly the original conception. Cubit represents a four dimensional surface in three dimensions by assigning every point in a certain region of space a color. Yellow represents a positive value and blue represents a negative value. The intensity of the color corresponds to the magnitude of the value at that point. Normally, this wouldn't do much good, as one could only see the outer layer of a completely filled three-dimensional space. This design relies heavily, though, on transparency through the use of gl's alpha channel. The values close to zero are not only less intense, but are actually less substantial. Even with such a system., in a volume filled largely with values of high magnitude, it can become difficult to see very deeply into the volume. For this reason, two parameters were incorporated to filter out unwanted clutter. One parameter alters the system so that the intensity of a point is not linearly determined from its value, but is instead determined from a variable exponential function. This has the effect of picking out only values nearer the allowed extremes of values, filtering out small disturbances. The other parameter determines the maximum opacity of any point. If this value is reduced, even the extreme values will remain translucent, allowing one to see more of the volume. Unfortunately, neither of these filtering abilities prove useful with the wave equation, but the ability is there. The main difficulty with this program was in generating an efficient back-to-front drawing algorithm for the object. Normally this is unnecessary in gl, as it implements z-buffering, which is designed to eliminate conflicts about polygon drawing order. With translucent objects, however, drawing order is still important. The first algorithm implemented started drawing from the farthest corner of the cube and used an algorithm that drew sets of three component squares (the smallest division in the object) until it reached the near corner. This method worked well in an orthographic view, but in perspective the algorithm could break down and generate blatantly incorrect images. The final algorithm still starts drawing from the farthest vertex, but it uses an entirely different approach. From the current transformation matrix, it determines the plane whose normal vector is most closely parallel to the viewer's line of sight (i.e. the plane that looks flattest to the viewer) and draws the entire backmost panel (a panel is the size of an entire face of the object) parallel to that plane. It the determines the second flattest plane and draws a strip of that back plane (a strip is as long as a panel but only one square wide) along one of the edges of the panel it's drawn. It then fills in squares oriented in the third (least flat) plane along strip so that one side of each square is against the strip and one against the panel. When this is done, it lays another strip against the first panel, against a third side of the squares. When the entire panel is covered in strips and squares, a new panel is drawn on top of the completed layer. This continues until the entire cube is drawn. This algorithm doesn't draw in the front faces, though, so those are done as a special case afterwards. This algorithm works fine for solids of arbitrary dimensions, which are supported by the program. That is another feature of the program that is unused, though. The executables all use nine by nine by nine cubes. The algorithm still isn't perfect, though. It draws some squares in the wrong order under a very few orientations in perspective. Fortunately, they are minor errors and only occur with squares that are almost transparent due to orientation anyway. It's very difficult to notice them even while specifically looking for them in a worst-case situation. The algorithm also works very adequately for speed. The nine by nine by nine cube used in the executables consists of slightly over three thousand polygons. The program only gets around nine frames per second at the initial distance, but the vast majority of the time is spent in the actual rendering. Actually, the speed of the program was improved by ten to twenty percent by turning off z-buffering (since the program draws back to front anyway); The program supports any initial set of values in the volume. Unfortunately, there wasn't time to implement this interactively. It can only be changed in the source code and then executed after recompiling. The approximation of the three-dimensional wave equation is implemented essentially as cellular automata. Each point determines its next value based on its current value, its past value, and the values of its neighbors in a manner derived from an incremental derivative approximation applied to the three-dimensional wave equation. The finishing touch feature is a set of rays radiating from the near and far vertices (near radiates yellow and far radiates blue) to help the viewer follow the motion of the cube (it can be confusing with some wave patterns).