Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
1
Help us understand the problem. What is going on with this article?
@jdeseno

Generating Simple Voronoi Diagrams with Lua and Love2d

More than 5 years have passed since last update.

Generating Simple Voronoi Diagrams with Lua and Love2d

-- http://en.wikipedia.org/wiki/Manhattan_distance
local manhattan = function(a, b)
  return math.abs(a.x - b.x) + math.abs(a.y - b.y)
end

local voronoi = function(width, height, dst)
  local random_points = {}

  -- ideally a point per 25x25 pixels
  local count  = (width * height) / (25 * 25)

  -- generate random points
  for i=1,count do
    table.insert(random_points, {
      x = tonumber(math.random() * width),
      y = tonumber(math.random() * height),
      pixels = {}
    })
  end

  -- for every pixel available
  for x=1,width do
    for y=1,height do
      -- find the closest random point to this pixel
      local point = {x = x, y = y}
      local closest_point = random_points[1]

      for i=2,#random_points do
        if dst(point, closest_point) > dst(point, random_points[i]) then
          closest_point = random_points[i]
        end
      end

      table.insert(closest_point.pixels, point)
    end
  end

  return {
    width = width,
    height = height,
    points = random_points
  }
end

-- return a new rgb value with each call
local nextColor = (function()
  local i, colors = 0, {}
  for r=0,255,32 do
    for g=0,255,32 do table.insert(colors, {r, g, 82}) end
    for b=0,255,32 do table.insert(colors, {r, 82, b}) end
  end

  return function()
    i = i + 1
    if i > #colors then i = 1 end
    return unpack(colors[i])
  end
end)()

-- draw voronoi on a love2d canvas
local createCanvas = function(vrn)
  local canvas = love.graphics.newCanvas(vrn.width, vrn.height)
  love.graphics.setCanvas(canvas)
  canvas:clear(255, 255, 255, 255)
  -- love.graphics.setBlendMode('alpha')

  for i,point in ipairs(vrn.points) do
    -- with a new drawing color
    love.graphics.setColor(nextColor())

    -- draw every nearby pixel
    -- love2d centers pixels, so offset them by 0.5 for crispness
    for i,pixel in ipairs(point.pixels) do
      love.graphics.point(pixel.x - 0.5, pixel.y - 0.5)
    end

    -- draw the center dot
    love.graphics.setColor(0, 0, 0)
    love.graphics.point(point.x - 0.5, point.y - 0.5)
  end

  love.graphics.setCanvas()
  love.graphics.setColor(255, 255, 255)

  return canvas
end

local canvas;

function love.load()
  -- reseed RNG
  math.randomseed(os.time())

  -- set a smaller window; drawing pixels 1-by-1 can be slow
  local width, height = 400, 400
  love.window.setMode(width, height)
  love.window.setTitle("Voronoi")

  vrn    = voronoi(width, height, manhattan)
  canvas = createCanvas(vrn)
end

function love.draw()
  love.graphics.draw(canvas, 0, 0)
end
1
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
jdeseno
CTO and cofounder Fishbowl VR

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
1
Help us understand the problem. What is going on with this article?