intersections method
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 [];
}