import 'package:fis_measure/interfaces/date_types/point.dart'; import 'package:fis_measure/interfaces/date_types/vector.dart'; class LineUtils { // 计算两条直线是否有交点 static DPoint? calculateIntersection( DPoint startA, DPoint endA, DPoint startB, DPoint endB, ) { return _getIntersectionPointCloneCSharp(startA, endA, startB, endB); // final lineA = _IntersectionTempLine.fromPoints(startA, endA); // final lineB = _IntersectionTempLine.fromPoints(startB, endB); // if (lineA.isVertical && lineB.isVertical) { // // 两条直线都是垂直线,没有交点 // return null; // } else if (lineA.isVertical) { // // 第一条直线是垂直线,交点的x坐标是第一条直线的x坐标 // return DPoint( // lineA.intercept, lineB.slope * lineA.intercept + lineB.intercept); // } else if (lineB.isVertical) { // // 第二条直线是垂直线,交点的x坐标是第二条直线的x坐标 // return DPoint( // lineB.intercept, lineA.slope * lineB.intercept + lineA.intercept); // } else if (lineA.slope == lineB.slope) { // // 斜率相同,直线平行或重合,没有交点 // return null; // } else { // // 斜率不同,计算交点 // double x = // (lineB.intercept - lineA.intercept) / (lineA.slope - lineB.slope); // double y = lineA.slope * x + lineA.intercept; // return DPoint(x, y); // } } static bool isPointOnLine(DPoint p1, DPoint p2, DPoint point) { // 计算向量v和w DVector v = p2 - p1; DVector w = point - p1; // 计算叉积和点积 double crossProduct = v.x * w.y - v.y * w.x; double dotProduct = _dotVector(v, w); // 判断点是否在线上 // 叉积接近0表示点在与线垂直的线上,点积在0到v的模的平方之间表示点在p1和p2之间 return crossProduct.abs() < 1e-10 && dotProduct >= 0 && dotProduct <= _dotVector(v, v); } static double _dotVector(DVector a, DVector b) { return a.x * b.x + a.y * b.y; } static DPoint? _getIntersectionPointCloneCSharp( DPoint p1, DPoint p2, DPoint p3, DPoint p4) { double denom = (p4.x - p3.x) * (p2.y - p1.y) - (p2.x - p1.x) * (p4.y - p3.y); if (denom == 0) return null; double t1 = ((p3.x - p1.x) * (p3.y - p4.y) - (p3.y - p1.y) * (p3.x - p4.x)) / denom; return DPoint(p1.x + t1 * (p2.x - p1.x), p1.y + t1 * (p2.y - p1.y)); } } class _IntersectionTempLine { final double slope; final double intercept; final bool isVertical; _IntersectionTempLine(this.slope, this.intercept, this.isVertical); // 根据两个端点创建直线对象 factory _IntersectionTempLine.fromPoints(DPoint p1, DPoint p2) { if (p1.x == p2.x) { // 垂直线 return _IntersectionTempLine(double.nan, p1.x, true); } else { // 斜率 double m = (p2.y - p1.y) / (p2.x - p1.x); // y轴截距 double b = p1.y - m * p1.x; return _IntersectionTempLine(m, b, false); } } }