Add histogram
This commit is contained in:
parent
a55b50622b
commit
8f261ad354
143
init.lua
143
init.lua
@ -28,6 +28,8 @@ local FORMSPEC_BOX_COLOR = "#00000080"
|
||||
-- Color for the section titles in the formspec
|
||||
local FORMSPEC_HEADER_COLOR = "#000000FF"
|
||||
|
||||
local HISTOGRAM_BUCKETS = 10
|
||||
|
||||
local S = minetest.get_translator("perlin_explorer")
|
||||
local F = minetest.formspec_escape
|
||||
|
||||
@ -404,7 +406,16 @@ local update_map = function(pos, set_nodes)
|
||||
stats = {}
|
||||
stats.avg = 0
|
||||
local sum_of_values = 0
|
||||
local value_count = 0
|
||||
stats.value_count = 0
|
||||
|
||||
stats.histogram = {}
|
||||
local min_possible, max_possible = analyze_noiseparams(current_perlin.noiseparams)
|
||||
local cutoff_points = {}
|
||||
for d=1,HISTOGRAM_BUCKETS do
|
||||
cutoff_points[d] = min_possible + ((max_possible-min_possible) / HISTOGRAM_BUCKETS) * d
|
||||
stats.histogram[d] = 0
|
||||
end
|
||||
|
||||
for x=0, endpos.x - startpos.x do
|
||||
for y=0, y_max do
|
||||
for z=0, endpos.z - startpos.z do
|
||||
@ -433,8 +444,15 @@ local update_map = function(pos, set_nodes)
|
||||
elseif perlin_value > stats.max then
|
||||
stats.max = perlin_value
|
||||
end
|
||||
-- Histogram
|
||||
for c=1, HISTOGRAM_BUCKETS do
|
||||
if perlin_value < cutoff_points[c] or c >= HISTOGRAM_BUCKETS then
|
||||
stats.histogram[c] = stats.histogram[c] + 1
|
||||
break
|
||||
end
|
||||
end
|
||||
sum_of_values = sum_of_values + perlin_value
|
||||
value_count = value_count + 1
|
||||
stats.value_count = stats.value_count + 1
|
||||
|
||||
-- Calculate color (param2) for node
|
||||
local zeropoint = 0
|
||||
@ -478,7 +496,8 @@ local update_map = function(pos, set_nodes)
|
||||
end
|
||||
end
|
||||
end
|
||||
stats.avg = sum_of_values / value_count
|
||||
stats.avg = sum_of_values / stats.value_count
|
||||
stats.histogram_points = cutoff_points
|
||||
|
||||
if set_nodes then
|
||||
-- Set vmanip, return stats
|
||||
@ -516,28 +535,28 @@ local create_perlin = function(pos, options)
|
||||
local set_nodes = options.set_nodes ~= false
|
||||
local stats = update_map(mpos, set_nodes)
|
||||
|
||||
-- Show a particle in the center of the newly generated area
|
||||
local center = vector.new()
|
||||
center.x = mpos.x + options.size/2
|
||||
if current_perlin.dimensions == 2 then
|
||||
center.y = mpos.y + 3
|
||||
else
|
||||
center.y = mpos.y + options.size/2
|
||||
if set_nodes then
|
||||
-- Show a particle in the center of the newly generated area
|
||||
local center = vector.new()
|
||||
center.x = mpos.x + options.size/2
|
||||
if current_perlin.dimensions == 2 then
|
||||
center.y = mpos.y + 3
|
||||
else
|
||||
center.y = mpos.y + options.size/2
|
||||
end
|
||||
center.z = mpos.z + options.size/2
|
||||
minetest.add_particle({
|
||||
pos = center,
|
||||
expirationtime = 4,
|
||||
size = 16,
|
||||
texture = "perlin_explorer_new_noisechunk.png",
|
||||
glow = minetest.LIGHT_MAX,
|
||||
})
|
||||
end
|
||||
center.z = mpos.z + options.size/2
|
||||
minetest.add_particle({
|
||||
pos = center,
|
||||
expirationtime = 4,
|
||||
size = 16,
|
||||
texture = "perlin_explorer_new_noisechunk.png",
|
||||
glow = minetest.LIGHT_MAX,
|
||||
})
|
||||
|
||||
if stats then
|
||||
minetest.log("info", "[perlin_explorer] Perlin noise generated at %s! Stats: min. value=%.3f, max. value=%.3f, avg. value=%.3f", minetest.pos_to_string(mpos), stats.min, stats.max, stats.avg)
|
||||
local fo = function(str)
|
||||
return string.format("%.3f", str)
|
||||
end
|
||||
return S("Perlin noise generated at @1! Stats: min. value=@2, max. value=@3, avg. value=@4", minetest.pos_to_string(mpos), fo(stats.min), fo(stats.max), fo(stats.avg))
|
||||
return S("Perlin noise generated at @1!", minetest.pos_to_string(mpos)), stats
|
||||
else
|
||||
minetest.log("error", "[perlin_explorer] Could not get stats!")
|
||||
return false
|
||||
@ -692,6 +711,58 @@ minetest.register_chatcommand("perlin_generate", {
|
||||
end,
|
||||
})
|
||||
|
||||
local show_histogram_formspec = function(player, stats)
|
||||
local txt = ""
|
||||
local maxh = 6.0
|
||||
local boxes = ""
|
||||
for h=1, HISTOGRAM_BUCKETS do
|
||||
local count = stats.histogram[h]
|
||||
local ratio = (stats.histogram[h] / stats.value_count)
|
||||
local perc = ratio * 100
|
||||
local perc_f = string.format("%.1f", perc)
|
||||
local x = (h-1) * 0.9
|
||||
local height = maxh * ratio
|
||||
local coords = x..","..maxh-height..";0.8,"..height
|
||||
local box = ""
|
||||
if count > 0 then
|
||||
box = box .. "box["..coords..";#00FF00FF]"
|
||||
box = box .. "tooltip["..coords..";"..count.."]"
|
||||
end
|
||||
box = box .. "label["..x..",6.3;"..F(S("@1%", perc_f)).."]"
|
||||
|
||||
local min, max
|
||||
if h <= 1 then
|
||||
min = ""
|
||||
else
|
||||
min = F(S(">= @1", stats.histogram_points[h-1]))
|
||||
end
|
||||
if h >= HISTOGRAM_BUCKETS then
|
||||
max = ""
|
||||
else
|
||||
max = F(S("< @1", stats.histogram_points[h]))
|
||||
end
|
||||
|
||||
box = box .. "label["..x..",6.8;"..max.."\n"..min.."]"
|
||||
|
||||
boxes = boxes .. box
|
||||
end
|
||||
local labels = "label[0,0;"..F(S("Values calculated: @1", stats.value_count)).."]"
|
||||
|
||||
local form = [[
|
||||
formspec_version[4]size[10,11]
|
||||
container[0.25,0.25]
|
||||
box[0,0;9.5,10;]]..FORMSPEC_BOX_COLOR..[[]
|
||||
box[0,0;9.5,0.4;]]..FORMSPEC_HEADER_COLOR..[[]
|
||||
label[0.25,0.2;]]..F(S("Noise Parameter Histogram"))..[[]
|
||||
container[0.25,0.8]
|
||||
]]..labels..[[
|
||||
]]..boxes..[[
|
||||
container_end[]
|
||||
container_end[]
|
||||
]]
|
||||
minetest.show_formspec(player:get_player_name(), "perlin_explorer:histogram", form)
|
||||
end
|
||||
|
||||
-- Analyzes the given noise params and shows the result in a pretty-printed formspec to player
|
||||
local analyze_noiseparams_and_show_formspec = function(player, noiseparams)
|
||||
local min, max, waves = analyze_noiseparams(noiseparams)
|
||||
@ -725,7 +796,8 @@ local analyze_noiseparams_and_show_formspec = function(player, noiseparams)
|
||||
label[0.25,2.5;]]..F(S("Y wavelengths: @1", print_waves(waves.y)))..[[]
|
||||
label[0.25,3;]]..F(S("Z wavelengths: @1", print_waves(waves.z)))..[[]
|
||||
|
||||
button[3,3.75;3,0.75;done;]]..F(S("Done"))..[[]
|
||||
button[2,3.75;3,0.75;done;]]..F(S("Done"))..[[]
|
||||
button[5,3.75;3,0.75;deep_analyze;]]..F(S("Deep analyze"))..[[]
|
||||
|
||||
container_end[]
|
||||
--]]
|
||||
@ -903,12 +975,29 @@ local fix_noiseparams = function(noiseparams)
|
||||
end
|
||||
|
||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
if formname == "perlin_explorer:analyze" and fields.done then
|
||||
local noiseparams = formspec_states[player:get_player_name()].noiseparams
|
||||
show_noise_formspec(player, noiseparams)
|
||||
return
|
||||
-- Analysis window
|
||||
if formname == "perlin_explorer:analyze" then
|
||||
if fields.done then
|
||||
local noiseparams = formspec_states[player:get_player_name()].noiseparams
|
||||
show_noise_formspec(player, noiseparams)
|
||||
return
|
||||
elseif fields.deep_analyze then
|
||||
local pos = vector.zero()
|
||||
local size
|
||||
if current_perlin.dimensions == 2 then
|
||||
size = 2048
|
||||
else -- 3 dimensions
|
||||
size = 162 -- 163^3 is roughly equal to 2048
|
||||
end
|
||||
local _, stats = create_perlin(pos, {dimensions=current_perlin.dimensions, size=size, set_nodes=false})
|
||||
if stats then
|
||||
show_histogram_formspec(player, stats)
|
||||
end
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-- Creator window
|
||||
if formname ~= "perlin_explorer:creator" then
|
||||
return
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user