Calculating the distance of a vertex from the center of a "Perlin Noisy" sphere

I have some weird problems. I would need some help.

import peasy.*;
int resolution = 100;
float r = 500;
float lat,lon;
float xoff,yoff;
PVector[][] globularLandscape;
float rangeMin = 0;
float rangeMax = 40;

PeasyCam cam;

void setup() {
  size(400,400, P3D);
  cam = new PeasyCam(this, 1000);
  globularLandscape = new PVector[resolution+1][resolution+1];
  noStroke();
  frameRate(30);
  //fill(50);
  
}

void draw() {
  background(0);
  for (int i = 0; i < resolution+1; i++) {
    lat = map(i, 0, resolution, 0, PI);
    xoff = 0;
    for (int j = 0; j < resolution+1; j++) {
      lon = map(j, 0, resolution, 0, TWO_PI);
      float x = r * sin(lat) * cos(lon) + map(noise(xoff, yoff),0 ,1, rangeMin, rangeMax);
      float y = r * sin(lat) * sin(lon) + map(noise(xoff, yoff),0 ,1, rangeMin, rangeMax);
      float z = r * cos(lat) + map(noise(xoff, yoff),0 ,1, rangeMin, rangeMax);
      //float x = r * sin(lat) * cos(lon) + random(-10,100);
      //float y = r * sin(lat) * sin(lon) + random(-10,100);
      //float z = r * cos(lat) + random(-10,100);
      globularLandscape[i][j] = new PVector(x, y, z);
      xoff += 0.05;
      //PVector v = PVector.random3D();
      //v.mult(7.7);
      //globularLandscape[i][j].add(v);
    }
  yoff += 0.05;
  }
  for (int i = 0; i < resolution; i++) {
    beginShape(TRIANGLE_STRIP);
    for (int j = 0; j < resolution+1; j++) {
    PVector v1 = globularLandscape[i][j];
    PVector v2 = globularLandscape[i+1][j];
    float x = (v1.x + v2.x) / 2;
    float y = (v1.y + v2.y) / 2;
    float z = (v1.z + v2.z) / 2;
    float def = sqrt(x * x + y * y + z * z);
    if(def > r) {
       fill(255, 255, 255);
      } else if (def < r) {
       fill(183, 109, 31);
      } else {
       fill(62, 201, 24); 
      }
    vertex(v1.x, v1.y, v1.z);
    //println(def);
    vertex(v2.x, v2.y, v2.z);
    }
  endShape();
  }
}

‘def’ is the value which holds the distance of the vertex. Basicaly I would like to make mountains with snow on it ,but the results can be seen on the picture. Can somebody help me or explain what`s going on ?

P.S. Sorry for bad language. :frowning:

1 Like

Hi,

Please format your code using </> in the message editor.

I think that the problem is that if you set the fill() color multiple times between beginShape(TRIANGLE_STRIP) and endShape(), the resulting fill color will be the last one.

For example :

void setup(){
  size(400,400);
  background(0);
  noLoop();
}

void draw(){
  beginShape();
  fill(255,0,0); //red
  vertex(0,0);
  fill(0,255,0); //green
  vertex(100,0);
  fill(0,0,255); //blue
  vertex(100,100);
  endShape();
}

fill_example

The result fill color is blue.

1 Like

Multiple issues here – it looks like this isn’t a true noisy sphere – it is ruptured on one side, because you aren’t joining your triangle strip points up, and your noise isn’t doing what (I think) you think it is doing. If you make your sphere static and inspect coloring and noise distortion, you will also notice that coloring also may not be working the way that you think it is – inspect this example of changing to a different color after each vertex.

import peasy.*;
int resolution = 20;
float r = 500;
float lat, lon;
float xoff, yoff;
PVector[][] globularLandscape;
float rangeMin = 0;
float rangeMax = 200;

int myHue = 0;

PeasyCam cam;

void setup() {
  size(400, 400, P3D);
  cam = new PeasyCam(this, 1000);
  globularLandscape = new PVector[resolution+1][resolution+1];
  noStroke();
  frameRate(30);
  colorMode(HSB, 360, 100, 100);
  //fill(50);

  for (int i = 0; i < resolution+1; i++) {
    lat = map(i, 0, resolution, 0, PI);
    xoff = 0;
    for (int j = 0; j < resolution+1; j++) {
      lon = map(j, 0, resolution, 0, TWO_PI);
      float x = r * sin(lat) * cos(lon) + map(noise(xoff, yoff), 0, 1, rangeMin, rangeMax);
      float y = r * sin(lat) * sin(lon) + map(noise(xoff, yoff), 0, 1, rangeMin, rangeMax);
      float z = r * cos(lat) + map(noise(xoff, yoff), 0, 1, rangeMin, rangeMax);
      globularLandscape[i][j] = new PVector(x, y, z);
      xoff += 0.05;
    }
    yoff += 0.05;
  }
}

void draw() {
  background(0);
  myHue = 0;
  for (int i = 0; i < resolution; i++) {
    beginShape(TRIANGLE_STRIP);
    for (int j = 0; j < resolution+1; j++) {
      PVector v1 = globularLandscape[i][j];
      PVector v2 = globularLandscape[i+1][j];
      myHue+=45;
      fill(myHue%360, 100, 100);
      vertex(v1.x, v1.y, v1.z);
      myHue+=45;
      fill(myHue%360, 100, 100);
      vertex(v2.x, v2.y, v2.z);
    }
    endShape(CLOSE);
  }
}

Note also that a triangle strip has two initial points, then it adds a new triangle for every additional point (not each additional two points) – see the example from the createShape reference.

-  3 pts = 1 triangle
-  4 pts = 2 triangles
-  5 pts = 3 triangles
1 Like