/** * @param vRayStart Start point of an infinite ray. * @param vRayOffset Direction of the ray, parametric t multiplier. * @param fT0 Filled in with time of first intersection (if present). * @param fT1 Filled in with time of second intersection (if present). * @return The number of intersections found. */ UINT32 CCircle::GetLineIntersectionTimes(CFVec2Arg vRayStart, CFVec2Arg vRayOffset, GDE::FLOAT32 &fT0, GDE::FLOAT32 &fT1) const { const CFVec2 vToRay = vRayStart - m_vCentre; // TODO: reformulate without the square root? const FLOAT32 fExtentsRecip = 1.0f/vRayOffset.Magnitude(); const FLOAT32 fRayDotToRay = vToRay.DotProduct( vRayOffset ) * fExtentsRecip; const FLOAT32 fDiscr = fRayDotToRay*fRayDotToRay - (vToRay.SquareMagnitude()-m_fRadius*m_fRadius); if ( fDiscr < 0.0f ) { return 0; // no intersections. } if ( fDiscr == 0.0f ) { fT0 = -fRayDotToRay * fExtentsRecip; return 1; // one intersection, just touching } else { const FLOAT32 fRoot = sqrtf( fDiscr ); fT0 = (-fRayDotToRay - fRoot) * fExtentsRecip; fT1 = (-fRayDotToRay + fRoot) * fExtentsRecip; return 2; // two intersections. } }