bool Intersects(const Circle &circle1, const Circle &circle2) { const Vector2 ¢re1(circle1.GetCentre()); float radius1(circle1.GetRadius()); const Vector2 ¢re2(circle2.GetCentre()); float radius2(circle2.GetRadius()); return Intersects(centre1, radius1, centre2, radius2); }
int IntersectionPoints(const Circle &circleA, const Circle &circleB, Vector2 &point1, Vector2 &point2) { const Vector2 ¢reA(circleA.GetCentre()); const Vector2 ¢reB(circleB.GetCentre()); float radiusA(circleA.GetRadius()); float radiusB(circleB.GetRadius()); Vector2 aToB(centreB - centreA); float distSq = aToB.MagnitudeSquared(); if (distSq == 0.0f) { // circles have the same centre // either 0 or infinite number of intersection points return 0; } float dist = Sqrt(distSq); if (dist > radiusA + radiusB || dist < Abs(radiusA - radiusB)) { // Circles are not intersecting or one is contained within the other return 0; } float distInv = 1.0f / dist; float radiusASq(radiusA * radiusA); float radiusBSq(radiusB * radiusB); float a = (radiusASq - radiusBSq + distSq) * (0.5f * distInv); float h = Sqrt(radiusASq - a * a); Vector2 aToBDir(aToB * distInv); Vector2 m(centreA + a * aToBDir); Vector2 aToBNorm(-aToBDir.y, aToBDir.x); if (h == 0.0f) { point1 = m; return 1; } else { point1 = m + h * aToBNorm; point2 = m - h * aToBNorm; return 2; } }
bool Intersects(const Circle &circle, const Vector2 &point) { float radius(circle.GetRadius()); const Vector2 ¢re(circle.GetCentre()); return ((point - centre).MagnitudeSquared() <= radius * radius); }
bool Intersects(const Ray2 &ray, const Circle &circle, float *distance) { const Vector2 &rayDir = ray.GetDirection(); // Adjust ray origin relative to circle center const Vector2 &rayOrig = ray.GetOrigin() - circle.GetCentre(); float radius = circle.GetRadius(); // Check origin inside first if (rayOrig.MagnitudeSquared() <= radius * radius) { SetPtrValue(distance, 0.0f); return true; } // Mmm, quadratics // Build coeffs which can be used with std quadratic solver // ie t = (-b +/- sqrt(b * b + 4ac)) / 2a float a = Vector2::DotProduct(rayDir, rayDir); float b = 2 * Vector2::DotProduct(rayOrig, rayDir); float c = Vector2::DotProduct(rayOrig, rayOrig) - radius * radius; // Calc determinant float d = (b * b) - (4 * a * c); if (d < 0) { // No intersection SetPtrValue(distance, 0.0f); return false; } else { // BTW, if d=0 there is one intersection, if d > 0 there are 2 // But we only want the closest one, so that's ok, just use the // '-' version of the solver float negB(-b); float sqrtD(Sqrt(d)); float twoA(2 * a); float t = (negB - sqrtD) / twoA; if (t < 0) { t = (negB + sqrtD) / twoA; } if (t > 0) { SetPtrValue(distance, t); return true; } return false; } }
int TangentIntersects(const Circle &circle, const Vector2 &external, Vector2 &point1, Vector2 &point2) { Vector2 externalToCentreA(circle.GetCentre() - external); Vector2 externalToCentreAMid(externalToCentreA * 0.5f); Vector2 centreB(external + externalToCentreAMid); float radiusB(externalToCentreAMid.Magnitude()); Circle circleB(centreB, radiusB); return IntersectionPoints(circle, circleB, point1, point2); }
bool Intersects(const Circle &circle, const AARect &rect) { if (rect.IsNull()) { return false; } // Use splitting planes const Vector2 ¢er = circle.GetCentre(); float radius = circle.GetRadius(); const Vector2 &min = rect.GetMinimum(); const Vector2 &max = rect.GetMaximum(); // just test facing planes, early fail if circle is totally outside if (center.x < min.x && min.x - center.x > radius) { return false; } if (center.x > max.x && center.x - max.x > radius) { return false; } if (center.y < min.y && min.y - center.y > radius) { return false; } if (center.y > max.y && center.y - max.y > radius) { return false; } // Must intersect return true; }