[英]Find the point(s) where the tangent to an SVG path is horizontal with svgpathtools and numpy
我想在它的切线是水平(或垂直)的点处分割一条路径。
使用 svgpathtools 我可以像这样计算任何给定点的切线:
from svgpathtools import parse_path, kinks
path = parse_path('m 269.903,19.8186 c -11.91711,-0.51685 -32.27731,1.070319 -53.46034,13.363287 -7.57964,4.398624 -15.09441,10.115707 -21.7639,17.309543 -6.10547,6.585479 -11.48984,14.405852 -15.42262,23.411503 -1.88956,4.341093 -3.20655,8.762796 -4.45743,13.203647 -0.006,0.02087 -0.16665,0.593017 -0.17253,0.613887 -0.92526,3.298648 -2.13708,7.795125 -3.58284,11.703021 -0.0335,0.0905 -0.0643,0.181961 -0.0924,0.274263 -10.08152,33.076419 -13.8021,65.940699 -18.03284,106.519239 -0.0282,0.27038 -0.0341,0.54266 -0.0175,0.814 0.98132,16.11317 1.53474,33.95368 3.54713,50.93551 2.03496,17.17236 5.60753,34.19583 12.80558,50.3898 0.01,0.0224 0.02,0.0446 0.0303,0.0669 2.63691,5.70301 4.88806,11.66869 7.07194,17.50312 2.39713,6.40418 4.5705,12.24991 7.19584,18.13489 8.15411,19.54232 16.41702,37.29627 23.38065,53.17688 10.17192,23.19711 16.22795,38.97872 20.92776,53.58235 a 4.9485337,4.9485337 90 0 0 9.4212,-3.03198 c -4.83331,-15.01844 -11.02505,-31.12699 -21.28502,-54.5249 -7.02031,-16.00985 -15.28013,-33.76328 -23.33392,-53.06904 -0.0157,-0.0377 -0.032,-0.0753 -0.0486,-0.11262 -2.4887,-5.57281 -4.56,-11.13612 -6.98887,-17.62505 -2.16627,-5.78741 -4.53371,-12.07537 -7.34197,-18.15331 -6.63971,-14.94999 -10.03852,-30.89399 -12.00657,-47.50167 -1.9519,-16.47139 -2.48119,-33.55744 -3.4719,-49.96405 4.19097,-40.19716 7.83789,-72.12408 17.5727,-104.11915 1.59772,-4.346868 2.91877,-9.259422 3.77871,-12.325233 -0.007,0.02482 0.17656,-0.62828 0.1696,-0.603457 1.2399,-4.401869 2.40609,-8.261978 4.00337,-11.931579 3.44767,-7.894808 8.18241,-14.785879 13.6081,-20.638137 5.93027,-6.396497 12.64887,-11.517647 19.47371,-15.47825 19.10508,-11.087085 37.44871,-12.495977 48.06391,-12.035592 A 4.9485337,4.9485337 90 0 0 269.903,19.8186 Z')
step = 1 / (10 * len(path))
p = 0
print(path.unit_tangent(p))
while p < 1:
print(path.unit_tangent(p))
p += step
print(path.unit_tangent(1))
我也可以使用 numpy 来找到多项式符号、它的导数和导数的根,我希望它应该给我水平点。 像这样:
path = parse_path('m 269.903,19.8186 c -11.91711,-0.51685 -32.27731,1.070319 -53.46034,13.363287 -7.57964,4.398624 -15.09441,10.115707 -21.7639,17.309543 -6.10547,6.585479 -11.48984,14.405852 -15.42262,23.411503 -1.88956,4.341093 -3.20655,8.762796 -4.45743,13.203647 -0.006,0.02087 -0.16665,0.593017 -0.17253,0.613887 -0.92526,3.298648 -2.13708,7.795125 -3.58284,11.703021 -0.0335,0.0905 -0.0643,0.181961 -0.0924,0.274263 -10.08152,33.076419 -13.8021,65.940699 -18.03284,106.519239 -0.0282,0.27038 -0.0341,0.54266 -0.0175,0.814 0.98132,16.11317 1.53474,33.95368 3.54713,50.93551 2.03496,17.17236 5.60753,34.19583 12.80558,50.3898 0.01,0.0224 0.02,0.0446 0.0303,0.0669 2.63691,5.70301 4.88806,11.66869 7.07194,17.50312 2.39713,6.40418 4.5705,12.24991 7.19584,18.13489 8.15411,19.54232 16.41702,37.29627 23.38065,53.17688 10.17192,23.19711 16.22795,38.97872 20.92776,53.58235 a 4.9485337,4.9485337 90 0 0 9.4212,-3.03198 c -4.83331,-15.01844 -11.02505,-31.12699 -21.28502,-54.5249 -7.02031,-16.00985 -15.28013,-33.76328 -23.33392,-53.06904 -0.0157,-0.0377 -0.032,-0.0753 -0.0486,-0.11262 -2.4887,-5.57281 -4.56,-11.13612 -6.98887,-17.62505 -2.16627,-5.78741 -4.53371,-12.07537 -7.34197,-18.15331 -6.63971,-14.94999 -10.03852,-30.89399 -12.00657,-47.50167 -1.9519,-16.47139 -2.48119,-33.55744 -3.4719,-49.96405 4.19097,-40.19716 7.83789,-72.12408 17.5727,-104.11915 1.59772,-4.346868 2.91877,-9.259422 3.77871,-12.325233 -0.007,0.02482 0.17656,-0.62828 0.1696,-0.603457 1.2399,-4.401869 2.40609,-8.261978 4.00337,-11.931579 3.44767,-7.894808 8.18241,-14.785879 13.6081,-20.638137 5.93027,-6.396497 12.64887,-11.517647 19.47371,-15.47825 19.10508,-11.087085 37.44871,-12.495977 48.06391,-12.035592 A 4.9485337,4.9485337 90 0 0 269.903,19.8186 Z')
for s in path:
print(s)
print(s.poly())
print(s.poly().deriv())
print(roots(s.poly().deriv()))
现在我被困在:
在我放弃并求助于迭代近似之前,我如何找到具有垂直或水平切线的所有点?
在你的例子中:
number_of_steps = 100
step = 1 / (number_of_steps - 1)
p = 0
relevant_points = []
while p <= 1:
unit = path.unit_tangent(p)
# dealing with floats I would recommend to test against a very small epsilon. Maybe if unit.real * unit.imag < 0.000001
if (unit.real == 0) or (unit.imag == 0):
# vertical or horizontal line
relevant_points.append(path.point(p))
# ... do the rest of your processing here
p += step
更多详细信息: path.unit_tangent
返回一个单位向量,为您提供切线方向。 如果该矢量具有其维数是0(之一real
或imag
,因为它是一个python complex
)它是垂直或水平线。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.