给定一个单位向量,找到使该向量与轴对齐的两个旋转角度
Given a unit vector find the two angles of rotation that aligns that vector with an axis
所以我不太精通线性代数,所以我正在努力解决这个问题。
我有一个单位向量v
。我想找到两个角度(角度 1,绕 x 轴旋转,角度 2,绕 z 轴旋转),这样当我按它们旋转 v
时,它会将向量 v
与 y 对齐-轴。从 问题我有一个函数可以找到任意向量和 returns 旋转之间的角度。但是这个函数returns3个角度。本质上有无限数量的 3d 旋转 v
与 y 轴对齐,所以我想要两个独特的角度。
这是我现在的代码,它需要 numpy 和 scipy:
import numpy as np
import random
from scipy.spatial.transform import Rotation as R
def rotation_from_unit_vectors(a, b):
v = np.cross(a, b)
c = np.dot(a, b)
s = np.linalg.norm(v)
kmat = np.array([[0, -v[2], v[1]], [v[2], 0, -v[0]], [-v[1], v[0], 0]])
rotation_matrix = np.eye(3) + kmat + kmat.dot(kmat) * ((1 - c) / (s ** 2))
return R.from_matrix(rotation_matrix)
y_axis = np.asarray([0.0, 1.0, 0.0])
alpha = random.uniform(0, 10)
beta = random.uniform(0, 10)
gamma = random.uniform(0, 10)
v = np.asarray([alpha, beta, gamma])
v = v / np.linalg.norm(v)
r = rotation_from_unit_vectors(v, y_axis)
print(r.as_euler('xyz', degrees = True))
print(r.apply(v))
嗯,不标准的问题,需要思考一下
给定 v1
和 v2
您希望 rotate_z(rotate_x(v1, alpha), beta)
与 v2
.
方向相同
我们知道对齐向量可以通过简单的scaling缩放得到v2
,这样就得到x1,y3,z3 = v3 = v2 * |v1| / |v2|
。由于绕 z 轴旋转不影响 z 坐标,我们可以确定 alpha,使得 rotate_x(v1, alpha)
的 z 坐标等于 z3
。之后我们确定角度 beta
以正确对齐放置 X 和 Y 坐标
import numpy as np
def alignment_angles(v1, v2):
x1,y1,z1 = v1 # initial vector
x2,y2,z2 = v2 # reference vector
# magnitude of the two vectors
r1 = np.sqrt(x1**2 + y1**2 + z1**2)
r2 = np.sqrt(x2**2 + y2**2 + z2**2)
# this will be the result when aligning v1 to v2
# it has the magnitude of v1 and the direction of v2
x3,y3,z3 = x2*r1/r2, y2*r1/r2, z2*r1/r2
# the rotation in x must set the z coordinate to the
# final value, since the rotation over the z axis will
# not affect the z coordinate (this have two solutions)
rho1 = np.sqrt(z1**2 + y1**2)
if(abs(z3 / rho1) > 1):
raise ValueError('Cannot align these vectors')
alpha = np.arcsin(z3 / rho1) - np.arctan2(z1, y1);
# apply the rotation to make easier to calcualte the next stage
y1, z1 = (y1 * np.cos(alpha) - z1 * np.sin(alpha),
y1 * np.sin(alpha) + z1 * np.cos(alpha))
np.allclose(rho1, np.sqrt(z1**2 + y1**2))
#assert(np.allclose(z1, z3))
# now it is just a matter of aligning (x1, y1) to (x3, y3)
beta = np.arctan2(y3, x3) - np.arctan2(y1, x1)
x1, y1 = (x1 * np.cos(beta) - y1 * np.sin(beta),
x1 * np.sin(beta) + y1 * np.cos(beta))
# ensure the fotated v1 was correctly aligned
assert(np.allclose([x1, y1, z1], [x3, y3, z3]))
return alpha, beta
那你就打电话
alignment_angles((1,2,3), (3,4,5))
或者您也可以使用 3 行的 numpy 数组。
一开始我以为是球坐标系的应用,如果第二次旋转的轴是根据第一次旋转相应旋转的z轴就是这种情况。
编辑
有些向量无法与 x 轴上的旋转和 y 轴上的旋转对齐。
假设你想对齐向量 v1 = (1, 0, 0)
到向量 v2 = (0, 0, 1)
x 的旋转不会影响 v1,它总是指向 x 方向,那么当你绕 z 轴旋转时它总是在 XY 计划上。
你给出的例子确实给出了错误的答案,因为 asin
不是单射的。
我更改了函数以在无法对齐给定向量时引发值错误。
利用固定目标对齐方式,这可以通过三角函数以简单的方式完成:
import math
def to_y(x,y,z):
rx=-math.atan2(z,y) # or +math.atan2(z,-y)
y2=y*math.cos(rx)-z*math.sin(rx) # -> (x,y2,0)
return rx,math.atan2(x,y2)
当从 +x 或+z[=20 看原点时,旋转被定义为逆时针方向 =](右手法则);旋转方向始终是幅度较小的方向,但有可能找到物理上 更小 的旋转,如评论中所示。请注意,输入不需要归一化,并且永远不会产生 NaN(除非它出现在输入中)。
所以我不太精通线性代数,所以我正在努力解决这个问题。
我有一个单位向量v
。我想找到两个角度(角度 1,绕 x 轴旋转,角度 2,绕 z 轴旋转),这样当我按它们旋转 v
时,它会将向量 v
与 y 对齐-轴。从 v
与 y 轴对齐,所以我想要两个独特的角度。
这是我现在的代码,它需要 numpy 和 scipy:
import numpy as np
import random
from scipy.spatial.transform import Rotation as R
def rotation_from_unit_vectors(a, b):
v = np.cross(a, b)
c = np.dot(a, b)
s = np.linalg.norm(v)
kmat = np.array([[0, -v[2], v[1]], [v[2], 0, -v[0]], [-v[1], v[0], 0]])
rotation_matrix = np.eye(3) + kmat + kmat.dot(kmat) * ((1 - c) / (s ** 2))
return R.from_matrix(rotation_matrix)
y_axis = np.asarray([0.0, 1.0, 0.0])
alpha = random.uniform(0, 10)
beta = random.uniform(0, 10)
gamma = random.uniform(0, 10)
v = np.asarray([alpha, beta, gamma])
v = v / np.linalg.norm(v)
r = rotation_from_unit_vectors(v, y_axis)
print(r.as_euler('xyz', degrees = True))
print(r.apply(v))
嗯,不标准的问题,需要思考一下
给定 v1
和 v2
您希望 rotate_z(rotate_x(v1, alpha), beta)
与 v2
.
我们知道对齐向量可以通过简单的scaling缩放得到v2
,这样就得到x1,y3,z3 = v3 = v2 * |v1| / |v2|
。由于绕 z 轴旋转不影响 z 坐标,我们可以确定 alpha,使得 rotate_x(v1, alpha)
的 z 坐标等于 z3
。之后我们确定角度 beta
以正确对齐放置 X 和 Y 坐标
import numpy as np
def alignment_angles(v1, v2):
x1,y1,z1 = v1 # initial vector
x2,y2,z2 = v2 # reference vector
# magnitude of the two vectors
r1 = np.sqrt(x1**2 + y1**2 + z1**2)
r2 = np.sqrt(x2**2 + y2**2 + z2**2)
# this will be the result when aligning v1 to v2
# it has the magnitude of v1 and the direction of v2
x3,y3,z3 = x2*r1/r2, y2*r1/r2, z2*r1/r2
# the rotation in x must set the z coordinate to the
# final value, since the rotation over the z axis will
# not affect the z coordinate (this have two solutions)
rho1 = np.sqrt(z1**2 + y1**2)
if(abs(z3 / rho1) > 1):
raise ValueError('Cannot align these vectors')
alpha = np.arcsin(z3 / rho1) - np.arctan2(z1, y1);
# apply the rotation to make easier to calcualte the next stage
y1, z1 = (y1 * np.cos(alpha) - z1 * np.sin(alpha),
y1 * np.sin(alpha) + z1 * np.cos(alpha))
np.allclose(rho1, np.sqrt(z1**2 + y1**2))
#assert(np.allclose(z1, z3))
# now it is just a matter of aligning (x1, y1) to (x3, y3)
beta = np.arctan2(y3, x3) - np.arctan2(y1, x1)
x1, y1 = (x1 * np.cos(beta) - y1 * np.sin(beta),
x1 * np.sin(beta) + y1 * np.cos(beta))
# ensure the fotated v1 was correctly aligned
assert(np.allclose([x1, y1, z1], [x3, y3, z3]))
return alpha, beta
那你就打电话
alignment_angles((1,2,3), (3,4,5))
或者您也可以使用 3 行的 numpy 数组。
一开始我以为是球坐标系的应用,如果第二次旋转的轴是根据第一次旋转相应旋转的z轴就是这种情况。
编辑
有些向量无法与 x 轴上的旋转和 y 轴上的旋转对齐。
假设你想对齐向量 v1 = (1, 0, 0)
到向量 v2 = (0, 0, 1)
x 的旋转不会影响 v1,它总是指向 x 方向,那么当你绕 z 轴旋转时它总是在 XY 计划上。
你给出的例子确实给出了错误的答案,因为 asin
不是单射的。
我更改了函数以在无法对齐给定向量时引发值错误。
利用固定目标对齐方式,这可以通过三角函数以简单的方式完成:
import math
def to_y(x,y,z):
rx=-math.atan2(z,y) # or +math.atan2(z,-y)
y2=y*math.cos(rx)-z*math.sin(rx) # -> (x,y2,0)
return rx,math.atan2(x,y2)
当从 +x 或+z[=20 看原点时,旋转被定义为逆时针方向 =](右手法则);旋转方向始终是幅度较小的方向,但有可能找到物理上 更小 的旋转,如评论中所示。请注意,输入不需要归一化,并且永远不会产生 NaN(除非它出现在输入中)。