splitOnIntersections method

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

Implementation

List<Line> splitOnIntersections(List<PointD> polygon, Line segment) {
  final double error = max(5, segment.length * 0.1);
  final List<IntersectionInfo> intersections = [];
  for (int i = 0; i < polygon.length; i++) {
    final PointD p1 = polygon[i];
    final PointD p2 = polygon[(i + 1) % polygon.length];
    final Line polygonSegment = Line(p1, p2);
    if (segment.intersects(polygonSegment)) {
      final PointD? ip = segment.intersectionWith(polygonSegment);
      if (ip != null) {
        final double d0 = Line(ip, segment.source).length;
        final 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());
    final 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 [];
      }
    }
    final List<PointD> splitPoints =
        [segment.source] + intersectionPoints + [segment.target];
    final List<Line> splitLines = [];
    for (int i = 0; i < (splitPoints.length - 1); i += 2) {
      final 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 [];
  }
}