projectToRectEdge function
Implementation
Offset projectToRectEdge({required Offset p, required Offset v, required Rect rect}) {
const double epsilon = 1e-10;
final dx = v.dx;
final dy = v.dy;
final isNearlyZeroDx = _isNearlyZero(dx);
final isNearlyZeroDy = _isNearlyZero(dy);
if (isNearlyZeroDx && isNearlyZeroDy) return _closestPointOnRectEdge(p: p, rect: rect);
double tx1, tx2, ty1, ty2;
if (isNearlyZeroDx) {
tx1 = double.negativeInfinity;
tx2 = double.infinity;
} else {
tx1 = (rect.left - p.dx) / dx;
tx2 = (rect.right - p.dx) / dx;
}
if (isNearlyZeroDy) {
ty1 = double.negativeInfinity;
ty2 = double.infinity;
} else {
ty1 = (rect.top - p.dy) / dy;
ty2 = (rect.bottom - p.dy) / dy;
}
final txMin = min(tx1, tx2);
final txMax = max(tx1, tx2);
final tyMin = min(ty1, ty2);
final tyMax = max(ty1, ty2);
final tEnter = max(txMin, tyMin);
final tExit = min(txMax, tyMax);
if (tExit < max(tEnter, epsilon)) return _closestPointOnRectEdge(p: p, rect: rect);
final clamped = _clampPoint(p, rect);
final inside = (p == clamped);
final tHit = inside ? tExit : max(tEnter, epsilon);
return Offset(p.dx + dx * tHit, p.dy + dy * tHit);
}