1D to 2D? (Perlin noise)

Started by Sinjin, December 02, 2023, 15:07:56

Previous topic - Next topic

Sinjin

Hello, lately I was looking into Perlin noise and I can't figure out how to map the 1D values to 2D.
Using 2 of those values would do the trick but how do I blend them together?
'---main code
const maxfloat#=$7fffffbf '2.14748352e+009

global starter#'=$20000'-100
global divi#=100
global perlin:tperlin=new tperlin
type tperlin
  const maxwrap%=$20000-1'intuitive max float rounding error(loop point), use doubles
  field rr:trnd=new trnd
  field oi%,n0#,n1#

  method new()
    rr.rnd_set 0
    n0=rr.rnd_updf(1)
    rr.rnd_set 1
    n1=rr.rnd_updf(1)
  endmethod

  method noise#(t#,oct%=1)
    local amp#=1-1.0/(oct+1)
    local i%=t,p#=t-i
    i:&maxwrap
    if (oi<>i) then
      oi=i
      rr.rnd_set i
      n0=rr.rnd_updf(1)
      rr.rnd_set (i+1)&maxwrap
      n1=rr.rnd_updf(1)
    endif
    local n2#=n0*amp,n3#=n1*amp
    local ret#=n2+(n3-n2)*p*p*(3-2*p)

    amp=1-amp
    t:*oct'/2.0
    i=t
    p=t-i
    i:&maxwrap
    rr.rnd_set i
    n2=rr.rnd_updf(amp)
    rr.rnd_set (i+1)&maxwrap
    n3=rr.rnd_updf(amp)
    return ret+n2+(n3-n2)*p*p*(3-2*p)
  endmethod

  method noisefsm#(t#)
    seedrnd t
    rnd 0
    local n0#=rnd(1)
    seedrnd t+1
    rnd 0
    local n1#=rnd(1)
    return n0+(n1-n0)*(t-int(t))
  endmethod

  method perlin#(t#,oct%=1)
    local amp#=1,ampsum#
    local i%=t,p#=t-i
    i:&maxwrap
    if (oi<>i) then
      oi=i
      rr.rnd_set i
      n0=rr.rnd_updf(1)
      rr.rnd_set (i+1)&maxwrap
      n1=rr.rnd_updf(1)
    endif
    local ret#=n0+(n1-n0)*p*p*(3-2*p)

    repeat
      ampsum:+amp
      oct:-1
      if not oct then return ret/ampsum
      amp:*0.5
      t:+t
      i=t
      p=t-i
      i:&maxwrap
      rr.rnd_set i
      local n2#=rr.rnd_updf(amp)
      rr.rnd_set (i+1)&maxwrap
      local n3#=rr.rnd_updf(amp)
      ret:+n2+(n3-n2)*p*p*(3-2*p)
    forever
  endmethod

  method noisef#(t#)
    local i%=t,p#=t-i
    i:&maxwrap
    if (oi<>i) then
      oi=i
      rr.rnd_set i
      n0=rr.rnd_updf(1)
      rr.rnd_set (i+1)&maxwrap
      n1=rr.rnd_updf(1)
    endif
    return n0+(n1-n0)*p
  endmethod

  method noisefc#(t#)
't=abs(t)
    local i%=t,p#=t-i
    i:&maxwrap
    if (oi<>i) then
      oi=i
      rr.rnd_set i
      n0=rr.rnd_updf(1)
      rr.rnd_set (i+1)&maxwrap
      n1=rr.rnd_updf(1)
    endif
    return n0+(n1-n0)*p*p*(3-2*p)
'    return n0+(n1-n0) * (1-cos(p*180))*0.5
  endmethod

  method noise2d#(x#,y#,oct%=1)
    local n0#=noise(x,oct)
    local n1#=noise(y,oct)
    return (n0+n1)*0.5
  endmethod
endtype

type trnd
  field seed%,n1%,n2%

  method prepare()
    seed:+1
    n1:+seed*-$1357
    n2:+n1 shl 2*n1
  endmethod

  method rnd_set(s%)
    seed=s
    n1=0
    n2=0
    prepare
  endmethod

  method rnd_updf#(v#)
    prepare
    return abs(n2/maxfloat)*v
  endmethod
