В настоящее время я создаю код, который имеет дело с трехмерными векторами и вычисляет угол между ними после их поворота в соответствии с набором углов Эйлера. Частично это нормализация векторов по оси 0,0,1. В основном это просто для того, чтобы я мог легко построить графики распределения и векторные диаграммы и т. Д. c. Чтобы вычислить смещение и вектор, вокруг которого нужно повернуть, я просто использую точечные и перекрестные произведения, как показано ниже:
def RotationMatrix(axis, rotang):
"""
This uses Euler-Rodrigues formula.
"""
#Input taken in degrees, here we change it to radians
theta = rotang * 0.0174532925
axis = np.asarray(axis)
#Ensure axis is a unit vector
axis = axis/math.sqrt(np.dot(axis, axis))
#calclating a, b, c and d according to euler-rodrigues forumla requirments
a = math.cos(theta/2)
b, c, d = axis*math.sin(theta/2)
a2, b2, c2, d2 = a*a, b*b, c*c, d*d
bc, ad, ac, ab, bd, cd = b*c, a*d, a*c, a*b, b*d, c*d
#Return the rotation matrix
return np.array([[a2+b2-c2-d2, 2*(bc-ad), 2*(bd+ac)],
[2*(bc+ad), a2+c2-b2-d2, 2*(cd-ab)],
[2*(bd-ac), 2*(cd+ab), a2+d2-b2-c2]])
def ApplyRotationMatrix(vector, rotationmatrix):
"""
This function take the output from the RotationMatrix function and
uses that to apply the rotation to an input vector
"""
a1 = (vector[0] * rotationmatrix[0, 0]) + (vector[1] * rotationmatrix[0, 1]) + (vector[2] * rotationmatrix[0, 2])
b1 = (vector[0] * rotationmatrix[1, 0]) + (vector[1] * rotationmatrix[1, 1]) + (vector[2] * rotationmatrix[1, 2])
c1 = (vector[0] * rotationmatrix[2, 0]) + (vector[1] * rotationmatrix[2, 1]) + (vector[2] * rotationmatrix[2, 2])
return np.array((a1, b1, c1))
def CalculateAngleBetweenVector(vector, vector2):
"""
Does what it says on the tin, outputs an angle in degrees between two input vectors.
"""
dp = np.dot(vector, vector2)
maga = math.sqrt((vector[0] ** 2) + (vector[1] ** 2) + (vector[2] ** 2))
magb = math.sqrt((vector2[0] ** 2) + (vector2[1] ** 2) + (vector2[2] ** 2))
magc = maga * magb
dpmag = dp / magc
#These if statements deal with rounding errors of floating point operations
if dpmag > 1:
error = dpmag - 1
print('error = {}, do not worry if this number is very small'.format(error))
dpmag = 1
elif dpmag < -1:
error = 1 + dpmag
print('error = {}, do not worry if this number is very small'.format(error))
dpmag = -1
angleindeg = ((math.acos(dpmag)) * 180) / math.pi
return angleindeg
axis = (0,0,1)
Vector1 = (0,1,0)
#ensure things are unit vectors
Vector1 = Vector1 / np.linalg.norm(Vector1)
#calculate the offset and axis of rotation to take vector to the z axis
angle1 = CalculateAngleBetweenVector(axis, Vector1)
cross1 = np.cross(axis, Vector1)
RM1 = RotationMatrix(cross1, angle1)
Vector1rot = ApplyRotationMatrix(Vector1, RM1)
print(Vector1rot)
Кажется, все работает нормально, однако, если вы просто скопируете и вставите приведенный выше код, вы получите скорее всего обнаружит, что повернутый вектор равен 1x10 ^ -9, 0, 1, а не 0,0,1.
Есть ли простой способ решить эту проблему с операциями с плавающей запятой?