Added histogram for sanity checks, checked sanity and found it wanting.
Fixed bug where variance was calculated incorrectly.
This commit is contained in:
parent
77982a0ace
commit
52599c02f2
70
histogram.lua
Normal file
70
histogram.lua
Normal file
@ -0,0 +1,70 @@
|
||||
local Histogram = setmetatable({}, {__call=function(self,options)
|
||||
local h = setmetatable({},{__index=self})
|
||||
h:init(options)
|
||||
return h
|
||||
end})
|
||||
|
||||
function Histogram:init(options)
|
||||
self.pos = options.pos
|
||||
self.size = options.size
|
||||
local total = 0
|
||||
for _,entry in ipairs(options.data) do
|
||||
local x, count = unpack(entry)
|
||||
total = total + count
|
||||
end
|
||||
local t = 0
|
||||
local iqrMin, iqrMax
|
||||
for _,entry in ipairs(options.data) do
|
||||
local x, count = unpack(entry)
|
||||
t = t + count
|
||||
if not iqrMin and t >= .25*total then iqrMin = x end
|
||||
if not iqrMax and t >= .75*total then iqrMax = x end
|
||||
end
|
||||
local h = 2*(iqrMax-iqrMin)*total^(1/3)
|
||||
local xmin, xmax = options.xmin or options.data[1][1], options.xmax or options.data[#options.data][1]
|
||||
local numBuckets = options.numBuckets or math.max(3, math.min(options.size.x/10, math.ceil((xmax - xmin) * total / h)))
|
||||
local buckets = {}
|
||||
for i=1,numBuckets do
|
||||
buckets[i] = 0
|
||||
end
|
||||
local ymax = 0
|
||||
for _,entry in ipairs(options.data) do
|
||||
local x, count = unpack(entry)
|
||||
local b = 1 + math.floor((x - xmin)/(xmax - xmin) * (numBuckets-1))
|
||||
buckets[b] = (buckets[b] or 0) + count
|
||||
ymax = math.max(buckets[b], ymax)
|
||||
end
|
||||
self.ymax = ymax
|
||||
self.xmax = xmax
|
||||
self.buckets = buckets
|
||||
function self:getX(x)
|
||||
return self.pos.x + self.size.x * (x-xmin)/(xmax-xmin)
|
||||
end
|
||||
end
|
||||
|
||||
function Histogram:fromList(list, options)
|
||||
table.sort(list)
|
||||
local data = {}
|
||||
for _,x in ipairs(list) do
|
||||
if not data[#data] or data[#data][1] ~= x then
|
||||
table.insert(data, {x,1})
|
||||
else
|
||||
data[#data][2] = data[#data][2] + 1
|
||||
end
|
||||
end
|
||||
options.data = data
|
||||
return Histogram(options)
|
||||
end
|
||||
|
||||
function Histogram:draw()
|
||||
local height = self.size.y / (#self.buckets-1)
|
||||
for i,count in ipairs(self.buckets) do
|
||||
if count > 0 then
|
||||
local width = count/self.ymax * self.size.x
|
||||
love.graphics.rectangle('fill', self.pos.x,
|
||||
self.pos.y+(#self.buckets-i-1)*height, width, height)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return Histogram
|
44
main.lua
44
main.lua
@ -1,5 +1,6 @@
|
||||
lg = love.graphics
|
||||
W,H = lg.getDimensions()
|
||||
Histogram = require 'histogram'
|
||||
local Noise = require "noise"
|
||||
local DRAW_RES = love.window.toPixels(4)
|
||||
local SCALE = 100
|
||||
@ -10,10 +11,10 @@ local function rng()
|
||||
local r = love.math.newRandomGenerator(1)
|
||||
return function() return r:random() end
|
||||
end
|
||||
local n1 = Noise.make1d(5,rng(),decay)
|
||||
local n2 = Noise.make2d(7,rng(),decay)
|
||||
local n1 = Noise.make1d(8,rng(),decay)
|
||||
local n2 = Noise.make2d(9,rng(),decay)
|
||||
local n3 = Noise.make3d(11,rng(),decay)
|
||||
local s1 = Noise.make1dShader(7,rng(),decay)
|
||||
local s1 = Noise.make1dShader(9,rng(),decay)
|
||||
local s2 = Noise.make2dShader(13,rng(),decay)
|
||||
local s3 = Noise.make3dShader(17,rng(),decay)
|
||||
|
||||
@ -25,6 +26,20 @@ function love.load()
|
||||
yOffset = 0
|
||||
t0 = love.timer.getTime()
|
||||
love.mouse.setCursor(love.mouse.getSystemCursor("hand"))
|
||||
|
||||
local data1,data2,data3 = {},{},{}
|
||||
for i=1,100000 do
|
||||
local x = math.random()*100000
|
||||
local y = math.random()*100000
|
||||
local z = math.random()*100000
|
||||
table.insert(data1, n1(x))
|
||||
table.insert(data2, n2(x,y))
|
||||
table.insert(data3, n3(x,y,z))
|
||||
end
|
||||
histogram1 = Histogram:fromList(data1,{pos={x=0,y=0},size={x=W/2,y=H/3},xmin=0,xmax=1,numBuckets=30})
|
||||
histogram2 = Histogram:fromList(data2,{pos={x=0,y=H/3},size={x=W/2,y=H/3},xmin=0,xmax=1,numBuckets=30})
|
||||
histogram3 = Histogram:fromList(data3,{pos={x=0,y=2*H/3},size={x=W/2,y=H/3},xmin=0,xmax=1,numBuckets=30})
|
||||
|
||||
end
|
||||
|
||||
function love.mousepressed()
|
||||
@ -36,13 +51,22 @@ function love.mousereleased()
|
||||
end
|
||||
|
||||
function love.draw()
|
||||
if love.keyboard.isDown('h') then
|
||||
lg.setColor(0,100,0)
|
||||
histogram1:draw()
|
||||
lg.setColor(0,0,150)
|
||||
histogram2:draw()
|
||||
lg.setColor(125,0,0)
|
||||
histogram3:draw()
|
||||
end
|
||||
|
||||
lg.setColor(255,255,255)
|
||||
lg.setLineWidth(love.window.toPixels(2))
|
||||
lg.setLineJoin("none")
|
||||
local p1 = {}
|
||||
for x=0,W-H/3,DRAW_RES do
|
||||
table.insert(p1,x)
|
||||
table.insert(p1,n1(x/SCALE+xOffset)*H/3)
|
||||
table.insert(p1,(1-n1(x/SCALE+xOffset))*H/3)
|
||||
end
|
||||
lg.line(p1)
|
||||
|
||||
@ -50,7 +74,7 @@ function love.draw()
|
||||
local t = love.timer.getTime()-t0
|
||||
for x=0,W-H/3,DRAW_RES do
|
||||
table.insert(p2,x)
|
||||
table.insert(p2,(1+n2(x/SCALE+xOffset,t))*H/3)
|
||||
table.insert(p2,(1+1-n2(x/SCALE+xOffset,t))*H/3)
|
||||
end
|
||||
lg.line(p2)
|
||||
|
||||
@ -58,7 +82,7 @@ function love.draw()
|
||||
local p3 = {}
|
||||
for x=0,W-H/3,DRAW_RES do
|
||||
table.insert(p3,x)
|
||||
table.insert(p3,2/3*H+H/6*n3(x/SCALE+xOffset,y/SCALE+yOffset,t)+y)
|
||||
table.insert(p3,2/3*H+H/6*(1-n3(x/SCALE+xOffset,y/SCALE+yOffset,t))+y)
|
||||
end
|
||||
lg.line(p3)
|
||||
end
|
||||
@ -69,7 +93,7 @@ function love.draw()
|
||||
local x2 = x + slant*y
|
||||
if x2 < -2*DRAW_RES then goto continue end
|
||||
table.insert(p3,x2)
|
||||
table.insert(p3,2/3*H+H/6*n3(x2/SCALE+xOffset,y/SCALE+yOffset,t)+y)
|
||||
table.insert(p3,2/3*H+H/6*(1-n3(x2/SCALE+xOffset,y/SCALE+yOffset,t))+y)
|
||||
if x2 > W/2 then break end
|
||||
::continue::
|
||||
end
|
||||
@ -93,7 +117,11 @@ function love.draw()
|
||||
lg.draw(canv,W-cw,2*ch)
|
||||
lg.setShader(nil)
|
||||
|
||||
lg.setColor(255,200,0)
|
||||
lg.setColor(0,0,0,100)
|
||||
lg.rectangle('fill',0,0,W,font:getHeight()+love.window.toPixels(5))
|
||||
lg.rectangle('fill',0,H/3,W,font:getHeight()+love.window.toPixels(5))
|
||||
lg.rectangle('fill',0,2*H/3,W,font:getHeight()+love.window.toPixels(5))
|
||||
lg.setColor(255,230,50)
|
||||
lg.setFont(font)
|
||||
lg.printf("1D_Noise(x)", 5,5, W)
|
||||
lg.printf("2D_Noise(x,time)", 5,5+H/3, W)
|
||||
|
@ -44,6 +44,7 @@ end
|
||||
noise.make2d = function(resolution,random,decayFn)
|
||||
resolution,random,decayFn = _defaultArgs(resolution,random,decayFn)
|
||||
local amplitudes,sigma,offsets = _amplitudesAndOffsets(decayFn,resolution,2*resolution,random)
|
||||
sigma = sigma/sqrt(2)
|
||||
return function(x,y)
|
||||
local noise = 0
|
||||
for i,a in ipairs(amplitudes) do
|
||||
@ -59,6 +60,7 @@ end
|
||||
noise.make3d = function(resolution,random,decayFn)
|
||||
resolution,random,decayFn = _defaultArgs(resolution,random,decayFn)
|
||||
local amplitudes,sigma,offsets = _amplitudesAndOffsets(decayFn,resolution,3*resolution,random)
|
||||
sigma = sigma/sqrt(3)
|
||||
return function(x,y,z)
|
||||
-- Find the biggest fibonacci number F_n such that F_n < resolution
|
||||
local n = floor(log((resolution-1)*SQRT5 + .5)/LOG_GR)
|
||||
@ -117,6 +119,7 @@ noise.make2dShader = function(resolution,random,decayFn)
|
||||
local shader = lg.newShader("noise2d.glsl")
|
||||
resolution,random,decayFn = _defaultArgs(resolution,random,decayFn)
|
||||
local amplitudes,sigma,offsets = _amplitudesAndOffsets(decayFn,resolution,2*resolution,random)
|
||||
sigma = sigma/sqrt(2)
|
||||
local offsets2 = {}
|
||||
for i=1,#offsets-1,2 do
|
||||
table.insert(offsets2, {offsets[i],offsets[i+1]})
|
||||
@ -134,6 +137,7 @@ noise.make3dShader = function(resolution,random,decayFn)
|
||||
local shader = lg.newShader("noise3d.glsl")
|
||||
resolution,random,decayFn = _defaultArgs(resolution,random,decayFn)
|
||||
local amplitudes,sigma,offsets = _amplitudesAndOffsets(decayFn,resolution,3*resolution,random)
|
||||
sigma = sigma/sqrt(3)
|
||||
local offsets2 = {}
|
||||
for i=1,#offsets-1,3 do
|
||||
table.insert(offsets2, {offsets[i],offsets[i+1],offsets[i+2]})
|
||||
|
Loading…
Reference in New Issue
Block a user