Need Help Connecting Points in 2D Array

Hi,

The sketch that I’m working on makes a random ripple on the screen, or when you click inside the ripple. Right now I have it with a bunch of points moving up and down on the Z axis along a grid. I’m having trouble figuring out how I can now connect the points the create a surface. Suggestions? The for statement I’m having trouble with is on line 174.

Thanks

float[][] particle;
float[][] particlesSpeed;

float[][] particlesNew;
float[][] particlesSpeedNew;

float particelGain = 0.00999;
float forceGain = 0.999;  // Speed

int funberOfPArticles = 100;
float CameraX = 500;
float CameraY = 501;
float CameraZ = 850;
//float CameraZ = 1520;


float CameraMovments = 0;
int CameraMovInt = 0;

float zoom = 1000 / funberOfPArticles;
float offset = 0;

float waveOrNot = -20;

long hitTime = 0;
int muonX;
int muonY;
boolean mouse = false;
int MouseXIndex; 
int MouseYIndex;
boolean Print = false;

void setup() {
  size(1000, 1000, P3D);
  //fullScreen(P3D);
  //pixelDensity(2);
  particle = new float[funberOfPArticles][funberOfPArticles];
  particlesSpeed = new float[funberOfPArticles][funberOfPArticles];
  particlesNew = new float[funberOfPArticles][funberOfPArticles];
  particlesSpeedNew = new float[funberOfPArticles][funberOfPArticles];

  for (int x = 1; x<funberOfPArticles-1; x++) {
    for (int y = 1; y<funberOfPArticles-1; y++) {

      particle[x][y] = 0.0;
      particlesNew[x][y] = 0.0;
      particlesSpeed[x][y] = 0.0;
      particlesSpeedNew[x][y] = 0.0;
    }
  }

  noFill();
  stroke(0);
  noStroke();
}

void draw() {

  //pointLight(255, 255, 255, mouseX, mouseY, 600);
  //ambientLight(102, 102, 102);  
  //lights();

  camera(CameraX, CameraY, CameraZ, 500, 500, 0.0, 
    0.0, 0.0, -1.0);



  updateMesh();
  background(255);
  //fill(255, 255, 0);
  //ellipse(mouseX, mouseY, 20, 20);
  drawMesh();
}


void updateMesh() {


  for (int x = 1; x<funberOfPArticles-2; x++) {
    for (int y = 1; y<funberOfPArticles-2; y++) {
      //under 
      float force1 = 0.0;
      force1 += particle[x-1][y-1] - particle[x][y];
      force1 += particle[x-1][y] - particle[x][y];
      force1 += particle[x-1][y+1] - particle[x][y];
      //over
      force1 += particle[x+1][y-1] - particle[x][y];
      force1 += particle[x+1][y] - particle[x][y];
      force1 += particle[x+1][y+1] - particle[x][y];
      //sidene
      force1 += particle[x][y-1] - particle[x][y];
      force1 += particle[x][y+1] - particle[x][y];

      force1 -= particle[x][y+1] / 8;

      //force1 = constrain(force1, -1, 1);

      particlesSpeedNew[x][y] = 0.995 * particlesSpeedNew[x][y] + force1/100;

      particlesNew[x][y] = particle[x][y] + particlesSpeedNew[x][y];
    }
  }

  for (int x = 1; x<funberOfPArticles-1; x++) {
    for (int y = 1; y<funberOfPArticles-1; y++) {
      particle[x][y] = particlesNew[x][y];
    }
  }
  if (waveOrNot != 0) {
    offset += .1;
    MouseXIndex = 2 + (funberOfPArticles-4) * muonX / width;
    MouseYIndex = 2 + (funberOfPArticles-4) * muonY / height;
    if (Print == true) {
      Print = false;
      print("xIndex " + MouseXIndex + ", yIndex " + MouseYIndex + " | ");
      println(muonX + ", " + muonY + " | Seconds Passed " + ((millis() - hitTime))/1000 + " | frameRate " + int(frameRate));
    }
    particlesSpeedNew[MouseXIndex][MouseYIndex] = waveOrNot;
    particlesSpeedNew[MouseXIndex+1][MouseYIndex+1] = waveOrNot;
    particlesSpeedNew[MouseXIndex+1][MouseYIndex] = waveOrNot;
    particlesSpeedNew[MouseXIndex+1][MouseYIndex-1] = waveOrNot;
    particlesSpeedNew[MouseXIndex][MouseYIndex-1] = waveOrNot;
    particlesSpeedNew[MouseXIndex-1][MouseYIndex+1] = waveOrNot;
    particlesSpeedNew[MouseXIndex-1][MouseYIndex] = waveOrNot;
    particlesSpeedNew[MouseXIndex-1][MouseYIndex-1] = waveOrNot;

    particle[MouseXIndex][MouseYIndex] = waveOrNot*10;
    particle[MouseXIndex+1][MouseYIndex+1] = waveOrNot*5;
    particle[MouseXIndex+1][MouseYIndex] = waveOrNot*10;
    particle[MouseXIndex+1][MouseYIndex-1] = waveOrNot*5;
    particle[MouseXIndex][MouseYIndex-1] = waveOrNot*10;
    particle[MouseXIndex-1][MouseYIndex+1] = waveOrNot*5;
    particle[MouseXIndex-1][MouseYIndex] = waveOrNot*10;
    particle[MouseXIndex-1][MouseYIndex-1] = waveOrNot*5;

    //particlesSpeedNew[40a][40] = 100.0 * sin( offset);
  }

  if (frameCount % int(random(30, 800)) == 0 || mouse == true) {
    muonX = int(random(0, width));
    muonY = int(random(0, height));
    if (mouse == true) {
      muonX = mouseX;
      muonY = mouseY;
    }
    Print = true;
    waveOrNot = -20;
    hitTime = millis();
    mouse = false;
  }

  if (millis() - hitTime > 500) {
    waveOrNot = 0;
  }
}

