Esempio n. 1
0
   bool Intersects(const Circle &circle1, const Circle &circle2)
   {
      const Vector2 &centre1(circle1.GetCentre());
      float radius1(circle1.GetRadius());

      const Vector2 &centre2(circle2.GetCentre());
      float radius2(circle2.GetRadius());

      return Intersects(centre1, radius1, centre2, radius2);
   }
Esempio n. 2
0
   int IntersectionPoints(const Circle &circleA, const Circle &circleB, Vector2 &point1, Vector2 &point2)
   {
      const Vector2 &centreA(circleA.GetCentre());
      const Vector2 &centreB(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;
      }
   }
Esempio n. 3
0
   bool Intersects(const Circle &circle, const Vector2 &point)
   {
      float radius(circle.GetRadius());
      const Vector2 &centre(circle.GetCentre());

      return ((point - centre).MagnitudeSquared() <= radius * radius);
   }
Esempio n. 4
0
   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;
      }
   }
Esempio n. 5
0
   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);
   }
Esempio n. 6
0
   bool Intersects(const Circle &circle, const AARect &rect)
   {
      if (rect.IsNull()) 
      {
         return false;
      }

      // Use splitting planes
      const Vector2 &center = 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;
   }