(警告:ここでは2つの近似を使用しています。1つ目はdを弧の長さとして、2つ目は直交長として取得します。これらの近似はどちらもdの値が比較的小さい場合に適していますが、これらは満たされません。コメントで明確にされた正確な質問)
幸いなことに、これに関する数学は比較的単純です。まず、中心位置から現在の位置までの相対ベクトルを見つけることができます。
deltaX = oX-cX;
deltaY = oY-cY;
そして、この相対ベクトルが得られたら、作業中の円の長さを知ることで、その半径を知ることができます。
radius = sqrt(deltaX*deltaX+deltaY*deltaY);
さらに、相対ベクトルから、cXからoXへの直線の正確な角度を見つけることができます。
curTheta = atan2(deltaX, deltaY);
今、物事は少しトリッキーになります。まず、円の円周、つまり角度が2πの円弧の「弧の長さ」は2πrであることを理解してください。一般に、半径rの円に沿った角度測定値がθの弧の弧長は、ちょうどθrです。ダイアグラムでdを弧の長さとして使用する場合、半径がわかっているので、分割するだけでシータの変化を見つけて新しい位置に移動できます。
deltaTheta = d/radius; // treats d as a distance along the arc
dを直線距離にする必要がある場合、状況は少し複雑になりますが、幸い、それほど多くはありません。そこでは、dは、他の2つの辺が円の半径である(それぞれcX / cYからoX / oYおよびaX / aYである)二等辺三角形の片側であり、この二等辺三角形を2等分すると、それぞれ2つの直角三角形が得られます。片側はd / 2、斜辺は半径です。これは、角度の半分の正弦が(d / 2)/半径であることを意味します。したがって、全角度はこれの2倍です。
deltaTheta = 2*asin(d/(2*radius)); // treats d as a linear distance
この式からアシンを取り、2をキャンセルした場合、これは最後の式と同じになることに注意してください。これは、sin(x)がxの小さな値の場合およそxであるということと同じであり、これは知っておくと便利な近似です。
これで、加算または減算するだけで新しい角度を見つけることができます。
newTheta = curTheta+deltaTheta; // This will take you to aX, aY. For bX/bY, use curTheta-deltaTheta
新しい角度を取得したら、基本的なトリガーを使用して、更新された相対ベクトルを見つけることができます。
newDeltaX = radius*cos(newTheta);
newDeltaY = radius*sin(newTheta);
そして、中心位置と相対ベクトルから(最終的に)ターゲットポイントを見つけることができます。
aX = cX+newDeltaX;
aY = cY+newDeltaY;
さて、これらすべてについて、いくつかの大きな注意点があります。まず、この数学はほとんどが浮動小数点であり、実際にはほぼ浮動小数点数であることがわかります。このメソッドを使用してループで更新し、すべてのステップで整数値に丸めると、円が閉じない(ループを回るたびに内側または外側に螺旋を描く)から最初に開始しないまで、すべてのことができます。場所!(dが小さすぎる場合、aX / aYまたはbX / bYの丸められたバージョンが、開始位置oX / oYがあった場所とまったく同じであることに気付く場合があります。)別の場合、これは、特に、行う; あなたのキャラクターが円弧状に移動されようとしている知っていれば、一般的には、事前に全体のアークを計画しなければならないではありませんここで最も高価な計算の多くをフロントローディングしてコストを削減できるため、このようにフレームごとにチェックしてください。本当にこのようにインクリメンタルに更新したい場合、コストを削減するもう1つの良い方法は、そもそもtrigを使用しないことです。dが小さく、正確である必要はないが非常に近い場合、中心に向かうベクトルに直交する長さdのベクトルをoX / oYに追加することにより、「トリック」を行うことができます(a (dX、dY)に直交するベクトルは(-dY、dX))で与えられ、それを正しい長さに縮小します。このコードについては、段階を追って説明することはしませんが、これまでに見てきたことを踏まえると、理解できると思います。最後のステップで新しいデルタベクトルを暗黙的に「縮小」することに注意してください。
deltaX = oX-cX; deltaY = oY-cY;
radius = sqrt(deltaX*deltaX+deltaY*deltaY);
orthoX = -deltaY*d/radius;
orthoY = deltaX*d/radius;
newDeltaX = deltaX+orthoX; newDeltaY = deltaY+orthoY;
newLength = sqrt(newDeltaX*newDeltaX+newDeltaY*newDeltaY);
aX = cX+newDeltaX*radius/newLength; aY = cY+newDeltaY*radius/newLength;
d
直線距離またはそれがアークのですか?