SHOW:
|
|
- or go back to the newest paste.
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.8 |
6 | + | local persistence = 0.5 |
7 | local noised = {} | |
8 | - | function cos_interpolate(a, b, x) |
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 | - | function noise_2d(x, y, i, seed) |
15 | + | |
16 | - | randomseed((x * seed + y * i ^ 1.1 + 14) / 789221 + 33 * x + 15731 * y * seed) |
16 | + | local function noise_2d(x, y, i, seed) |
17 | local nx = noised[x] | |
18 | ||
19 | if (nx and nx[y]) then | |
20 | - | return random(-1000, 1000) / 1000 |
20 | + | return nx[y] |
21 | else | |
22 | nx = nx or {} | |
23 | - | function smooth_noise_2d(x, y, i, seed) |
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 | - | function interpolate_noise_2d(x, y, i, seed) |
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 | - | function perlin_2d(x, y, seed) |
48 | + | |
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 | - | --[[ |
63 | + | |
64 | - | USAGE (generate a two-dimensional array of points): |
64 | + | |
65 | - | local size = 50 --number of samples |
65 | + | |
66 | - | local smoothiness = 8 |
66 | + | |
67 | ||
68 | total = total + interpolate_noise_2d(x * frequency, y * frequency, i, seed) * amplitude | |
69 | - | for x = -size, size do |
69 | + | |
70 | - | points[x] = {} |
70 | + | |
71 | - | local ax = points[x] |
71 | + | |
72 | - | for y = -size, size do |
72 | + | |
73 | - | ax[y] = min(max(perlin_2d(x / smoothiness, y / smoothiness, 4923), -1), 1) |
73 | + | |
74 | ||
75 | local points = {} | |
76 | - | ]] |
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 |