2012-12-04 229 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); 

但是,這就是我得到:

Result

任何幫助,將不勝感激

回答

35

的問題是int center = radius你是設置爲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 –