2021/06/21(月) [n年前の日記]
#2 [love2d] love2dで凸多角形の内外判定
Windows10 x64 20H2 + love2d 11.3 の環境で、点が凸多角形の内外にあるか判定する処理を書いてみた。昨日は、三角形の内外判定を外積を使って行ってみたけど、座標値の数が増えても処理できるように対応させた。
_main.lua
_conf.lua
main.lua と conf.lua を任意のディレクトリに置いて、love ディレクトリ名、で実行。
比較的簡単な処理なので、凸多角形にしか対応してないあたりがアレだけど…。凹多角形ではおかしな結果になるはず。たぶん。
もっとも、凹多角形については、事前に人力で複数の凸多角形に分割しておけば済む予感。
_main.lua
function love.load() polys = { {60, 100, 150, 180, 150, 300, 60, 380}, {160, 60, 440, 60, 360, 180, 240, 180}, {470, 130, 560, 170, 550, 270}, {420, 280, 540, 300, 540, 420, 470, 450, 370, 350}, {260, 280, 320, 320, 320, 400, 260, 440, 190, 400, 190, 320}, } hits = {} for i = 1, #polys do hits[i] = false end end function getCrossVec2D(vx1, vy1, vx2, vy2) return (vx1 * vy2 - vx2 * vy1) end function checkInConvexPoly(pos, mx, my) local cc = {} local x0, y0, x1, y1 x0, y0 = pos[#pos-1], pos[#pos] for i = 1, #pos-1 ,2 do x1, y1 = pos[i], pos[i+1] table.insert(cc, (getCrossVec2D(x1 - x0, y1 - y0, mx - x1, my - y1) < 0)) x0, y0 = x1, y1 end local c0, c1 c0 = cc[1] for i = 2, #cc do c1 = cc[i] if c0 ~= c1 then return false end c0 = c1 end return true end function love.update(dt) local mx, my mx, my = love.mouse.getPosition() for i = 1, #polys do hits[i] = checkInConvexPoly(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("fill", 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
_conf.lua
function love.conf(t) t.window.width = 640 t.window.height = 480 t.window.title = "Collision Polygon" t.window.fullscreen = false -- t.window.fullscreentype = "exclusive" end
main.lua と conf.lua を任意のディレクトリに置いて、love ディレクトリ名、で実行。
比較的簡単な処理なので、凸多角形にしか対応してないあたりがアレだけど…。凹多角形ではおかしな結果になるはず。たぶん。
もっとも、凹多角形については、事前に人力で複数の凸多角形に分割しておけば済む予感。
[ ツッコむ ]
以上です。