Graphics Transformation Matrix Functions

File: transformation_matrix.py

#! /usr/bin/python3
# ===================================================================
#
# ===================================================================

from copy import deepcopy
import numpy as np


identity_matrix_2d = np.array([ [1.0, 0.0, 0.0],
                                [0.0, 1.0, 0.0],
                                [0.0, 0.0, 1.0] ])


identity_matrix_3d = np.array([ [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] ])

# -------------------------------------------------------------------
# ---- Function: clone a np.array
# -------------------------------------------------------------------

def clone_np_array(ary):
    return deepcopy(ary)

# -------------------------------------------------------------------
# ---- Function: return a copy of 2D or 3D identity matrix
# -------------------------------------------------------------------

def get_identity_matrix_2d():
    return clone_np_array(identity_matrix_2d)

def get_identity_matrix_3d():
    return clone_np_array(identity_matrix_3d)

# -------------------------------------------------------------------
# ---- Function: return a 2D or 3D translation matrix
# ---- Note: dx and dy are the change (delta) in x and y coordinates
# -------------------------------------------------------------------

def get_translation_matrix_2d(dx, dy):

    tm = clone_np_array(identity_matrix_2d)
    tm[0][2] = dx
    tm[1][2] = dy
    return tm

def get_translation_matrix_3d(dx, dy, dz):

    tm = clone_np_array(identity_matrix_3d)
    tm[0][3] = dx
    tm[1][3] = dy
    tm[2][3] = dz
    return tm

# -------------------------------------------------------------------
# ---- Function: return a 2D or 3D Z axis rotation matrix
# ---- Note: angle is in degrees
# -------------------------------------------------------------------

def get_z_rotation_matrix_2d(deg):

    rad = np.deg2rad(deg % 360.0)

    tm = clone_np_array(identity_matrix_2d)
    tm[0][0] =  np.cos(rad)
    tm[0][1] = -np.sin(rad)
    tm[1][0] =  np.sin(rad)
    tm[1][1] =  np.cos(rad)
    return tm

def get_z_rotation_matrix_3d(deg):

    rad = np.deg2rad(deg)

    tm = clone_np_array(identity_matrix_3d)
    tm[0][0] =  np.cos(rad)
    tm[0][1] = -np.sin(rad)
    tm[1][0] =  np.sin(rad)
    tm[1][1] =  np.cos(rad)
    tm[2][2] = 1
    tm[3][3] = 1
    return tm

# -------------------------------------------------------------------
# ---- Function: return a 3D Y axis rotation matrix
# ---- Note: angle is in degrees
# -------------------------------------------------------------------

def get_y_rotation_matrix_3d(deg):

    rad = np.deg2rad(deg % 360.0)

    tm = clone_np_array(identity_matrix_3d)
    tm[0][0] =  np.cos(rad)
    tm[0][2] =  np.sin(rad)
    tm[2][0] = -np.sin(rad)
    tm[2][2] =  np.cos(rad)
    return tm

# -------------------------------------------------------------------
# ---- Function: return a 3D X axis rotation matrix
# ---- Note: angle is in degrees
# -------------------------------------------------------------------

def get_x_rotation_matrix_3d(deg):

    rad = np.deg2rad(deg % 360.0)

    tm = clone_np_array(identity_matrix_3d)
    tm[1][1] =  np.cos(rad)
    tm[1][2] = -np.sin(rad)
    tm[2][1] =  np.sin(rad)
    tm[2][2] =  np.cos(rad)
    return tm

# -------------------------------------------------------------------
# ---- Function: return a 2D or 3D scaling matrix
# -------------------------------------------------------------------

def get_scaling_matrix_2d(sx,sy):

    tm = clone_np_array(identity_matrix_2d)
    tm[0][0] = sx
    tm[1][1] = sy
    return tm

def get_scaling_matrix_3d(sx,sy,sz):

    tm = clone_np_array(identity_matrix_3d)
    tm[0][0] = sx
    tm[1][1] = sy
    tm[2][2] = sz
    return tm

# -------------------------------------------------------------------
# ---- main
# -------------------------------------------------------------------

if __name__ == '__main__':

    # ---- verify the original (np.arry) identity matrix data types

    print()
    print('-----------------------------------------------')
    print(f'2D array id  ={id(identity_matrix_2d)}')
    print(f'2D array type ={type(identity_matrix_2d)}')
    im = get_identity_matrix_2d()
    print(f'2D array[0]   ={type(im[0])}')
    print(f'2D array[0][0]={type(im[0][0])}')
    print('-----------------------------------------------')


    # ---- verify returned identity matrix (np.array) is not
    # ---- the original matrix (np.array)

    print()
    print('---------- identity matrix -------------------------')
    print(f'original numpy.array id = {id(identity_matrix_2d)}')
    m = get_identity_matrix_2d()
    print(f'clone    numpy.array id = {id(m)}')
    m[0][0] = 100
    print('---------- original')
    print(identity_matrix_2d)
    print('---------- clone')
    print(m)

    # ---- verify the x,y,z rotation matrix code works

    deg = 390 % 360.0

    print()
    print(f'deg = {deg}')
    print(f'sin({deg}) = {np.sin(np.deg2rad(deg))}')
    print(f'cos({deg}) = {np.cos(np.deg2rad(deg))}')

    print()
    print('---------- Z axiz rotation -------------------------')
    mz = get_z_rotation_matrix_2d(deg)
    print(mz)
    print()
    mz = get_z_rotation_matrix_3d(deg)
    print(mz)
    print()
    print('---------- Y axiz rotation -------------------------')
    my = get_y_rotation_matrix_3d(deg)
    print(my)
    print()
    print('---------- X axiz rotation -------------------------')
    mx = get_x_rotation_matrix_3d(deg)
    print(mx)