Suppose we have several points located in three-dimensional space. Now, we specify two points, named point1 and point2. To simplify the problem, we consider these two points as a line. Now we move point1 to the origin. This translation is such that all the points are displaced accordingly. Now, all points must be rotated so that point2 is exactly on the Y-axis, meaning its x and z coordinates should be zero. But what specific calculations need to be performed to determine the directions in which all these points should rotate so that point2 is precisely positioned on the Y-axis?
I would really appreciate your help.
If I want to ask my question more precisely, how should the values of Ax, Ay, and Az be calculated?
import numpy as np
points = np.array([[0.36266313,0.70320135,0.88975275],
[0.26227164,0.32188661,0.39514979],
[0.26100571,0.63643259,0.20245194],
[0.25701545,0.59125069,0.80146842],
[0.23185588,0.19422526,0.68689653]])
point1, point2 = points[0], points[2]
points = points - point1
point2 = point2 - point1
point1 = point1 - point1
def rotate_points_around_point(points, angle_degrees, axis, center_point):
translated_points = points - center_point
angle_radians = np.radians(angle_degrees)
rotation_matrix = {
'x': np.array([[1, 0, 0],
[0, np.cos(angle_radians), -np.sin(angle_radians)],
[0, np.sin(angle_radians), np.cos(angle_radians)]]),
'y': np.array([[np.cos(angle_radians), 0, np.sin(angle_radians)],
[0, 1, 0],
[-np.sin(angle_radians), 0, np.cos(angle_radians)]]),
'z': np.array([[np.cos(angle_radians), -np.sin(angle_radians), 0],
[np.sin(angle_radians), np.cos(angle_radians), 0],
[0, 0, 1]])
}
rotated_points = np.dot(translated_points, rotation_matrix[axis].T)
rotated_points = rotated_points + center_point
return rotated_points
# ======== Question ========
Ax = 96
Ay = -3.0626
Az = -8.38675
# ======== Question ========
points = rotate_points_around_point(points, Ax, "x", point1)
points = rotate_points_around_point(points, Ay, "y", point1)
points = rotate_points_around_point(points, Az, "z", point1)
print(points)
Result:
[[ 0. 0. 0. ]
[-0.004306 0.538135 -0.332422]
[ 0. 0.697979 0. ]
[-0.084459 0.11303 -0.107608]
[-0.066404 0.267493 -0.49128 ]]
I value the insights and guidance you provide.
Translate the points such that your first reference point is at the origin.
Let B be the position vector of the second reference point after translation.
KEY STEP: take the vector cross product of B and a unit vector in the y direction (in that order). The resulting vector will have direction the ultimate rotation axis and magnitude norm(B)x1xsin(theta), where theta is the angle of rotation.
You can create a rotation matrix from this axis and the rotation angle. This is the single rotation matrix that you require.
The following code does this. Note that floating-point operations leave you with x and z coordinates in point[2] that are of order 1e-16: effectively 0.
import math
import numpy as np
import matplotlib.pyplot as plt
def rotationMatrix( a, theta ): # rotation matrix for a rotation of angle theta about axis a
R = np.zeros( ( 3, 3 ) )
n = a / np.linalg.norm( a )
C = math.cos( theta )
S = math.sin( theta )
R[0,0] = C + n[0] * n[0] * ( 1.0 - C )
R[0,1] = n[0] * n[1] * ( 1.0 - C ) - n[2] * S
R[0,2] = n[0] * n[2] * ( 1.0 - C ) + n[1] * S
R[1,1] = C + n[1] * n[1] * ( 1.0 - C )
R[1,2] = n[1] * n[2] * ( 1.0 - C ) - n[0] * S
R[1,0] = n[1] * n[0] * ( 1.0 - C ) + n[2] * S
R[2,2] = C + n[2] * n[2] * ( 1.0 - C )
R[2,0] = n[2] * n[0] * ( 1.0 - C ) - n[1] * S
R[2,1] = n[2] * n[1] * ( 1.0 - C ) + n[0] * S
return R
points = np.array([[0.36266313,0.70320135,0.88975275],
[0.26227164,0.32188661,0.39514979],
[0.26100571,0.63643259,0.20245194],
[0.25701545,0.59125069,0.80146842],
[0.23185588,0.19422526,0.68689653]])
A = points[0] # First reference point
points -= A # Translate such that A goes to origin
B = points[2] # B is the point you want to rotate onto the y axis (did you mean [2]?)
Y = np.array( [0.0, 1.0, 0.0 ] ) # Unit vector along y axis
axis = np.cross( B, Y ) # Axis of rotation (not normalised)
mag = np.linalg.norm( axis )
if ( abs(mag) < 1.0e-20 ): axis = np.array([1.0,0,0]) # Already on y axis, so rotation axis is irrelevant
sintheta = mag / np.linalg.norm( B ) # Sine of angle of rotation
theta = math.asin( sintheta )
if np.dot( B, Y ) < 0: theta = math.pi - theta # Appropriate angle to rotate to the POSITIVE y axis
R = rotationMatrix( axis, theta ) # Find rotation matrix
points = ( R @ (points.T) ).T # Rotate points
print( points )
Output:
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[-7.51354446e-02 5.38134329e-01 -3.23848081e-01]
[-3.85256819e-17 6.97979012e-01 -2.79186184e-16]
[-1.05473850e-01 1.13030002e-01 -8.71090761e-02]
[-1.69698494e-01 2.67492963e-01 -4.65798002e-01]]