web-dev-qa-db-ja.com

C#の角度から円周上の点を計算していますか?

これは簡単な質問だと思いますが、現在のコードでは奇妙な結果が出ており、その理由を完全に理解するための数学の知識がありません。タイトルで述べたように、私の目標は単純です。中心点からある距離と角度でポイントを見つけたいだけです。

私の現在のコード:

Point centerPoint = new Point ( 0, 0 );
Point result      = new Point ( 0, 0 );
double angle      = 0.5; //between 0 and 2 * PI, angle is in radians
int distance      = 1000;

result.Y = centerPoint.Y + (int)Math.Round( distance * Math.Sin( angle ) );
result.X = centerPoint.X + (int)Math.Round( distance * Math.Cos( angle ) );

一般に、これはかなり適切に機能するようですが、さまざまな場所で問題が発生します。特に、角度がx軸とy軸の負の点に対応している場合に顕著です。明らかに私は何か間違ったことをしています-それは何についての考えですか?

更新:これは私の間違いでした。このコードは正常に機能します。機能しなかったいくつかの外れ値は、実際には1.5PIの角度の計算方法のバグが原因でした。私はそれを十分にチェックしたと思いましたが、明らかにチェックしていませんでした。時間を割いてくださった皆さんに感謝します。うまくいけば、上記の作業コードが他の誰かに役立つことを証明してくれるでしょう。

40
x4000

中心点を追加するのを忘れました:

result.Y = (int)Math.Round( centerPoint.Y + distance * Math.Sin( angle ) );
result.X = (int)Math.Round( centerPoint.X + distance * Math.Cos( angle ) );

残りは大丈夫です...(どのような奇妙な結果が出ましたか?正確な入力を与えることができますか?)

34
MartinStettner

まず、ラジアンを使用しているので、角度を次のように定義することはおそらく有益です。

double angle = (Math.PI / 3); // 60 degrees...

関数自体は正常に動作しています。丸めは、距離が十分に小さい場合にのみ回答に影響します。それ以外は、答えはうまく出てくるはずです。

気になる丸めの場合は、デフォルトで.NETが 銀行の丸め を行うことに注意してください。

result.X = (int)Math.Round(centerPoint.X + distance * Math.Cos(angle), MidpointRounding.AwayFromZero);
result.Y = (int)Math.Round(centerPoint.Y + distance * Math.Sin(angle), MidpointRounding.AwayFromZero);

代わりに。

さらに、あなたが望む質問では距離Xと角度Y...私はあなたがそれを点(X,Y)、それは完全に異なるからです。

距離の式は次のとおりです。

double distance = Math.Sqrt((centerPoint.X + result.X)^2 + (centerPoint.Y + result.Y)^2);
6
John Rasch

Swift3バージョン

func pointOnCircle(radius: Double, angleInDegrees: Double, Origin: CGPoint) -> CGPoint {
    let x = abs(Double(Origin.x) + radius * cos(angleInDegrees * (.pi / 180)))
    let y = abs(Double(Origin.y) - radius * sin(angleInDegrees * (.pi / 180)))

    return CGPoint(x: x, y: y)
}
3
Joe Susnick

正確なエラーに関する詳細情報がないと、何が問題なのかを判断するのは困難です。方程式は正しく見え、機能するはずです。渡した角度が90度を超える角度に対して正しいことを確認しますか?他に考えられる唯一のことは、あなたが距離(int)にMath.sin(double)の結果を掛けていることですが、それは実際には問題になりません。

1
JonBWalsh
-(NSMutableArray *)GetPointsForCircle
    {
       NSMutableArray *Points = [[NSMutableArray alloc] init];
       CGPoint CenterPoint = CGPointMake(160, 230);
       CGPoint Point;
       for (float Angel = 0; Angel <= 360; Angel+= 60)
         {
           Point.x = CenterPoint.x + 100 * cos(Angel);
           Point.y = CenterPoint.y + 100 * sin(Angel);
           [Points addObject:[NSValue valueWithCGPoint:Point]];
         }
       return Points;
    }

    - (CGPoint)pointOnCircle:(int)thisPoint withTotalPointCount:(int)totalPoints
     {
        CGPoint centerPoint = CGPointMake(self.view.frame.size.width / 2, self.view.frame.size.height / 2);
        float radius = 100.0;
        float angle = ( 2 * M_PI / (float)totalPoints ) * (float)thisPoint;
        CGPoint newPoint;
        newPoint.x = (centerPoint.x) + (radius * cosf(angle));
        newPoint.y = (centerPoint.y) + (radius * sinf(angle));
        return newPoint;   
    }
1
Waseem

とにかく、どこかにポイントを描画しようとしている場合は、Y軸が画面の上から下に伸びていることを考慮する必要があるので、あなたのsin要素は-sin(...)であり、+ sin(...)ではない

そう

result.Y = centerPoint.Y + (int)Math.Round( distance * Math.Sin( angle ) );

になるはずです:

result.Y = centerPoint.Y - (int)Math.Round( distance * Math.Sin( angle ) );

あなたがそれらを描こうとしないなら、私は問題が何であるか想像することができませんでした、あなたはいくつかの例をあげることができますか?

0
Andrea Ambu