Last active
February 17, 2016 01:47
-
-
Save 2bt/6c97dc223fd69b4ef1f5 to your computer and use it in GitHub Desktop.
love2d polygon substraction
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local G = love.graphics | |
function splitPoly(poly, mx, my, dx, dy) | |
local poly_a = {} | |
local poly_b = {} | |
local ax = poly[#poly-1] | |
local ay = poly[#poly ] | |
for i = 1, #poly, 2 do | |
local bx = poly[i ] | |
local by = poly[i+1] | |
local abx = bx - ax | |
local aby = by - ay | |
local max = ax - mx | |
local may = ay - my | |
local f = max * dy - may * dx | |
if f >= 0 then | |
poly_a[#poly_a+1] = ax | |
poly_a[#poly_a+1] = ay | |
end | |
if f <= 0 then | |
poly_b[#poly_b+1] = ax | |
poly_b[#poly_b+1] = ay | |
end | |
-- intersect | |
local det = dx*aby - dy*abx | |
if math.abs(det) > 0.0001 then -- not parallel | |
local d = (max*dy - may*dx) / det | |
if d and d > 0 and d < 1 then | |
local sx = ax + (bx - ax) * d | |
local sy = ay + (by - ay) * d | |
poly_a[#poly_a+1] = sx | |
poly_a[#poly_a+1] = sy | |
poly_b[#poly_b+1] = sx | |
poly_b[#poly_b+1] = sy | |
end | |
end | |
ax = bx | |
ay = by | |
end | |
if #poly_a < 6 then poly_a = nil end | |
if #poly_b < 6 then poly_b = nil end | |
return poly_a, poly_b | |
end | |
-- input: two convex polygons | |
-- output: list of convex polygons making up the difference | |
function subtractPoly(minuend, subtrahend) | |
local result = {} | |
local bar = minuend | |
local foo | |
local ax = subtrahend[#subtrahend-1] | |
local ay = subtrahend[#subtrahend ] | |
for i = 1, #subtrahend, 2 do | |
local bx = subtrahend[i ] | |
local by = subtrahend[i+1] | |
foo, bar = splitPoly(bar, ax, ay, bx - ax, by - ay) | |
if foo then result[#result+1] = foo end | |
if not bar then return { minuend } end | |
ax = bx | |
ay = by | |
end | |
return result | |
end | |
poly = {} | |
brush = {} | |
for i = 1, 16 do | |
poly[i*2-1] = 200 + math.floor(math.cos(i / 8 * math.pi) * 100) | |
poly[i*2 ] = 200 + math.floor(math.sin(i / 8 * math.pi) * 100) | |
brush[i*2-1] = math.floor(math.cos(i / 8 * math.pi) * 80) | |
brush[i*2 ] = math.floor(math.sin(i / 8 * math.pi) * 80) | |
end | |
function love.draw() | |
local mx, my = love.mouse.getPosition() | |
local subtr = {} | |
for i = 1, #brush, 2 do | |
subtr[i ] = brush[i ] + mx | |
subtr[i+1] = brush[i+1] + my | |
end | |
G.setLineWidth(3) | |
G.setColor(255, 255, 255, 30) | |
G.polygon("line", subtr) | |
local ps = subtractPoly(poly, subtr) | |
for _, p in ipairs(ps) do | |
G.setColor(255, 255, 255, 30) | |
G.polygon("fill", p) | |
G.setColor(255, 255, 255) | |
G.setLineWidth(1) | |
G.polygon("line", p) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment