An IDLgrModel object is a container for any visualization objects that are to be rotated, translated, or scaled. Each IDLgrModel object has a transformation property (set via the TRANSFORM keyword to the IDLgrModel::Init or SetProperty method), which is a 4 x 4 floating-point matrix. For a general discussion of transformation matrices and three-dimensional graphics, see Coordinates of 3-D Graphics.
Note: A model object's transformation matrix is akin to the transformation matrix used by IDL Direct Graphics and stored in the !P.T system variable field. Transformation matrices associated with a model object do not use the value of !P.T, however, and are not affected by the T3D procedure used in Direct Graphics.
By default, a model object's transformation matrix is set equal to a 4-by-4 identity matrix:
[[1.0, 0.0, 0.0, 0.0],
[ 0.0, 1.0, 0.0, 0.0],
[ 0.0, 0.0, 1.0, 0.0],
[ 0.0, 0.0, 0.0, 1.0]]
You can change the transformation matrix of a model object directly, using the TRANSFORM keyword to the IDLgrModel::Init or SetProperty method:
myModel = OBJ_NEW('IDLgrModel', TRANSFORM = tmatrix)
where tmatrix is a 4-by-4 transformation matrix.
Alternatively, you can use the Translate, Rotate, and Scale methods to the IDLgrModel object to alter the model's transformation matrix.
Translation
The IDLgrModel::Translate method takes three arguments specifying the amount to translate the model object and its contents in the X, Y, and Z directions. For example, to translate a model and its contents by 1 unit in the X-direction, you could use the following statements:
dx = 1 & dy = 0 & dz = 0
myModel->Translate, dx, dy, dz
How does this affect the transformation matrix? Notice that we could change the transformation matrix in an identical way using the following statements:
dx = 1 & dy = 0 & dz = 0
myModel->GetProperty, TRANSFORM = oldT
transT = [[1.0, 0.0, 0.0, dx], $
[0.0, 1.0, 0.0, dy], $
[0.0, 0.0, 1.0, dz], $
[0.0, 0.0, 0.0, 1.0]]
newT = oldT # transT
myModel->SetProperty, TRANSFORM = newT
Rotation
The IDLgrModel::Rotate method takes two arguments specifying the axis about which to rotate and the number of degrees to rotate the model object and its contents. For example, to rotate a model and its contents by 90 degrees around the y-axis, you could use the following statements:
axis = [0,1,0] & angle = 90
myModel->Rotate, axis, angle
How does this affect the transformation matrix? Notice that we could change the transformation matrix in an identical way using the following statements:
axis = [0,1,0] & angle = 90
myModel->GetProperty, TRANSFORM = oldT
cosa = COS(!DTOR*angle)
sina = SIN(!DTOR*angle)
rotT = [[cosa, 0.0, sina, 0.0], $
[0.0, 1.0, 0.0, 0.0], $
[-sina, 0.0, cosa, 0.0], $
[0.0, 0.0, 0.0, 1.0]]
newT = oldT # rotT
myModel->SetProperty, TRANSFORM = newT
Scaling
The IDLgrModel::Scale method takes three arguments specifying the amount to scale the model object and its contents in the x, y, and z directions. For example, to scale a model and its contents by 2 units in the y direction, you could use the following statements:
sx = 1 & sy = 2 & sz = 1
myModel->Scale, sx, sy, sz
How does this affect the transformation matrix? Notice that we could change the transformation matrix in an identical way using the following statements:
sx = 1 & sy = 2 & sz = 1
myModel->GetProperty, TRANSFORM = oldT
scaleT = [[sx, 0.0, 0.0, 0.0], $
[0.0, sy, 0.0, 0.0], $
[0.0, 0.0, sz, 0.0], $
[0.0, 0.0, 0.0, 1.0]]
newT = oldT # scaleT
myModel->SetProperty, TRANSFORM = newT
Combining Transformations
Note that model transformations are cumulative. That is, a model object contained in another model is subject to both its own transformation and to that of its container. All transformation matrices that apply to a given model object are multiplied together when the object is rendered. For example, consider a model that contains another model:
model1 = OBJ_NEW('IDLgrModel', TRANSFORM = trans1)
model2 = OBJ_NEW('IDLgrModel', TRANSFORM = trans2)
model2->Add, model1
The model1 object is now subject to both its own transformation matrix (trans1) and to that of its container (trans2). The result is that when model1 is rendered, it will be rendered with a transformation matrix = trans1 # trans2.