forked from Middlerun/lovecraft
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathperlin.lua
140 lines (130 loc) · 3.91 KB
/
perlin.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
-- takes table of L values and returns N*(L-3) interpolated values
function interpolate1D(values, N)
newData = {}
for i = 1, #values - 3 do
P = (values[i+3] - values[i+2]) - (values[i] - values[i+1])
Q = (values[i] - values[i+1]) - P
R = (values[i+2] - values[i])
S = values[i+1]
for j = 0, N-1 do
x = j/N
table.insert(newData, P*x^3 + Q*x^2 + R*x + S)
end
end
return newData
end
function perlinComponent1D(seed, length, N, amplitude)
rawData = {}
finalData = {}
for i = 1, math.ceil(length/N) + 3 do
rawData[i] = amplitude * rand:get(seed, i)
end
interpData = interpolate1D(rawData, N)
assert(#interpData >= length)
for i = 1, length do
finalData[i] = interpData[i]
end
return finalData
end
function perlin1D(seed, length, persistence, N, amplitude)
data = {}
for i = 1, length do
data[i] = 0
end
for i = N, 1, -1 do
compInterp = 2^(i-1)
compAmplitude = amplitude * persistence^(N-i)
comp = perlinComponent1D(seed+i, length, i, compAmplitude)
for i = 1, length do
data[i] = data[i] + comp[i]
end
end
return data
end
function interpolate2D(values, N)
newData1 = {}
for r = 1, #values do
newData1[r] = {}
for c = 1, #values[r] - 3 do
P = (values[r][c+3] - values[r][c+2]) - (values[r][c] - values[r][c+1])
Q = (values[r][c] - values[r][c+1]) - P
R = (values[r][c+2] - values[r][c])
S = values[r][c+1]
for j = 0, N-1 do
x = j/N
table.insert(newData1[r], P*x^3 + Q*x^2 + R*x + S)
end
end
end
newData2 = {}
for r = 1, (#newData1-3) * N do
newData2[r] = {}
end
for c = 1, #newData1[1] do
for r = 1, #newData1 - 3 do
P = (newData1[r+3][c] - newData1[r+2][c]) - (newData1[r][c] - newData1[r+1][c])
Q = (newData1[r][c] - newData1[r+1][c]) - P
R = (newData1[r+2][c] - newData1[r][c])
S = newData1[r+1][c]
for j = 0, N-1 do
x = j/N
newData2[(r-1)*N+j+1][c] = P*x^3 + Q*x^2 + R*x + S
end
end
end
return newData2
end
function perlinComponent2D(seed, width, height, N, amplitude)
rawData = {}
finalData = {}
for r = 1, math.ceil(height/N) + 3 do
rawData[r] = {}
for c = 1, math.ceil(width/N) + 3 do
rawData[r][c] = amplitude * rand:get(seed+r, c)
end
end
interpData = interpolate2D(rawData, N)
assert(#interpData >= height and #interpData[1] >= width)
for r = 1, height do
finalData[r] = {}
for c = 1, width do
finalData[r][c] = interpData[r][c]
end
end
return finalData
end
function perlin2D(seed, width, height, persistence, N, amplitude)
data = {}
for r = 1, height do
data[r] = {}
for c = 1, width do
data[r][c] = 0
end
end
for i = N, 1, -1 do
compInterp = 2^(i-1)
compAmplitude = amplitude * persistence^(N-i)
comp = perlinComponent2D(seed+i*1000, width, height, compInterp, compAmplitude)
for r = 1, height do
for c = 1, width do
data[r][c] = data[r][c] + comp[r][c]
end
end
end
return data
end
function plot1D(values)
love.graphics.line(0, love.graphics.getHeight()/2 - 200, love.graphics.getWidth(), love.graphics.getHeight()/2 - 200)
love.graphics.line(0, love.graphics.getHeight()/2 + 200, love.graphics.getWidth(), love.graphics.getHeight()/2 + 200)
for i = 1, #values - 1 do
love.graphics.line((i-1)/(#values-1)*love.graphics.getWidth(), love.graphics.getHeight()/2 - values[i] * 400, (i)/(#values-1)*love.graphics.getWidth(), love.graphics.getHeight()/2 - values[i+1] * 400)
end
end
function plot2D(values)
for r = 1, #values do
for c = 1, #(values[1]) do
love.graphics.setColor(128 + 80 * values[r][c], 128 + 80 * values[r][c], 128 + 80 * values[r][c], 255)
love.graphics.rectangle("fill", (c-1)/(#(values[1]))*love.graphics.getWidth(), (r-1)/(#values)*love.graphics.getHeight(), love.graphics.getWidth()/#(values[1]), love.graphics.getHeight()/#values)
end
end
end