none
WPFのC#で塗りつぶしパイを描画する方法を教えてください。 RRS feed

  • 質問

  • いつもお世話になります。
    VisualC#2010、WindowsXPでの動作について質問があります。
    WPFのC#で塗りつぶしパイを描画する方法を教えてください。
    円は、

    Ellipse ellipse = new Ellipse();
    ellipse.Fill = Brushes.Aqua;
    ellipse.Width = 200;
    ellipse.Height = 200;
    Canvas.SetLeft(ellipse, 10);
    Canvas.SetTop(ellipse, 10);

    Canvas canvas = new Canvas();
    canvas.Children.Add(ellipse);

    window.Content = canvas;

    のように描けます。

    三角形であれば、

    Polygon lines = new Polygon();
    lines.Stroke = Brushes.Black;
    lines.Fill = Brushes.Aqua;
    lines.Points.Add(new Point(200,200));
    lines.Points.Add(new Point(300,400));
    lines.Points.Add(new Point(400,300));

    Canvas canvas = new Canvas();
    canvas.Children.Add(lines);

    window.Content = canvas;

    のように描けます。
    では、この三角形の短い辺の部分を円弧にしたパイ型にするにはどうしたらよかろうか、というのではたと困っています。
    アドバイスをお願いします。

    2010年10月27日 13:58

