Skip to content

Instantly share code, notes, and snippets.

@Castux
Created June 6, 2024 18:53
Show Gist options
  • Select an option

  • Save Castux/e556320d14502c644368c74d730f43c6 to your computer and use it in GitHub Desktop.

Select an option

Save Castux/e556320d14502c644368c74d730f43c6 to your computer and use it in GitHub Desktop.

Revisions

  1. Castux created this gist Jun 6, 2024.
    122 changes: 122 additions & 0 deletions pyramid-y.lua
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,122 @@
    -- 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