Scaling and rotating objects in 3D - using NumPy - Phyton

emergency9177

New member
Joined
Dec 16, 2021
Messages
19
Use 8 vectors to describe corners of a cube, which is centered in the axis system, with sides aligned with coordinate system.
Next, scale cube in x, y and z direction by a0, b0 and c0.
Write a function, which will generate a matrix for scaling.
In the next step, generate rotation matrices and rotate the scaled cube by a1, b1 and c1 angles around x, y and z axis.
Prepare a program using numpy that will calculate and print out the vectors of the scaled and rotated cube.
Check if the order of scaling and rotation change the result.

_______________________________________________________________________________________________________________________________________________________________________

Untill now I've tried to write an algorithm using Numpy. I am not sure about the code, because I cannot find the right code to connect the vertices (cornes) of the cube in x, y and z direction by a0, b0 and c0, ; generating rotation matrices to rotate the scaled cube by a1, b1 and c1 angles around x, y and z axis.

When I run the program it works independently if I put the values of the vertices or not.

Thanks for help.

This is what I've solved:

Python:
import numpy as np
from math import sin,cos

vertices = np.array(
    [
        [-1, -1, -1],
        [+1, -1, -1],
        [+1, +1, -1],
        [-1, +1, -1],
        [-1, -1, +1],
        [+1, -1, +1],
        [+1, +1, +1],
        [-1, +1, +1],
    ]
)
def test_double_rotation():
    data['vectors'][0] = numpy.array([[-1, -1, -1],
                                      [+1, -1, -1],
                                      [+1, +1, -1],
                                      [-1, +1, -1],
                                      [-1, -1, +1],
                                      [+1, -1, +1],
                                      [+1, +1, +1],
                                      [-1, +1, +1],])
    combined_rotation_matrix = numpy.dot(rotation_matrix, rotation_matrix)
def get_rx(angle):
    cs = cos(angle*np.pi/180.)
    sn = sin(angle*np.pi/180.)
    return np.array([[1.0,0.0,0.0],[0.0,cs,-sn],[0.0,sn,cs]])
def get_ry(angle):
    cs = cos(angle*np.pi/180.)
    sn = sin(angle*np.pi/180.)
    return np.array([[cs,0.0,sn],[0.0,1.0,0.0],[-sn,0.0,cs]])
def get_rz(angle):
    cs = cos(angle*np.pi/180.)
    sn = sin(angle*np.pi/180.)
    return np.array([[cs,-sn,0.0],[sn,cs,0.0],[0.0,0.0,1.0]])
def dot(m,a):
    c1 = np.sum(m[0,:] * a)
    c2 = np.sum(m[1,:] * a)
    c3 = np.sum(m[2,:] * a)
    return np.array([c1,c2,c3])

print(get_rx(30.0))
#print(get_ry(30.0))
#print(get_rz(30.0))

mx = get_rx(30.0)
my = get_ry(60.0)
mz = get_rz(45.0)
a = np.array([0.,0.,0.])

print("a:",a)
print("Rx a;" ,np.dot(mx,a))
print("RyRx a;" ,np.dot(my,np.dot(mx,a)))
print("RzRyRx a;" ,np.dot(mz,np.dot(my,np.dot(mx,a))))

r = np.dot(mz,np.dot(my,mx))
print("R = (RzRyRx) a;" ,np.dot(r,a))

print("\n----------------------")
import numpy.linalg as ln
print("\nR  :\n" ,r)
rinv = ln.inv(r)
print("\nR-1:\n" ,rinv)
print("\nR  :\n" ,a)
ra = np.dot(r,a)
print("\nRa  :\n" ,ra)
rb = np.dot(rinv,ra)
print("\nRinvRa  :\n" ,rb)
 
What kind of help are you asking for?
I cannot find the right code that will connect the data of matrix (vertices - cornes of the cube) in x, y and z direction by a0, b0 and c0, ; in order to generate matrices that will rotate the scaled cube by a1, b1 and c1 angles around x, y and z axis.

Thanks.
 
...connect the data of matrix (vertices - corners of the cube) in x, y and z direction by a0, b0 and c0,
I don't understand the quoted phrase, but I am guessing that you need a matrix which scales by a0,b0 and c0 in x,y and z directions respective -- am I right.
... generate matrices that will rotate the scaled cube by a1, b1 and c1 angles around x, y and z axis.
Rotation matrices will rotate everything, not just your cube, by those angles.
Do you know how to build a rotation matrix in 2D ?
 
I don't understand the quoted phrase, but I am guessing that you need a matrix which scales by a0,b0 and c0 in x,y and z directions respective -- am I right.

