Psychedelic Noise in JRubyArt

There is a sketch on OpenProcessing which seems to have much more detail with OpenSimplexNoise:-

attr_reader :img, :colors, :theta, :phi, :remap1, :remap2

R = 5
RR = 1

def setup
  sketch_title 'PNoise Pattern'
  color_mode(RGB, 1.0)
  @theta = 0
  @phi = 0
  # the dimensions of the image are twice the dimentions of
  # the canvas to add antialiasing when the image is reduced
  @img = create_image(2 * width, 2 * height, RGB)
  @colors = (0..255).map { color(rand, rand, rand) }
  @remap1 = ->(a, b, c) { ((SmoothNoise.noise(a, b, c) + 1) * 128).floor }
  @remap2 = ->(a, b) { ((SmoothNoise.noise(a, b) + 1) * 128).floor }
end

def noisef(a, b, c, t)
  remap2.call(remap1.call(a, b, c), t)
end

def draw
  # fill the array with rand colors
  # create pattern
  img.load_pixels

  grid(img.width, img.height) do |x, y|
    # map x and y to angles between 0 and TWO_PI
    @theta = map1d(x, 0..img.width, 0..TWO_PI)
    @phi = map1d(y, 0..img.height, 0..TWO_PI)

    # calculate the parameters of noise with the equation of a torus
    # this is used to make the pattern seamless
    nx = (R + RR * cos(phi)) * cos(theta)
    ny = (R + RR * cos(phi)) * sin(theta)
    nz = RR * sin(phi)

    # normalize noise parameters so that the de pattern has homogeneous dimensions
    nx = norm(nx, 0, R + RR)
    ny = norm(ny, 0, R + RR)
    nz = norm(nz, 0, RR)
    # apply noise twice and use the equivalent color on the pallete
    img.pixels[x + y * img.width] = colors[noisef(nx, ny, nz, frame_count / 5)]
  end
  img.update_pixels
  # display pattern
  image(img, 0, 0, width, height) # the image is reduce to the size of the canvas to make it smooth
end

def key_pressed
  save(data_path('image.png'))
end

def settings
  size(500, 500)
end

image

An interesting thing that came out of this experiment is you have to be careful where you declare your lambda functions (in this case within setup made most sense). I made virtue out of necessity when I created my remap lambdas necessary because of SimplexNoise range (-1.0..1.0) cf processing (and Perlin) noise range(0..1.0).

4 Likes

it is strange but comparing the above image with the result of the online open-processing version does look like their “fuzziness is almost the same”, but using the exact java code in P3, P4 and standalone java, looks different with an obvious symmetry alignment. Can you see what causes such behavior?


In other words openprocessing online output is different than desktop/java. Can you think of a way to recover or emulate the “fuzzy” randomness?

update: these is apparently a difference in the noise algorithm used in open-processing online and desktop mode. Using an other noise implementation instead of the core one, creates the randomness. The core symmetry is very interesting though.

the code, almost the same as the original openprocessing link:

PImage img;  // image used to draw the pattern
color[] c;  // aray of colors


/*-------------*/


void setup() {
  size(500, 500);
  
  // the dimensions of the image are twice the dimentions of
  // the canvas to add antialiasing when the image is reduced
  img = createImage(2*width, 2*height, RGB);   
  
  // noise detail is changed to make the pattern smooth
  noiseDetail(1, 0.3);
  
  c = new color[255];  // the array has 255 colors, one color for each possible grayscale color
  
  noLoop();
}


/*-------------*/


void draw() {
  // fill the array with random colors
  for (int i = 0; i < c.length; i += 1) {
    c[i] = color(random(255), random(255), random(255));
  }
  
  // create pattern
  img.loadPixels();  
  float nx, ny, nz;
  float theta = 0, phi = 0;
  float R = 5, r = 1;
  for (int x = 0; x < img.width; x += 1) {
    for (int y = 0; y < img.height; y += 1) {
      // map x and y to angles between 0 and TWO_PI
      theta = map(x, 0, img.width, 0, TWO_PI);
      phi = map(y, 0, img.height, 0, TWO_PI);
      
      // calculate the parameters of noise with the equation of a torus
      // this is used to make the pattern seamless
      nx = (R+r*cos(phi))*cos(theta);
      ny = (R+r*cos(phi))*sin(theta);
      nz = r*sin(phi);
      
      // normalize noise parameters so that the de pattern has homogeneous dimensions
      nx = norm(nx, 0, R+r);
      ny = norm(ny, 0, R+r);
      nz = norm(nz, 0, r);
      
      // apply noise twice and use the equivalent color on the pallete
      img.pixels[x + y*img.width] = c[floor(255*noise(floor(255*noise(nx, ny, nz)), 0.1))];
    }
  }
  img.updatePixels();
  
  // display pattern
  image(img, 0, 0, width, height);  // the image is reduce to the size of the canvas to make it smooth
}


/*-------------*/


void mousePressed() { 
  noiseSeed((long)random(0,1000f));
  //noiseSeed(undefined);  // edited to work on openProcessing beta
  redraw();
}


/*-------------*/


void keyPressed() {
  save("image.png");
}
1 Like

To my mind, ruby processing has tremendous advantages over vanilla processing /(java) in that everything is an object I have also chosen implement noise using the latest java OpenSimplex. In my example, I was also able to replace the nested for loop (nasty) with the grid method

1 Like

As is discussed above, there are obvious directional artifacts in the P3, P4 and standalone java sketch. It appears to me, subjectively, that there are some subtler directional artifacts in the OpenProcessing one, but that is an informal judgment made by eye. Perhaps that is an impression fostered by the rectangular shape of the sketch. On the other hand, there are no obvious directional artifacts in the JRubyArt sketch, at least to me. Again, the above are subjective judgements.

Is it actually true that the JRubyArt sketch is relatively free of such directional artifacts? If so, can that be demonstrated objectively?

Your best bet is to take a look at @KdotJPG work also found at github OpenSimplex he has spent a considerable amount of time studying these issues

2 Likes

Thanks! This looks really interesting: KdotJPG / OpenSimplex2

Noise examples with JRubyArt see Etiennes work there was a tutorial.

1 Like

a multi version of noise algorithms with a useful visual GUI and huge amounts of ready to use parameters in code