回答

  • Path は、Segments に追加した順番に描かれます。また、円弧の角度が 180 度をこえない場合、IsLargeArc は false を指定します。

    半径100、角度90度のパイを描画するサンプルを掲載しておきます。

    LineSegment line1 = new LineSegment();
    line1.Point = new Point(100, 30);
    
    ArcSegment arc = new ArcSegment();
    arc.Size = new Size(100, 100);
    arc.IsLargeArc = false;
    arc.SweepDirection = SweepDirection.Clockwise;
    arc.Point = new Point(30, 100);
    
    LineSegment line2 = new LineSegment();
    line2.Point = new Point(30, 30);
    
    PathFigure figure = new PathFigure();
    figure.StartPoint = new Point(30, 30);
    figure.Segments.Add(line1);
    figure.Segments.Add(arc);
    figure.Segments.Add(line2);
    
    PathGeometry geometory = new PathGeometry();
    geometory.Figures.Add(figure);
    
    Path path = new Path();
    path.Fill = Brushes.Red;
    path.Stroke = Brushes.Black;
    path.StrokeThickness = 2;
    path.Data = geometory;
    
    

    なかむら(http://d.hatena.ne.jp/griefworker)
    • 回答としてマーク d-kot 2010年10月29日 3:48
    2010年10月29日 0:44

すべての返信

  • Path クラスを使えばいいと思います。

    http://msdn.microsoft.com/ja-jp/library/ms747393(VS.80).aspx#paths

     


    なかむら(http://d.hatena.ne.jp/griefworker)
    2010年10月27日 23:49
  • pathで円か直線(線分)かベジェ曲線を描けるようですが、円弧はどうやるんでしょう?
    ベジェ曲線で正円の円弧を近似できるものなのでしょうか?
    ひょっとして線分をつなぐとか?
    それだと直線ですが、充分細かくとれば円にはなりますね。
    2010年10月28日 6:54
  • Path と ArcSegment を使えば、楕円の円弧を描けます。

    http://msdn.microsoft.com/ja-jp/library/ms745030(v=VS.80).aspx

    これを、直線を描く LineSegment とつなげれば、パイの形をした図を描けると思います。

     


    なかむら(http://d.hatena.ne.jp/griefworker)
    2010年10月28日 7:13
  • なかむらさん、ありがとうございます。
    次のようにしてみて、(150,150)を中心に、90度の円弧というか、三角形を描けました。
    この時点でふたつ疑問と問題があります。

    arc.SweepDirection = "CounterClockwise";
    の行の指定がわからないので、この行はエラーになり、コメントアウトしました。
    ここで、膨らむ方向に指定できれば円弧になると思います。
    この指定方法を教えてください。

    もうひとつは、円弧の開始位置と終了位置を指定していますが、角度と半径を指定して、円弧を描くことはできないでしょうか?

    //円弧
    ArcSegment arc = new ArcSegment();
    arc.RotationAngle = 90;
    arc. IsLargeArc = true;
    //arc.SweepDirection = "CounterClockwise";
    arc.Point = new Point(150,50); //円弧の開始位置
    arc.Point = new Point(250,150); //円弧の終了位置

    //線分
    LineSegment line1 = new LineSegment();
    line1.Point = new Point(150,50);

    LineSegment line2 = new LineSegment();
    line2.Point = new Point(300,150);

    PathFigure figure = new PathFigure();
    figure.StartPoint = new Point(150,150);
    figure.Segments.Add(line1);
    figure.Segments.Add(line2);
    figure.Segments.Add(arc);

    PathGeometry pathgeometry = new PathGeometry();
    pathgeometry.Figures.Add(figure);

    Path path = new Path();
    path.Data = pathgeometry;
    path.Stroke = Brushes.Black;

    window.Content = path;

    2010年10月28日 8:16
  • いくつも思い違いをしているようです。

    //円弧
    ArcSegment arc = new ArcSegment();
    arc.RotationAngle = 90;
    //arc. IsLargeArc = true; trueにすると弧の長さが逆。
    arc.SweepDirection = SweepDirection.Counterclockwise;
    //arc.Point = new Point(150,50); //円弧の開始位置 //開始位置の指定はここではない?
    arc.Point = new Point(250,150); //円弧の終了位置

    //線分
    LineSegment line1 = new LineSegment();
    line1.Point = new Point(150,50);//円周までの半径の終了位置

    LineSegment line2 = new LineSegment();
    line2.Point = new Point(150,150);//円弧の終了から中心の終了位置

    PathFigure figure = new PathFigure();
    figure.StartPoint = new Point(150,150);//開始位置
    figure.Segments.Add(line1);//ひょっとしてAddする順番に描く?
    figure.Segments.Add(arc);
    figure.Segments.Add(line2);

    PathGeometry pathgeometry = new PathGeometry();
    pathgeometry.Figures.Add(figure);

    Path path = new Path();
    path.Data = pathgeometry;
    path.Stroke = Brushes.Black;

    window.Content = path;
    のようにしていますが、開始位置も弧の向きも設定できていないようです。
    添削お願いします。

    2010年10月28日 15:03
  • Path は、Segments に追加した順番に描かれます。また、円弧の角度が 180 度をこえない場合、IsLargeArc は false を指定します。

    半径100、角度90度のパイを描画するサンプルを掲載しておきます。

    LineSegment line1 = new LineSegment();
    line1.Point = new Point(100, 30);
    
    ArcSegment arc = new ArcSegment();
    arc.Size = new Size(100, 100);
    arc.IsLargeArc = false;
    arc.SweepDirection = SweepDirection.Clockwise;
    arc.Point = new Point(30, 100);
    
    LineSegment line2 = new LineSegment();
    line2.Point = new Point(30, 30);
    
    PathFigure figure = new PathFigure();
    figure.StartPoint = new Point(30, 30);
    figure.Segments.Add(line1);
    figure.Segments.Add(arc);
    figure.Segments.Add(line2);
    
    PathGeometry geometory = new PathGeometry();
    geometory.Figures.Add(figure);
    
    Path path = new Path();
    path.Fill = Brushes.Red;
    path.Stroke = Brushes.Black;
    path.StrokeThickness = 2;
    path.Data = geometory;
    
    

    なかむら(http://d.hatena.ne.jp/griefworker)
    • 回答としてマーク d-kot 2010年10月29日 3:48
    2010年10月29日 0:44
  • なかむらさん、ありがとうございました。
    arc.Size = new Size(100,100);
    という行を設定するのが抜けていたのがいちばんの要因だったようです。
    追加する順番は、昨日ひょっとしてと思いついてトライして見ていましたが、試行錯誤であまりうまくいってませんでした。
    arc.pointを2回指定していたのも不要だとわかりました。
    ありがとうございました。
    2010年10月29日 3:48