int mglnrel::ptInArea( const Point2d& pt, int count, const Point2d* pts, int& order, const Tol& tol, bool closed) { int i; int odd = 1; // 1: 交点数为偶数, 0: 交点数为奇数 float minDist = tol.equalPoint(); Point2d nearpt; order = -1; for (i = 0; i < count && tol.equalPoint() < 1.e5f; i++) { // P与某顶点重合. 返回 kPtAtVertex, order = 顶点号 [0, count-1] float d = pt.distanceTo(pts[i]); if (minDist > d) { minDist = d; order = i; } } if (order >= 0) { return kPtAtVertex; } order = -1; minDist = tol.equalPoint(); for (i = 0; i < (closed ? count : count - 1); i++) { const Point2d& p1 = pts[i]; const Point2d& p2 = (i+1 < count) ? pts[i+1] : pts[0]; // P在某条边上. 返回 kPtOnEdge, order = 边号 [0, count-1] float d = mglnrel::ptToBeeline2(p1, p2, pt, nearpt); if (minDist > d) { minDist = d; order = i; } else if (!PtInArea_Edge(odd, pt, p1, p2, i > 0 ? pts[i-1] : pts[count-1])) { continue; } } if (order >= 0) { return kPtOnEdge; } // 如果射线和多边形的交点数为偶数, 则 p==1, P在区外, 返回 kPtOutArea // 为奇数则p==0, P在区内, 返回 kPtInArea return 0 == odd ? kPtInArea : kPtOutArea; }
bool mglnrel::isBetweenLine2( const Point2d& a, const Point2d& b, const Point2d& pt, const Tol& tol) { if (!mglnrel::isColinear2(a, b, pt, tol)) return false; // If ab not vertical, check betweenness on x; else on y. if (a.x != b.x) { return ((a.x <= pt.x + tol.equalPoint()) && (pt.x <= b.x + tol.equalPoint())) || ((a.x >= pt.x - tol.equalPoint()) && (pt.x >= b.x - tol.equalPoint())); } else { return ((a.y <= pt.y + tol.equalPoint()) && (pt.y <= b.y + tol.equalPoint())) || ((a.y >= pt.y - tol.equalPoint()) && (pt.y >= b.y - tol.equalPoint())); } }
bool mglnrel::isLeftOn2( const Point2d& a, const Point2d& b, const Point2d& pt, const Tol& tol) { float dist = (b-a).distanceToVector(pt-a); return dist > -tol.equalPoint(); }
bool mglnrel::isColinear2( const Point2d& a, const Point2d& b, const Point2d& pt, const Tol& tol) { float dist = (b-a).crossProduct(pt-a); return fabsf(dist) < tol.equalPoint(); }
// 判断点pt是否在有向直线a->b的左边 GEOMAPI bool mgIsLeft2( const Point2d& a, const Point2d& b, const Point2d& pt, const Tol& tol) { float dist = (b-a).distanceToVector(pt-a); return dist > tol.equalPoint(); }