polyline method

List<List<Point>> polyline(
  1. List<Point> points,
  2. BBox bbox, [
  3. List<List<Point>>? start
])

Cohen-Sutherland line clipping algorithm, adapted to efficiently handle polylines rather than just segments.

Implementation

List<List<Point>> polyline(List<Point> points, BBox bbox, [List<List<Point>>? start]) {
  final List<List<Point>> result = start ?? [];
  if (points.isEmpty) return result;

  final int len = points.length;
  int codeA = _bitCode(points.first, bbox);
  List<Point> part = [];

  for (int i = 1; i < len; i++) {
    Point a = points[i - 1];
    Point b = points[i];
    int codeB = _bitCode(b, bbox);
    int lastCode = codeB;

    int lastCodes = -1;
    while (true) {
      if ((codeA << 4) + codeB == lastCodes) {
        throw StateError('Stuck in an infinite loop. CodeA=$codeA, CodeB=$codeB.');
      }
      lastCodes = (codeA << 4) + codeB;

      if (codeA | codeB == 0) { // accept
        part.add(a);

        if (codeB != lastCode) { // start a new line
          part.add(b);

          if (i < len - 1) {
            result.add(part);
            part = [];
          }
        } else if (i == len - 1) {
          part.add(b);
        }
        break;

      } else if (codeA & codeB != 0) { // trivial reject
        break;

      } else if (codeA != 0) { // a outside, intersect with clip edge
        a = _intersect(a, b, codeA, bbox);
        codeA = _bitCode(a, bbox);

      } else { // b outside
        b = _intersect(a, b, codeB, bbox);
        codeB = _bitCode(b, bbox);
      }
    }

    codeA = lastCode;
  }

  if (part.isNotEmpty) result.add(part);
  return result;
}