如何判断一个点是否在凸多边形内 - C++

判断一个点是否在凸多边形内的方法很多,此处仅给出使用向量叉积法判断点是否在凸多边形内的方法。

以下图为例说明问题:

原理:

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;
}
 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值