4

我想使用反余弦函数计算由三个点(其中一个点是两条线的交点)形成的两条线之间的角度,如下所示:

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 之间的值(例如,逆时针方向)?

4

2 回答 2

6

我不知道您使用的是什么语言,但通常有一个 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 是你想要的。

于 2011-08-04T12:59:49.957 回答
2

找到了一个简单的解决方案......这来自高中数学!首先做一个由原点和形式的初始位置组成的直线方程y = mx+c。位于这条线两侧的点将满足y < mx+cy > 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))

于 2011-08-05T05:04:32.630 回答