lineSegmentIntersections method

List<Vector2> lineSegmentIntersections(
  1. LineSegment lineSegment, {
  2. double epsilon = double.minPositive,
})

Returns the locus of points in which the provided line segment intersects the circle.

This can be an empty list (if they don't intersect), one point (if the line is tangent) or two points (if the line is secant). An edge point of the lineSegment that originates on the edge of the circle doesn't count as an intersection.

Implementation

List<Vector2> lineSegmentIntersections(
  LineSegment lineSegment, {
  double epsilon = double.minPositive,
}) {
  // A point on a line is `from + t*(to - from)`. We're trying to solve the
  // equation `‖point - center‖² == radius²`. Or, denoting `Δ₂₁ = to - from`
  // and `Δ₁₀ = from - center`, the equation is `‖t*Δ₂₁ + Δ₁₀‖² == radius²`.
  // Expanding the norm, this becomes a square equation in `t`:
  // `t²Δ₂₁² + 2tΔ₂₁Δ₁₀ + Δ₁₀² - radius² == 0`.
  _delta21
    ..setFrom(lineSegment.to)
    ..sub(lineSegment.from); // to - from
  _delta10
    ..setFrom(lineSegment.from)
    ..sub(absoluteCenter); // from - absoluteCenter
  final a = _delta21.length2;
  final b = 2 * _delta21.dot(_delta10);
  final c = _delta10.length2 - radius * radius;

  return solveQuadratic(a, b, c)
      .where((t) => t > 0 && t <= 1)
      .map((t) => lineSegment.from.clone()..addScaled(_delta21, t))
      .toList();
}