//マウス移動時、終端のアンカーポイント移動とその他の制御点の位置調整 private void MyCanvas_MouseMove(object sender, MouseEventArgs e) { PointCollection ps = MySegment.Points; Point mouseP = e.GetPosition(MyCanvas);//マウスカーソル位置 if (ps.Count > 5) { //終端のアンカーの座標は今のカーソル座標 ps[ps.Count - 1] = mouseP; Point preAP = ps[ps.Count - 4]; //一個前のアンカーポイント Point prepreAP; //二個前のアンカーポイント if (ps.Count < 7) { var pg = (PathGeometry)MyPath.Data; var pathFigureCollection = pg.Figures; prepreAP = pathFigureCollection[0].StartPoint; } else { prepreAP = ps[ps.Count - 7]; } //終端アンカーと二個前のアンカーとの距離の1 / 4 double xDiff = (mouseP.X - prepreAP.X) / 4.0; double yDiff = (mouseP.Y - prepreAP.Y) / 4.0; //一個前のアンカーポイントの制御点座標 ps[ps.Count - 5] = new Point(preAP.X - xDiff, preAP.Y - yDiff); //終端から遠いほう ps[ps.Count - 3] = new Point(preAP.X + xDiff, preAP.Y + yDiff); //終端から近いほう //矢印の回転角度 //角度はマウスカーソル座標と一個前のアンカーの手前側の制御点との直線の角度 double angle = Math.Atan2(mouseP.Y - ps[ps.Count - 3].Y, mouseP.X - ps[ps.Count - 3].X); angle = angle / Math.PI * 180; //ラジアンから度数へ変換 angle += 90; //調整、元の矢印は上向きだけど0度は右向きだから //矢印回転 ArrowHead.RenderTransform = new RotateTransform(angle); MyLabel.Content = "Angle = " + angle.ToString(); //矢印の位置、先端をマウスカーソルに合わせる mouseP.Offset(-OffsetFinePoint.X, -OffsetFinePoint.Y); Canvas.SetLeft(ArrowHead, mouseP.X); Canvas.SetTop(ArrowHead, mouseP.Y); //終端座標決定 //矢印の後ろ(接続座標)をベジェ曲線の終端にする //接続座標はTransformToVisualで計算 GeneralTransform gt = ArrowHead.TransformToVisual(MyCanvas); Point lastAnc = gt.Transform(ContactPoint); ps[ps.Count - 1] = lastAnc; //終端(アンカー)と一個前のアンカーの距離の1/4 xDiff = (lastAnc.X - ps[ps.Count - 3].X) / 4.0; yDiff = (lastAnc.Y - ps[ps.Count - 3].Y) / 4.0; //終端の制御点座標 Point lastControlP = new Point(lastAnc.X - xDiff, lastAnc.Y - yDiff); ps[ps.Count - 2] = lastControlP; } else if (ps.Count > 0) { //終端はカーソル位置 ps[ps.Count - 1] = e.GetPosition(MyCanvas);//カーソル位置に //矢印の位置調整 mouseP.Offset(-OffsetFinePoint.X, -OffsetFinePoint.Y); Canvas.SetLeft(ArrowHead, mouseP.X); Canvas.SetTop(ArrowHead, mouseP.Y); } }