Add noise 1d example - experimental

This commit is contained in:
Alex Clink 2022-01-27 23:04:24 -05:00
parent e601c7fb87
commit 4aae686c45
4 changed files with 101 additions and 1 deletions

49
examples/noise_1d.cr Normal file
View file

@ -0,0 +1,49 @@
require "../src/game"
require "../src/controller"
require "../src/noise"
module PF
class Noise1d < Game
@noise : Noise = Noise.new
@noise_scale : Float64
@noise_zoom : Float64
def initialize(*args, **kwargs)
super
@noise_scale = height / 4
@noise_zoom = width / 4
@xpos = 0.0
@controller = PF::Controller(LibSDL::Scancode).new({
LibSDL::Scancode::UP => "scale up",
LibSDL::Scancode::DOWN => "scale down",
LibSDL::Scancode::RIGHT => "zoom up",
LibSDL::Scancode::LEFT => "zoom down",
})
end
def update(dt, event)
@controller.map_event(event)
@noise_scale += (@noise_scale * 0.8) * dt if @controller.held?("scale up")
@noise_scale -= (@noise_scale * 0.8) * dt if @controller.held?("scale down")
@noise_zoom += (@noise_zoom * 0.8) * dt if @controller.held?("zoom up")
@noise_zoom -= (@noise_zoom * 0.8) * dt if @controller.held?("zoom down")
@xpos += 20.0 * dt
end
def draw
clear(50, 127, 200)
step = width // 15
mid = height // 2
0.upto(width) do |x|
y = mid + (@noise.get((x + @xpos) / @noise_zoom) * @noise_scale).to_i
draw_point(x, y, Pixel.yellow)
end
end
end
end
game = PF::Noise1d.new(300, 200, 2)
game.run!

13
spec/noise_spec.cr Normal file
View file

@ -0,0 +1,13 @@
require "./spec_helper"
require "../src/noise"
include PF
describe Noise do
describe ".cos_interpolate" do
it "interpolates" do
i = Noise.cosine_interpolate(0.0, 10.0, 0.5)
(4.9..5.1).includes?(i).should eq(true)
end
end
end

View file

@ -1,5 +1,5 @@
module PF
class Lehmer32
struct Lehmer32
include Random
@state : UInt32
@ -9,6 +9,7 @@ module PF
def new_seed(n : Number)
@state = n.to_u32!
self
end
# Generate the next number in the squence

37
src/noise.cr Normal file
View file

@ -0,0 +1,37 @@
require "./lehmer32"
module PF
@[Experimental("Undergoing development")]
struct Noise
# Cosine interpolation
def self.cosine_interpolate(point1 : Float64, point2 : Float64, position : Float64)
ft = position * Math::PI
f = (1 - Math.cos(ft)) * 0.5
point1 * (1 - f) + point2 * f
end
# Linear interpolation
def self.linear_interpolate(point1 : Float64, point2 : Float64, position : Float64)
point1 * (1 - position) + point2 * position
end
@prng : Lehmer32
@seed : UInt32
def initialize(@seed = ::rand(UInt32))
@prng = Lehmer32.new
end
# Returns 1d noise
def get(x : Float64)
x += @seed
n1 = @prng.new_seed(x.to_u32!).rand(-1.0..1.0)
n2 = @prng.new_seed(x.to_u32! + 1).rand(-1.0..1.0)
Noise.cosine_interpolate(n1, n2, x - x.to_u32!)
end
# Returns 2d noise
# def get(x : Float64, y : Float64)
# end
end
end