Rotation matrices will rotate everything, not just your cube, by those angles.
Do you know how to build a rotation matrix in 2D ?
1. Correct. You are right.
2. No, I don't know how to build a rotation matrix in 2D... as far as I know:

Rotation matrices are:

Python:
import numpy as np
from math import sin,cos

def get_rx(angle):
    cs = cos(angle*np.pi/180.)
    sn = sin(angle*np.pi/180.)
    return np.array([[1.0,0.0,0.0],[0.0,cs,-sn],[0.0,sn,cs]])
def get_ry(angle):
    cs = cos(angle*np.pi/180.)
    sn = sin(angle*np.pi/180.)
    return np.array([[cs,0.0,sn],[0.0,1.0,0.0],[-sn,0.0,cs]])
def get_rz(angle):
    cs = cos(angle*np.pi/180.)
    sn = sin(angle*np.pi/180.)
    return np.array([[cs,-sn,0.0],[sn,cs,0.0],[0.0,0.0,1.0]])

print(get_rx(30.0))
print(get_ry(30.0))
print(get_rz(30.0))

To rotate the vector, we need to do dot product:

Python:
def dot(m,a):
    c1 = np.sum(m[0,:] * a)
    c2 = np.sum(m[1,:] * a)
    c3 = np.sum(m[2,:] * a)
    return np.array([c1,c2,c3])

a = np.array([5.,3.,0.])
print("a:",a)
mx = get_rx(30.0)
print("Rx a:",dot(mx,a))
print("test:",np.dot(mx,a))

Finally, we can combine rotations into a single matrix:

Python:
mx = get_rx(30.0)
my = get_ry(60.0)
mz = get_rz(45.0)
a = np.array([5.,3.,0.])

print("a:\n",a)
print("Rx a\n",np.dot(mx,a))
print("RyRx a\n",np.dot(my,np.dot(mx,a)))
print("RzRyRx a\n",np.dot(mz,np.dot(my,np.dot(mx,a))))

r = np.dot(mz,np.dot(my,mx))
print("R = (RzRyRx) a\n",np.dot(r,a))

...more...(but I think is not our case, so this is could be redundant)... if we would like to find an inverse of the matrix, we need to import linalg module:

Python:
import numpy.linalg as ln
print("\nR  :\n",r)
rinv = ln.inv(r)
print("\nR-1:\n",rinv)
print("\na  :\n",a)
ra = np.dot(r,a)
print("\nRa  :\n",ra)
rb = np.dot(rinv,ra)
print("\nRinvRa  :\n",rb)

Also, in the case of rotation matrices, the inverse is similar to the transpose:

Python:
print("inverted R\n",rinv)
print("transposed R\n",r.T)
 
1. Correct. You are right.
2. No, I don't know how to build a rotation matrix in 2D... as far as I know:

Rotation matrices are:

Python:
import numpy as np
from math import sin,cos

def get_rx(angle):
    cs = cos(angle*np.pi/180.)
    sn = sin(angle*np.pi/180.)
    return np.array([[1.0,0.0,0.0],[0.0,cs,-sn],[0.0,sn,cs]])
def get_ry(angle):
    cs = cos(angle*np.pi/180.)
    sn = sin(angle*np.pi/180.)
    return np.array([[cs,0.0,sn],[0.0,1.0,0.0],[-sn,0.0,cs]])
def get_rz(angle):
    cs = cos(angle*np.pi/180.)
    sn = sin(angle*np.pi/180.)
    return np.array([[cs,-sn,0.0],[sn,cs,0.0],[0.0,0.0,1.0]])

print(get_rx(30.0))
print(get_ry(30.0))
print(get_rz(30.0))

To rotate the vector, we need to do dot product:

Python:
def dot(m,a):
    c1 = np.sum(m[0,:] * a)
    c2 = np.sum(m[1,:] * a)
    c3 = np.sum(m[2,:] * a)
    return np.array([c1,c2,c3])

a = np.array([5.,3.,0.])
print("a:",a)
mx = get_rx(30.0)
print("Rx a:",dot(mx,a))
print("test:",np.dot(mx,a))

Finally, we can combine rotations into a single matrix:

Python:
mx = get_rx(30.0)
my = get_ry(60.0)
mz = get_rz(45.0)
a = np.array([5.,3.,0.])

print("a:\n",a)
print("Rx a\n",np.dot(mx,a))
print("RyRx a\n",np.dot(my,np.dot(mx,a)))
print("RzRyRx a\n",np.dot(mz,np.dot(my,np.dot(mx,a))))

r = np.dot(mz,np.dot(my,mx))
print("R = (RzRyRx) a\n",np.dot(r,a))

