2012-12-04 5 views
17

특정 그래픽을 그리는 작업이 있습니다. 이 작업의 일부로 도트를 45도 회전해야합니다.다른 점을 중심으로 한 점 회전

수식을 계산하는 데 이미 2 일을 소비했지만 제대로 처리하지 못했습니다. 나는이 특정 웹 사이트를 포함하여 곳곳에서 검색을 해왔다. 나는 아주 가까이 다가 가고 있지만 아직 거기에 없다. 여기

그것입니다 내가 4 가지 점

내가 여기에 질문의 범위를 벗어난이지만,이 위치를 계산하기 위해 특정 공식을 그릴 필요가있다 나는 결과로 얻고 무엇을 그것을 :

result

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); 
는 지금은 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) 
    }; 
} 

이렇게 사용하십시오. 중심점은 항상 0,0 경우

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

은 분명히 당신은 그에 따라 기능을 단순화하거나, 다른 사람, 또는 메소드를 오버로드하여 기본 매개 변수를 통해 중심점은 선택 할 수 있습니다. 또한 재사용 가능한 수학의 일부를 다른 정적 방법으로 캡슐화하기를 원할 수도 있습니다.

/// <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 –

관련 문제