bool PointProjectionTools::segmentIntersect(const CCVector2& A, const CCVector2& B, const CCVector2& C, const CCVector2& D) { CCVector2 AB = B-A; CCVector2 AC = C-A; CCVector2 AD = D-A; PointCoordinateType cross_AB_AC = AB.cross(AC); PointCoordinateType cross_AB_AD = AB.cross(AD); //both C and D are on the same side of AB? if (cross_AB_AC * cross_AB_AD > 0) { //no intersection return false; } CCVector2 CD = D-C; CCVector2 CB = B-C; PointCoordinateType cross_CD_CA = -CD.cross(AC); PointCoordinateType cross_CD_CB = CD.cross(CB); //both A and B are on the same side of CD? if (cross_CD_CA * cross_CD_CB > 0) { //no intersection return false; } PointCoordinateType cross_AB_CD = AB.cross(CD); if (fabs(cross_AB_CD) != 0) //AB and CD are not parallel { //where do they intersect? //PointCoordinateType v = cross_AB_AC/cross_AB_CD; //assert(v >= 0 && v <= 1); return true; } else //AB and CD are parallel (therefore they are colinear - see above tests) { PointCoordinateType dAB = AB.norm(); PointCoordinateType dot_AB_AC = AB.dot(AC); if (dot_AB_AC >= 0 && dot_AB_AC < dAB * AC.norm()) { //C is between A and B return true; } PointCoordinateType dot_AB_AD = AB.dot(AD); if (dot_AB_AD >= 0 && dot_AB_AD < dAB * AD.norm()) { //D is between A and B return true; } //otherwise there's an intersection only if B and C are on both sides! return (dot_AB_AC * dot_AB_AD < 0); } }
//! Returns true if the AB and CD segments intersect each other bool Intersect(const CCVector2& A, const CCVector2& B, const CCVector2& C, const CCVector2& D) { if (cross(A,B,C) * cross(A,B,D) >= 0) //both points are on the same side? No intersection return false; CCVector2 AB = B-A; CCVector2 AC = C-A; CCVector2 CD = D-C; PointCoordinateType q = CD.y * AB.x - CD.x * AB.y; if (fabs(q) > ZERO_TOLERANCE) //AB and CD are not parallel { //where do they interest? PointCoordinateType p = AC.x * AB.y - AC.y * AB.x; PointCoordinateType v = p/q; if (v <= 0 || v >= 1) //not CD! return false; //test further with AB p = CD.y * AC.x - CD.x * AC.y; v= p/q; return (v > 0 && v < 1); //not AB? } else //AB and CD are parallel { PointCoordinateType dAB = AB.norm(); PointCoordinateType dAC = AC.norm(); PointCoordinateType dot = AB.dot(AC) / (dAB * dAC); if (fabs(dot) < 0.999) { //not colinear return false; } else { //colinear --> do they actually intersect? return (dAC < dAB || (D-A).norm() < dAB); } } }