### IGraphic Hierarchies and Groups

Class architecture shows that IGraphicGroup derives from IGraphicHierarchy, which derives from IMGraphic.

IGraphicGroup provides a concrete implementation of iterating its children. The IGraphicIterator created iterates only one level. If you need to iterate more than one level deep, create iterators on subsequent IGraphicGroups.

### IGraphicHierarchy

IGraphicHierarchy is an abstract base class that defines a hierarchy protocol for graphics that are grouped together into a graphic conglomerate.

You can create groups or hierarchies to descend from the base class IGraphicHierarchy for making available the iterator polymorphically.

The 2D Graphics framework provides a concrete subclass of IGraphicHierarchy, IGraphicGroup, which allows creation of trees of graphics to allow manipulation of a conglomerate group.

### IGraphicGroup

IGraphicGroup is a concrete class, derived from IGraphicHierarchy, that implements a group of graphics as a tree structure. It allows you to combine 2D graphics into a unit that is treated as a whole. IGraphicGroup inherits directly from IMGraphic and thus each of the nodes owns its own IGrafBundle and can thus affect its own side of the hierarchy.

IGraphicGroup, as an IMGraphic subclass, references other IMGraphic objects. Although all manipulative behavior of complex IMGraphics is similar to simple IMGraphics, unlike the previous types, these objects do not completely encapsulate IMGraphic objects they refer to. IGraphicGroup descends from the abstract base class IGraphicHierarchy which makes available polymorphically the methods to create iterators for traversing groups.

IGraphicGroup does not provide support for DAGs (Directed Acyclic Graphics).

IGraphicGroup does not allow its children to have more than one parent in a team. (IGraphicGroup does no checks for this you must check for multiple references).

The destructor of IGraphicGroup destroys itself and all its children.

### IGraphicGroup Relationships

IGraphicGroup creates a collection of IMGraphic objects forming a group. Each of the IMGraphic objects can be an IGraphicGroup itself, so one can create a hierarchy of objects. The figure shows an example of a hierarchy created by IGraphicGroup to create the image of a simplified bicycle:

In the figure, the elements have the following relationships:

- A, B and C are IGraphicGroups.
- D, E, F and G are different simple IMGraphics encapsulating more than one geometry.
- A has references to the following elements:
  - B, the rear wheel
  - C, the front wheel
  - F, the body of the bike
- B refers to D.
- C refers to the IMGraphics G and E.

Groups B and C control the transformations associated to the rear and the front wheel respectively. The two wheel are represented by the primitive geometries D and G. E represents the handle-bar of the bike. Thus moving node C moves both the front wheel and the handle-bar. Moving node A moves the entire bike.

While applying transformation matrix to the children at the time of rendering, the group creates a temporary IGrafPort object and concatenates its matrix with that stored in the IGrafPort. This new IGrafPort renders its children and is destroyed once the child is completely rendered. The IGrafPort objects are created on the stack.

### IGraphicGroup Attribute and Transformation Hierarchy

Each IGraphicGroup, if it so chooses, defines its own attributes and transformation. By default the attribute bundle is NIL and the transformation matrix is set to identity. As IGraphicGroup is a complex IMGraphic, it has references to other IMGraphics, its children. By definition, each of the child must inherit the attribute traits and transformations of its parent. However, since each child can be multiply referenced, it inherits these by concatenating the parents information, without modifying its own at the time of rendering. The concatenation of these attributes is achieved at the time of the draw call.

Both the attribute and the matrix are concatenated with the IGrafPort object which is passed as a parameter to the draw call.

The IGraphicGroup constructors let you instantiate a group with an attribute bundle. There is a default constructor.

> IGraphicGroup(IGrafBundle* adoptedBundle);

In addition, each graphic adopted into a group can have its own attribute bundle. The attribute bundle of the graphic overrides the attribute bundle for the group into which the graphic is adopted.

In the bicycle example described in IGraphicGroup relationships, attributes and transformations of object A (body of bike) are concatenated with the IGrafPort object passed to A (as a parameter to the member function draw) and a new IGrafPort object, APortObject, is created on the stack. APortObject is passed to object C which concatenates its state and creates a new port object, CPortObject. This new CPortObject is passed to object E to be rendered. Object E concatenates its state with CPortObject and renders itself using this new state.

Matrix concatenation is simple post concatenation of the parent's matrix with that of the child. Thus, the matrix used to render object E is:

( E's Matrix ) * ( C's Matrix ) * ( A's Matrix )

In the wagon example, described in Complex IMGraphic, the wagon group has no attribute bundle so it has a default bundle. When the wagon body is adopted into the wagon group, it has a bundle that specifies fill and frame attributes that override the default bundle of the wagon group. When the wagon wheels are adopted into the wagon group, they also have attribute bundles that specify fill and frame attributes that override the default bundle of the wagon group. Because the wagon body and wagon wheel groups are at the same level in the hierarchy, their bundles have no affect on each other.

To transform the entire group, apply a transformation to the top-most graphic in the hierarchy. To transform only a part of the entire group, apply a transformation to the appropriate nested group. You can, of course, always transform any graphic before you adopt it into its group.

In the wagon example, a translation is applied to the wagon group to make the wagon body and four wheels move a specified distance. A rotation is applied to each wheel group so that the wheels rotate in addition to the translation.

The transformation matrix of the parent is post-concatenated with the matrix of the child. For example, the transformation and rotation matrix for the wagon wheels is found by multiplying the wagon group transformation matrix by the wagon wheel rotation matrix as follows:

( ( wagon wheel rotation matrix ) * ( wagon group translation matrix ) )

IGraphic Hierarchy and Group Iteration

Complex IMGraphic