public override SegmentCollide TestSegment(XForm transform, out float lambda, out Vec2 normal, Segment segment, float maxLambda)
{
lambda = 0f;
normal = Vec2.Zero;
Vec2 position = transform.Position + Common.Math.Mul(transform.R, _localPosition);
Vec2 s = segment.P1 - position;
float b = Vec2.Dot(s, s) - _radius * _radius;
// Does the segment start inside the circle?
if (b < 0.0f)
{
lambda = 0f;
return SegmentCollide.StartInsideCollide;
}
// Solve quadratic equation.
Vec2 r = segment.P2 - segment.P1;
float c = Vec2.Dot(s, r);
float rr = Vec2.Dot(r, r);
float sigma = c * c - rr * b;
// Check for negative discriminant and short segment.
if (sigma < 0.0f || rr < Common.Settings.FLT_EPSILON)
{
return SegmentCollide.MissCollide;
}
// Find the point of intersection of the line with the circle.
float a = -(c + Common.Math.Sqrt(sigma));
// Is the intersection point on the segment?
if (0.0f <= a && a <= maxLambda * rr)
{
a /= rr;
lambda = a;
normal = s + a * r;
normal.Normalize();
return SegmentCollide.HitCollide;
}
return SegmentCollide.MissCollide;
}