Points in xyz space are expressed by vectors of homogeneous coordinates. These vectors are translated, rotated, scaled, and projected onto the two-dimensional drawing surface by multiplying them by transformation matrices. The geometrical transformations used by IDL, and many other graphics packages, are taken from Chapters 7 and 8 of Foley and Van Dam (1982). The reader is urged to consult this book for a detailed description of homogeneous coordinates and transformation matrices since this section presents only an overview.
A point in homogeneous coordinates is represented as a four-element column vector of three coordinates and a scale factor w ¹¹¹ 0. For example:
P(wx, wy, wz, w) º P(x/w, y/w, z/w, 1) º (x, y, z)
One advantage of this approach is that translation, which normally must be expressed as an addition, can be represented as a matrix multiplication. Another advantage is that homogeneous coordinate representations simplify perspective transformations. The notion of rows and columns used by IDL is opposite that of Foley and Van Dam (1982). In IDL, the column subscript is first, while in Foley and Van Dam (1982) the row subscript is first. This changes all row vectors to column vectors and transposes matrices.
The coordinate system is right-handed so that when looking from a positive axis to the origin, a positive rotation is counterclockwise. As usual, the x-axis runs across the display, the y-axis is vertical, and the positive z-axis extends out from the display to the viewer. For example, a 90-degree positive rotation about the z-axis transforms the x-axis to the y-axis.
| Note |
Transformation matrices, which post-multiply a point vector to produce a new point vector, must be (4, 4). A series of transformation matrices can be concatenated into a single matrix by multiplication. If A1, A2, and A3 are transformation matrices to be applied in order, and the matrix A is the product of the three matrices, the following applies.
((P · A1) · A2) · A3 º P · ((A1 · A2) · A3) = P · A
IDL stores the concatenated transformation matrix in the system variable field
Each of the operations of translation, scaling, rotation, and shearing can be represented by a transformation matrix.
The transformation matrix to translate a point by (Dx, Dy, Dz) is shown below.
Scaling by factors of Sx, Sy, and Sz about the x-, y-, and z-axes respectively, is represented by the matrix below.
Rotation about the x-, y-, and z-axes is represented respectively by the following three matrices:
The IDL procedure T3D creates and accumulates transformation matrices, storing them in the system variable field
Set this keyword to reset the transformation matrix to the identity matrix to begin a new accumulation of transformations. If this keyword is not present, the current transformation matrix
This keyword argument accepts a 3-element vector. The viewpoint is translated by the three-element vector [Tx, Ty, Tz].
This keyword argument accepts a 3-element vector. The viewing area is scaled by factor [Sx, Sy, Sz].
This keyword accepts a 3-element vector. The viewing area is rotated about each axis by the amount [qx, qy, qz], in degrees.
A scalar (p) indicating the z distance of the center of the projection in the negative direction. Objects are projected into the xy plane, at z = 0, and the eye is at point (0, 0, -p).
A two-element vector, [d, a], specifying the parameters for an oblique projection. Points are projected onto the xy-plane at z = 0 as follows:
x0 = x + z(d cos a)
y0 = y + z(d sin a)
An oblique projection is a parallel projection in which the normal to the projection plane is the z-axis, and the unit vector (0, 0, 1) is projected to (d cos a, d sin a) where a is expressed in degrees.
If set, exchanges the x- and y-axes.
If set, exchanges the x- and z-axes.
If set, exchanges the y- and z-axes.
The SURFACE procedure creates a transformation matrix from its keyword parameters AX and AZ as follows:
These transformations can be created using T3D as shown below. The SCALE3 procedure, documented in the IDL Reference Guide, mimics the transformation matrix created by SURFACE using the following method:
; Translate to move center of cube to origin. T3D, /RESET, TRANSLATE = [-.5, -.5, -.5] ; Rotate 90 degrees about x-axis, so +z axis is now +y. ; Then rotate AZ degrees about y-axis. T3D, ROTATE = [-90, AZ, 0] ; Rotate AX about x axis: T3D, ROTATE = [AX, 0, 0] ; Restore origin. T3D, TRANSLATE = [0.5, 0.5, 0.5]
The SCALE3 procedure, scales the unit cube by a fixed factor, 1/SQRT(3) to ensure that the corners of the rotated cube fit within the drawing area. If requested, it also will set the data scaling. Animations involving rotations or the SURFACE procedure should have their scaling and viewing transformation set by SCALE3 rather than the obsolete SURFR procedure, so that the scaling does not vary between frames.
To convert from a three-dimensional coordinate to a two-dimensional coordinate, IDL follows these steps:
P¢ = P · !P.T
N¢x = P¢x/P¢w and N¢y = P¢y/P¢w
The CONVERT_COORD function performs the above process when converting to and from coordinate systems when the T3D keyword is specified. For example, if a three-dimensional coordinate system is established, then the device coordinates of the data point (0, 1, 2) can be computed as follows:
D = CONVERT_COORD(0, 1, 2, /TO_DEVICE, /T3D, /DATA)
On completion, the three-element vector D will contain the desired device coordinates. The process of converting from three-dimensional to two-dimensional coordinates also can be written as an IDL function. This function accepts a three-dimensional data coordinate, returns a two-element vector containing the coordinate transformed to two-dimensional normalized coordinates using the current transformation matrix:
FUNCTION CVT_TO_2D, X, Y, Z ; Make a homogeneous vector of normalized 3D coordinates: P = [!X.S[0] +!X.S[1] * X,!Y.S[0] +!Y.S[1] * Y, $ !Z.S[0] +!Z.S[1] * Z, 1] ; Transform by!P.T: P = P #!P.T ; Return the scaled result as a two-element, ; two-dimensional, xy vector: RETURN, [P[0] / P[3], P[1] / P[3]] END
Usually, scaling parameters for coordinate conversion are set up by the higher-level procedures. To set up your own three-dimensional coordinate system with a given transformation matrix and x, y, z data range, follow these steps:
!X.S = [ -Xmin, 1 ] / (Xmax - Xmin)!Y.S = [ -Ymin, 1 ] / (Ymax - Ymin)!Z.S = [ -Zmin, 1 ] / (Zmax - Zmin)
This example draws four views of a simple house. The procedure HOUSE defines the coordinates of the front and back faces of the house. The data-to-normal coordinate scaling is set, as shown above, to a volume about 25 percent larger than that enclosing the house. The PLOTS procedure is called to draw lines describing and connecting the front and back faces. XYOUTS is called to label the front and back faces.
The commands shown after the definition of the HOUSE procedure contain four sequences of calls to T3D to establish the coordinate transformation, each followed by a call to HOUSE. If you prefer not to enter the IDL code by hand, run the batch file showhaus with the following command at the IDL prompt:
@showhaus
See Running the Example Code if IDL does not find the batch file.
PRO HOUSE ; X coordinates of 10 vertices. First 5 are front face, ; second 5 are back face. The range is 0 to 16. house_x = [0, 16, 16, 8, 0, 0, 16, 16, 8, 0] ; The corresponding y values range from 0 to 16. house_y = [0, 0, 10, 16, 10, 0, 0, 10, 16, 10] ;The z values range from 30 to 54. house_z = [54, 54, 54, 54, 54, 30, 30, 30, 30, 30] ; Define max and min xy values to scale. ; Slightly larger than data range. min_x = -4 & max_x = 20. ; Set x data scale to range from -4 to 20. !X.S = [-(-4), 1.]/(20 - (-4)) ; Same for y. !Y.S =!X.S ; The z range is from 10 to 70. !Z.S = [-10, 1.]/(70 - 10) ; Indices of front face. face = [INDGEN(5), 0] ; Draw front face. PLOTS, house_x[face], house_y[face], $ house_z[face], /T3D, /DATA ; Draw back face. PLOTS, house_x[face + 5], house_y[face + 5], $ house_z[face + 5], /T3D, /DATA ; Connecting lines from front to back. FOR I = 0, 4 DO PLOTS, [house_x[i], house_x[i + 5]], $ [house_y[i], house_y[i + 5]], $ [house_z[i], house_z[i + 5]], /T3D, /DATA ; Annotate front peak. XYOUTS, house_x[3], house_y[3], Z = house_z[3], 'Front', $ /T3D, /DATA, SIZE = 2 ; Annotate back. XYOUTS, house_x[8], house_y[8], Z = house_z[8], 'Back', $ /T3D, /DATA, SIZE = 2 END
The HOUSE procedure could be called from the IDL command line to produce a number of different plots. For example:
; Set up no rotation, scale, and draw house.
T3D, /RESET & HOUSE
; Create a handy constant.
H = [0.5, 0.5, 0.5]
; Straight projection after rotating 30 degrees about x and y axes.
T3D, /RESET, TRANS = -H, ROT = [30, 30, 0] & $
T3D, TR = H & HOUSE
; No rotation, oblique projection, z factor = 0.5, angle = 45.
T3D, /RESET, TRANS = -H, ROT=[0, 0, 0], OBLIQUE=[.5, -45] & $
T3D, TR = H & HOUSE
; Rotate 6 degrees about x and y, then apply perspective.
T3D, /RESET, TR=-H, ROT=[-6, 6, 0], PERS=4 & $
T3D, TR=H & HOUSE
The figure illustrates the different transformations. The four rotations are:
A common procedure for visualizing three-dimensional data is to animate the data by rotating it about one or more axes. To make an animation of the house in the preceding example with the XINTERANIMATE procedure, use the following example.
; Initialize animation: set frame size and number of frames. sizx = 300 sizy = 300 nframes = 16 XINTERANIMATE, SET=[sizx, sizy, nframes] ; Rotate about the z axis. Draw the house.Save the window. FOR i = 0, nframes - 1 DO BEGIN $ SCALE3, AX = 75, AZ = i * 360. / nframes & $ ERASE & $ HOUSE & $ SCALE3, AX = 75, AZ = i * 360. / nframes & $ XINTERANIMATE, FRAME=i, WINDOW=!D.WINDOW & $ ENDFOR ; Show the animation. XINTERANIMATE
In the above example, SCALE3 rather than SCALE3D is used to maintain the same scaling in all rotations. If you prefer not to enter the IDL code by hand, run the batch file animhaus with the following command at the IDL prompt:
@animhaus
See Running the Example Code if IDL does not find the batch file.