我想用反余弦函数计算由三个点(其中一个点是两条线的交点)形成的两条线之间的角度,如下所示:
CGFloat a = initialPosition.x - origin.x;
CGFloat b = initialPosition.y - origin.y;
CGFloat c = currentPosition.x - origin.x;
CGFloat d = currentPosition.y - origin.y;
CGFloat angle = (180/M_PI) * acosf(((a*c) + (b*d)) / ((sqrt(a*a + b*b)) * (sqrt(c*c + d*d))));
不幸的是,acosf只返回介于0和pi之间的值。如何找到介于0和2 * pi之间的值(例如,以逆时针方式)?
答案 0 :(得分:7)
我不知道你使用的语言是什么,但通常有一个atan2函数可以提供360度的全部值。在这种情况下,您需要使用它两次,然后添加一些额外的逻辑。
某些伪代码将有助于清理问题:
initialAngle = atan2(initialPosition.y - origin.y, initialPosition.x - origin.x)
currentAngle = atan2(currentPosition.y - origin.y, currentPosition.x - origin.x)
# angle is measured from x axis anti-clock, so lets find the value starting from
# initial and rotating anti-clock to current, as a positive number
# so we want current to be larger than initial
if (currentAngle < initialAngle) {currentAngle += 2 pi}
# and then we can subtract
return currentAngle - initialAngle
我知道这不是使用acos,但这是多值的,所以这样做最终会使用大量关于容易出错的差异迹象的逻辑。 atan2就是你想要的。
答案 1 :(得分:2)
找到了一个简单的解决方案......这来自高中数学!首先制作一个由y = mx+c
形式的原点和initialPosition组成的线的等式。位于此行两侧的点将满足y < mx+c
或y > mx+c
,具体取决于它的位置。如果以顺时针或逆时针方向找到角度,请进行以下检查:
currentPosition.y < (currentPosition.x *(initialPosition.y - origin.y) + (initialPosition .x * origin.y - initialPosition.y * origin.x)) / (initialPosition.x - origin.x)
如果上述条件为真,则由origin和currentPosition形成的直线与origin和initialPosition形成的直线之间的角度小于180度(顺时针方向)。否则,它在顺时针方向上的角度大于180度,在逆时针方向的角度小于180度......依此类推。根据要求,最终角度为(angle returned by acos)
或(360 - (angle returned by acos))
。