endtype
.
.
.
'--draw
'divi:-0.1
starter:+5/divi
drawline 0,50,800,50
drawtext "Linear",200,50
for local x%=0 until 800
   plot x,50+100*perlin.noisef(starter+x/divi)
next
drawline 0,150,800,150
drawtext "Cubic",200,150
for local x%=0 until 800
   plot x,150+100*perlin.noisefc(starter+x/divi)
next
drawline 0,250,800,250
drawtext "Perlin",200,250
for local x%=0 until 800
   plot x,250+100*perlin.perlin(starter+x/divi,3)
next
drawline 0,350,800,350
drawtext "Quick noise",200,350
for local x%=0 until 800
   plot x,350+100*perlin.noise(starter+x/divi,3)
next
drawline 0,450,800,450
drawtext "2D?",200,450
for local x%=0 until 800
   plot x,450+100*perlin.noise2d(starter+x/divi,2*starter+x/divi)
next
drawline 0,550,800,550
drawtext "RND :(",200,550
for local x%=0 until 800
   plot x,550+100*perlin.noisefsm(starter+x/divi)
next
drawline 0,650,800,650

for local y%=0 until 200
for local x%=0 until 200
  local c1#=perlin.noise2d(starter+x/divi*10,starter+y/divi*10)*255
  setcolor c1,c1,c1
  plot x,y
next;next
setcolor 255,255,255

Baggey

I had to alter some of the code just to get it to run.

Ive guessed the graphics resolution and worked out its actually BlitzmaxNG

So we have something runnable in BlitzMaxNG now  :D

'---main code
Const maxfloat#=$7fffffbf '2.14748352e+009

Global starter#'=$20000'-100
Global divi#=100
Global perlin:tperlin=New tperlin
Type tperlin
  Const maxwrap%=$20000-1'intuitive max float rounding error(loop point), use doubles
  Field rr:trnd=New trnd
  Field oi%,n0#,n1#

  Method New()
    rr.rnd_set 0
    n0=rr.rnd_updf(1)
    rr.rnd_set 1
    n1=rr.rnd_updf(1)
  EndMethod

  Method noise#(t#,oct%=1)
    Local amp#=1-1.0/(oct+1)
    Local i%=t,p#=t-i
    i:&maxwrap
    If (oi<>i) Then
      oi=i
      rr.rnd_set i
      n0=rr.rnd_updf(1)
      rr.rnd_set (i+1)&maxwrap
      n1=rr.rnd_updf(1)
    EndIf
    Local n2#=n0*amp,n3#=n1*amp
    Local ret#=n2+(n3-n2)*p*p*(3-2*p)

    amp=1-amp
    t:*oct'/2.0
    i=t
    p=t-i
    i:&maxwrap
    rr.rnd_set i
    n2=rr.rnd_updf(amp)
    rr.rnd_set (i+1)&maxwrap
    n3=rr.rnd_updf(amp)
    Return ret+n2+(n3-n2)*p*p*(3-2*p)
  EndMethod

  Method noisefsm#(t#)
    SeedRnd t
    Rnd 0
    Local n0#=Rnd(1)
    SeedRnd t+1
    Rnd 0
    Local n1#=Rnd(1)
    Return n0+(n1-n0)*(t-Int(t))
  EndMethod

  Method perlin#(t#,oct%=1)
    Local amp#=1,ampsum#
    Local i%=t,p#=t-i
    i:&maxwrap
    If (oi<>i) Then
      oi=i
      rr.rnd_set i
      n0=rr.rnd_updf(1)
      rr.rnd_set (i+1)&maxwrap
      n1=rr.rnd_updf(1)
    EndIf
    Local ret#=n0+(n1-n0)*p*p*(3-2*p)

    Repeat
      ampsum:+amp
      oct:-1
      If Not oct Then Return ret/ampsum
      amp:*0.5
      t:+t
      i=t
      p=t-i
      i:&maxwrap
      rr.rnd_set i
      Local n2#=rr.rnd_updf(amp)
      rr.rnd_set (i+1)&maxwrap
      Local n3#=rr.rnd_updf(amp)
      ret:+n2+(n3-n2)*p*p*(3-2*p)
    Forever
  EndMethod

  Method noisef#(t#)
    Local i%=t,p#=t-i
    i:&maxwrap
    If (oi<>i) Then
      oi=i
      rr.rnd_set i
      n0=rr.rnd_updf(1)
      rr.rnd_set (i+1)&maxwrap
      n1=rr.rnd_updf(1)
    EndIf
    Return n0+(n1-n0)*p
  EndMethod

  Method noisefc#(t#)
