在python中,我有一个脚本可以用来确定两条边之间的角度差异:
#python
import math
def uDirection (v1, v2):
return (v2[0]-v1[0], v2[1]-v1[1])
def dotUV (u1, u2):
return (u1[0]*u2[0] + u1[1]*u2[1])
def uLength (u):
return math.sqrt(dotUV(u,u))
def uNormalize (u):
r = [0.0] * 2
u_len = uLength(u)
if u_len > 0.0:
u_invLen = 1.0 / u_len
r[0] = u[0] * u_invLen
r[1] = u[1] * u_invLen
return r
def angle(dotProduct):
return math.degrees(math.acos(dotProduct))
p1,p2 = (0,0),(1,1) #<---- edge 1
p3,p4 = (0,0),(1,0) #<---- edge 2
dir = uDirection(p1,p2)
dir2 = uDirection(p3,p4)
dir_n = uNormalize(dir)
dir2_n = uNormalize(dir2)
dotProduct = dotUV(dir_n, dir2_n)
ang1 = angle(dotProduct)
#ang1 = 45
差异角度为45度,如果我想旋转边缘2(p3,p4)以匹配边缘1(p1,p2),我需要确定所需的旋转是顺时针还是逆时针。目前逆时针方向,但如果边缘的位置反转,它仍然会给我45度的差异,但方向边缘2必须顺时针移动。有没有办法可以修改我要确定的顺时针方向v逆时针方向?
答案 0 :(得分:0)
让两个向量e1
和e2
。我假设您试图在这两者之间旋转小角度:
if e1[0] * e2[1] - e1[0] * e2[1] < 0:
pass # Rotate CW
else
pass # Rotate CCW
应该做的伎俩。
如果您打算及时逐步轮换e2
,则需要控制转速以及dt
(当前帧和最后一帧之间的时间差值),类似于:
rotspeed = .5 # Whatever suits your framerate and desired speed
if e1[0] * e2[1] - e1[0] * e2[1] < 0:
angle = 2 * math.pi - rotspeed * dt # Rotate CW
else:
angle = rotspeed * dt # Rotate CCW
x = math.cos(math.atan2(e2[0], e2[1]) + angle)
y = math.sin(math.atan2(e2[0], e2[1]) + angle)
next_e2 = [x, y]
答案 1 :(得分:0)
您获得45
两种方式的原因是因为cos
函数是偶数函数,因此相同幅度的负点和正点积将映射达到相同的价值。
您可以使用dotProduct
的 arcsin 来确定转换为旋转方向的角度符号:
def angle(dotProduct):
sign = math.asin(dotProduct) // abs(math.asin(dotProduct))
return sign * math.degrees(math.acos(dotProduct))
+ve
表示顺时针方向和-ve
辅助方向,反之亦然。