2009-08-20 4 views
4

System.Drawing.Drawing2D.GraphicsPath.AddArc를 사용하여 0도에서 시작하여 135도까지 스윕하는 타원 호를 그립니다.GraphicsPath.AddArc는 startAngle 및 sweepAngle 매개 변수를 어떻게 사용합니까?

나는 타원에 대해 그려진 아크가 내가 기대했던 것과 일치하지 않는다는 점에 대해 언급하고 있습니다.

예를 들어, 다음 코드는 아래 이미지를 생성합니다. 녹색 원은 호의 끝점이 타원을 따라 점에 대한 수식을 사용할 것으로 기대합니다. 내 수식은 원에서는 작동하지만 타원에서는 사용할 수 없습니다.

이것은 극 좌표 대 데카르트 좌표와 관련이 있습니까?

private PointF GetPointOnEllipse(RectangleF bounds, float angleInDegrees) 
    { 
     float a = bounds.Width/2.0F; 
     float b = bounds.Height/2.0F; 

     float angleInRadians = (float)(Math.PI * angleInDegrees/180.0F); 

     float x = (float)((bounds.X + a) + a * Math.Cos(angleInRadians)); 
     float y = (float)((bounds.Y + b) + b * Math.Sin(angleInRadians)); 

     return new PointF(x, y); 
    } 

    private void Form1_Paint(object sender, PaintEventArgs e) 
    { 
     Rectangle circleBounds = new Rectangle(250, 100, 500, 500); 
     e.Graphics.DrawRectangle(Pens.Red, circleBounds); 

     System.Drawing.Drawing2D.GraphicsPath circularPath = new System.Drawing.Drawing2D.GraphicsPath(); 
     circularPath.AddArc(circleBounds, 0.0F, 135.0F); 
     e.Graphics.DrawPath(Pens.Red, circularPath); 

     PointF circlePoint = GetPointOnEllipse(circleBounds, 135.0F); 
     e.Graphics.DrawEllipse(Pens.Green, new RectangleF(circlePoint.X - 5, circlePoint.Y - 5, 10, 10)); 

     Rectangle ellipseBounds = new Rectangle(50, 100, 900, 500); 
     e.Graphics.DrawRectangle(Pens.Blue, ellipseBounds); 

     System.Drawing.Drawing2D.GraphicsPath ellipticalPath = new System.Drawing.Drawing2D.GraphicsPath(); 
     ellipticalPath.AddArc(ellipseBounds, 0.0F, 135.0F); 
     e.Graphics.DrawPath(Pens.Blue, ellipticalPath); 

     PointF ellipsePoint = GetPointOnEllipse(ellipseBounds, 135.0F); 
     e.Graphics.DrawEllipse(Pens.Green, new RectangleF(ellipsePoint.X - 5, ellipsePoint.Y - 5, 10, 10)); 
    } 

alt text

답변

3

GraphicsPath.AddArc는 당신이 그것을 물어 정확히 않습니다 - 그것은 호를 타원의 중심에서 돌출 라인까지 시계 방향으로 x 축에서 135도 정확한 각도로 .

그리기 원하는 원형 차트 조각의 직접 비율로 각도를 사용하면 불행히도 도움이되지 않습니다. 당신은 라디안 원에서 작동 각도 주어진, AddArc와 함께 사용할 필요가 B, 각도를 확인하려면 사용

B = Math.Atan2(sin(A) * height/width, cos(A)) 

높이이 타원의 그 어디.

ellipticalPath = new System.Drawing.Drawing2D.GraphicsPath(); 
ellipticalPath.AddArc(
    ellipseBounds, 
    0.0F, 
    (float) (180.0/Math.PI * Math.Atan2(
     Math.Sin(135.0 * Math.PI/180.0) * ellipseBounds.Height/ellipseBounds.Width, 
     Math.Cos(135.0 * Math.PI/180.0)))); 
e.Graphics.DrawPath(Pens.Black, ellipticalPath); 

과 같아야 결과는 다음과 같습니다 : alt text http://img216.imageshack.us/img216/1905/arcs.png

+0

쿨! 그거야. 그러나 나는 아직도 그것이 작동하는 이유를 이해하지 못합니다. 계산의 논리는 무엇입니까? 이것은 극 좌표 대 데카르트 좌표와 관련이 있습니까? – jameswelle

+0

GetPointOnEllipse는 두 단계로 점을 찾습니다. 1. X 축에서 각도 A로 R = 1 인 원의 원주를 (cos (A), sin (A)) 에 찾습니다. 2. 스트레치 변환을 사용하여 포인트를 (w * cos (A), h * sin (A))로 변환합니다. 스트레치 변환이 각도를 변경합니다! (우리가 원을 아주 넓게 펼쳤다면 어떤 각도가 될지 상상해 보라.) 새로운 각도 B를 찾으려면 tan (B) = y/x 따라서 B = atan (y/x)를주의하라. 0으로 나누는 것을 피하기 위해 우리는 B = atan2 (y, x) 을 사용할 것입니다. (x, y) = (w * cos (A), h * sin (A))로하면 B = atan2 (A) * w/cos (A)) 의미가 있습니까? –

+0

당신의 진술을 완전히 이해하지 못합니다 : "스트레치 변환이 각도를 변경합니다!". 출력 이미지에서 각이 다르다는 것을 알 수 있습니다. 그러나 내가 혼란스럽게 생각하는 것은 타원에 대한 공식입니다. 공식은 x = a cos (theta), y = b sin (theta)입니다.다른 점에서 그려지는 사실은 측정되는 각도가 AddArc에 의해 측정되는 각도와 다르다는 것을 의미합니까? 나는이 주제에 또 하나의 실을 발견했다. 그것은 극좌표와 관련이있는 문제를 지적하는 것 같습니다. http://bytes.com/topic/c-sharp/answers/665773-drawarc-ellipse-geometry-repost – jameswelle

2

enter image description here 내가 GraphicsPath.AddArc가 어떻게 작동하는지에 대해 혼란스러워지고 있다고 샘플 코드에서

, Form1_Paint의 끝에 다음을 추가하십시오 & 괜찮은 다이어그램을 찾을 수 없어 하나를 그렸습니다. 다른 누구도 이와 비슷한 고통을 겪었을 경우를 대비하여! http://imgur.com/lNBewKZ