splitOnIntersections method

List<Line> splitOnIntersections(
  1. List<PointD> polygon,
  2. Line segment
)

Implementation

List<Line> splitOnIntersections(List<PointD> polygon, Line segment) {
  double error = max(5, segment.length * 0.1);
  List<IntersectionInfo> intersections = [];
  for (int i = 0; i < polygon.length; i++) {
    PointD p1 = polygon[i];
    PointD p2 = polygon[(i + 1) % polygon.length];
    Line polygonSegment = Line(p1, p2);
    if (segment.intersects(polygonSegment)) {
      PointD ip = segment.intersectionWith(polygonSegment);
      if (ip != null) {
        double d0 = Line(ip, segment.source).length;
        double d1 = Line(ip, segment.target).length;
        if (d0 > error && d1 > error) {
          intersections.add(IntersectionInfo(point: ip, distance: d0));
        }
      }
    }
  }
  if (intersections.length > 1) {
    intersections.sort((a, b) => (a.distance - b.distance).ceil());
    List<PointD> intersectionPoints =
        intersections.map((d) => d.point).toList();
    if (segment.source.isInPolygon(polygon)) {
      intersectionPoints.removeAt(0);
    }
    if (segment.target.isInPolygon(polygon)) {
      intersectionPoints.removeLast();
    }
    if (intersectionPoints.length <= 1) {
      if (segment.isMidPointInPolygon(polygon)) {
        return [segment];
      } else {
        return [];
      }
    }
    List<PointD> splitPoints =
        [segment.source] + intersectionPoints + [segment.target];
    List<Line> splitLines = [];
    for (int i = 0; i < (splitPoints.length - 1); i += 2) {
      Line subSegment = Line(splitPoints[i], splitPoints[i + 1]);
      if (subSegment.isMidPointInPolygon(polygon)) {
        splitLines.add(subSegment);
      }
    }
    return splitLines;
  } else if (segment.isMidPointInPolygon(polygon)) {
    return [segment];
  } else {
    return [];
  }
}