void mouseClicked() {
  mouse = true;
}

boolean c = true;

void drawMesh() {
  strokeWeight(3);
  stroke(0);

  //fill(255, 0, 0);
  //ellipse(muonX, muonY, 20, 20);

  //vertical lines
  for (int x = 0; x<funberOfPArticles; x++) {

    beginShape();
    for (int y = 0; y<funberOfPArticles; y++) {
      //fill(0);
      //vertex( (x)*zoom, (y)*zoom, particle[x][y] );
      point( (x)*zoom, (y)*zoom, particle[x][y] );
    }
    endShape();
  }
}




int adjAmt = 50;

void keyPressed() {
  if (keyCode == UP) {
    CameraY -= adjAmt;
  } else if (keyCode == DOWN) {
    CameraY += adjAmt;
  }
  if (keyCode == RIGHT) {
    CameraX += adjAmt;
  }  
  if (keyCode == LEFT) {
    CameraX -= adjAmt;
  }

  if (key==' ') {
    if (waveOrNot == 0) {
      waveOrNot = -20;
    } else {
      waveOrNot = 0;
    }
  }

  if (key == 'a') {
    CameraZ += adjAmt;
  }  
  if (key == 'z') {
    CameraZ -= adjAmt;
  }
  println(" " + CameraX + ", " + CameraY + ", " + CameraZ);
}

1 Like

Looks neat! Have you considered creating a vertex shape or quad between 4 points and fill this with a transparent color? So for instance, if you’d go for quad(x1, y1, x2, y2, x3, y3, x4, y4):

x1, y1 = the very first point in the left top
x2, y2 = one point to the right
x3, y3 = the second point to the left on the second row
x4, y4 = the first point to the left on the second row

update
Woopsie Daisy, just crossed my mind that quads don’t have z-values so guess the suggestion above won’t work. ‘Quad vertices’ probably will though :slight_smile:

3 Likes

I noticed you commented out some code at Line 175:

  for (int x = 0; x<funberOfPArticles; x++) {

    beginShape();
    for (int y = 0; y<funberOfPArticles; y++) {
      //fill(0);
      //vertex( (x)*zoom, (y)*zoom, particle[x][y] );
      point( (x)*zoom, (y)*zoom, particle[x][y] );
    }
    endShape();
  }

Was vertex() not working for you?

1 Like

Vertex does work, it looks better than just the points, but I’d like to create triangles or quads at the Z (particle[x][y]) locations.

What I’m having trouble with is how to create a for statement to link the Z’s together.

Okay, I got it. Was thinking of how to construct the shape wrong. Below is the working code. Only thing is, when the Z axis goes too low, Processing glitches out and doesn’t draw the shape correctly.

float[][] particle;
float[][] particlesSpeed;

float[][] particlesNew;
float[][] particlesSpeedNew;

float particelGain = 0.00999;
float forceGain = 0.999;  // Speed

