Advertisement
LPGhatguy

Perlin Noise - LOVE2D

Feb 23rd, 2013
880
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. local random, randomseed = math.random, math.randomseed
  2. local floor = math.floor
  3. local max, min = math.max, math.min
  4.  
  5. local octaves = 3
  6. local persistence = 0.5
  7. local noised = {}
  8.  
  9. local function cos_interpolate(a, b, x)
  10.     local ft = x * math.pi
  11.     local f = (1 - math.cos(ft)) * .5
  12.  
  13.     return  a * (1 - f) + b * f
  14. end
  15.  
  16. local function noise_2d(x, y, i, seed)
  17.     local nx = noised[x]
  18.  
  19.     if (nx and nx[y]) then
  20.         return nx[y]
  21.     else
  22.         nx = nx or {}
  23.         randomseed((x * seed + y * i ^ 1.1 + 14) / 789221 + 33 * x + 15731 * y * seed)
  24.     end
  25.  
  26.     random()
  27.  
  28.     noised[x] = nx
  29.     nx[y] = random(-1000, 1000) / 1000
  30.  
  31.     return nx[y]
  32. end
  33.  
  34. local function smooth_noise_2d(x, y, i, seed)
  35.     local corners = (noise_2d(x - 1, y - 1, i, seed) + noise_2d(x + 1, y - 1, i, seed) + noise_2d(x - 1, y + 1, i, seed) + noise_2d(x + 1, y + 1, i, seed)) / 16
  36.     local sides = (noise_2d(x - 1, y, i, seed) + noise_2d(x + 1, y, i, seed) + noise_2d(x, y - 1, i, seed) + noise_2d(x, y + 1, i, seed)) / 8
  37.     local center = noise_2d(x, y, i, seed) / 4
  38.     return corners + sides + center
  39. end
  40.  
  41. local function interpolate_noise_2d(x, y, i, seed)
  42.     local int_x = floor(x)
  43.     local frac_x = x - int_x
  44.  
  45.     local int_y = floor(y)
  46.     local frac_y = y - int_y
  47.  
  48.     local v1 = smooth_noise_2d(int_x, int_y, i, seed)
  49.     local v2 = smooth_noise_2d(int_x + 1, int_y, i, seed)
  50.     local v3 = smooth_noise_2d(int_x, int_y + 1, i, seed)
  51.     local v4 = smooth_noise_2d(int_x + 1, int_y + 1, i, seed)
  52.  
  53.     local i1 = cos_interpolate(v1, v2, frac_x)
  54.     local i2 = cos_interpolate(v3, v4, frac_x)
  55.  
  56.     return cos_interpolate(i1, i2, frac_y)
  57. end
  58.  
  59. local function perlin_2d(x, y, seed)
  60.     local total = 0
  61.     local p = persistence
  62.     local n = octaves - 1
  63.  
  64.     for i = 0, n do
  65.         local frequency = 2 ^ i
  66.         local amplitude = p ^ i
  67.  
  68.         total = total + interpolate_noise_2d(x * frequency, y * frequency, i, seed) * amplitude
  69.     end
  70.  
  71.     return total
  72. end
  73.  
  74.  
  75. local points = {}
  76. local size = 150
  77. local scale = 2
  78. local can
  79. local time_taken = 0
  80.  
  81. local mx, my = 0, 0
  82.  
  83. function love.update()
  84.     mx, my = love.mouse.getPosition()
  85.     mx = floor((mx + 100 + (size / 2)) / scale)
  86.     my = floor((my + 100 + (size / 2)) / scale)
  87. end
  88.  
  89. function love.keydown(key)
  90.     if (key == "escape") then
  91.         love.event.push("quit")
  92.     end
  93. end
  94.  
  95. function love.load()
  96.     local start = love.timer.getMicroTime()
  97.  
  98.     for x = -size, size do
  99.         points[x] = {}
  100.         local ax = points[x]
  101.         for y = -size, size do
  102.             ax[y] = min(max(perlin_2d(x / 4, y / 4, 4923), -1), 1)
  103.         end
  104.     end
  105.  
  106.     time_taken = love.timer.getMicroTime() - start
  107.  
  108.     can = love.graphics.newCanvas()
  109.     love.graphics.setCanvas(can)
  110.  
  111.     love.graphics.setPointStyle("rough")
  112.     love.graphics.setPointSize(scale)
  113.  
  114.     for x = -size, size do
  115.         local ax = points[x]
  116.         for y = -size, size do
  117.             local c = ax[y] * 127.5 + 127.5
  118.             love.graphics.setColor(c, c, c)
  119.             love.graphics.point(x, y)
  120.         end
  121.     end
  122.  
  123.     love.graphics.setCanvas()
  124. end
  125.  
  126. function love.draw()
  127.     love.graphics.setColor(255, 255, 255)
  128.     love.graphics.print("Generated in " .. time_taken .. " seconds!", 4, 4)
  129.  
  130.     if (points[mx] and points[mx][my]) then
  131.         love.graphics.print("(" .. mx .. ", " .. my .. "): " .. points[mx][my], 4, 20)
  132.     end
  133.  
  134.     love.graphics.draw(can, 100, 100, 0, scale, scale)
  135. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement