예제 #1
0
파일: CLine.cpp 프로젝트: cugone/Abrams2010
bool Line::Intersects(const Circle& circle) const {
    double r2 = circle.GetRadius();
    r2 *= r2;
    bool eOne_result = ((_extent_one - circle.GetPosition()).GetLengthSquared() < r2);
    bool eTwo_result = ((_extent_two - circle.GetPosition()).GetLengthSquared() < r2);
    if(eOne_result) return true;
    if(eTwo_result) return true;
    return this->GetDistance(Point(circle.GetPosition())) <= circle.GetRadius();
}
예제 #2
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);
   }
예제 #3
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;
      }
   }
bool 
collides( const Circle & c, const LineSegment & l)
{
  
  Vector2 posToCenter = c.GetCenter() - l.GetStart();
  Vector2 dirVec      = l.GetEnd()    - l.GetStart();

  float segmentLength = dirVec.Length();
  // direction vector must be unit vector (ie. length = 1) in this case!
  // otherwise we would need another formula for scalar projection.
  dirVec = dirVec / segmentLength; 

  // scalar projection of posToCenter to direction vector.
  float d = dirVec.Dot(posToCenter);

  // if d value exceeds original segment length, then we put a cap on it.
  // if these two lines are dismissed, then algorithm sees line segment 
  // as a infinite line.
  if ( d >  segmentLength ) d = segmentLength;
  if ( d < -segmentLength ) d = -segmentLength;
  
  // compute closest point to circle center from line start 
  // along direction vector.
  Vector2 closest_point =l.GetStart() + dirVec * d;

  // vectorfrom circle center to closest point on line
  Vector2 S = closest_point - c.GetCenter();

  return (S.Length() <= c.GetRadius());
}
예제 #5
0
void Circle::CollisionWithCircle(Circle& circle, ContactManifold& contactManifold)
{
    float r = this->GetRadius() + circle.GetRadius();
    float r2 = r * r;

    glm::vec2 n = circle.GetNewPos() - this->GetNewPos();
    if (glm::length2(n) > r2)
    {
        return;
    }

    // Circles collided... compute manifold point!
    ManifoldPoint newPoint;
    float d = glm::length(n);

    if (d != 0.0f)
    {
        newPoint.penetration = r - d;
        // Convert n to unit vector, already used a sqrt for d, so use it.
        newPoint.contactNormal = n / d;
        newPoint.contactPos = this->GetNewPos() + newPoint.contactNormal * this->GetRadius();
    }
    else
    {
        // Circles have same position... so default penetration to this' radius and normal as up.
        newPoint.penetration = this->GetRadius();
        newPoint.contactPos = this->GetNewPos();
        newPoint.contactNormal = glm::vec2(1.0f, 0.0f);
    }
    newPoint.contactID1 = this;
    newPoint.contactID2 = &circle;
    newPoint.responded = false;

    contactManifold.Add(newPoint);
}
예제 #6
0
bool Rectangle::Intersects(const Circle& circle) const {

    double radius = circle.GetRadius();

    auto cp = circle.GetPosition();

    auto t = GetTop();
    double distTop = Math::GetDistance(cp, t.GetPointOne(), t.GetPointTwo());

    auto l = GetLeft();
    double distLeft = Math::GetDistance(cp, l.GetPointOne(), l.GetPointTwo());

    auto r = GetRight();
    double distRight = Math::GetDistance(cp, r.GetPointOne(), r.GetPointTwo());

    auto b = GetBottom();
    double distBottom = Math::GetDistance(cp, b.GetPointOne(), b.GetPointTwo());

    bool resultTop = distTop <= radius;
    bool resultLeft = distLeft <= radius;
    bool resultRight = distRight <= radius;
    bool resultBottom = distBottom <= radius;
    bool isInside = Intersects(Point(circle.GetPosition()));
    return (isInside || resultTop || resultLeft || resultRight || resultBottom);
}
예제 #7
0
   bool Intersects(const Circle &circle, const Vector2 &point)
   {
      float radius(circle.GetRadius());
      const Vector2 &centre(circle.GetCentre());

      return ((point - centre).MagnitudeSquared() <= radius * radius);
   }
