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; }
// 功能: 判断一点是否在一多边形范围内 GEOMAPI MgPtInAreaRet mgPtInArea( const Point2d& pt, int count, const Point2d* vertexs, int& order, const Tol& tol) { int i; int odd = 1; // 1: 交点数为偶数, 0: 交点数为奇数 order = -1; for (i = 0; i < count; i++) { // P与某顶点重合. 返回 kMgPtAtVertex, order = 顶点号 [0, count-1] if (pt.isEqualTo(vertexs[i], tol)) { order = i; return kMgPtAtVertex; } } for (i = 0; i < count; i++) { const Point2d& p1 = vertexs[i]; const Point2d& p2 = (i+1 < count) ? vertexs[i+1] : vertexs[0]; // P在某条边上. 返回 kMgPtOnEdge, order = 边号 [0, count-1] if (mgIsBetweenLine2(p1, p2, pt, tol)) { order = i; return kMgPtOnEdge; } if (!PtInArea_Edge(odd, pt, p1, p2, i > 0 ? vertexs[i-1] : vertexs[count-1])) continue; } // 如果射线和多边形的交点数为偶数, 则 p==1, P在区外, 返回 kMgPtOutArea // 为奇数则p==0, P在区内, 返回 kMgPtInArea return 0 == odd ? kMgPtInArea : kMgPtOutArea; }