bool Circle::CircleCircleIntersect( Circle *a, Circle *b, Vector2 *pointAOut, Vector2 *pointBOut ){ Vector2 *d = b->m_pos->Sub( a->m_pos ); float centerDist = d->get_m_Len(); if( centerDist > a->m_radius + b->m_radius ){ // separated pointAOut = pointBOut = 0; return false; } else { // partial intersection float r0Sqr = a->m_radius*a->m_radius; float newCenterDist = ( r0Sqr-b->m_radius*b->m_radius+centerDist*centerDist )/( 2*centerDist ); float sqr = r0Sqr-newCenterDist*newCenterDist; if( sqr <= 0.0 ){ // containment pointAOut = pointBOut = 0; return false; } Vector2 *P2 = a->m_pos->Add( d->MulScalar( newCenterDist/centerDist ) ); float radius = sqrt( sqr ); Vector2 *perp = b->m_pos->Sub( a->m_pos )->get_m_Perp()->get_m_Unit(); Vector2 *temp_a = P2->Add(perp->MulScalar(radius)); //TESTME Vector2 *temp_b = P2->Sub(perp->MulScalar(radius)); pointAOut->m_x = temp_a->m_x; pointAOut->m_y = temp_a->m_y; pointBOut->m_x = temp_b->m_x; pointBOut->m_y = temp_b->m_y; return true; } }
PointAndDistanceContainer *Circle::ClosestPointAndDistOnEdge( Vector2 *p ){ Vector2 *d = p->Sub(m_pos); float distCenter = d->get_m_Len(); float penetration = distCenter - m_radius; if( distCenter == 0 ){ return new PointAndDistanceContainer( m_pos->Add(new Vector2( m_radius, 0 )), -m_radius ); } // generate point on edge Vector2 *pow = d->MulScalar(m_radius/distCenter)->AddTo(m_pos); return new PointAndDistanceContainer(pow, penetration); }