nor*_*esh 3 python math bezier
我目前正在使用 python 库从 TrueType 字体中提取笔划 - 在这里,我将笔划定义为在测试点与其反射点之间运行的中线。我使用术语“反射点”来指代“墨水”区域另一侧的最近点,在正常情况下(除了在衬线词干处),该点的切线方向也与测试点相反.
我正在使用 fontTools 和从http://pomax.github.io/bezierinfo/#extremities 中描述的处理代码推出的贝塞尔库在 python 中工作。
目前我被困在如何找到具有给定切线的二次贝塞尔曲线上的点,我的数学技能在美好的一天非常基本,头脑清晰[现在不是仪式]所以我希望头脑更敏锐的人可以指出如何实现这一目标的鸟瞰概述。
目前,我唯一能想到的就是用类似于 Newton-Raphson 求根算法的方法在数值上接近它,但根据目标方向值评估一阶导数。然而,我希望有一个象征性的解决方案,因为这需要在字形轮廓中的每条曲线的每条其他曲线上运行。
使用http://pomax.github.io/bezierinfo/#extremities 中给出的符号,二次贝塞尔曲线由下式给出:
B(t) = P1*(1-t)**2 + 2*P2*(1-t)*t + P3*t**2
Run Code Online (Sandbox Code Playgroud)
因此,(通过取导数的B相对于t)的切线曲线由下式给出
B'(t) = -2*P1*(1-t) + 2*P2*(1-2*t) + 2*P3*t
= 2*(P1 - 2*P2 + P3)*t + 2*(-P1 + P2)
Run Code Online (Sandbox Code Playgroud)
给定一些切线方向V,求解
B'(t) = V
Run Code Online (Sandbox Code Playgroud)
为t。如果有解,t = ts,则贝塞尔曲线上具有切线方向的V点由 给出B(ts)。
我们本质上想知道两个向量(B'(t)和V)是平行还是反平行。有一个技巧可以做到这一点。
如果它们的点积为零,则两个向量X和Y是垂直的。如果和随后的点积和由下式给出X = (a,b)Y = (c,d)XY
a*c + b*d
Run Code Online (Sandbox Code Playgroud)
因此,如果和是垂直的,X并且 和Y是平行的,其中是垂直于 的向量。XY_perpY_perpY
在二维中,如果在坐标中,Y = (a,b)则Y_perp = (-b, a). (还有两个垂直的向量可能的,但是这一次就行了。)请注意, -使用上述公式-的点积Y和Y_perp是
a*(-b) + b*(a) = 0
Run Code Online (Sandbox Code Playgroud)
因此,确实,这与垂直向量的点积等于 0 的说法不谋而合。
现在,要解决我们的问题:让
B'(t) = (a*t+b, c*t+d)
V = (e, f)
Run Code Online (Sandbox Code Playgroud)
ThenB'(t)平行(或反平行)到Vif 或 when
B'(t)垂直于V_perp,这发生在
dot product((a*t+b, c*t+d), (-f, e)) = 0
-(a*t+b)*f + (c*t+d)*e = 0
Run Code Online (Sandbox Code Playgroud)
我们知道a,b,c,d,e和f。求解t。如果t介于 0 和 1 之间,则B(t)是P1和之间的贝塞尔曲线段的一部分P3。
| 归档时间: |
|
| 查看次数: |
975 次 |
| 最近记录: |