mirror of https://github.com/axmolengine/axmol.git
closed #2494: add isLineOverlap, isLineParallel, isSegmentOverlap method to Point.
This commit is contained in:
parent
9a3a03d6ef
commit
1e452bf0bc
|
@ -116,7 +116,7 @@ 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)
|
||||
bool Point::isOneDemensionSegmentOverlap(float A, float B, float C, float D, float *S, float *E)
|
||||
{
|
||||
float ABmin = MIN(A, B);
|
||||
float ABmax = MAX(A, B);
|
||||
|
@ -126,7 +126,6 @@ bool Point::isOneDemensionLineIntersect(float A, float B, float C, float D, floa
|
|||
if (ABmax < CDmin || CDmax < ABmin)
|
||||
{
|
||||
// ABmin->ABmax->CDmin->CDmax or CDmin->CDmax->ABmin->ABmax
|
||||
*S = (CDmin - A) / (B - A);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
|
@ -134,17 +133,20 @@ bool Point::isOneDemensionLineIntersect(float A, float B, float C, float D, floa
|
|||
if (ABmin >= CDmin && ABmin <= CDmax)
|
||||
{
|
||||
// CDmin->ABmin->CDmax->ABmax or CDmin->ABmin->ABmax->CDmax
|
||||
*S = ABmin==A ? 0 : 1;
|
||||
if (S != nullptr) *S = ABmin;
|
||||
if (E != nullptr) *E = CDmax < ABmax ? CDmax : ABmax;
|
||||
}
|
||||
else if (ABmax >= CDmin && ABmax <= CDmax)
|
||||
{
|
||||
// ABmin->CDmin->ABmax->CDmax
|
||||
*S = ABmax==A ? 0 : 1;
|
||||
if (S != nullptr) *S = CDmin;
|
||||
if (E != nullptr) *E = ABmax;
|
||||
}
|
||||
else
|
||||
{
|
||||
// ABmin->CDmin->CDmax->ABmax
|
||||
*S = (CDmin - A) / (B - A);
|
||||
if (S != nullptr) *S = CDmin;
|
||||
if (E != nullptr) *E = CDmax;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -159,58 +161,83 @@ bool Point::isLineIntersect(const Point& A, const Point& B,
|
|||
{
|
||||
return false;
|
||||
}
|
||||
const float BAx = B.x - A.x;
|
||||
const float BAy = B.y - A.y;
|
||||
const float DCx = D.x - C.x;
|
||||
const float DCy = D.y - C.y;
|
||||
const float ACx = A.x - C.x;
|
||||
const float ACy = A.y - C.y;
|
||||
|
||||
const float denom = DCy*BAx - DCx*BAy;
|
||||
|
||||
*S = DCx*ACy - DCy*ACx;
|
||||
*T = BAx*ACy - BAy*ACx;
|
||||
const float denom = crossProduct2Vector(A, B, C, D);
|
||||
|
||||
if (denom == 0)
|
||||
{
|
||||
if (*S == 0 || *T == 0)
|
||||
{
|
||||
// Lines incident
|
||||
if (A.x != B.x)
|
||||
{
|
||||
isOneDemensionLineIntersect(A.x, B.x, C.x, D.x, S);
|
||||
}
|
||||
else
|
||||
{
|
||||
isOneDemensionLineIntersect(A.y, B.y, C.y, D.y, T);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
// Lines parallel and not incident
|
||||
// Lines parallel or overlap
|
||||
return false;
|
||||
}
|
||||
|
||||
*S = *S / denom;
|
||||
*T = *T / denom;
|
||||
|
||||
// Point of intersection
|
||||
// CGPoint P;
|
||||
// P.x = A.x + *S * (B.x - A.x);
|
||||
// P.y = A.y + *S * (B.y - A.y);
|
||||
if (S != nullptr) *S = crossProduct2Vector(C, D, C, A) / denom;
|
||||
if (T != nullptr) *T = crossProduct2Vector(A, B, C, A) / denom;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Point::isLineParallel(const Point& A, const Point& B,
|
||||
const Point& C, const Point& D)
|
||||
{
|
||||
// FAIL: Line undefined
|
||||
if ( (A.x==B.x && A.y==B.y) || (C.x==D.x && C.y==D.y) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (crossProduct2Vector(A, B, C, D) == 0)
|
||||
{
|
||||
// line overlap
|
||||
if (crossProduct2Vector(C, D, C, A) == 0 || crossProduct2Vector(A, B, C, A) == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Point::isLineOverlap(const Point& A, const Point& B,
|
||||
const Point& C, const Point& D)
|
||||
{
|
||||
// FAIL: Line undefined
|
||||
if ( (A.x==B.x && A.y==B.y) || (C.x==D.x && C.y==D.y) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (crossProduct2Vector(A, B, C, D) == 0 &&
|
||||
(crossProduct2Vector(C, D, C, A) == 0 || crossProduct2Vector(A, B, C, A) == 0))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Point::isSegmentOverlap(const Point& A, const Point& B, const Point& C, const Point& D, Point* S, Point* E)
|
||||
{
|
||||
|
||||
if (isLineOverlap(A, B, C, D))
|
||||
{
|
||||
return isOneDemensionSegmentOverlap(A.x, B.x, C.x, D.x, &S->x, &E->x) &&
|
||||
isOneDemensionSegmentOverlap(A.y, B.y, C.y, D.y, &S->y, &E->y);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Point::isSegmentIntersect(const Point& A, const Point& B, const Point& C, const Point& D)
|
||||
{
|
||||
float S, T;
|
||||
|
||||
if (isLineIntersect(A, B, C, D, &S, &T )&&
|
||||
(S >= 0.0f && S <= 1.0f && T >= 0.0f && T <= 1.0f))
|
||||
(S >= 0.0f && S <= 1.0f && T >= 0.0f && T <= 1.0f))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -245,20 +245,6 @@ 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)
|
||||
|
@ -276,7 +262,29 @@ public:
|
|||
*/
|
||||
static bool isLineIntersect(const Point& A, const Point& B,
|
||||
const Point& C, const Point& D,
|
||||
float *S, float *T);
|
||||
float *S = nullptr, float *T = nullptr);
|
||||
|
||||
/*
|
||||
returns true if Line A-B overlap with segment C-D
|
||||
@since v3.0
|
||||
*/
|
||||
static bool isLineOverlap(const Point& A, const Point& B,
|
||||
const Point& C, const Point& D);
|
||||
|
||||
/*
|
||||
returns true if Line A-B parallel with segment C-D
|
||||
@since v3.0
|
||||
*/
|
||||
static bool isLineParallel(const Point& A, const Point& B,
|
||||
const Point& C, const Point& D);
|
||||
|
||||
/*
|
||||
returns true if Segment A-B overlap with segment C-D
|
||||
@since v3.0
|
||||
*/
|
||||
static bool isSegmentOverlap(const Point& A, const Point& B,
|
||||
const Point& C, const Point& D,
|
||||
Point* S = nullptr, Point* E = nullptr);
|
||||
|
||||
/*
|
||||
returns true if Segment A-B intersects with segment C-D
|
||||
|
@ -291,6 +299,13 @@ public:
|
|||
static Point getIntersectPoint(const Point& A, const Point& B, const Point& C, const Point& D);
|
||||
|
||||
static const Point ZERO;
|
||||
|
||||
private:
|
||||
// returns true if segment A-B intersects with segment C-D. S->E is the ovderlap part
|
||||
static bool isOneDemensionSegmentOverlap(float A, float B, float C, float D, float *S, float * E);
|
||||
|
||||
// cross procuct of 2 vector. A->B X C->D
|
||||
static float crossProduct2Vector(const Point& A, const Point& B, const Point& C, const Point& D) { return (D.y - C.y) * (B.x - A.x) - (D.x - C.x) * (B.y - A.y); }
|
||||
};
|
||||
|
||||
class CC_DLL Size
|
||||
|
|
Loading…
Reference in New Issue