告诉我,如何在贝塞尔曲线的末端画一个箭头?有很多关于如何对直线(1、2、3)执行此操作的示例,但是对于我无法执行的曲线。
有这样的代码,但它像在 gif 上一样工作。
XML:
<Canvas>
<Path x:Name="pathMain" Stroke="Blue" StrokeThickness="2"/>
</Canvas>
代码隐藏:
public PolyLineSegment DrawArrow(Point a, Point b)
{
double HeadWidth = 10; // Ширина между ребрами стрелки
double HeadHeight = 5; // Длина ребер стрелки
double X1 = a.X;
double Y1 = a.Y;
double X2 = b.X;
double Y2 = b.Y;
double theta = Math.Atan2(Y1 - Y2, X1 - X2);
double sint = Math.Sin(theta);
double cost = Math.Cos(theta);
Point pt3 = new Point(
X2 + (HeadWidth * cost - HeadHeight * sint),
Y2 + (HeadWidth * sint + HeadHeight * cost));
Point pt4 = new Point(
X2 + (HeadWidth * cost + HeadHeight * sint),
Y2 - (HeadHeight * cost - HeadWidth * sint));
PolyLineSegment arrow = new PolyLineSegment();
arrow.Points.Add(b);
arrow.Points.Add(pt3);
arrow.Points.Add(pt4);
arrow.Points.Add(b);
return arrow;
}
private void DrawLine(MouseEventArgs e)
{
Point endPoint = e.GetPosition(this);
PathFigure pathFigure = new PathFigure
{
StartPoint = new Point(800, 500),
IsClosed = false
};
//Кривая Безье
Vector vector = endPoint - pathFigure.StartPoint;
Point point1 = new Point(pathFigure.StartPoint.X + vector.X / 2, pathFigure.StartPoint.Y);
Point point2 = new Point(pathFigure.StartPoint.X + vector.X / 1.5, pathFigure.StartPoint.Y + vector.Y/ 0.95);
BezierSegment curve = new BezierSegment(point1, point2, endPoint, true);
PolyLineSegment arrow = DrawArrow(pathFigure.StartPoint, endPoint);
PathGeometry path = new PathGeometry();
path.Figures.Add(pathFigure);
pathFigure.Segments.Add(curve);
pathFigure.Segments.Add(arrow);
pathMain.Data = path;
}
如果DrawArrow(point2, endPoint)不是DrawArrow(pathFigure.StartPoint, endPoint);,那么它的工作原理如下:


我在你的曲线上添加了锚点(动画中的红色多段线):
事实是箭头正确显示:参考线最后一段的方向。箭头确实显示了极值点处的切线方向。但是你对中间点的计算产生了太多的扭结,所以曲线的表观方向与切线的方向相差太大。
尝试更改选择中间点的算法,我认为问题出在其中。(我不能提供我自己的算法,因为我不知道你的问题是什么。)
关于算法,这段代码表现得更好:
为了以防万一,这里有一个完整的例子:
主窗口.xaml:
主窗口.xaml.cs: