判断一个点是否在凸多边形内的方法很多,此处仅给出使用向量叉积法判断点是否在凸多边形内的方法。
以下图为例说明问题:
原理:
1. 将多边形的第 i 条边的第一个顶点指向点 P 得到向量 v1,然后将从第一个顶点指向第二个顶点得到向量 v2,叉乘这两个向量。
2. 如果叉乘结果与上一条边的叉乘结果的乘积大于 0 则继续执行;如果乘积小于 0,表示点 P 不在凸多边形内,直接返回即可。
切记:要求凸多边形的点以固定的顺序给出,例如固定为逆时针或顺时针。
实验结果如下图,main函数最后有判断几个点是否在多边形中的举例
实现的代码如下:
#include<stdio.h> #include<vector> using namespace std; struct Point { float x; float y; Point() :x(0), y(0){} Point(float inx, float iny) { x = inx; y = iny; } }; Point SubPoint(const Point& vTarget1, const Point& vTarget2) { Point vPoint; vPoint.x = vTarget1.x - vTarget2.x; vPoint.y = vTarget1.y - vTarget2.y; return vPoint; } float CrossProduct(const Point& vTarget1, const Point& vTarget2) { return vTarget1.x * vTarget2.y - vTarget2.x * vTarget1.y; } bool IsPointInConvexPolygon(const vector<Point>& aPoints, const Point& vTarget) { if (aPoints.size() == 0) return false; float nCurCrossProduct = 0, nLastValue = 0; for (int i = 0; i < aPoints.size(); i++) { Point vU = SubPoint(vTarget, aPoints[i]); int nNextIndex = (i + 1) % aPoints.size(); Point vV = SubPoint(aPoints[nNextIndex], aPoints[i]); nCurCrossProduct = CrossProduct(vU, vV); if (i > 0 && nCurCrossProduct * nLastValue <= 0) { return false; } nLastValue = nCurCrossProduct; } return true; } int main() { vector<Point> duobian; duobian.push_back(Point{x:0,y:0}); duobian.push_back(Point{x:0,y:1158}); duobian.push_back(Point{x:346,y:1345}); duobian.push_back(Point{x:750,y:1118}); duobian.push_back(Point{x:750,y:0}); bool bSuc1 = IsPointInConvexPolygon(duobian, Point{x:350, y:1160}); printf("bSuc1=%d \n", bSuc1); bool bSuc2 = IsPointInConvexPolygon(duobian, Point{x:2, y:1190}); printf("bSuc2=%d \n", bSuc2); bool bSuc3 = IsPointInConvexPolygon(duobian, Point{x:749, y:1118}); printf("bSuc3=%d \n", bSuc3); return 0; }