Color gradient on imported points (Perlin Noise)

Hello community! I am using Processing the third day, and it doesn’t let me sleep! xD

I have a task to assign RGB values affected by Perlin Noise to a cloud of imported points.

I managed to import the points, and I understand how to create 2D Perlin Noise. However I cannot manage to put one on another.
I will then affect the Perlin Noise by a slider, so I need it to dynamically affect the colors.

There are two issues I currently face with my code:

  1. The array with Perlin Noise values returns NULL values.
  2. cannot convert from float to int, even though I use only floats…

I am attaching the code, and the table of points bellow.

The main code.pda :

float inc = 0.1; // SIZE oF NOISE
int scl = 10; // SCALE of GRID
int cols, rows; // columns and rows
float[] vals; // values of Perlin Noise

/* this imports points from table.csv */

Point[] points; // An Array of Points
Table table;

float[][] rgb; // 2 dimentional array
int[] amnt; // number of points

void setup () {
  size(1500,1500,P3D); //P3D - is a 3D renderer. It is needed to 3 dimentional points
  noSmooth(); // Draws all geometry and fonts with jagged edges
  strokeCap(PROJECT); // appearance of the points: ROUND - circle, PROJECT - square
  strokeWeight(10);  // thicknes of the points
  
  
  
  loadData();
  //println(amnt);
}

void draw () {
  background(255);
  
  perlin();
  println(vals); //null - WHY? 1. The array with Perlin Noise values returns NULL values. 
  
  for (int i = 0; i < points.length; i++) {
    points[i].display();
  }
  
  stroke(255,150.6,255);
}

void loadData() { // LOAD THE TABLE.CSV
  // Load CSV file into a Table object
  Table table = loadTable("points.csv", "header"); // load the data
  
  points = new Point[table.getRowCount()]; // The size of the array is determined by the rows
  
  for (int i = 0; i < table.getRowCount(); i++){ // iterate over all the rows
  TableRow row = table.getRow(i); //how many rows are in the table
  // get all the needed data: 
  float ptX = row.getFloat("ptX");
  float ptY = row.getFloat("ptY");
  float ptZ = row.getFloat("ptZ");
  int ptR = row.getInt("ptR");
  int ptG = row.getInt("ptG");
  int ptB = row.getInt("ptB");
  // Mak point objects out of the data
  points[i] = new Point(ptX,ptY,ptZ,ptR,ptG,ptB);
  
  amnt = new int [table.getRowCount()];
  }
}

void perlin() {
  float yoff = 0;
  for (float y = 0; y < rows; y++) {
    float xoff = 0;
    for (float x = 0; x < cols; x++) {
      vals = new float [noise(xoff, yoff) * 255]; // 2. cannot convert from float to int, even though I use only floats..
      println(vals);
      xoff += inc;
    }
    yoff += inc;
  }
}

Point.pda :

class Point {
  
  float ptX;
  float ptY;
  float ptZ;
  float ptR;
  float ptG;
  float ptB;
  
  //Constructor (to create the points):
  Point(float ptX_, float ptY_, float ptZ_, int ptR_, int ptG_, int ptB_) {
    ptX = ptX_;
    ptY = ptY_;
    ptZ = ptZ_;
    ptR = ptR_;
    ptG = ptG_;
    ptB = ptB_;
  }
  
  void display() {
      /* affect the data */
      //float distance = dist(mouseX,mouseY,ptX,ptY);//dist from pt to mouse
      
      /* render the data */
      point(ptX,ptY,ptZ);
      //stroke(50);
  }

}

points.csv : (in order not to make it too long, I send a shorter version)

ptX,ptY,ptZ,ptR,ptG,ptB
604.930497,680.876059,357.814335,0,0,0
608.129213,674.459458,357.940409,0,0,0
611.365347,668.093494,357.909026,0,0,0
614.619025,661.765535,358.010781,0,0,0
619.735182,652.414927,357.974548,0,0,0
626.907415,640.224812,357.937257,0,0,0
634.794037,628.638257,357.859191,0,0,0
643.745675,618.093564,357.747627,0,0,0
653.764881,608.892539,357.618064,0,0,0
668.405343,599.443791,357.434975,0,0,0
662.510488,602.782693,357.612365,0,0,0
681.021594,594.040936,357.558076,0,0,0
674.584624,596.479484,357.600418,0,0,0
1 Like

several problems here…

Usage of arrays

