Introduction to the Figure Package - Coordinate Systems
[Introduction to figPac | figPac API ]
Coordinate Systems
Every Figure and each of its fSubFigures comes equipped with its own coordinate system.
I call the coordinate system of the main figure usr coordinates. This coordinate system is
determined by a function that maps usr coordinates to the coordinates of the computer
screen or printer, that I call dvc coordinates. The name of this function is usr2dvc.
Similarly, the coordinate system of each
fSubFigure, that I call patch coordinates, is determined by a function
patch2parent, that maps patch coordinates to the coordinate system of the
fSubFigure's parent. Typically the fSubFigure will be an element of the main
Figure, in which case the Figure is the parent. Otherwise, the parent will be another
fSubFigure, that containing the current fSubFigure as an element.
Technically, each coordinate map can be any instance of any class that implements the
interface V2V, which stand for "vector to vector".
This interface just requires a method (called map) that takes as input one vector (i.e. a double[] variable)
and provides as output another vector. Usually, coordinate maps will be invertible
and accordingly will implement the interface
invertibleV2V. This interface extends
V2V and requires two methods (called map and invmap) each taking as input one double[] variable
and providing as output another double[] variable. In fact, almost invariably, coordinate maps
will be affine linear transformations. That is, a transformation which maps (x,y) to
(ax+by+c, ux+vy+w). Such transformations are instances of the class
Affine2dV2V, which implements
invertibleV2V. The class Affine2dV2V contains a double[][] variable called matrix and
a second one called invmatrix (which is the matrix for the inverse affine map, when the
inverse exists). The Affine2dV2V method map(in) returns the two component array out,
defined by
out[0] = matrix[0][0]*in[0]+matrix[0][1]*in[1]+matrix[0][2] ;
out[1] = matrix[1][0]*in[0]+matrix[1][1]*in[1]+matrix[1][2] ;
The Affine2dV2V method invmap(in) returns the two component array out,
defined by
out[0] = invmatrix[0][0]*in[0]+invmatrix[0][1]*in[1]+invmatrix[0][2] ;
out[1] = invmatrix[1][0]*in[0]+invmatrix[1][1]*in[1]+invmatrix[1][2] ;
The class Affine2d2V2V also contains methods that replace the affine map with
a new one consisting of the old one composed with a rotation, translation or scaling.
FigPac allows you to change coordinate systems in the middle of drawing a
figure. To keep straight what coordinate system is used for the various parts of the figure,
it is important to remember the sequence of operations that figPac executes each time
the figure is drawn.
- First it initializes the coordinate map usr2dvc by composing baseUsr2dvc
with a map that takes into account the effects of dragging, zooming, margins and
so on.
- Then it initializes the drawing environment by executing the method initEnv().
- Then it executes the drawgfx (or drawps) method of each figure element in turn.
The user may control the initial coordinate system baseUser2dvc (which defaults to a system
having origin at the lower left corner of the figure and using Adobe points as units, that is,
having 72 units to the inch). Here are the statements, and their effects, that can be used to
control the baseUser2dvc of a Figure named, for example, "fig":
- fig.limits(xmin, ymin, xmax, ymax) sets baseUser2dvc to the affine linear map having x=xmin
as the left hand edge of the figure, y=ymin as the bottom of the figure and so on.
- fig.setBaseUsr2dvc(coordmap) sets baseUsr2dvc to the class coordmap, which must implement
the interface V2V.
- fig.rotate(angle) composes baseUser2dvc with a rotation by angle radians.
- fig.scale(xfactor, yfactor) composes baseUser2dvc with a scaling by a factor of xfactor in the
x direction and yfactor in the y direction.
- fig.translate(x, y) composes baseUser2dvc with a translation by x units in the x direction
and y units in the y direction.
In addition you can change usr2dvc in midfigure by inserting figure elements that modify the
coordinate system. For example
- fig.append( new fSetUsr2dvc(coordmap) ) sets usr2dvc to the class coordmap, which must implement
the interface V2V.
- fig.append( new fRotate(angle) ) composes usr2dvc with a rotation by angle radians.
- fig.append( new fScale(xfactor, yfactor) ) composes usr2dvc with a scaling by a factor of xfactor in the
x direction and yfactor in the y direction.
- fig.append( new fTranslate(x, y) ) composes usr2dvc with a translation by x units in the x direction
and y units in the y direction.
Similary, each time FigPac draws a subfigure to the screen or to PostScript, it executes the following
sequence of operations.
- First it initializes the coordinate map patch2dvc (from patch coordinates to device
coordinates) by composing basePatch2parent
with the map parent2dvc, that its parent supplies.
- Then it initializes the drawing environment by appending to the Hashtable env of its parent
its own personal Hashtable env entries.
- Then it executes the drawgfx (or drawps) method of each of its figure elements in turn.
The user may control the initial coordinate system basePatch2parent (which defaults to the
identity map). Here are the statements, and their effects, that can be used to
control the basePatch2parent of an fSubFigure named, for example, "subfig":
- subfig.setBasePatch2parent(coordmap) sets basePatch2parent to the class coordmap, which must implement
the interface V2V.
- subfig.rotate(angle) composes basePatch2parent with a rotation by angle radians.
- subfig.scale(xfactor, yfactor) composes basePatch2parent with a scaling by a factor of xfactor in the
x direction and yfactor in the y direction.
- subfig.translate(x, y) composes basePatch2parent with a translation by x units in the x direction
and y units in the y direction.
In addition you can change patch2dvc in midfigure by inserting figure elements that modify the
coordinate system. For example
- subfig.append( new fSetPatch2parent(coordmap) ) sets patch2dvc to the class coordmap, which must implement
the interface V2V, composed with parent2dvc.
- subfig.append( new fRotate(angle) ) composes patch2dvc with a rotation by angle radians.
- subfig.append( new fScale(xfactor, yfactor) ) composes patch2dvc with a scaling by a factor of xfactor in the
x direction and yfactor in the y direction.
- subfig.append( new fTranslate(x, y) ) composes patch2dvc with a translation by x units in the x direction
and y units in the y direction.
[Introduction to figPac | figPac API ]