-- Collison concave polygon -- -- 多角形の内外判定(javascriptでの実装を添えて) - 加具留矢流余 -- https://mikebird28.hatenablog.jp/entry/2020/09/23/002409 function love.load() polys = { {20, 80, 80, 20, 120, 140}, {140, 80, 200, 20, 260, 100, 200, 180}, {340, 20, 400, 60, 380, 160, 320, 160, 280, 80}, {460, 60, 520, 20, 600, 60, 600, 160, 520, 180, 460, 140}, {140, 340, 260, 340, 280, 420, 100, 440, 20, 360, 40, 200, 100, 200}, {500, 320, 460, 220, 380, 240, 440, 340, 300, 360, 340, 440, 500, 420, 520, 460, 620, 420, 600, 320} } hits = {} for i = 1, #polys do hits[i] = false end end function sign(x) return (x < 0 and -1) or 1 end function getDeg(x1, y1, x2, y2) local abs1, abs2, theta, s abs1 = math.sqrt(x1 * x1 + y1 * y1) abs2 = math.sqrt(x2 * x2 + y2 * y2) theta = math.acos((x1 * x2 + y1 * y2) / (abs1 * abs2)) s = sign(x1 * y2 - y1 * x2) return theta * s end function checkInPoly(pos, mx, my) local thetaSum = 0 local x0, y0, x1, y1 local v1x, v1y, v2x, v2y x0, y0 = pos[#pos-1], pos[#pos] if x0 == mx and y0 == my then return true end for i = 1, #pos-1, 2 do x1, y1 = pos[i], pos[i+1] if x1 == mx and y1 == my then return true end v1x, v1y = x0 - mx, y0 - my v2x, v2y = x1 - mx, y1 - my thetaSum = thetaSum + getDeg(v1x, v1y, v2x, v2y) x0, y0 = x1, y1 end thetaSum = math.abs(thetaSum) if thetaSum >= 0.1 then return true end return false end function love.update(dt) local mx, my mx, my = love.mouse.getPosition() for i = 1, #polys do hits[i] = checkInPoly(polys[i], mx, my) end end function love.draw() -- clear canvas love.graphics.clear(0, 0, 0, 1) -- draw polygon for i = 1, #polys do if hits[i] then love.graphics.setColor(1, 0, 0, 1) else love.graphics.setColor(0, 1, 0, 1) end love.graphics.polygon("line", polys[i]) end -- draw text love.graphics.setColor(1, 1, 1, 1) love.graphics.print("ESC to exit.", 8, 8) end function love.keypressed(key, scancode, isrepeat) if key == "escape" then love.event.quit() end end