Я пытаюсь реализовать и изучить код здесь, но у меня возникают проблемы с интерполировать это. Это мой код из моей реализации в Julia:
lerp(a, b, w) = a * (1 - w) + b * w
function Noise(x, y)
n = x + y * 53;
n = (n << 13) $ n;
return (1.0 - ( (n * ((n * n * 15731) + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0);
end
function coherentNoise(x,y)
x₁ = convert(Int64,modf(x)[2])
y₁ = convert(Int64,modf(y)[2])
xᵣ = x - x₁
yᵣ = y - y₁
q1 = Noise(x₁-1,y₁+1)
q2 = Noise(x₁+1,y₁+1)
q3 = Noise(x₁-1,y₁-1)
q4 = Noise(x₁-1,y₁+1)
v = lerp(q1,q2,xᵣ)
v1 = lerp(q3,q4,xᵣ)
return abs(lerp(v,v1,yᵣ))
#value = bilinear(q1,q2,q3,q4,x₁,x₁-1,x₁+1,y₁,y₁-1,y₁+1)
#return abs(value)
end
arr = Array{Float64}(height,width)
for x = 1:height
for y = 1:width
nx = x/60
ny = y/60
arr[x,y]=coherentNoise(nx,ny)
end
end
вот результат:
Я пробовал также использовать эту функцию билинейной интерполяции, но получил худший результат.
# bilinear interpolation
function bilinear(Q1,Q2,Q3,Q4,x,x1,x2,y,y1,y2)
R1 = ((x2-x)/(x2-x1))*Q3 + ((x-x1)/(x2-x1))*Q4
R2 = ((x2-x)/(x2-x1))*Q1 + ((x-x1)/(x2-x1))*Q2
P = ((y2-y)/(y2-y1))*R1 + ((y-y1)/(y2-y1))*R2
return P
end
результат:
Я не знаю, проблема в функции theNoise
или в чем-то еще.
Обновлять
Я получаю наилучшие результаты, используя билинейную интерполяцию со следующей функцией генератора шума:
function coherentNoise(x,y,n::Int64)
#octa3e
o = 0.25
#octave x and y
x /=n
y /=n
#decimal value
x₁ = x < 0 ? x : x-o
y₁ = y < 0 ? y : y-o
x₂ = x+o
y₂ = y+o
#calculate corners data
q1 = abs(Noise(floor(Int64,x₁),floor(Int64,y₂)))
q2 = abs(Noise(floor(Int64,x₂),floor(Int64,y₂)))
q3 = abs(Noise(floor(Int64,x₁),floor(Int64,y₁)))
q4 = abs(Noise(floor(Int64,x₂),floor(Int64,y₁)))
#bilenear interpolation
value = bilinear(q2,q1,q4,q3,x,x₁,x₂,y,y₁,y₂)
return abs(value)
end
Результат:
Я думаю, что проблема в том, как я выбираю точки для билинейной интерполяции, не знаю, как это сделать правильно.
Обновление 2:
Это код для создания изображений:
for x = 1:height
for y = 1:width
arr[x,y]=coherentNoise(x,y,50)
end
end
imwrite(convert(Image,arr),"desktop/projects/julia/Noise/test2.png")
Обновление 3
Благодаря ответу Дэна Гетца я получаю лучший результат, но с некоторыми странными "червями"
выход:
coherentNoise(x,y)
в первом листингеq1 = Noise(x₁-1,y₁+1)
должно бытьq1 = Noise(x₁,,y₁+1)
без-1
.x₁
иy₁
шагают на 1, когдаx
иy
изменяются медленно, и цель состоит в том, чтобы интерполировать функциюNoise
из углов 1 квадрата, а не 2 квадратов (то же самое относится к следующим аналогичным линиям). - person Dan Getz   schedule 18.10.2016coherentNoise(x,y)
в первом листингеq1
иq4
одинаковы и должны находиться в разных углах. Хорошо ... ПереписанныйcoherentNoise
в ответе. - person Dan Getz   schedule 18.10.20160.5*(arr+1.0)
. Лучше? - person Dan Getz   schedule 18.10.20160.5*(arr+1.0)
. И почему функция шума возвращает отрицательные числа, если они являются проблемой? Спасибо! опять таки - person exsnake   schedule 18.10.2016Noise
возвращает случайное число от -1,0 до 1,0, аcoherentNoise
плавно интерполирует его между точками сетки. Таким образом, изображение имеет плавные числа от -1,0 до 1,0. Для изображений необходимо выбрать уровень яркости, который обычно представлен числом от 0,0 до 1,0. Таким образом,0.5*(arr+1.0)
преобразует масштаб (-1,0,1,0) в масштаб (0,0,1,0). - person Dan Getz   schedule 18.10.2016