Skip to content

Instantly share code, notes, and snippets.

@mrk21
Created August 14, 2018 23:47
Show Gist options
  • Save mrk21/f51cd8d7250f498a53a87e0f9c88b0ce to your computer and use it in GitHub Desktop.
Save mrk21/f51cd8d7250f498a53a87e0f9c88b0ce to your computer and use it in GitHub Desktop.
中点変位法
def midpoint_displacement(size, rect = [], x = 0, y = 0, depth = 0)
result = {}
avg_height = ->(heights) {
heights.sum / heights.size.to_f
}
rand_height = ->(h) {
(rand - 0.5) * (2.0 ** -(depth * h))
}
crop_height = ->(height) {
[[height, 1.0].min, 0.0].max
}
mid_height = ->(heights) {
crop_height[avg_height[heights] + rand_height[0.3]]
}
if (size <= 1)
result[[x , y ]] = rect[0]
result[[x + size, y ]] = rect[1]
result[[x + size, y + size ]] = rect[2]
result[[x , y + size ]] = rect[3]
return result
end
4.times { rect << rand } if rect.empty?
center = mid_height[rect]
mid01 = mid_height[[rect[0], rect[1]]]
mid12 = mid_height[[rect[1], rect[2]]]
mid23 = mid_height[[rect[2], rect[3]]]
mid30 = mid_height[[rect[3], rect[0]]]
next_size = size >> 1
next_depth = depth + 1
result.merge! midpoint_displacement(next_size, [ rect[0], mid01 , center , mid30 ], x , y , next_depth)
result.merge! midpoint_displacement(next_size, [ mid01 , rect[1], mid12 , center ], x + next_size, y , next_depth)
result.merge! midpoint_displacement(next_size, [ center , mid12 , rect[2], mid23 ], x + next_size, y + next_size, next_depth)
result.merge! midpoint_displacement(next_size, [ mid30 , center , mid23 , rect[3] ], x , y + next_size, next_depth)
return result
end
loop do
n = 100
result = midpoint_displacement(n)
File.open('data.dat', 'w') do |file|
result.each do |(x, y), z|
file.puts [x, y, z].join(' ')
end
end
IO::popen('gnuplot', 'w') do |io|
m = [n, 20].max
io.puts "set dgrid3d #{m},#{m}"
io.puts 'splot "data.dat" u 1:2:3 with pm3d'
gets
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment