2-D Hierarchical Modeling System
Eric Leive, Xiang Lan Zhuo

Functions implemented

Structure operations
  • beginStructure()
  • endStructure()
  • drawStructure()
  • deleteStructure()
  • makeStructData()
  • makeStruct()
  • setGlobalVTM()
  • initGlobalTransform()


Model Structure Data Type

     We used a singly linked list to implement our model structure data type. Each node stores the following informations: operation code (i.e. drawLine, drawCircle, translate2D ... etc), argument type Point_t, argument type int/double, argument type Color_t, pointer to the next node, and pointer to internal structure if there's any. The struct type Structure contains a pointer that points to the first node of each structure. In order to traverse through the list from beginning to end, we used a globally defined variable called GLOBAL_STRUCTURE to keep track of the present working node when a structure is opened. Essentially, a pointer is created when a new structure is defined and this pointer will always points to the head of the list of operations. At the same time, GLOBAL_STRUCTURE is initialized to point to the current empty node. When the next operation is pushed onto the list, GLOBAL_STRUCTURE initializes the next empty Node (GLOBAL_STRUCTURE->data->next) and set it to be current working node. This continues until endStructure() is called. To draw the structure is only a matter of traversing the structure list from it's head.
     In the case where there are drawStructure() calls within a structure, drawing is disabled. Instead, the head of this enclosed structure is stored into the current working node. Therefore, drawStructure() is recursive. And the level of recursion depends on number of enclosed structures within.

Draw Structure Routine

     The drawStructure() routine can be viewed as another operation itself. If it's called within another structure, insteading of drawing the structure right away, a pointer is stored in the current working node that points to the head of the enclosed structure. In order for drawStructure to distinguish the different operations that are stored in the structure list, we defined a list of tokens as type int in our data record. Because GLOBAL_STRUCTURE will always create an empty node when a new operation if stored onto the list without knowing if it's the last one, every structure list ends with an empty node. To traverse the list and perform the stored operation in sequence, we first tested to see if the the next node is NULL. As long as the next node is not NULL, drawing the structure is simply stepping through each operation (which can be easily implemented with a swtich statement testing for opcode of the node).

Viewing Window Transform Matrix

     The Viewing Transformation Matrix (VTM) that gets map to the final image is implemented as a global variable. The VTM gets map to every point in drawStrcture routine as: p' = VTM * GTM * LTM * p.

How To Use Our Modeling System

     Here are the precedures to use our modeling system in main() :
  1. Must initialize global GTM and VTM.
  2. If a different VTM is desired other than the image itself, set new VTM before calling drawStructure using setGlobalVTM().
  3. Set the local transformation matrix (ltm) to an identity matrix.
  4. To create a new structure, first declare a pointer of type Structure. You can then begin recording structure list by *pointer = beginStructure(); .
  5. Within a structure, call primitive functions as you would normally do to create an image.
  6. End recording of structure by endStructure().

Images