...more...(but I think is not our case, so this is could be redundant)... if we would like to find an inverse of the matrix, we need to import linalg module:

Python:
import numpy.linalg as ln
print("\nR  :\n",r)
rinv = ln.inv(r)
print("\nR-1:\n",rinv)
print("\na  :\n",a)
ra = np.dot(r,a)
print("\nRa  :\n",ra)
rb = np.dot(rinv,ra)
print("\nRinvRa  :\n",rb)

Also, in the case of rotation matrices, the inverse is similar to the transpose:

Python:
print("inverted R\n",rinv)
print("transposed R\n",r.T)

1. Correct. You are right.
2. No, I don't know how to build a rotation matrix in 2D... as far as I know:

Rotation matrices are:

Python:
import numpy as np
from math import sin,cos

def get_rx(angle):
    cs = cos(angle*np.pi/180.)
    sn = sin(angle*np.pi/180.)
    return np.array([[1.0,0.0,0.0],[0.0,cs,-sn],[0.0,sn,cs]])
def get_ry(angle):
    cs = cos(angle*np.pi/180.)
    sn = sin(angle*np.pi/180.)
    return np.array([[cs,0.0,sn],[0.0,1.0,0.0],[-sn,0.0,cs]])
def get_rz(angle):
    cs = cos(angle*np.pi/180.)
    sn = sin(angle*np.pi/180.)
    return np.array([[cs,-sn,0.0],[sn,cs,0.0],[0.0,0.0,1.0]])

print(get_rx(30.0))
print(get_ry(30.0))
print(get_rz(30.0))

To rotate the vector, we need to do dot product:

Python:
def dot(m,a):
    c1 = np.sum(m[0,:] * a)
    c2 = np.sum(m[1,:] * a)
    c3 = np.sum(m[2,:] * a)
    return np.array([c1,c2,c3])

a = np.array([5.,3.,0.])
print("a:",a)
mx = get_rx(30.0)
print("Rx a:",dot(mx,a))
print("test:",np.dot(mx,a))

Finally, we can combine rotations into a single matrix:

Python:
mx = get_rx(30.0)
my = get_ry(60.0)
mz = get_rz(45.0)
a = np.array([5.,3.,0.])

print("a:\n",a)
print("Rx a\n",np.dot(mx,a))
print("RyRx a\n",np.dot(my,np.dot(mx,a)))
print("RzRyRx a\n",np.dot(mz,np.dot(my,np.dot(mx,a))))

r = np.dot(mz,np.dot(my,mx))
print("R = (RzRyRx) a\n",np.dot(r,a))

...more...(but I think is not our case, so this is could be redundant)... if we would like to find an inverse of the matrix, we need to import linalg module:

Python:
import numpy.linalg as ln
print("\nR  :\n",r)
rinv = ln.inv(r)
print("\nR-1:\n",rinv)
print("\na  :\n",a)
ra = np.dot(r,a)
print("\nRa  :\n",ra)
rb = np.dot(rinv,ra)
print("\nRinvRa  :\n",rb)

Also, in the case of rotation matrices, the inverse is similar to the transpose:

Python:
print("inverted R\n",rinv)
print("transposed R\n",r.T)
Somebody can help me please?

Thanks.
 
I don't know what help you need. You seem to have most of the pieces but for some reason you're not putting it all together. You just need to loop through the vertices and apply the rotation and scaling. The following code will do this for rotation only...

Python:
# tag this on to the end of your code in post#1
for v in vertices:
    print("  ", v," after rotation is ", np.dot(r,v)) # consider using matmul instead of dot

You will also need to write code that gives a scaling matrix(click). I can't see that anywhere in your work.

NOTE: The quoted question in post#1 seems to be in the wrong order. It asks you to scale the cube before asking you to write a function to give a matrix for scaling ?. Did you write the question exactly as it was given to you? (Please translate it into English if it was in a different language but try to preserve the order of the tasks).
 
I don't know what help you need. You seem to have most of the pieces but for some reason you're not putting it all together. You just need to loop through the vertices and apply the rotation and scaling. The following code will do this for rotation only...

Python:
# tag this on to the end of your code in post#1
for v in vertices:
    print("  ", v," after rotation is ", np.dot(r,v)) # consider using matmul instead of dot

You will also need to write code that gives a scaling matrix(click). I can't see that anywhere in your work.

NOTE: The quoted question in post#1 seems to be in the wrong order. It asks you to scale the cube before asking you to write a function to give a matrix for scaling ?. Did you write the question exactly as it was given to you? (Please translate it into English if it was in a different language but try to preserve the order of the tasks).
I've got it, I'll try.

Thank you! ;)
 
Top