点在凸多边形内判断:Lua函数顶点顺时针方向检测异常
问题分析与修正
你的顶点顺时针判断逻辑出错的核心原因是计算顶点顺序的公式用错了,原代码里的累加项(x2 - x1) * (y2 + y1)是无向面积的计算方式,无法通过符号准确判断顶点的环绕方向。
修正后的完整函数
local function pointInConvexPolygon(x, y, poly) -- poly 格式: {x1,y1, x2,y2, x3,y3, ...} local vertexCount = #poly // 2 -- 顶点总数 if vertexCount < 3 then return false end -- 至少3个顶点才是多边形 local function isVerticesClockwise(poly) local sum = 0 -- 遍历每个顶点,计算有向叉积的累加和 for i = 1, vertexCount do local x1, y1 = poly[2*i-1], poly[2*i] -- 获取下一个顶点,最后一个顶点的下一个是第一个顶点 local nextIdx = i % vertexCount + 1 local x2, y2 = poly[2*nextIdx-1], poly[2*nextIdx] -- 有向叉积项:用于计算多边形的有向面积 sum = sum + (x1 * y2 - x2 * y1) end -- Love2D 中y轴向下,所以sum>0对应顺时针,sum<0对应逆时针 local isClockwise = sum > 0 love.window.setTitle(isClockwise and 'clockwise' or 'counterclockwise') return isClockwise end local sign = isVerticesClockwise(poly) and 1 or -1 -- 从最后一个顶点开始遍历每条边 local lastIdx = vertexCount local x1, y1 = poly[2*lastIdx-1], poly[2*lastIdx] for i = 1, vertexCount do local x2, y2 = poly[2*i-1], poly[2*i] -- 计算点到边的方向叉积(判断点是否在边的同侧) local cross = (x - x1) * (y2 - y1) - (y - y1) * (x2 - x1) if sign * cross < 0 then return false end x1, y1 = x2, y2 end return true end
关键改动说明
顶点顺序判断的公式修正:
改用x1*y2 - x2*y1作为累加项,这是计算多边形有向面积的核心部分,其正负直接反映顶点的环绕方向。在Love2D的y轴向下坐标系中,累加和为正表示顺时针,为负表示逆时针。循环逻辑优化:
直接通过顶点数量遍历,避免原代码中基于数组长度的循环边界问题,逻辑更清晰,也避免了重复处理顶点的情况。点在凸多边形内的判断逻辑修正:
原代码中的dotProduct其实应该是叉积(判断点相对于边的位置),修正为(x - x1) * (y2 - y1) - (y - y1) * (x2 - x1),确保正确判断点是否在所有边的同侧(凸多边形的核心判断逻辑)。
内容的提问来源于stack exchange,提问作者darkfrei
相关产品推荐
相关产品推荐

