判断点是否在多边形内(多边形问题:一)cocos2d-x lua

写在前面:最近在做控制人物在地图上行走寻路时遇到了这样的问题,延伸出:1判断点在多边形内 ,2多边形内随机产生一点 ,3多边形外一点到该多边形最近点的坐标。参考网上,慢慢整理一下。都是实测过,用在自己项目里的代码。不定时更新。

下面是:判断点是否在多边形内

方法一:射线法

思路:
1,以测试点向右或左向无穷点左射线,若射线与多边形交点个数是奇数个,则点在内部;若交点个数是偶数个,则点在外部;(这里使用左无穷点)
2,若是凸多边形,条件1完全正确,若是凹多边形,则需要多考虑几种特殊情况
代码如下:(凹凸多边形都可以

function UIUtil:bPointInPolygen(posList, posTarget) -- posList:多边形顶点坐标(按照顺时针或逆时针排序), posTarget:要判断点的坐标 
    local polygenSides = #posList -- 多边形边数
    local flag = 0 -- 与多边形交点个数
    for i = 1, polygenSides do 
        local Xa, Ya = posList[i].x, posList[i].y -- 首坐标
        local Xb, Yb = posList[i].x, posList[i].y -- 尾坐标
        local Xp, Yp = posTarget.x, posTarget.y -- 目标坐标
        if posList[i + 1] then 
            Xb, Yb = posList[i + 1].x, posList[i + 1].y
        else 
            Xb, Yb = posList[1].x, posList[1].y -- 最后一个点 需要与第一个点连成线段
        end 

        -- 只有以下情况才会相交

        -- 点 与 多边形顶点 重合
        if (Xp == Xa and Yp == Ya) or (Xp == Xb and Yp == Yb) then 
            -- print("点 与 多边形顶点 重合 -----true")
            return true
        end 

        --Y轴 在 线断两端点Y轴 内(外永不相交)
        if (Yp <= Yb and Yp >= Ya) or (Yp >= Yb and Yp <= Ya) then 
            -- 线段上 与 射线 坐标相同的点的 X轴坐标
            local tempX = Xa + (Yp - Ya) * (Xb - Xa) / (Yb - Ya)
            -- print("pointX is ----", tostring(tempX))

            -- 点在多边形的边上
            if Xp == tempX then 
                -- print("点在多边形的边上 -----true")
                return true
            end 
    
            -- 射线穿过多边形的边界
            if Xp > tempX then 
                flag = flag + 1
            end 
        end 
    end 

    -- print("flag, bFlag is ----", tostring(flag))
    if flag % 2 == 0 then 
        return false
    else
        return true
    end 
end
方法二:向量叉积法 (凸多边形)

– 向量叉积定义:(x1,y1) x (x2,y2) = x1y2 - x2y1 叉积大小为两向量围成的平行四边形的有向面积
思路:
– 选择固定某一方向(顺时针或逆时针),每相邻两个点组成一个向量ab,再连接这个向量起点a与目标点p组成另一个向量ap
– 结论:flag = ab x ap 向量ab叉积
– flag > 0,ab在ap的顺时针方向(180度范围内)
– flag < 0,ab在ap的逆时针方向(180度范围内)
– flag = 0,ab与ap同向或反向

function bPointInPolygon(posList, posTarget) -- posList:多边形顶点坐标(按照顺时针或逆时针排序), posTarget:要判断点的坐标 
    local polygenSides = #posList -- 多边形边数
    local bIn = true -- 是否在多边形内
    for i = 1, polygenSides do 
        local Xa, Ya = posList[i].x, posList[i].y -- 首坐标 a
        local Xb, Yb = posList[i].x, posList[i].y -- 尾坐标 b
        local Xp, Yp = posTarget.x, posTarget.y -- 目标坐标 p
        if posList[i + 1] then 
            Xb, Yb = posList[i + 1].x, posList[i + 1].y
        else 
            Xb, Yb = posList[1].x, posList[1].y -- 最后一个点 需要与第一个点连成线段
        end 
      
        -- 向量ab = (Xb, Yb) - (Xa, Ya)
        local pointAB = {
     x = Xb - Xa, y = Yb - Ya}
        local pointAP = {
     x = Xp - Xa,  y = Yp - Ya}

        -- 向量ab、向量ap叉积
        local flag = pointAB.x * pointAP.y - pointAP.x * pointAB.y

        -- 这种情况 点不在多边形内
        if flag >= 0 then 
            bIn = false
            break
        end 

    end 

    print("bIn is ----", tostring(bIn))
    return bIn
end

判断点是否在多边形内(多边形问题:一)cocos2d-x lua_第1张图片

你可能感兴趣的:(cocos-lua,cocos2d,lua,多边形)