如何判断Canvas中两条直线是否相交?Path.combine判断失效求助
解决Flutter中用Path.combine判断直线相交结果始终为false的问题
问题根源
Path.combine(PathOperation.intersect)的作用是计算两个路径闭合区域的交集。你创建的是开放直线路径(仅通过moveTo和lineTo绘制线段,没有闭合形成有面积的区域),两条直线本身没有面积,因此它们的交集区域为空,导致intersection.getBounds().isEmpty始终为true,最终判断结果为false。
替代解决方案:直接判断线段相交
通过计算几何中的向量叉积方法,可以直接判断两条线段是否相交,这是处理开放线段相交的标准方案:
import 'dart:math'; class Point { final double x; final double y; Point(this.x, this.y); } // 判断两条线段是否相交 bool doSegmentsIntersect(Point a1, Point a2, Point b1, Point b2) { // 计算三点构成的叉积 double crossProduct(Point p1, Point p2, Point p3) { return (p2.x - p1.x) * (p3.y - p1.y) - (p2.y - p1.y) * (p3.x - p1.x); } // 检查点是否在线段范围内 bool isPointOnSegment(Point p, Point a, Point b) { return min(a.x, b.x) <= p.x && p.x <= max(a.x, b.x) && min(a.y, b.y) <= p.y && p.y <= max(a.y, b.y); } final double d1 = crossProduct(b1, b2, a1); final double d2 = crossProduct(b1, b2, a2); final double d3 = crossProduct(a1, a2, b1); final double d4 = crossProduct(a1, a2, b2); // 一般情况:两条线段互相跨立 if (((d1 > 0 && d2 < 0) || (d1 < 0 && d2 > 0)) && ((d3 > 0 && d4 < 0) || (d3 < 0 && d4 > 0))) { return true; } // 特殊情况:端点落在另一条线段上 if (d1 == 0 && isPointOnSegment(a1, b1, b2)) return true; if (d2 == 0 && isPointOnSegment(a2, b1, b2)) return true; if (d3 == 0 && isPointOnSegment(b1, a1, a2)) return true; if (d4 == 0 && isPointOnSegment(b2, a1, a2)) return true; return false; } // 在你的绘制代码中使用 void checkIntersection() { final a1 = Point(100, 300); final a2 = Point(300, 300); final b1 = Point(200, 200); final b2 = Point(200, 400); bool intersects = doSegmentsIntersect(a1, a2, b1, b2); print(intersects); // 输出 true }
如果需要处理闭合路径的区域交集,Path.combine是有效的,但对于开放线段,必须使用线段相交的几何算法。
内容的提问来源于stack exchange,提问作者Daniel Roldán
相关产品推荐
相关产品推荐

