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(); }
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 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()); }
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); }
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); }
bool Intersects(const Circle &circle, const Vector2 &point) { float radius(circle.GetRadius()); const Vector2 ¢re(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 ); }
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; } }
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)); }
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; }
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; }
int Dial::GetRadius() { Circle* area = static_cast<Circle*>(this->GetClientArea()); return area->GetRadius(); }