快速找出贝塞尔曲线的所有交点)
svgpathtools交点检测实战用intersect()快速找出贝塞尔曲线的所有交点【免费下载链接】svgpathtoolsA collection of tools for manipulating and analyzing SVG Path objects and Bezier curves.项目地址: https://gitcode.com/gh_mirrors/sv/svgpathtoolssvgpathtools是一个 Python 图形计算工具库专门用于处理和解析SVG Path 对象与贝塞尔曲线。它内置的intersect()方法可以高效地计算两条路径之间的交点检测一行调用就能找出贝塞尔曲线、直线、圆弧之间所有的交点是碰撞检测、路径切割、图形分析类项目的常用工具。为什么需要 SVG 路径交点检测在实际开发中你可能会遇到这些场景判断两条曲线是否相交图形碰撞检测找出所有交叉点用于切割或拆分路径检测一个路径是否完全包含在另一个路径内通常基于交点数量判断手写交点计算非常麻烦——贝塞尔曲线两两相交需要解高次方程。svgpathtools 把这层数学全部封装好了底层由 svgpathtools/bezier.py 中的bezier_intersections完成数值求解对外只暴露一个简单的方法。两种用法分段级与路径级svgpathtools 把intersect()分成了两个层级都在 svgpathtools/path.py 中实现1. 路径级Path.intersect() 一次找出所有交点对Path对象调用 Path.intersect()它会遍历两条路径的每一对分段汇总全部交点from svgpathtools import svg2paths paths, attributes svg2paths(test.svg) redpath paths[0] for path in paths[1:]: for (T1, seg1, t1), (T2, seg2, t2) in redpath.intersect(path): print(redpath.point(T1), other_path.point(T2))返回值的结构值得记住每个交点是一个双元组((T1, seg1, t1), (T2, seg2, t2))参数含义T1/T2交点在整条路径弧长参数上的位置seg1/seg2交点所在的路径分段Line、CubicBezier 等t1/t2交点在该分段上的局部参数取值范围 0~1拿到T1后用redpath.point(T1)就能得到交点的真实坐标复数形式.real是 x.imag是 y。两个常用参数justonemodeTrue只要判断是否相交开启后找到第一个交点立即返回速度更快tol容差默认1e-12用于合并路径接点处产生的重复交点2. 分段级Segment.intersect() 精确定位单个分段如果你已经确定交点在两个具体分段之间可以直接对分段调用intersect()例如 QuadraticBezier.intersect()t_pairs seg_a.intersect(seg_b, tol1e-12) # 返回 [(t1, t2), ...]满足 seg_a.point(t1) seg_b.point(t2)分段级实现里有一个很实用的性能细节先比较两分段的包围盒x 或 y 方向不重叠就立刻返回空列表避免不必要的方程求解。实战标记 test.svg 中所有交点官方示例的完整流程在 README.md 的 Intersections between Bezier curves 一节。核心思路用红色路径与文件中其余路径逐一求交再用disvg把交点画成圆点paths, attributes svg2paths(test.svg) redpath paths[0] intersections [] for path in paths[1:]: for (T1, seg1, t1), (T2, seg2, t2) in redpath.intersect(path): intersections.append(redpath.point(T1)) disvg(paths, filenameoutput_intersections.svg, attributesattributes, nodesintersections, node_radii[5]*len(intersections))生成的 output_intersections.svg 会把每个交点都标出方便肉眼验证结果是否正确。原始输入文件是仓库根目录的 test.svg。避坑指南 ⚠️两条路径重合时慎用文档明确指出若两段曲线有无限多个公共点如重合线段算法会迭代到最大深度或抛出错误。Arc 分段支持有限Arc.intersect() 的注释写着 NOT FULLY IMPLEMENTED圆弧相关的交点只做了部分支持测试也较少。纯贝塞尔直线场景则非常稳定。接点重复交点已自动去重路径连接点处可能同时被上一分段和下一分段报告Path.intersect()内部会用tol检查并剔除冗余结果。方向对称性p1.intersect(p2)与p2.intersect(p1)的交点数量应相同可用来做结果自检参考 test/test_path.py 中Test_intersect测试类的断言方式。相关源码与测试文件速查核心类与intersect()实现svgpathtools/path.py底层贝塞尔求交算法bezier_intersectionssvgpathtools/bezier.py交点检测单元测试含直线、二次/三次曲线、圆弧组合test/test_path.py路径生成与示例svgpathtools/paths2svg.py、README.md小结svgpathtools 的交点检测 API 设计得非常直接Path.intersect()负责找全部分段级intersect()负责精确算justonemode负责只判相交。掌握了(T, seg, t)三层参数结构你就能把交点精确定位到任意一条贝塞尔曲线上的任意位置——这也是后续做路径切割、包含检测等高级操作的基础。【免费下载链接】svgpathtoolsA collection of tools for manipulating and analyzing SVG Path objects and Bezier curves.项目地址: https://gitcode.com/gh_mirrors/sv/svgpathtools创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考