int funberOfPArticles = 80;
float CameraX = 500;
float CameraY = 501;
float CameraZ = 850;
//float CameraZ = 1520;


float CameraMovments = 0;
int CameraMovInt = 0;

float zoom = 1000 / funberOfPArticles;
float offset = 0;

float waveOrNot = -5;

long hitTime = 0;
int muonX;
int muonY;
boolean mouse = false;
int MouseXIndex; 
int MouseYIndex;
boolean Print = false;

void setup() {
  size(1000, 1000, P3D);
  //fullScreen(P3D);
  //pixelDensity(2);
  particle = new float[funberOfPArticles][funberOfPArticles];
  particlesSpeed = new float[funberOfPArticles][funberOfPArticles];
  particlesNew = new float[funberOfPArticles][funberOfPArticles];
  particlesSpeedNew = new float[funberOfPArticles][funberOfPArticles];

  for (int x = 1; x<funberOfPArticles-1; x++) {
    for (int y = 1; y<funberOfPArticles-1; y++) {

      particle[x][y] = 0.0;
      particlesNew[x][y] = 0.0;
      particlesSpeed[x][y] = 0.0;
      particlesSpeedNew[x][y] = 0.0;
    }
  }

  noFill();
  stroke(0);
  noStroke();
}

void draw() {

  pointLight(255, 255, 255, 200, 400, 600);
  //ambientLight(102, 102, 102);  
  //lights();

  camera(CameraX, CameraY, CameraZ, 500, 500, 0.0, 
    0.0, 0.0, -1.0);



  updateMesh();
  background(0);
  //fill(255, 255, 0);
  //ellipse(mouseX, mouseY, 20, 20);
  drawMesh();
}


void updateMesh() {


  for (int x = 1; x<funberOfPArticles-2; x++) {
    for (int y = 1; y<funberOfPArticles-2; y++) {
      //under 
      float force1 = 0.0;
      force1 += particle[x-1][y-1] - particle[x][y];
      force1 += particle[x-1][y] - particle[x][y];
      force1 += particle[x-1][y+1] - particle[x][y];
      //over
      force1 += particle[x+1][y-1] - particle[x][y];
      force1 += particle[x+1][y] - particle[x][y];
      force1 += particle[x+1][y+1] - particle[x][y];
      //sidene
      force1 += particle[x][y-1] - particle[x][y];
      force1 += particle[x][y+1] - particle[x][y];

      force1 -= particle[x][y+1] / 8;

      //force1 = constrain(force1, -1, 1);

      particlesSpeedNew[x][y] = 0.995 * particlesSpeedNew[x][y] + force1/100;

      particlesNew[x][y] = particle[x][y] + particlesSpeedNew[x][y];
    }
  }

  for (int x = 1; x<funberOfPArticles-1; x++) {
    for (int y = 1; y<funberOfPArticles-1; y++) {
      particle[x][y] = particlesNew[x][y];
    }
  }
  if (waveOrNot != 0) {
    offset += .1;
    MouseXIndex = 2 + (funberOfPArticles-4) * muonX / width;
    MouseYIndex = 2 + (funberOfPArticles-4) * muonY / height;
    if (Print == true) {
      Print = false;
      print("xIndex " + MouseXIndex + ", yIndex " + MouseYIndex + " | ");
      println(muonX + ", " + muonY + " | Seconds Passed " + ((millis() - hitTime))/1000 + " | frameRate " + int(frameRate));
    }
    particlesSpeedNew[MouseXIndex][MouseYIndex] = waveOrNot;
    particlesSpeedNew[MouseXIndex+1][MouseYIndex+1] = waveOrNot;
    particlesSpeedNew[MouseXIndex+1][MouseYIndex] = waveOrNot;
    particlesSpeedNew[MouseXIndex+1][MouseYIndex-1] = waveOrNot;
    particlesSpeedNew[MouseXIndex][MouseYIndex-1] = waveOrNot;
    particlesSpeedNew[MouseXIndex-1][MouseYIndex+1] = waveOrNot;
    particlesSpeedNew[MouseXIndex-1][MouseYIndex] = waveOrNot;
    particlesSpeedNew[MouseXIndex-1][MouseYIndex-1] = waveOrNot;

    particle[MouseXIndex][MouseYIndex] = waveOrNot*10;
    particle[MouseXIndex+1][MouseYIndex+1] = waveOrNot*5;
    particle[MouseXIndex+1][MouseYIndex] = waveOrNot*10;
    particle[MouseXIndex+1][MouseYIndex-1] = waveOrNot*5;
    particle[MouseXIndex][MouseYIndex-1] = waveOrNot*10;
    particle[MouseXIndex-1][MouseYIndex+1] = waveOrNot*5;
    particle[MouseXIndex-1][MouseYIndex] = waveOrNot*10;
    particle[MouseXIndex-1][MouseYIndex-1] = waveOrNot*5;

    //particlesSpeedNew[40a][40] = 100.0 * sin( offset);
  }

  if (frameCount % int(random(30, 800)) == 0 || mouse == true) {
    muonX = int(random(0, width));
    muonY = int(random(0, height));
    if (mouse == true) {
      muonX = mouseX;
      muonY = mouseY;
    }
    Print = true;
    waveOrNot = -5;
    hitTime = millis();
    mouse = false;
  }

  if (millis() - hitTime > 500) {
    waveOrNot = 0;
  }
}

