# IC Python API:Transform Math

## Contents

Main article: RL Python Samples.

This article will go some recipes for common 3D transformational math. You'll find this helpful if you need to perform spacial calculations.

## Transform Point

Transforms position of a point from local-space to world-space. The returned position is affected by scale.

```def transform_point(world_transform, local_position):
# Get the transform matrix4
world_matrix = world_transform.Matrix()

# New matrix4 for the local position
point_world_matrix = RLPy.RMatrix4()
point_world_matrix.MakeIdentity()
point_world_matrix.SetTranslate(local_position)

# Combine the 2 matrix4s
point_world_matrix = point_world_matrix * world_matrix

# Return the translation element of the combined matrix4
return RLPy.RVector3(point_world_matrix.GetTranslate())
```

### Transform Point with Specific Rotation

In order to assign a specific rotation, use the following instead:

```def transform_point(world_transform, specific_rotation, local_position):
# Get the transform matrix4
world_matrix = world_transform.Matrix()
world_matrix.SetSR(specific_rotation)

# New matrix4 for the local position
point_world_matrix = RLPy.RMatrix4()
point_world_matrix.MakeIdentity()
point_world_matrix.SetTranslate(local_position)

# Combine the 2 matrix4
point_world_matrix = point_world_matrix * world_matrix

# Return the translation element of the combined matrix4
return RLPy.RVector3(point_world_matrix.GetTranslate())
```

## Inverse Transform Point

Transforms a position point from world-space to local-space. This function is the opposite of Transform Point, which is used to convert local to world-space.

```def inverse_transform_point(world_transform, world_point):
transform_matrix = world_transform.Matrix()
local_position = world_point - transform_matrix.GetTranslate()  # Can also use transform.T()
transform_matrix.SetTranslate(RLPy.RVector3.ZERO)  # Zero out transform matrix translation

# New matrix4 for the local position
point_world_matrix = RLPy.RMatrix4()
point_world_matrix.MakeIdentity()
point_world_matrix.SetTranslate(local_position)

# Convert local space to transform space
point_transform_matrix = point_world_matrix * transform_matrix.Inverse()

# Return the translation element of the combined matrix4
return point_transform_matrix.GetTranslate()
```

## Transform Direction

Transforms direction of a vector from local-space to world-space. The returned vector has the same length as the direction.

```def transform_direction(world_transform, local_position):
# Get the transform rotation 3x3 matrix
world_rot_matrix = world_transform.Rotate()

# New matrix4 for world direction
world_dir = RLPy.RMatrix4()
world_dir.MakeIdentity()
world_dir.SetSR(world_rot_matrix)

# New matrix for the local position
point_world_matrix = RLPy.RMatrix4()
point_world_matrix.MakeIdentity()
point_world_matrix.SetTranslate(local_position)

# Combine the 2 matrix4
point_world_matrix = point_world_matrix * world_dir

# Return the translation element of the combined matrix4
return RLPy.RVector3(point_world_matrix.GetTranslate())
```

## Transform Lerp

Lerps between two transformational matrices given a point between 0 and 1.

```def transform_lerp(from_transform, to_transform, point):
x = y = z = 0

# Convert transform quaternion rotations to euler angles (in radians)
from_rotation = from_transform.R().ToRotationMatrix().ToEulerAngle(RLPy.EEulerOrder_XYZ, x, y, z)
to_rotation = to_transform.R().ToRotationMatrix().ToEulerAngle(RLPy.EEulerOrder_XYZ, x, y, z)

# Lerp between the start and end eular angle values
euler_rotation = RLPy.RVector3(
(1 - point) * from_rotation + point * to_rotation,
(1 - point) * from_rotation + point * to_rotation,
(1 - point) * from_rotation + point * to_rotation
)

# Convert the final euler roation back to a rotation matrix3 (3x3 matrix)
matrix_rotation = RLPy.RMatrix3().FromEulerAngle(RLPy.EEulerOrder_XYZ, euler_rotation.x, euler_rotation.y, euler_rotation.z)

# Return an interpolated transform matrix4 (4x4 matrix)
# The transform entry order is: Scale (Vector3), Rotation (Quaternion), Translation (Vector3)
return RLPy.RTransform(
RLPy.RVector3(
(1 - point) * from_transform.S().x + point * to_transform.S().x,
(1 - point) * from_transform.S().y + point * to_transform.S().y,
(1 - point) * from_transform.S().z + point * to_transform.S().z
),
RLPy.RQuaternion().FromRotationMatrix(matrix_rotation),  # Convert matrix3 rotation back to quaternion
RLPy.RVector3(
(1 - point) * from_transform.T().x + point * to_transform.T().x,
(1 - point) * from_transform.T().y + point * to_transform.T().y,
(1 - point) * from_transform.T().z + point * to_transform.T().z
)
)
```

The returned transformation matrix can be applied by setting the value for the Transform control of a prop:

```box = RLPy.RScene.FindObject(RLPy.EObjectType_Prop, "Box")
box.GetControl("Transform").SetValue(RLPy.RGlobal.GetTime(), transform)
```