intersections method

List<Vector2> intersections(
  1. LineSegment otherSegment
)

Returns an empty list if there are no intersections between the segments. If the segments intersect in a single point, that point is returned in a list with a single element. If the segments are collinear and overlap, the end points of the overlapping section are returned.

Implementation

List<Vector2> intersections(LineSegment otherSegment) {
  const epsilon = 0.01;
  final otherFrom = otherSegment.from;
  final otherTo = otherSegment.to;
  if (max(from.x, to.x) + epsilon < min(otherFrom.x, otherTo.x) ||
      min(from.x, to.x) - epsilon > max(otherFrom.x, otherTo.x) ||
      max(from.y, to.y) + epsilon < min(otherFrom.y, otherTo.y) ||
      min(from.y, to.y) - epsilon > max(otherFrom.y, otherTo.y)) {
    return const [];
  }
  final a1 = to.y - from.y;
  final b1 = from.x - to.x;
  final c1 = to.y * from.x - from.y * to.x;
  final a2 = otherTo.y - otherFrom.y;
  final b2 = otherFrom.x - otherTo.x;
  final c2 = otherTo.y * otherFrom.x - otherFrom.y * otherTo.x;
  final determinant = a1 * b2 - a2 * b1;
  if (determinant != 0) {
    // The lines are not parallel
    final intersection = Vector2(
      (b2 * c1 - b1 * c2) / determinant,
      (a1 * c2 - a2 * c1) / determinant,
    );
    if (containsPoint(intersection) &&
        otherSegment.containsPoint(intersection)) {
      // The intersection point is on both line segments
      return [intersection];
    }
  } else {
    // In here we know that the lines are parallel
    final overlaps = {
      if (otherSegment.containsPoint(from)) from,
      if (otherSegment.containsPoint(to)) to,
      if (containsPoint(otherSegment.from)) otherSegment.from,
      if (containsPoint(otherSegment.to)) otherSegment.to,
    };
    if (overlaps.isNotEmpty) {
      return overlaps.toList(growable: false);
    }
  }
  return const [];
}