closed #2494: Fix bug when two line is incident, the Point::isSegmentIntersect() may return wrong result

This commit is contained in:
boyu0 2013-08-23 14:37:56 +08:00
parent 77f89956a3
commit 3f23a4a661
2 changed files with 57 additions and 0 deletions

View File

@ -116,6 +116,40 @@ Point Point::rotateByAngle(const Point& pivot, float angle) const
return pivot + (*this - pivot).rotate(Point::forAngle(angle));
}
bool Point::isOneDemensionLineIntersect(float A, float B, float C, float D, float *S)
{
float ABmin = MIN(A, B);
float ABmax = MAX(A, B);
float CDmin = MIN(C, D);
float CDmax = MAX(C, D);
if (ABmax < CDmin || CDmax < ABmin)
{
// ABmin->ABmax->CDmin->CDmax or CDmin->CDmax->ABmin->ABmax
*S = (CDmin - A) / (B - A);
return false;
}
else
{
if (ABmin >= CDmin && ABmin <= CDmax)
{
// CDmin->ABmin->CDmax->ABmax or CDmin->ABmin->ABmax->CDmax
*S = ABmin==A ? 0 : 1;
}
else if (ABmax >= CDmin && ABmax <= CDmax)
{
// ABmin->CDmin->ABmax->CDmax
*S = ABmax==A ? 0 : 1;
}
else
{
// ABmin->CDmin->CDmax->ABmax
*S = (CDmin - A) / (B - A);
}
return true;
}
}
bool Point::isLineIntersect(const Point& A, const Point& B,
const Point& C, const Point& D,
float *S, float *T)
@ -142,6 +176,15 @@ bool Point::isLineIntersect(const Point& A, const Point& B,
if (*S == 0 || *T == 0)
{
// Lines incident
if (C.x != D.x)
{
isOneDemensionLineIntersect(A.x, B.x, C.x, D.x, S);
}
else
{
isOneDemensionLineIntersect(A.x, B.x, C.x, D.x, S);
}
return true;
}
// Lines parallel and not incident

View File

@ -245,6 +245,20 @@ public:
return Point(cosf(a), sinf(a));
}
/** A general line-line intersection test
@param A the startpoint for the first line L1 = (A - B)
@param B the endpoint for the first line L1 = (A - B)
@param C the startpoint for the second line L2 = (C - D)
@param D the endpoint for the second line L2 = (C - D)
@param S the range for a hitpoint in L1 (p = A + S*(B - A))
@returns whether these two lines interects.
Note that if two line is intersection, S in line in [0..1]
the hit point also is A + S * (B - A);
@since 3.0
*/
static bool isOneDemensionLineIntersect(float A, float B, float C, float D, float *S);
/** A general line-line intersection test
@param A the startpoint for the first line L1 = (A - B)
@param B the endpoint for the first line L1 = (A - B)