raycast method
Implementation
void raycast(
ParticleRaycastCallback callback,
Vector2 point1,
Vector2 point2,
) {
if (proxyBuffer.isEmpty) {
return;
}
final firstProxy = lowerBound(
proxyBuffer,
computeTag(
inverseDiameter * min(point1.x, point2.x) - 1,
inverseDiameter * min(point1.y, point2.y) - 1,
),
);
final lastProxy = upperBound(
proxyBuffer,
computeTag(
inverseDiameter * max(point1.x, point2.x) + 1,
inverseDiameter * max(point1.y, point2.y) + 1,
),
);
var fraction = 1.0;
// solving the following equation:
// ((1-t)*point1+t*point2-position)^2=diameter^2
// where t is a potential fraction
final vx = point2.x - point1.x;
final vy = point2.y - point1.y;
var v2 = vx * vx + vy * vy;
v2 = v2 == 0 ? double.maxFinite : v2;
for (var i = firstProxy; i < lastProxy; ++i) {
// TODO(spydon): Is this correct now when we are not rotating the buffers?
final positionI = proxyBuffer[i].particle.position;
final px = point1.x - positionI.x;
final py = point1.y - positionI.y;
final pv = px * vx + py * vy;
final p2 = px * px + py * py;
final determinant = pv * pv - v2 * (p2 - squaredDiameter);
if (determinant >= 0) {
final sqrtDeterminant = sqrt(determinant);
// find a solution between 0 and fraction
var t = (-pv - sqrtDeterminant) / v2;
if (t > fraction) {
continue;
}
if (t < 0) {
t = (-pv + sqrtDeterminant) / v2;
if (t < 0 || t > fraction) {
continue;
}
}
final n = _tempVec;
_tempVec.x = px + t * vx;
_tempVec.y = py + t * vy;
n.normalize();
final point = Vector2(point1.x + t * vx, point1.y + t * vy);
final f = callback.reportParticle(i, point, n, t);
fraction = min(fraction, f);
if (fraction <= 0) {
break;
}
}
}
}