Last active
September 30, 2017 20:12
-
-
Save socantre/14f5790f0d95781b3ad025a1f7147188 to your computer and use it in GitHub Desktop.
regions.lua composing bitmaps
This file contains 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 module = {} | |
function module.circle(cx, cy, radius) | |
return function(x, y) return (x - cx)^2 + (y - cy)^2 < radius^2 end | |
end | |
function module.halfspace(rise, run, x0, y0) | |
return function(x, y) return run*(y - y0) < rise*(x - x0) end | |
end | |
function module.complement(r) | |
return function(x, y) return not r(x, y) end | |
end | |
function module.union(...) | |
local region = {...}; | |
return function(x, y) | |
local result = false; | |
for i, r in ipairs(region) do | |
result = result or r(x, y) | |
end | |
return result | |
end | |
end | |
function module.intersection(...) | |
local region = {...}; | |
return function(x, y) | |
if #region == 0 then return false end | |
local result = true; | |
for i, r in ipairs(region) do | |
result = result and r(x, y) | |
end | |
return result | |
end | |
end | |
function module.difference(r1, r2) | |
return function(x, y) return r1(x, y) and not r2(x, y) end | |
end | |
function module.xor(r1, r2) | |
return function(x, y) return r1(x, y) ~= r2(x, y) end | |
end | |
function module.translate(r, tx, ty) | |
return function(x, y) | |
return r(x - tx, y - ty) | |
end | |
end | |
function module.scale(r, s) | |
return function(x, y) | |
return r(x/s, y/s) | |
end | |
end | |
function module.rotate(r, radians, cx, cy) | |
cx = cx or 0 | |
cy = cy or 0 | |
return function(x, y) | |
return r( | |
(x - cx)*math.cos(-radians) - (y - cy)*math.sin(-radians) + cx, | |
(y - cy)*math.cos(-radians) + (x - cx)*math.sin(-radians) + cy | |
) | |
end | |
end | |
function module.plot(r, output_width, output_height, x0, y0, x1, y1) | |
x0, y0, x1, y1 = x0 or 0, y0 or 0, x1 or 1, y1 or 1 | |
local x, y | |
io.write('P7\nWIDTH ', output_width, '\nHEIGHT ', output_height, '\nDEPTH 1\nMAXVAL 1\nTUPLTYPE BLACKANDWHITE_ALPHA\nENDHDR\n') | |
-- io.write('P1\n', output_width, ' ', output_height, '\n') | |
for i = 0, output_height - 1 do | |
y = y1 - (y1 - y0)/output_height * i | |
for j = 0, output_width - 1 do | |
x = (x1 - x0)/output_width * j + x0 | |
if r(x, y) then | |
io.write('\x00\x00') | |
else | |
io.write('\x00\x01') | |
end | |
end | |
end | |
end | |
return module | |
-- main.lua | |
--[[ | |
local regions = require 'regions' | |
local xor = regions.xor | |
local intersection = regions.intersection | |
local circle = regions.circle | |
local complement = regions.complement | |
local halfspace = regions.halfspace | |
local scale = regions.scale | |
local rotate = regions.rotate | |
local plot = regions.plot | |
local r = | |
xor( | |
intersection( | |
circle(0, 0, 9/16), | |
complement(circle(0, 1/3, 1/16)), | |
complement(circle(0, -1/3, 1/16)) | |
), | |
intersection( | |
halfspace(2, 1, 0, 0), | |
circle(0, 0, 1/2) | |
) | |
) | |
--r = scale(r, 2) | |
--r = rotate(r, math.atan2(1, 2)) | |
local width = arg[1] or 200 | |
local height = arg[2] or 200 | |
local subsamples = arg[3] or 4 | |
plot(r, width, height) | |
]] | |
-- main2.lua | |
--[[ | |
local regions = require "regions" | |
function square(x0, y0, x1, y1) | |
return function(x, y) return x0 < x and x < x1 and y0 < y and y < y1 end | |
end | |
local linewidth = 2/81 | |
local s = square(0 + linewidth/2, 0 + linewidth/2, 1/3 - linewidth/2, 1/3 - linewidth/2) | |
gliders = { | |
regions.union(s, | |
regions.translate(s, 1/3, 0/3), | |
regions.translate(s, 1/3, 1/3), | |
regions.translate(s, 2/3, 1/3), | |
regions.translate(s, 0/3, 2/3)), | |
regions.union(s, | |
regions.translate(s, 1/3, 0/3), | |
regions.translate(s, 2/3, 0/3), | |
regions.translate(s, 1/3, 2/3), | |
regions.translate(s, 2/3, 1/3)), | |
regions.union(regions.translate(s, 1/3, -1/3), | |
regions.translate(s, 1/3, 0/3), | |
regions.translate(s, 2/3, 0/3), | |
regions.translate(s, 0/3, 1/3), | |
regions.translate(s, 2/3, 1/3)), | |
regions.union(regions.translate(s, 1/3, -1/3), | |
regions.translate(s, 2/3, -1/3), | |
regions.translate(s, 2/3, 0/3), | |
regions.translate(s, 0/3, 0/3), | |
regions.translate(s, 2/3, 1/3)), | |
} | |
local framewidth = 1 + 2/3 | |
for i, glider in ipairs(gliders) do | |
gliders[i] = regions.translate(glider, (i-1)*framewidth, 0) | |
end | |
local r = regions.union(unpack(gliders)) | |
local pixels_high = 108 | |
local image_height = 1 + 1/3 | |
local x0, y0 = 0 + 1/(2*pixels_high), - 1/3 - 1/(2*pixels_high) -- offset by half a pixel to avoid boundary issues | |
local aspect_ratio = 18/4 | |
regions.plot(r, math.floor(pixels_high*aspect_ratio), pixels_high, x0, y0, x0+(image_height*aspect_ratio), y0+image_height) | |
]] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment