Last active
June 3, 2024 19:37
-
-
Save Castux/ee792e2631716ec0041aa2732d142a4b to your computer and use it in GitHub Desktop.
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
-- For the animation, run with the love2d game engine | |
-- For the SVG output, run with the standard Lua interpreter | |
local narrow = false -- Change this to true to fold around the narrow angle instead of the wide one | |
local size = 14 -- This is the number of hexes on the side of the flat rhombus | |
local base_hex = {} | |
local s32 = math.sqrt(3)/2 | |
local rad = 1/math.sqrt(3) | |
for i = 1,6 do | |
local alpha = (i + 0.5) * 2 * math.pi / 6 | |
table.insert(base_hex, {rad * math.cos(alpha), rad * math.sin(alpha)}) | |
end | |
local hexes = {} | |
for x = 0,size do | |
for y = 0,size do | |
local y_shift = narrow and 0.5 or -0.5 | |
local dx = x + y_shift * y | |
local dy = s32 * y | |
local hex = {} | |
for i = 1,6 do | |
hex[i] = { | |
base_hex[i][1] + dx, | |
base_hex[i][2] + dy | |
} | |
end | |
table.insert(hexes, hex) | |
end | |
end | |
local steps2 = 15 | |
local function to_segments(hex) | |
local coords = {} | |
for i = 1,6 do | |
local a = hex[i] | |
local b = hex[(i % 6) + 1] | |
for k = 0,steps2 do | |
local s = k / steps2 | |
table.insert(coords, { | |
(1-s) * a[1] + s * b[1], | |
(1-s) * a[2] + s * b[2] | |
}) | |
end | |
end | |
return coords | |
end | |
local function fold(p, factor) | |
local d = math.sqrt(p[1]^2 + p[2]^2) | |
local a = math.atan2(p[2], p[1]) | |
a = a * factor | |
local x = d * math.cos(a) | |
local y = d * math.sin(a) | |
return {x,y} | |
end | |
local function toSVG() | |
local svg = {} | |
table.insert(svg, '<svg xmlns="http://www.w3.org/2000/svg" width="1500" height="1000" viewBox="0 0 1500 1000">') | |
local factor = narrow and 6 or 3 | |
local scale = 20 | |
for _,hex in ipairs(hexes) do | |
local coords = "" | |
for _,p in ipairs(to_segments(hex)) do | |
p = fold(p, factor) | |
coords = coords .. string.format("%.2f,%.2f ", scale * p[1] + 600, scale * p[2] + 500) | |
end | |
table.insert(svg, string.format('<polygon points="%s" fill="white" stroke="black" stroke-width="3" />', coords)) | |
end | |
table.insert(svg, "</svg>") | |
return table.concat(svg, "\n") | |
end | |
if love then | |
function love.load() | |
love.window.setMode( 1500,1000 ) | |
end | |
function love.draw() | |
local max_factor = narrow and 5 or 2 | |
local factor = (math.sin(love.timer.getTime() / 10 * 2 * math.pi) + 1)/2 * max_factor + 1 | |
local scale = 20 | |
for _,hex in ipairs(hexes) do | |
local coords = {} | |
for _,p in ipairs(to_segments(hex)) do | |
p = fold(p, factor) | |
table.insert(coords, scale * p[1] + 600) | |
table.insert(coords, scale * p[2] + 500) | |
end | |
love.graphics.polygon("line", coords) | |
end | |
end | |
else | |
local fp = io.open("out.svg", "w") | |
fp:write(toSVG()) | |
fp:close() | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
TypeScript version here: https://gist.github.com/Perlkonig/25a9ffd67bbf40faec649f5b174c94c5