Translating, Rotating, and Scaling Objects

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:

; Define translation values:

dx = 1 & dy = 0 & dz = 0

 

; Get existing transformation matrix:

myModel->GetProperty, TRANSFORM = oldT

 

; Provide a transformation matrix that performs the translation:

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]]

 

; Multiply the existing transformation matrix by

; the matrix that performs the translation:

newT = oldT # transT

 

; Apply the new transformation matrix to the model object:

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:

; Define rotation values:

axis = [0,1,0] & angle = 90

 

; Get existing transformation matrix:

myModel->GetProperty, TRANSFORM = oldT

 

; Define sine and cosine of angle:

cosa = COS(!DTOR*angle)

sina = SIN(!DTOR*angle)

 

; Provide a transformation matrix that performs the rotation:

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]]

 

; Multiply the existing transformation matrix

; by the matrix that performs the rotation.

newT = oldT # rotT

 

; Apply the new transformation matrix to the model object:

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:

; Define scaling values:

sx = 1 & sy = 2 & sz = 1

 

; Get existing transformation matrix:

myModel->GetProperty, TRANSFORM = oldT

 

; Provide a transformation matrix that performs the scaling:

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]]

 

; Multiply the existing transformation matrix

; by the matrix that performs the scaling.

newT = oldT # scaleT

 

; Apply the new transformation matrix to the model object:

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.