web-dev-qa-db-ja.com

与えられた中心点、半径、次数を持つ円上の点を見つける

このような計算をしてから10年が経ちました... 2Dでゲームをプログラミングし、プレイヤーを動かしています。プレーヤーを動かすと、-360〜360の正のOR負のangle(degree)が与えられた場合、プレーヤーの位置から200ピクセル離れた円上の点を計算しようとしています。画面は画面の中心点が0,0の1280x720プレイヤーはこのデカルト座標系全体を動き回っています。見つけようとしている点は画面の外にある可能性があります。

私は記事で式を試しました 半径と角度でポイントを見つける しかし、角度を-360から360に渡すと奇妙な結果が得られるため、「角度」が何であるか理解していないと思いますCos(角度)またはSin(角度)。

だから、たとえば...

  • デカルト平面上の1280x720
  • センターポイント(プレーヤーの位置):
    • let x =最小-640から最大640までの数値
    • y =最小-360から最大360までの間の数値とします
  • プレーヤーの周囲の円の半径:常にr = 200とします
  • 角度:a = -360から360の間に与えられた数値(負の場合は下向きに、正の場合は上向きにできるため、-10と350で同じ答えが得られます)

円上のXを返す式は何ですか?

円でYを返す式は何ですか?

enter image description hereenter image description here

72
Kyle Anderson

リンクからの単純な方程式は、円上の点のX座標とY座標を与えます円の中心を基準にして

X = r * cosine(angle)  
Y = r * sine(angle)

これは、ポイントが円の中心からどれだけ離れているかを示します。中心の座標(Cx、Cy)があるので、計算されたオフセットを単純に追加します。

円上の点の座標は次のとおりです。

X = Cx + (r * cosine(angle))  
Y = Cy + (r * sine(angle))
59
yoozer8

使用しているコードを投稿する必要があります。それは問題を正確に特定するのに役立ちます。

ただし、角度を-360〜360の単位で測定することに言及したため、おそらく数学ライブラリに誤った単位を使用している可能性があります。三角関数の実装のほとんどは、入力にラジアンを使用します。そして、代わりに学位を使用する場合...あなたの答えは奇妙に間違っているでしょう。

x_oncircle = x_Origin + 200 * cos (degrees * pi / 180)
y_oncircle = y_Origin + 200 * sin (degrees * pi / 180)

また、象限が予期したものではない状況に陥ることがあることに注意してください。これは、角度ゼロがどこにあるかを慎重に選択するか、期待する象限を手動で確認し、結果値に独自の符号を適用することで修正できます。

12
Seth Battin

このタイプの操作にはマトリックスを使用することを強くお勧めします。これは最も一般的なアプローチです。以下の例を参照してください。

// 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); 
  • サイドノート、慣習は、反時計回りの開始フォーム(正)X軸の角度を測定することです
6
Johan Larsson

Cos(angle)またはSin(angle)に-360から360としてAngleを渡すと、奇妙な結果になります。

あなたの試みがうまくいかなかったのは、あなたが角度を度で渡していたからだと思います。 sinおよびcos三角関数はラジアンで表された角度を想定しているため、数値は0から2*M_PIの範囲である必要があります。 d度の場合、M_PI*d/180.0を渡します。 M_PIは、math.hヘッダーで定義された定数です。

5
dasblinkenlight

コードで時計の針の動きを形成するためにもこれが必要でした。私はいくつかの数式を試しましたが、それらは機能しませんでしたので、これが私が思いついたものです:

  • モーション-時計回り
  • ポイント-6度ごと(360度を60分で割ると6度になるため)
  • 手の長さ-65ピクセル
  • 中央-x = 75、y = 75

したがって、式は

x=Cx+(r*cos(d/(180/PI))
y=Cy+(r*sin(d/(180/PI))

ここで、xとyは円周上の点、CxとCyは中心のx、y座標、rは半径、dは度数です。

4
Wraithious

上記の貢献が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);

}
1
TomOfMilton

これがc#の実装です。このメソッドは、radiuscenterangle 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);
1

推奨:

 public static Vector3 RotatePointAroundPivot(Vector3 point, Vector3 
pivot, Vector3 angles)
    {
            return Quaternion.Euler(angles) * (point - pivot) + pivot;
    }
0
kid

答えは正反対でなければなりません。

X = Xc + rSin(角度)

Y = Yc + rCos(角度)

xcとYcは円の中心座標で、rは半径です。

0
Aditya Aggarwal