void
draw_circle( SDL_Renderer *renderer, Circle & c, int r, int g, int b, int a  )
{
  // just to make compiler happy
  int x = static_cast<int>(c.GetCenter().GetX());
  int y = static_cast<int>(c.GetCenter().GetY());
  filledCircleRGBA(renderer, x,y, c.GetRadius(), r,g,b,a );
}
예제 #9
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;
      }
   }
예제 #10
0
	void D3DRenderContext::RenderSolidCircle(const Circle& c, const ivec3& color) const {
		WireGeometryVertex points[CIRCLE_SECTORS_COUNT + 1];
		float pi2 = 2.0f * M_PI;
		float sectorSize = pi2 / CIRCLE_SECTORS_COUNT;

		int pointNo = 0;
		for(float angle = 0.0f; angle < pi2; angle += sectorSize, ++pointNo) {
			points[pointNo].x = c.GetOrigin().x + glm::cos(angle) * c.GetRadius();
			points[pointNo].y = c.GetOrigin().y + glm::sin(angle) * c.GetRadius();
			points[pointNo].z = MAX_ZCHOOORD;
			points[pointNo].color = D3DCOLOR_XRGB(color.x, color.y, color.z);
		}
		points[CIRCLE_SECTORS_COUNT].x = c.GetOrigin().x + c.GetRadius();
		points[CIRCLE_SECTORS_COUNT].y = c.GetOrigin().y;
		points[CIRCLE_SECTORS_COUNT].z = MAX_ZCHOOORD;
		points[CIRCLE_SECTORS_COUNT].color = D3DCOLOR_XRGB(color.x, color.y, color.z);

		m_d3dDevice->SetFVF(D3DFVF_WIRE_GEOMETRY_VERTEX);
		m_d3dDevice->DrawPrimitiveUP(D3DPT_LINESTRIP, CIRCLE_SECTORS_COUNT, static_cast<void*>(points), sizeof(WireGeometryVertex));
	}
예제 #11
0
bool Sector::Intersects(const Circle& circle) const {

    //Intersections performed fast to slow.
    //FAST:
    //If bounding circle and argument circle do not intersect: no.
    //If initial point intersects circle: yes.
    //If terminal point intersects circle: yes.
    //If central point intersects circle: yes.
    //SLOW:
    //If the angle between the circle and the sector is in-between the start and end angles (mapped to [0, 2pi]): yes.
    //If the circle intersects the initial line: yes.
    //If the circle intersects the terminal line: yes.
    //Otherwise: no.

    double my_x = this->GetX();
    double my_y = this->GetY();
    double your_x = circle.GetX();
    double your_y = circle.GetY();
    double radius_sum = this->GetRadius() + circle.GetRadius();
    if(a2de::Point::GetDistance(my_x, my_y, your_x, your_y) > radius_sum) return false;

    if(this->GetStartPoint().Intersects(circle)) return true;
    if(this->GetEndPoint().Intersects(circle)) return true;
    if(Point(this->GetPosition()).Intersects(circle)) return true;
    
    double angle = Vector2D::GetFacingAngle(circle.GetPosition(), this->GetPosition());

    //Map return values to [0, 360]
    double sA = this->GetStartAngle();
    if(sA > Math::A2DE_PI) {
        sA -= Math::A2DE_2PI;
    }
    double eA = this->GetEndAngle();
    if(eA > Math::A2DE_PI) {
        eA -= Math::A2DE_2PI;
    }
    bool within_sector = (sA <= angle && angle <= eA);
    if(within_sector) return true;

    Line sl(this->GetPosition(), this->GetStartPoint().GetPosition());
    Line tl(this->GetPosition(), this->GetEndPoint().GetPosition());

    if(sl.Intersects(circle)) return true;
    if(tl.Intersects(circle)) return true;

    return false;
}
예제 #12
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;
   }
예제 #13
0
파일: Dial.cpp 프로젝트: joe90p/Downfall
int Dial::GetRadius()
{
	Circle* area = static_cast<Circle*>(this->GetClientArea());
	return area->GetRadius();
}