void mouseClicked() {
  mouse = true;
}

boolean c = true;

void drawMesh() {
  strokeWeight(1);
  stroke(0);

  //fill(255, 0, 0);
  //ellipse(muonX, muonY, 20, 20);

  //vertical lines
  fill(0);


  for (int x = 0; x<funberOfPArticles-1; x++) {

    for (int y = 0; y<funberOfPArticles-1; y++) {
      fill(255);
      beginShape();
      vertex( (x)*zoom, (y)*zoom, particle[x][y] );
      vertex( (x)*zoom, (y+1)*zoom, particle[x][y+1] );      
      vertex( (x+1)*zoom, (y+1)*zoom, particle[x+1][y+1] );
      vertex( (x+1)*zoom, (y)*zoom, particle[x+1][y] );
      endShape();

      //fill(150);
      //beginShape();
      //vertex( (x+1)*zoom, (y)*zoom, particle[x+1][y] );
      //vertex( (x+1)*zoom, (y+1)*zoom, particle[x][y+1] );
      //vertex( (x)*zoom, (y+1)*zoom, particle[x][y] );
      //endShape();
    }
  }
  //fill(150);
  //for (int y = 0; y<funberOfPArticles-1; y++) {

  //  for (int x = 0; x<funberOfPArticles-1; x++) {
  //    //fill(0);
  //    //beginShape();
  //    //vertex( (x)*zoom, (y)*zoom, particle[x][y] );
  //    //vertex( (x+1)*zoom, (y)*zoom, particle[x+1][y] );
  //    //vertex( (x)*zoom, (y+1)*zoom, particle[x][y+1] );
  //    //endShape();

  //    fill(150);
  //    beginShape();
  //    vertex( (x+1)*zoom, (y)*zoom, particle[x][y] );
  //    vertex( (x+1)*zoom, (y+1)*zoom, particle[x][y+1] );
  //    vertex( (x)*zoom, (y+1)*zoom, particle[x+1][y] );
  //    endShape();
  //  }
  //}
}




int adjAmt = 50;

void keyPressed() {
  if (keyCode == UP) {
    CameraY -= adjAmt;
  } else if (keyCode == DOWN) {
    CameraY += adjAmt;
  }
  if (keyCode == RIGHT) {
    CameraX += adjAmt;
  }  
  if (keyCode == LEFT) {
    CameraX -= adjAmt;
  }

  if (key==' ') {
    if (waveOrNot == 0) {
      waveOrNot = -5;
    } else {
      waveOrNot = 0;
    }
  }

  if (key == 'a') {
    CameraZ += adjAmt;
  }  
  if (key == 'z') {
    CameraZ -= adjAmt;
  }
  println(" " + CameraX + ", " + CameraY + ", " + CameraZ);
}

1 Like

Z negative is away from you into your screen

Do you mean this? Does it get cut off when far away from?

Yeah, it doesn’t properly draw the square shapes that I’m using to get the surface if the Z goes too far toward the screen.

1 Like

Sounds like it might be helpful for you to understand the default perspective settings, and how they affect the rendering frustum.

You could translate your view farther back / your rendering farther forward. Or try changing the perspective.

2 Likes

maybe

// avoid clipping : https : // forum.processing.org/two/discussion/4128/quick-q-how-close-is-too-close-why-when-do-3d-objects-disappear
perspective(PI/3.0, (float) width/height, 1, 1000000);

2 Likes