Noise walker – Weird direction tendency

edited March 2016 in Questions about Code

Hi coders,

i've wrote a noise-walker-program, but i wonder why the direction of the walker is always top-left?! My intention was to write a program similar to Daniel Shiffmans random walker, but just with noise and a smooth, not so edgy motion... Here's the code:

Dot dot;

void setup() {
  size(900, 900);
  background(#222222);
  noStroke();
  dot = new Dot();
  fill(#eeeeee);
}

void draw() {
  dot.move();
  dot.display();
}



class Dot {

  int x = width/2;
  int y = height/2;
  float xoff =100;
  float yoff = 200;
  int xspeed;
  int yspeed;


  void move() {

    float thenoise1 = noise(xoff);  
    float thenoise2 = noise(yoff);  
    int stepx = int(map(thenoise1, 0, 1, 0, 3))-1; 
    int stepy = int(map(thenoise2, 0, 1, 0, 3))-1; 

    x = x + stepx;
    y = y + stepy;
    xoff = xoff + 10;
    yoff = yoff + 10;

    x = constrain(x, 0, width);
    y = constrain(y, 0, height);
  }

  void display() {
    ellipse(x, y, 2, 2);
  }
}

Answers

  • int(map(thenoise1, 0, 1, 0, 3))-1;

    0 maps to 0, ends up as -1

    1 maps to 3, ends up as +2

    that's not balanced

  • I've also got this online walker example. And unfortunately it tends to go up-left mostly: :|
    http://studio.ProcessingTogether.com/sp/pad/export/ro.91FXxn8BG2fPL

  • (change line 132 to inc = random(-.1, .1); and it's a lot less biassed.)

  • edited March 2016

    I believe Pjs' noise() implementation doesn't match P5's.
    inc = random(-.2, .1); works reasonable well in P5.
    Surprisingly inc = random(-.1, .1); is worse in P5.
    Perhaps it can be OK in Pjs... :-/

  • Thanks guys, this seems to be more tricky than i've thought.

    I am trying to do something like this:

    I think, i am far away from that.

    @koogs : I've changed the code in line 32, but the walker did not move anyway...What do you mean with "inc" and why do you use -.1 instead of -1 ?

    Dot dot;
    
    void setup() {
      size(900, 900);
      background(#222222);
      noStroke();
      dot = new Dot();
      fill(#eeeeee);
    }
    
    void draw() {
      dot.move();
      dot.display();
    }
    
    class Dot {
    
      int x = width/2;
      int y = height/2;
      float xoff =100;
      float yoff = 200;
      int xspeed;
      int yspeed;
    
    
      void move() {
    
        float thenoise1 = noise(xoff);  
        float thenoise2 = noise(yoff);  
        int stepx = int(map(thenoise1, 0, 1, -1, 2)); 
        int stepy = int(map(thenoise2, 0, 1, -1, 2)); 
    
        x = x + stepx;
        y = y + stepy;
        xoff = xoff + 0.01;
        yoff = yoff + 0.11;
    
        x = constrain(x, 0, width);
        y = constrain(y, 0, height);
      }
    
      void display() {
        ellipse(x, y, 2, 2);
      }
    }
    
  • my reply above, in brackets, was to gotoloop's post immediately before it.

    i replied to yours before that...

  • int stepx = int(map(thenoise1, 0, 1, -1, 2));
    

    the last two terms here should, i think, be equal but opposite.

  • _vk_vk
    edited March 2016

    A quick an dirty, and probably stupid, thought on that. I'm at work so it's really quick and really dirty...

    http://sketchpad.cc/YLUCYlknWi

  • edited March 2016
    • Noise seems to go from 0 to 0.94 with mean 0.47;
    • Your curve changes direction on steps because you’re using integers, change x, y, stepx and stepy to floats;
    • Adding a bigger value to yoff means y velocity will vary more than x velocity which will result in y position varying less than x position (since the velocity is changing fast between positive and negative values it won’t go far from the initial position).

      Dot[] dot;
      
      
      void setup() {
        size(900, 900);
        background(#222222);
        noStroke();
        dot = new Dot[10];
        for (int i = 0; i < dot.length; i++) {
          dot[i] = new Dot();
        }
        fill(#eeeeee);
      }
      
      
      void draw() {
        for (Dot d:dot) {
          d.move();
          d.display();
        }
      }
      
      
      class Dot {        
        float x = width/2;
        float y = height/2;
        float xoff = random(1000);
        float yoff = random(1000);
        int xspeed;
        int yspeed;
      
        void move() {       
          float thenoise1 = noise(xoff);  
          float thenoise2 = noise(yoff);  
          float stepx = map(thenoise1, 0, 0.94, -1, 1); 
          float stepy = map(thenoise2, 0, 0.94, -1, 1); 
      
          x = x + stepx;
          y = y + stepy;
          xoff = xoff + 0.01;
          yoff = yoff + 0.01;
      
          x = constrain(x, 0, width);
          y = constrain(y, 0, height);
        }
      
        void display() {
          ellipse(x, y, 1, 1);
        }
      }
      
  • Noise seems to go from 0 to 0.94 with mean 0.47;

    and the implementation appears to be different across the various versions of processing...

  • there's this on youtube which looks good, but not quite what you want. not entirely sure it's easy to reverse engineer from that though 8)

    and leafcutterjohn has a post about something similar

    http://leafcutterjohn.com/?p=552

    and more here:

    http://blog.soulwire.co.uk/laboratory/flash/perlin-noise-flow-field

  • edited March 2016 Answer ✓

    The value of xoff and yoff was too large the documentation suggests values between 0.005 and 0.03

    Also note that n = n + 45;
    can be written as
    n += 45;

    I have used this in your program

    Dot dot;
    
    void setup() {
      size(900, 900);
      background(#222222);
      noStroke();
      dot = new Dot();
      fill(#eeeeee);
    }
    
    void draw() {
      dot.move();
      dot.display();
    }
    
    
    class Dot {
    
      float x = width/2;
      float y = height/2;
      float xoff = 100;
      float yoff = 200;
      float xspeed = 3;
      float yspeed = 3;
    
    
      void move() {
    
        float thenoise1 = noise(xoff);  
        float thenoise2 = noise(yoff);  
        float stepx = map(thenoise1, 0, 1, -xspeed, xspeed); 
        float stepy = map(thenoise2, 0, 1, -yspeed, yspeed); 
    
        x = x + stepx;
        y = y + stepy;
        xoff += 0.008;
        yoff += 0.008;
        // Wrap line round screen edges
        x = (x + width) % width;
        y = (y + height) % height;
      }
    
      void display() {
        ellipse(x, y, 2, 2);
      }
    }
    
  • Wow, @quark, your version of my sketch is exactly what i was looking for.

    Thank you guys!!!

Sign In or Register to comment.