2009-08-20 13 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度の正確な角度で。

描画したい円グラフのスライスの正面に角度を使用している場合、残念ながら、これは役立ちません。サークル上で動作角度A与えられた、あなたはAddArcを使用する必要があり、角度Bを調べるには、ラジアンで、使用:

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

高さは楕円形のものです。あなたのサンプルコードで

、Form1_Paintの末尾に次を追加してみてください:次のように

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

Cool!それは動作します。しかし、私はまだそれが動作する理由を理解していない。あなたの計算の背後にある論理は何ですか?これは極座標対デカルト座標と何か関係がありますか? – jameswelle

+0

GetPointOnEllipseは、次の2つのステップでポイントを見つけます。 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)に注意してください。ゼロで割ることを避けるために、B = atan2(y、x)を使用する。 (x、y)=(w * cos(A)、h * sin(A))とすると、B = atan2 (A)* h/w、cos(A)) 意味がありますか? –

+0

私はあなたの声明を完全に理解していません。「ストレッチ変換は角度を変えます!出力画像から、角度が違うことがわかります。しかし、私が混乱しているのは、楕円上の点の数式です。式はx = acos(theta)、y = bsin(theta)です。異なる点を描くということは、測定される角度がAddArcによって測定される角度と異なることを意味しますか?私はこのテーマに別のスレッドを見つけました。極座標と関係がある問題を指摘しているようです。 http://bytes.com/topic/c-sharp/answers/665773-drawarc-ellipse-geometry-repost – jameswelle

2

enter image description hereを私はGraphicsPath.AddArcが働いたかについて混乱してきました。 &私はまともな図を見つけることができなかったので、私はそれを描きました。ちょうど誰かが同様に苦しんでいる場合に備えて! http://imgur.com/lNBewKZ

関連する問題