午後わてんのブログ

ベランダ菜園とWindows用アプリ作成(WPFとC#)

マウスクリックでCanvasに直線を描画その3、ベジェ曲線で直線、PolyBezierSegment

System.Windows.Media.PolyBezierSegment
PolyBezierSegmentを使って連続した直線を描画してみた
本当はベジェ曲線を描くのに使うんだけど直線も描けた
 
今回のアプリのダウンロード先
 
見た目的な結果は前々回や前回と全く同じ
イメージ 1
 
 
 
デザイン画面

f:id:gogowaten:20191213094320p:plain

前回とほとんど同じ
 
コード、見るよう

f:id:gogowaten:20191213094331p:plain

コピペ用
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
namespace _20180609_クリックで直線_ベジェ曲線で直線
{
    public partial class MainWindow : Window
    {
        PolyBezierSegment MySegment;//これのPointsにPointを追加していく

        public MainWindow()
        {
            InitializeComponent();
            
            MyInitialize();
            MyCanvas.MouseLeftButtonDown += MyCanvas_MouseLeftButtonDown;
            MyCanvas.MouseMove += MyCanvas_MouseMove;
            MyCanvas.MouseRightButtonDown += MyCanvas_MouseRightButtonDown;
        }
        private void MyCanvas_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            MySegment.Points.Clear();
        }
        //PathGeometry作成してPathのDataに指定
        private void MyInitialize()
        {
            MySegment = new PolyBezierSegment(new PointCollection(), true);
            var pf = new PathFigure();
            pf.Segments.Add(MySegment);
            var pg = new PathGeometry();
            pg.Figures.Add(pf);
            MyPath.Data = pg;
        }
        //最後のPointをマウスカーソルの位置にする
        private void MyCanvas_MouseMove(object sender, MouseEventArgs e)
        {
            if (MySegment.Points.Count > 0)
            {
                var ps = MySegment.Points;//PointCollection
                //最後のアンカーポイントのインデックスはCount-1
                int ap = ps.Count - 1;
                ps[ap] = e.GetPosition(MyCanvas);//カーソル位置に
            }
        }
        //左クリックで制御点2つとアンカーポイント追加
        //2つの制御点の座標を同じにすると直線になる
        private void MyCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            var p = e.GetPosition(MyCanvas);
            //最初のクリック時だけはStartPointを指定する
            if (MySegment.Points.Count == 0)
            {
                var pg = (PathGeometry)MyPath.Data;
                var pathFigureCollection = pg.Figures;
                pathFigureCollection[0].StartPoint = p;
                //制御点2つとアンカーポイント追加
                MySegment.Points.Add(p);
                MySegment.Points.Add(p);
                MySegment.Points.Add(p);
            }
            else
            {
                //制御点2つとアンカーポイント追加
                MySegment.Points.Add(p);
                MySegment.Points.Add(p);
                MySegment.Points.Add(p);
            }
        }
    }
}
 
 
イメージ 5
アンカーポイントと制御点を表示してみると
 
イメージ 4
灰色がアンカーポイント
紫色が制御点
上の数値はインデックス
下はx,y座標
 
制御点をアンカーポイントと同じ座標にすると
イメージ 11
直線になる
重ねたので見えてないけど02,05の下にアンカーポイントがある
 
 
Pathから目的のPointまでの関係

f:id:gogowaten:20191213094421p:plain

前々回と同じ感じ、赤文字のところ以下がLineSegmentからPolyBezierSegmentに変わった
上を簡単に書くと
Path.Data.PathFigure[0].PolyBezierSegment[0].Points
こうかな、こうしてみるとそんなに遠くない気もするけどやっぱり遠い
 
Pointsまで遠いのでPolyBezierSegmentを入れておく変数を用意
イメージ 7
フィールドにMySegmentって名前でPolyBezierSegmentを入れる変数を作っておいて、そこからPointsを取得するようにした
 
アプリ起動時にMyPath.Dataの初期設定
イメージ 8
MySegmentにPolyBezierSegmentを入れたり
Path.Data.PathFigure[0].PolyBezierSegment[0].Points
この部分の作成
 
 
左クリック時

f:id:gogowaten:20191213094435p:plain

最初のクリック時のときだけはPathFigureのStartPointを指定する必要があるから分岐
その後は制御点を2つとアンカーポイント1つを追加、座標は全部クリックした座標を指定
最初の座標はPathFigure.StartPointでそれ以降がPolyBezierSegment.Pointになる
もしPathFigure.StartPointを指定しないとPoint(0,0)がStartPointになる
 
 
マウス移動時
イメージ 10
最後のアンカーポイントの座標をマウスカーソルの位置にする
 
 
コード
 
 
関連記事
2018/06/11は2日後
マウスクリックでCanvasベジェ曲線で曲線、PolyBezierSegment ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/gogowaten/15544835.html
 
 
2018/06/08は昨日
マウスクリックでCanvasに直線を描画その2、Polyline、WPFC# ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/gogowaten/15540488.html
直線ならこの方法が一番ラク
 
 
2015/1/27は3年前
Pixtack紫陽花2.6.50.134_マウスクリックでもベジェ曲線を描けるようにした ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/gogowaten/12656208.html

3年前、このときはWindowsForm+VisualBasic
今はWPFC#でこれと同じことをしようとしている途中
ほとんど忘れていてなかなか進まない