# 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`.