如何在 WPF 中只绘制贝塞尔曲线的一部分?
How can I draw only a subsection of a Bezier curve in WPF?
我有一个需求,画小弯箭头。我可以计算出箭头的角度 OK,我打算使用 Beziers 来定义路径段。然而,我真正想做的是计算起点和终点之间的一条看不见的弯曲路径,并且只在起点之后和终点之前的一小段距离内绘制路径。
这会在起点和终点处的任何对象之间留出合适的间隙。有什么建议吗?
我想我可能在摸索了很久之后找到了一个可能的解决方案。假设您有一条贝塞尔曲线 A-B-C-D,其中 B 和 C 是控制点,A 和 D 是起点和终点。并且您想从 A 和 D 开始和结束距离 X:
生成初始贝塞尔曲线
调用GetFlattenedPathGeometry将其转化为一系列小段
求和得到贝塞尔曲线的长度除以X得到从头到尾的小数长度F
在原始贝塞尔曲线上调用PathGeometry.GetPointAtFractionLength,传入F和1-F。这将为缩短的贝塞尔曲线
的每一端产生一个 start/end 点和一个切向量
将start/end点加入切向量得到对应的控制点
使用这些点生成一个新的贝塞尔曲线,它应该与原始起点和终点相距 X
看到这种方法有什么问题吗?
箭头通常没有疯狂混乱的曲线,它们有非常平滑的曲线,末端附近的 t
值表现为纯立方体(因为贝塞尔函数由 (1-t) 支配³ 在起始坐标处,通过 t³ 在结束坐标处),因此在终点附近,您可以 "guestimate" 您需要插入的 "t" 值,以便通过使用立方体获得接近需要的坐标根:
// let's say we want "10% away from the end"
desiredDistance = 0.9;
// then the guestimate for the "t" value is simply the cube root of 0.9
probablyT = Math.pow(desiredDistance, 1/3);
// and the point we want to cut at is at that "t" value
cutPoint = get(probablyT, pts);
// and we can split up the curve into two segments at that "t" value
curves = split(probablyT, pts);
// and then keep the segment we need for the arrow
arrowcurve = curves[0];
请参阅 http://jsbin.com/dovodibaze/edit?js,output 了解这对接近终点的距离的近似程度(以及这显然只在您猜测的终点附近有效 =)
使用那个 probablyT
值,您可以拆分原始曲线,绘制从该拆分中获得的 "first" 曲线(覆盖原始 t=0 到 t=near-the-end 段) 然后在原来的终点画你的箭头。
我有一个需求,画小弯箭头。我可以计算出箭头的角度 OK,我打算使用 Beziers 来定义路径段。然而,我真正想做的是计算起点和终点之间的一条看不见的弯曲路径,并且只在起点之后和终点之前的一小段距离内绘制路径。
这会在起点和终点处的任何对象之间留出合适的间隙。有什么建议吗?
我想我可能在摸索了很久之后找到了一个可能的解决方案。假设您有一条贝塞尔曲线 A-B-C-D,其中 B 和 C 是控制点,A 和 D 是起点和终点。并且您想从 A 和 D 开始和结束距离 X:
生成初始贝塞尔曲线
调用GetFlattenedPathGeometry将其转化为一系列小段
求和得到贝塞尔曲线的长度除以X得到从头到尾的小数长度F
在原始贝塞尔曲线上调用PathGeometry.GetPointAtFractionLength,传入F和1-F。这将为缩短的贝塞尔曲线
的每一端产生一个 start/end 点和一个切向量
将start/end点加入切向量得到对应的控制点
使用这些点生成一个新的贝塞尔曲线,它应该与原始起点和终点相距 X
看到这种方法有什么问题吗?
箭头通常没有疯狂混乱的曲线,它们有非常平滑的曲线,末端附近的 t
值表现为纯立方体(因为贝塞尔函数由 (1-t) 支配³ 在起始坐标处,通过 t³ 在结束坐标处),因此在终点附近,您可以 "guestimate" 您需要插入的 "t" 值,以便通过使用立方体获得接近需要的坐标根:
// let's say we want "10% away from the end"
desiredDistance = 0.9;
// then the guestimate for the "t" value is simply the cube root of 0.9
probablyT = Math.pow(desiredDistance, 1/3);
// and the point we want to cut at is at that "t" value
cutPoint = get(probablyT, pts);
// and we can split up the curve into two segments at that "t" value
curves = split(probablyT, pts);
// and then keep the segment we need for the arrow
arrowcurve = curves[0];
请参阅 http://jsbin.com/dovodibaze/edit?js,output 了解这对接近终点的距离的近似程度(以及这显然只在您猜测的终点附近有效 =)
使用那个 probablyT
值,您可以拆分原始曲线,绘制从该拆分中获得的 "first" 曲线(覆盖原始 t=0 到 t=near-the-end 段) 然后在原来的终点画你的箭头。