Getting perlin noise values around a bunch of predefined values.

edited April 2018 in How To...

Hi community,

I am working on this project which requires perlin noise values around arbitrary values so that the the resulting sequences of perlin noise values have those values at their predefined locations and generate smooth transitions when visualized. Here is the code :

import peasy.PeasyCam;

PeasyCam cam;
float rotAngle = 0;
float frame = 0;

void setup() {
  size(480, 640, P3D);
  background(255);
  frameRate(120);
  cam = new PeasyCam(this, 1000);
}

void draw() {
  background(255);
  stroke(0);
  translate(0, -height/2, 0);
  float yoff = 0;
  for (int i = 0; i < 14; i++) {
    pushMatrix();
    yoff = 50*i;
    translate(0, yoff, 0);
    rotAngle = map(noise(yoff/500, frame), 0, 1, -PI/3, PI/3);
    rotateZ(rotAngle);
    line(-200, 0, 200, 0);
    popMatrix();
  }
  frame += .001;
}

This creates a column of horizontal lines which are rotated PI/3 radians clockwise to PI/3 radians anticlockwise, mapped by the 2D Perlin noise values generated using frame number and y location of line as inputs.

What if, say, the problem is to have the center line to be always perfectly horizontal and the other lines rotating around it with a smooth transition in harmony with that constant horizontal line in the center. I need a solution which allows me to give more than one arbitrary values and get perlin noise around those values.

Thanks !!

Tagged:

Answers

  • edited April 2018 Answer ✓

    It sounds like you want to correct the angle of each line based on setting the middle line angle to 0. One simple approach to doing that:

    1. save your series of noised angles to an array
    2. compute the correction - a difference between your nth angle and 0
    3. when rotating, apply the correction to each angle
    4. draw your rotated lines.

    Like this:

    import peasy.PeasyCam;
    PeasyCam cam;
    float rotAngle = 0;
    float frame = 0;
    float[] angles = new float[14];
    float angleCorrection = 0;
    
    void setup() {
      size(480, 640, P3D);
      background(255);
      frameRate(120);
      cam = new PeasyCam(this, 1000);
    }
    
    void draw() {
      background(255);
      stroke(0);
      translate(0, -height/2, 0);
      for (int i = 0; i < 14; i++) {
        angles[i] = map(noise(i/10.0, frame), 0, 1, -PI/3, PI/3);
      }
      angleCorrection = 0 - angles[7];
      for (int i = 0; i < 14; i++) {
        pushMatrix();
        translate(0, 50*i, 0);
        rotateZ(angles[i] + angleCorrection);
        line(-200, 0, 200, 0);
        popMatrix();
      }
      frame += .001;
    }
    

    The key thing that made this difficult was that you were using noise "live" -- so you didn't know what your 7th noise value would be, and thus couldn't correct values 0-6. Once you separate your angle generation and your drawing steps then the angle values are stored an array and the solution to correcting them all is fairly simple.

    A good next step might be to parameterize the numbers '14' (and compute '7') as those numbers appear in the code....

    Screen Shot 2018-04-11 at 7.46.54 AM

  • edited April 2018

    Thanks a lot @jeremydouglass :) That was very clever !! I have 3 doubts / questions regarding the same :

    (A) Diving deeper into the scenario I had a question if this method is creating any kind of bias in the natural Perlin noise quality of the sequence apart from the influence of the stationary line's orientation on other lines. I mean - doesn't adding/subtracting the constant angleCorrection to all individual angles creates a bias in the sequence ? What if all the angleCorrection values being added/subtracted also follow a perlin noise sequence around the angleCorrection value for the fixed line, 7th line here. Applying perlin noise at deeper levels in a fractral structure similar to how perlin noise is generated adding random values of higher and higher resolution called octaves !!

    (B) I couldn't understand the suggestion in the last line about parameterizing numbers , can you elaborate a little further ?

    and (C) How can I go about creating perlin noise sequence around more than one predefined arbitrary values at their arbitrary values. I couldn't think of a way out using your method as their would be more more than one unique correction angles. Can we than somehow use all those values to correct all the angles so that the predefined values are preserved and still all other lines have** unbiased harmony** between them. Here is the code with more than one angleCorrection variables with their differences with noise values stored in them.

    import peasy.PeasyCam;
    PeasyCam cam;
    float rotAngle = 0;
    float frame = 0;
    float[] angles = new float[14];
    
    float angleCorrection3;
    float angleCorrection7;
    float angleCorrection12;
    float angleCorrection13;
    
    
    void setup() {
      size(480, 640, P3D);
      background(255);
      frameRate(120);
      cam = new PeasyCam(this, 1000);
    }
    
    void draw() {
      background(255);
      stroke(0);
      translate(0, -height/2, 0);
      for (int i = 0; i < 14; i++) {
        angles[i] = map(noise(i/10.0, frame), 0, 1, -PI/3, PI/3);
      }
    
      angleCorrection3 = radians(30) - angles[3];
      angleCorrection7 = radians(260) - angles[7];
      angleCorrection12 = radians(0) - angles[12];
      angleCorrection13 = radians(20) - angles[13];
      for (int i = 0; i < 14; i++) {
        pushMatrix();
        translate(0, 50*i, 0);
        rotateZ(angles[i] + angleCorrection3);
        line(-200, 0, 200, 0);
        popMatrix();
      }
      frame += .001;
    }
    

    Thanks for being such a great help :)

  • re:

    creates a bias in the sequence

    Perlin noise values vary from 0-1. That means that over any given period of time, you might expect the center value from an arbitrary sequence of values to be anywhere from 0-1. If you constantly correct that central value to 0.5 and all other values accordingly, that means that the values around it range from will be unbalanced -- but over time, symmetrically so.

    Sometimes the central value was was 0, now it is 0.5, and the values above it could range 0.5 to 1.5 -- but symmetrically, sometimes the central value was 1, now it is 0.5, and the values below it could range 0.5 to -0.5

    So your total range is -0.5 to 1.5 instead of 0-1, but your aggregate values over time are not biased -- at least, not any more biased than any discrete sampling of a perlin noise field.

    Perlin noise output itself is usually very slightly biased -- although this usually only matters if you are accumulating values (you are not) and over a long period of time. For more details, see:

    Background -- the "noise walker" problem:

  • re:

    parameterizing numbers

    I literally mean use variables for your hard coded settings.

    int lineCount = 14;
    
    ...
    
    for (int i = 0; i < lineCount; i++) {
    
    ...
    
        angleCorrection = 0 - angles[lineCount/2];
    
  • re:

    How can I go about creating perlin noise sequence around more than one predefined arbitrary values at their arbitrary values.

    I've read this several times and I don't understand what you are asking, what the problem is you are trying to overcome or what the desired visual output is that you cannot achieve.

    It might be helpful if you described what visual output you are attempting to achieve. For example, in my demo above, we have an organically changing sequence of random line angles for which the middle angle is always horizontal. Can you describe -- or manually sketch -- what it is you are trying to do?

  • edited April 2018

    Can you describe -- or manually sketch -- what it is you are trying to do?

    @jeremydouglass So far we know how to create that organically changing sequence of random line angles for which the middle angle is always horizontal (or zero degree). But what if we have more than one line with their own fixed angles and other lines move in harmony with the fixed ones. This sketch should help you visualize.

    In this code I have declared desired angles for the lines in a unique variable. But I can't figure out how to go about correcting angles as their would be many unique angleCorrection value for each of lines with fixed desired angles.

    import peasy.PeasyCam;
    PeasyCam cam;
    float rotAngle = 0;
    float frame = 0;
    float[] angles = new float[14];
    
    float angleCorrection3;
    float angleCorrection7;
    float angleCorrection12;
    float angleCorrection13;
    
    
    void setup() {
      size(480, 640, P3D);
      background(255);
      frameRate(120);
      cam = new PeasyCam(this, 1000);
    }
    
    void draw() {
      background(255);
      stroke(0);
      translate(0, -height/2, 0);
      for (int i = 0; i < 14; i++) {
        angles[i] = map(noise(i/10.0, frame), 0, 1, -PI/3, PI/3);
      }
    
      angleCorrection3 = radians(30) - angles[3];
      angleCorrection7 = radians(260) - angles[7];
      angleCorrection12 = radians(0) - angles[12];
      angleCorrection13 = radians(20) - angles[13];
      for (int i = 0; i < 14; i++) {
        pushMatrix();
        translate(0, 50*i, 0);
        rotateZ(angles[i] + angleCorrection3);
        line(-200, 0, 200, 0);
        popMatrix();
      }
      frame += .001;
    }
    

    Thanks !!

  • edited April 2018

    Ok. So, taking a step back -- if for example lines 6 and 8 (from your sketch) are fixed, and only line 7 can move, what does the motion of line 7 have to do with noise?

    • Is it always exactly halfway between angles 6 and 8?
    • Is it moving freely, at an arbitrary angle?
    • Is it drifting back and forth some +/0 amount from the average of 6 and 8?

    Something else?

    Is this like pinning down several loops of a slinky and letting the areas in-between bounce?

  • I hope you were able to solve this problem. As I said, it isn't immediately clear what the desired behavior would be given e.g. your definition of lines 6, 7, 8 in your sketch. But it is a cool project, and I am wishing you luck with it.

Sign In or Register to comment.