't=abs(t)
    Local i%=t,p#=t-i
    i:&maxwrap
    If (oi<>i) Then
      oi=i
      rr.rnd_set i
      n0=rr.rnd_updf(1)
      rr.rnd_set (i+1)&maxwrap
      n1=rr.rnd_updf(1)
    EndIf
    Return n0+(n1-n0)*p*p*(3-2*p)
'    return n0+(n1-n0) * (1-cos(p*180))*0.5
  EndMethod

  Method noise2d#(x#,y#,oct%=1)
    Local n0#=noise(x,oct)
    Local n1#=noise(y,oct)
    Return (n0+n1)*0.5
  EndMethod
EndType

Type trnd
  Field seed%,n1%,n2%

  Method prepare()
    seed:+1
    n1:+seed*-$1357
    n2:+n1 Shl 2*n1
  EndMethod

  Method rnd_set(s%)
    seed=s
    n1=0
    n2=0
    prepare
  EndMethod

  Method rnd_updf#(v#)
    prepare
    Return Abs(n2/maxfloat)*v
  EndMethod
EndType

Graphics 800,600

While Not AppTerminate()

Cls

'--draw
'divi:-0.1
starter:+5/divi
DrawLine 0,50,800,50
DrawText "Linear",200,50
For Local x%=0 Until 800
   Plot x,50+100*perlin.noisef(starter+x/divi)
Next
DrawLine 0,150,800,150
DrawText "Cubic",200,150
For Local x%=0 Until 800
   Plot x,150+100*perlin.noisefc(starter+x/divi)
Next
DrawLine 0,250,800,250
DrawText "Perlin",200,250
For Local x%=0 Until 800
   Plot x,250+100*perlin.perlin(starter+x/divi,3)
Next
DrawLine 0,350,800,350
DrawText "Quick noise",200,350
For Local x%=0 Until 800
   Plot x,350+100*perlin.noise(starter+x/divi,3)
Next
DrawLine 0,450,800,450
DrawText "2D?",200,450
For Local x%=0 Until 800
   Plot x,450+100*perlin.noise2d(starter+x/divi,2*starter+x/divi)
Next
DrawLine 0,550,800,550
DrawText "RND :(",200,550
For Local x%=0 Until 800
   Plot x,550+100*perlin.noisefsm(starter+x/divi)
Next
DrawLine 0,650,800,650

For Local y%=0 Until 200
For Local x%=0 Until 200
  Local c1#=perlin.noise2d(starter+x/divi*10,starter+y/divi*10)*255
  SetColor c1,c1,c1
  Plot x,y
Next;Next
SetColor 255,255,255

Flip(0)

Wend


I dont know why im interested in Perlin noise but i like Age of Empires thats probably the only link i can think of.

Your variables you've used are floats and functions / methods are int's secondly i think the use of the correct format to get the alpha blending of pixels to work is the problem!

This is a little beyond me as ive tried altering pixels before and if the pixel format that your manipulating is not in the right format or the right canvas so to speak. Then, i think this is why you may not be getting true looking terrain! RGB values need to be seperated in to there Byte formats and the you need to know i its ARGB or ABGR etc. :-\

I may have completely missed the point but maybe somelse could help explain!? or get the colors of terrain to come through properly  :)

Kind regards Baggey
 
Running a PC that just Aint fast enough!? i7 Quad core 16GB ram 1TB SSD and NVIDIA Quadro K620 . DID Technology stop! Or have we been assimulated!

ZX Spectrum 48k, C64, ORIC Atmos 48K, Enterprise 128K, The SID chip. Im Misunderstood!

William

i think i know what your talking about i cant remember where i've seen it used though. is it called perlin noise? its like 2.5 or 1.5d
im still interested in oldschool app/gamedev