Skip to content

Instantly share code, notes, and snippets.

@Castux
Created June 6, 2024 18:53
Show Gist options
  • Save Castux/e556320d14502c644368c74d730f43c6 to your computer and use it in GitHub Desktop.
Save Castux/e556320d14502c644368c74d730f43c6 to your computer and use it in GitHub Desktop.
-- 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