不好
这是一个 GraphicsPath 的示例,它试图在行尾之外绘制一个箭头并导致 System.NotImplementedException。
GraphicsPath capPath = new GraphicsPath();
capPath.AddLine(0, 8, -5, 0);
capPath.AddLine(-5, 0, 5, 0);
arrowPen.CustomEndCap = new CustomLineCap(capPath, null); // System.NotImplementedException
这会失败,因为路径必须与负 Y 轴相交。但上面的路径只经过原点,实际上并没有碰到负 Y 轴。
remarks in the docs 至关重要:
fillPath 和strokePath 参数不能同时使用。一个参数必须传递一个空值。如果两个参数都没有传递空值,fillPath 将被忽略。如果strokePath 是null,fillPath 应该截取负 y 轴。
这是措辞不佳的情况之一。文档说“应该拦截”,但我认为这是“必须拦截”的情况,否则你会得到System.NotImplementedException。此拦截问题仅适用于fillPath,不适用于strokePath。 (文档也可能使用一些图片。)
好
这是一个GraphicsPath 的示例,它在行尾绘制了一个箭头并且可以正常工作。它很可能是大多数人无论如何都想画的那种箭头。
GraphicsPath capPath = new GraphicsPath();
capPath.AddLine(0, 0, -5, -8);
capPath.AddLine(-5, -8, 5, -8);
arrowPen.CustomEndCap = new CustomLineCap(capPath, null); // OK
修正你的例子
解决方法是从 y 中减去 triangleHeight。这会将箭头的尖端放置在 0,0(这是线末端的坐标),这很可能是您想要的,并将三角形的底部放置在 -triangleHeight。
float radius = 5.0f;
float triangleSide = 3.0f * radius / (float)Math.Sqrt(3.0f);
float triangleHeight = 3.0f * radius / 2.0f;
GraphicsPath capPath = new GraphicsPath();
capPath.AddLines(new PointF[] {
new PointF(-triangleSide / 2.0f, -triangleHeight),
new PointF(triangleSide / 2.0f, -triangleHeight),
new PointF(0, 0) }
);
arrowPen.CustomEndCap = new CustomLineCap(capPath, null);
为您提供的确切解决方法(在 Visual Basic 中):
Dim points() As PointF = New PointF() { _
New PointF(-triangleSide / 2, -triangleHeight), _
New PointF(triangleSide / 2, -triangleHeight), _
New PointF(0, 0) }
path.AddLines(points)