Created
June 6, 2024 18:53
-
-
Save Castux/e556320d14502c644368c74d730f43c6 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 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 = -size,size do | |
for y = 0,size do | |
if x - y >= -size and not (y == 0 and x < 0) then | |
local y_shift = -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 | |
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 = 2 | |
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 = 1 | |
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