2012-12-04 6 views
17

私は特定のグラフィックを描画するタスクがあります。この作業の一環として、あるドットを45度回転させる必要があります。別のポイントの周りの点を回転する

私はすでに数式の計算に2日間費やしましたが、それは正しくできませんでした。 私はこの特定のウェブサイトを含めて全面的に検索してきましたが、私はとても近づいていますが、私はまだそこにいません。

ここにある:私は質問の範囲外であるが位置を計算するための具体的な式を持っている私は、4つの異なるポイントに

を描画する必要が が、ここで私は、結果として得ているものですそれを:

int radius = 576; 
int diameter = radius * 2; 
Point blueA = new Point(561, 273); 
Point greenB = new Point(273, 561); 
Point yellowC = new Point (849, 561); 
Point redD = new Point (561, 849); 

result

今私は45度で、この点を回転させる必要があります。私はそれを達成するために、次のコードを使用します。

double rotationAngle = 45; 
double rotationRadians = rotationAngle * (Math.PI/180); 
int center = radius;  
result.X = (int)(Math.Cos(rotationRadians) * ((double)result.X - (double)center) - (double)Math.Sin(rotationRadians) * ((double)result.Y - center) + (double)center); 
result.Y = (int)(Math.Sin(rotationRadians) * ((double)result.X - (double)center) + (double)Math.Cos(rotationRadians) * ((double)result.Y - center) + (double)center); 

をしかし、それは私がなってんだよ:すべてのヘルプははるかに

答えて

35

問題はあなたがどのint center = radiusあると認識されるであろう

Result

int radius = 576を設定します。 xとyの位置を持つべき点を中心に回転しているので、これは意味をなさない。

原点を中心に回転すると、xyの両方が0ではなく、576である必要があります。

だから、これを試してください。

/// <summary> 
/// Rotates one point around another 
/// </summary> 
/// <param name="pointToRotate">The point to rotate.</param> 
/// <param name="centerPoint">The center point of rotation.</param> 
/// <param name="angleInDegrees">The rotation angle in degrees.</param> 
/// <returns>Rotated point</returns> 
static Point RotatePoint(Point pointToRotate, Point centerPoint, double angleInDegrees) 
{ 
    double angleInRadians = angleInDegrees * (Math.PI/180); 
    double cosTheta = Math.Cos(angleInRadians); 
    double sinTheta = Math.Sin(angleInRadians); 
    return new Point 
    { 
     X = 
      (int) 
      (cosTheta * (pointToRotate.X - centerPoint.X) - 
      sinTheta * (pointToRotate.Y - centerPoint.Y) + centerPoint.X), 
     Y = 
      (int) 
      (sinTheta * (pointToRotate.X - centerPoint.X) + 
      cosTheta * (pointToRotate.Y - centerPoint.Y) + centerPoint.Y) 
    }; 
} 

同様に使用してください。

明らか
Point center = new Point(0, 0); 
Point newPoint = RotatePoint(blueA, center, 45); 

中心点が常に0,0であれば、あなたはそれに応じて機能を簡素化するか、あるいはデフォルトパラメータを経由して、またはメソッドをオーバーロードすることにより、中心点をオプションにすることができます。また、再利用可能な数学のいくつかを他の静的メソッドにもカプセル化したいと思うでしょう。

/// <summary> 
/// Converts an angle in decimal degress to radians. 
/// </summary> 
/// <param name="angleInDegrees">The angle in degrees to convert.</param> 
/// <returns>Angle in radians</returns> 
static double DegreesToRadians(double angleInDegrees) 
{ 
    return angleInDegrees * (Math.PI/180); 
} 

/// <summary> 
/// Rotates a point around the origin 
/// </summary> 
/// <param name="pointToRotate">The point to rotate.</param> 
/// <param name="angleInDegrees">The rotation angle in degrees.</param> 
/// <returns>Rotated point</returns> 
static Point RotatePoint(Point pointToRotate, double angleInDegrees) 
{ 
    return RotatePoint(pointToRotate, new Point(0, 0), angleInDegrees); 
} 

同様に使用してください。

Point newPoint = RotatePoint(blueA, 45); 

最後に、GDIを使用している場合は、単にRotateTransformを実行することもできます。 を参照してください:http://msdn.microsoft.com/en-us/library/a0z3f662.aspx

Graphics g = this.CreateGraphics(); 
g.TranslateTransform(blueA); 
g.RotateTransform(45); 
+0

私は投稿後にこの投稿を見ました。この式は機能します。 –

+0

それは完璧です!ありがとうございました。 現在のスクリーンショットは次のとおりです。 http://s8.postimage.org/e7r44klcl/result.png –

+1

あなたは正しいです。かっこがひっくり返って単体テストで間違っていたので、OS libへの投稿者は手書きでこれをコピーしなければなりません。 –

1

あなたは数学が私には奇妙に見えますね。私はdx = r * Cos(theta)とdy = r * Sin(theta)だと思います。

これは私が書いた小さなプログラムですが、これは私を悩ましていたので、私は数学をやっていない年です。

Point center = new Point() { X = 576, Y = 576 }; 

Point previous = new Point() { X = 849, Y=561 }; 
double rotation = 45; 
double rotationRadians = rotation * (Math.PI/180); 

//get radius based on the previous point and r squared = a squared + b squared 
double r = Math.Sqrt(Math.Pow(previous.X - center.X, 2) + Math.Pow(previous.Y - center.Y, 2)); 
Console.WriteLine("r = " + r.ToString()); 

//calculate previous angle 
double previousAngle = Math.Atan((previous.Y - center.Y)/(previous.X - center.X)); 
Console.WriteLine("Previous angle: " + previousAngle.ToString()); 

double newAngle = previousAngle + rotationRadians; 

Point newP = new Point(); 
newP.X = center.X + r * Math.Cos(newAngle); 
newP.Y = center.Y + r * Math.Sin(newAngle); 

Console.WriteLine("(" + newP.X.ToString() + ", " + newP.Y.ToString() + ")"); 

Console.ReadLine(); 
+0

私はこのメソッドをコードのさまざまな部分で使い、ある段階でこれらの座標で "前の"点を得ました:X = 576 Y = 20. この場合、私は "DivideByZeroException"を取得しています ここに私が "try - > catch"ブロックを置いた場合の結果:http://s10.postimage.org/azjdc7rex/exception.png –

関連する問題