int Collision::RectVsCircle(RECT rect, float xO, float yO, float R) { //AB //CD //Hình chữ nhật ABCD, đường tròn tâm O, bán kính R //Tìm điểm M, là điểm gần O nhất float xM, yM, xA, yA, xB, yB, xC, yC, xD, yD; xA=xD=rect.left; xB=xC=rect.right; yA=yB=rect.top; yC=yD=rect.bottom; xM = MiddleNumber(xA, xO, xC); //Tìm tọa độ M yM = MiddleNumber(yA, yO, yC); if (Distance(xM,yM,xO,yO) < R) //Xảy ra va chạm { if (PointInLine(xM,yM,xA,yA,xB,yB)==0) //Nếu M nằm trên AB { if (PointInLine(xM,yM, xB, yB, xC, yC)==0) return 6; //Va chạm tại B if(PointInLine(xM,yM,xA,yA,xD,yD)==0)return 5; //Va chạm tại A else return 1; //Va chạm tại AB } if(PointInLine(xM,yM,xC,yC,xD,yD)==0) { if(PointInLine(xM,yM,xB,yB,xC,yC)==0)return 7; //C if (PointInLine(xM,yM, xA, yA, xD,yD)==0) return 8; //D else return 3; //CD } if (PointInLine(xM,yM, xB,yB, xC,yC)==0) return 2; //BC if (PointInLine(xM,yM, xD,yD, xA,yA) == 0) return 4; else return 9; //Nằm trọn trong ABCD } else return 0; }
// Checks if a line intersect with another line // inout Line : another line // Marge: optional, standard on MARGE (declared in MISC.CPP) // // return true : lines are crossing // false: lines are not crossing // int kbLine::CheckIntersect ( kbLine * lijn, double Marge ) { double distance = 0; // link must exist assert( m_link ); // lijn must exist assert( lijn ); // points may not be equal // must be an if statement because if an assert is used there will // be a macro expansion error if ( m_link->GetBeginNode() == m_link->GetEndNode() ) assert( !m_link ); int Take_Action1, Take_Action2, Total_Result; kbNode *bp, *ep; PointStatus Result_beginnode, Result_endnode; bp = lijn->m_link->GetBeginNode(); ep = lijn->m_link->GetEndNode(); Result_beginnode = PointInLine( bp, distance, Marge ); Result_endnode = PointInLine( ep, distance, Marge ); Take_Action1 = ActionOnTable1( Result_beginnode, Result_endnode ); switch ( Take_Action1 ) { case 0: Total_Result = false ; break; case 1: { bp = m_link->GetBeginNode(); ep = m_link->GetEndNode(); Result_beginnode = lijn->PointInLine( bp, distance, Marge ); Result_endnode = lijn->PointInLine( ep, distance, Marge ); Take_Action2 = ActionOnTable2( Result_beginnode, Result_endnode ); switch ( Take_Action2 ) { case 0: Total_Result = false; break; case 1: case 2: case 3: case 4: Total_Result = true; break; default: Total_Result = false; assert( Total_Result ); } } ; break; // This break belongs to the switch(Take_Action1) case 2: case 3: case 4: case 5: case 6: Total_Result = true; break; default: Total_Result = false; assert( Total_Result ); } return Total_Result; //This is the final decision }
// Intersects two lines // input Line : another line // Marge: optional, standard on MARGE // // return 0: If there are no crossings // 1: If there is one crossing // 2: If there are two crossings int kbLine::Intersect( kbLine * lijn, double Marge ) { double distance = 0; // lijn must exist assert( lijn ); // points may not be equal // must be an if statement because if an assert is used there will // be a macro expansion error if ( m_link->GetBeginNode() == m_link->GetEndNode() ) assert( !m_link ); kbNode *bp, *ep; PointStatus Result_beginnode, Result_endnode; int Take_Action1, Take_Action2, Number_of_Crossings = 0; // Get the nodes from lijn via the link bp = lijn->m_link->GetBeginNode(); ep = lijn->m_link->GetEndNode(); Result_beginnode = PointInLine( bp, distance, Marge ); Result_endnode = PointInLine( ep, distance, Marge ); Take_Action1 = ActionOnTable1( Result_beginnode, Result_endnode ); // The first switch will insert a crosspoint immediatly switch ( Take_Action1 ) { // for the cases see the returnvalue of ActionTable1 case 2: case 6: AddCrossing( ep ); Number_of_Crossings = 1; break; case 3: case 5: AddCrossing( bp ); Number_of_Crossings = 1; break; case 4: AddCrossing( bp ); AddCrossing( ep ); Number_of_Crossings = 2; break; } // This switch wil investigate the points of this line in relation to lijn switch ( Take_Action1 ) { // for the cases see the returnvalue of ActionTable1 case 1: case 5: case 6: { // Get the nodes from this line via the link bp = m_link->GetBeginNode(); ep = m_link->GetEndNode(); Result_beginnode = lijn->PointInLine( bp, distance, Marge ); Result_endnode = lijn->PointInLine( ep, distance, Marge ); Take_Action2 = ActionOnTable2( Result_beginnode, Result_endnode ); switch ( Take_Action2 ) { // for the cases see the returnvalue of ActionTable2 case 1: { // begin of scope to calculate the intersection double X, Y, Denominator; CalculateLineParameters(); Denominator = ( m_AA * lijn->m_BB ) - ( lijn->m_AA * m_BB ); // Denominator may not be 0 assert( Denominator != 0.0 ); // Calculate intersection of both linesegments X = ( ( m_BB * lijn->m_CC ) - ( lijn->m_BB * m_CC ) ) / Denominator; Y = ( ( lijn->m_AA * m_CC ) - ( m_AA * lijn->m_CC ) ) / Denominator; //make a decent rounding to B_INT AddLineCrossing( ( B_INT )X, ( B_INT )Y, lijn ); } // end of scope to calculate the intersection Number_of_Crossings++; break; case 2: lijn->AddCrossing( ep ); Number_of_Crossings++; break; case 3: lijn->AddCrossing( bp ); Number_of_Crossings++; break; case 4: lijn->AddCrossing( bp ); lijn->AddCrossing( ep ); Number_of_Crossings = 2; break; } } ; break; // This break belongs to the outer switch } return Number_of_Crossings; //This is de final number of crossings }