For example your usage of arrays: in perlin() you had

vals = new float [noise(xoff, yoff) * 255]; : This defines a new array of the length noise(xoff, yoff) * 255. Not what you want. (Hence the float / int issue in this line)

Instead say: vals[iVals] = .................; ! That’s how define one slot within the array.

  • e.g. vals[iVals] = int( map ( noise(xoff, yoff), 0, 1, 0, 255) ); or
  • vals[iVals] = int(noise(xoff, yoff) * 255);

Before the for - loops in perlin() say: vals = new int [ 100 ]; to define the array as a whole. You did this correctly for points array in the function loadData().

for-loop

The for-loop in perlin() wasn’t executed in the first place because rows and cols where both 0…

In draw()

In draw() say stroke( vals[i] ); before points[i].display();

Or when you want to use the class more, insert the perlin noise values as colors in the class. Because

  float ptR;
  float ptG;
  float ptB;

are meant for colors, right? Shorter would be color ptColor; by the way. You can pass this to the class also as ptColor_.

Chrisir

Full running sketch

I used the small csv from your data. Hence, I put some numbers in the for loop (10 and 10) in perlin() and made a number up for the size of the array vals (100). You need to correct that.


float inc = 1.1; // SIZE oF NOISE
int scl = 10; // SCALE of GRID
int cols, rows; // columns and rows
int[] vals; // values of Perlin Noise

/* this imports points from table.csv */

Point[] points; // An Array of Points
Table table;

float[][] rgb; // 2 dimentional array
int[] amnt; // number of points

void setup () {
  size(1500, 1500, P3D); //P3D - is a 3D renderer. It is needed to draw 3 dimensional points

  noSmooth(); // Draws all geometry and fonts with jagged edges
  strokeCap(PROJECT); // appearance of the points: ROUND - circle, PROJECT - square
  strokeWeight(10);  // thickness of the points

  noiseSeed(1232);
  perlin();
  printArray(vals); // The array with Perlin Noise values  

  loadData();
  //println(amnt);
}

void draw () {
  background(255);

  for (int i = 0; i < points.length; i++) {
    stroke( vals[i] ); 
    points[i].display();
  }

  stroke(255, 150.6, 255);
}

//------------------------------------------------------------------------------------------------------

void loadData() {
  // LOAD THE TABLE.CSV
  // Load CSV file into a Table object
  Table table = loadTable("points.csv", "header"); // load the data

  points = new Point[table.getRowCount()]; // The size of the array is determined by the rows

  for (int i = 0; i < table.getRowCount(); i++) { // iterate over all the rows
    TableRow row = table.getRow(i); // this row in the table
    // get all the needed data: 
    float ptX = row.getFloat("ptX");
    float ptY = row.getFloat("ptY");
    float ptZ = row.getFloat("ptZ");
    int ptR = row.getInt("ptR");
    int ptG = row.getInt("ptG");
    int ptB = row.getInt("ptB");
    // Make point objects out of the data
    points[i] = new Point(ptX, ptY, ptZ, ptR, ptG, ptB);

    amnt = new int [table.getRowCount()];
  }
}

void perlin() {

  vals = new int [ 100 ];  // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  int iVals=0;

  float yoff = 0;

  println(rows); // it's 0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 

  for (float y = 0; y < 10; y++) {
    float xoff = 0;
    for (float x = 0; x < 10; x++) {
      // println(noise(xoff, yoff)); 
      vals[iVals] = int(  map ( noise(xoff, yoff), 0, 1, 0, 255) );  // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      iVals++;
      // println(vals);
      xoff += inc;
    }
    yoff += inc;
  }
}

//=================================================================================================
//Point.pda :

class Point {

  float ptX;
  float ptY;
  float ptZ;
  float ptR;
  float ptG;
  float ptB;

  //Constructor (to create the points):
  Point(float ptX_, float ptY_, float ptZ_, 
    int ptR_, int ptG_, int ptB_) {
    ptX = ptX_;
    ptY = ptY_;
    ptZ = ptZ_;
    ptR = ptR_;
    ptG = ptG_;
    ptB = ptB_;
  }

  void display() {
    /* affect the data */
    //float distance = dist(mouseX,mouseY,ptX,ptY);//dist from pt to mouse

    /* render the data */
    point(ptX, ptY, ptZ);
    //stroke(50);
  }
}
3 Likes

Unbelievable :smile:. Thank you so much Chrisir!

1 Like