4

次のように逆余弦関数を使用して、3 つの点 (点の 1 つは 2 つの線の交点) によって形成される 2 つの線の間の角度を計算します。

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

使用している言語はわかりませんが、通常、360 度全体から値を取得する atan2 関数があります。この場合、それを 2 回使用してから、ロジックを少し追加する必要があります。

いくつかの疑似コードが問題を解決するのに役立ちます:

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

簡単な解決策を見つけました...これは高校の数学から来ています! 最初に、フォームの原点と initialPosition から作成される直線の方程式を作成しy = mx+cます。この線の両側にある点は、その位置に応じて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))ます。

于 2011-08-05T05:04:32.630 に答える