このような計算をしてから10年が経ちました... 2Dでゲームをプログラミングし、プレイヤーを動かしています。プレーヤーを動かすと、-360〜360の正のOR負のangle(degree)が与えられた場合、プレーヤーの位置から200ピクセル離れた円上の点を計算しようとしています。画面は画面の中心点が0,0の1280x720プレイヤーはこのデカルト座標系全体を動き回っています。見つけようとしている点は画面の外にある可能性があります。
私は記事で式を試しました 半径と角度でポイントを見つける しかし、角度を-360から360に渡すと奇妙な結果が得られるため、「角度」が何であるか理解していないと思いますCos(角度)またはSin(角度)。
だから、たとえば...
円上のXを返す式は何ですか?
円でYを返す式は何ですか?
リンクからの単純な方程式は、円上の点のX座標とY座標を与えます円の中心を基準にして。
X = r * cosine(angle)
Y = r * sine(angle)
これは、ポイントが円の中心からどれだけ離れているかを示します。中心の座標(Cx、Cy)があるので、計算されたオフセットを単純に追加します。
円上の点の座標は次のとおりです。
X = Cx + (r * cosine(angle))
Y = Cy + (r * sine(angle))
使用しているコードを投稿する必要があります。それは問題を正確に特定するのに役立ちます。
ただし、角度を-360〜360の単位で測定することに言及したため、おそらく数学ライブラリに誤った単位を使用している可能性があります。三角関数の実装のほとんどは、入力にラジアンを使用します。そして、代わりに学位を使用する場合...あなたの答えは奇妙に間違っているでしょう。
x_oncircle = x_Origin + 200 * cos (degrees * pi / 180)
y_oncircle = y_Origin + 200 * sin (degrees * pi / 180)
また、象限が予期したものではない状況に陥ることがあることに注意してください。これは、角度ゼロがどこにあるかを慎重に選択するか、期待する象限を手動で確認し、結果値に独自の符号を適用することで修正できます。
このタイプの操作にはマトリックスを使用することを強くお勧めします。これは最も一般的なアプローチです。以下の例を参照してください。
// The center point of rotation
var centerPoint = new Point(0, 0);
// Factory method creating the matrix
var matrix = new RotateTransform(angleInDegrees, centerPoint.X, centerPoint.Y).Value;
// The point to rotate
var point = new Point(100, 0);
// Applying the transform that results in a rotated point
Point rotated = Point.Multiply(point, matrix);
Cos(angle)またはSin(angle)に-360から360としてAngleを渡すと、奇妙な結果になります。
あなたの試みがうまくいかなかったのは、あなたが角度を度で渡していたからだと思います。 sin
およびcos
三角関数はラジアンで表された角度を想定しているため、数値は0
から2*M_PI
の範囲である必要があります。 d
度の場合、M_PI*d/180.0
を渡します。 M_PI
は、math.h
ヘッダーで定義された定数です。
コードで時計の針の動きを形成するためにもこれが必要でした。私はいくつかの数式を試しましたが、それらは機能しませんでしたので、これが私が思いついたものです:
したがって、式は
x=Cx+(r*cos(d/(180/PI))
y=Cy+(r*sin(d/(180/PI))
ここで、xとyは円周上の点、CxとCyは中心のx、y座標、rは半径、dは度数です。
上記の貢献がArduino LCDコンパスを生成するのにどのように役立ったかを共有したいと思いました。これが正しいエチケットであることを願っています...
上記のジオメトリジャイアントの肩の上に立っている間、このサンプルコンパスを作成できました。 複数のベアリングを備えたArduino TFTコンパス
私が繰り返し呼び出した関数のコード(小さな黄色のテキストで表示されるさまざまなベアリングの場合)はArduino(「C」のようなもの)で記述されており、かなり翻訳可能です。
void PaintCompassNeedle( int pBearingInDegrees, int pRadius, TSPoint pCentrePt ) {
// ******************************************************************************
// * Formula for finding pointX on the circle based on degrees around the circle:
// * x_oncircle = x_Origin + radius * cos (degrees * pi / 180)
// * y_oncircle = y_Origin - radius * sin (degrees * pi / 180) //minus explained
// * Thanks to folks at stackoverflow...standing on the shoulders of giants. :)
float bearingInRads = (pBearingInDegrees) * PI / 180;
// Degrees vs Rads...The math folks use Rads in their formulas
// *******************************************************************
// * bearingPt is the point on the circle that we are trying to find
TSPoint bearingPt;
// Find the X on the circle starting with orgin (centre)
bearingPt.x = pCentrePt.x + pRadius * sin(bearingInRads);
// Notice the "minus" R * cos()...because TFT the y is upside down bearingPt.y =
pCentrePt.y - pRadius * cos(bearingInRads);
// * Extra Explanation: The TFT is the graphical display I'm using and it
// * calculates x & y from the top left of screen (portrait mode) as (0,0)
// * ...so by Subtracting from the Y orgin...I flip it vertically
// * Other folks using x,y as increasing to the right and up respectively
// * would keep the plus sign after the pCentrePt.y
// *************************************************************************
// ***************************************************************
// * This part will change for the final product...but leaving
// * it because when call numerous times it shows it working for
// * a number of different quadrants (displaying yellow degrees text)
tft.fillCircle( bearingPt.x, bearingPt.y, 5, RED);
tft.setCursor( bearingPt.x, bearingPt.y );
tft.setTextSize( 1 );
tft.setTextColor( YELLOW );
tft.print( pBearingInDegrees );
TSPoint innerPt;
innerPt.x = pCentrePt.x + pRadius/2 * sin(bearingInRads);
innerPt.y = pCentrePt.y - pRadius/2 * cos(bearingInRads);
tft.drawLine(innerPt.x, innerPt.y, bearingPt.x, bearingPt.y, RED);
}
これがc#の実装です。このメソッドは、radius
、center
、angle interval
パラメータとして。角度はラジアンとして渡されます。
public static List<PointF> getCircularPoints(double radius, PointF center, double angleInterval)
{
List<PointF> points = new List<PointF>();
for (double interval = angleInterval; interval < 2 * Math.PI; interval += angleInterval)
{
double X = center.X + (radius * Math.Cos(interval));
double Y = center.Y + (radius * Math.Sin(interval));
points.Add(new PointF((float)X, (float)Y));
}
return points;
}
そして呼び出しの例:
List<PointF> LEPoints = getCircularPoints(10.0f, new PointF(100.0f, 100.0f), Math.PI / 6.0f);
推奨:
public static Vector3 RotatePointAroundPivot(Vector3 point, Vector3
pivot, Vector3 angles)
{
return Quaternion.Euler(angles) * (point - pivot) + pivot;
}
答えは正反対でなければなりません。
X = Xc + rSin(角度)
Y = Yc + rCos(角度)
xcとYcは円の中心座標で、rは半径です。