比较边缘以确定角度的差异是否需要顺时针或逆时针旋转才能匹配

时间:2016-08-04 20:33:55

标签: python rotation

在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逆时针方向?

2 个答案:

答案 0 :(得分:0)

让两个向量e1e2。我假设您试图在这两者之间旋转小角度

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辅助方向,反之亦然。