How can I rotate the Sketch in 3D while its drawing

Hi,
I am trying to draw points in 3D space and while the sketch draws it, I want to continuously rotate the sketch so that I can view the dots in 3D space.

Somehow I am not able to figure out how to do this.

Here is my code:

float dx, dy, dz,t; 
float ry; 
float r_step;
float sc;
void setup() {
  size(1000, 1000, P3D);
  dx = 0;
  dy = 0;
  dz = 0;
  t=0;
  ry = 0;
  r_step = 0.02;
  sc = 1.5;
  background(100);
  color(255);
  //noStroke();
}
void draw() {
  
  translate(width/2, height/2);
  pushMatrix();
  rotateY(ry);
  ry += r_step;
  popMatrix();
  dx = sin(t/5)*100+cos(t/8)*100+sin(t/15)*100;
  dy = cos(t/3)*100+sin(t/15)*100+cos(t/8)*100;
  dz = cos(t/15)*100+cos(t/4)*100+sin(t/3)*100;
  //ellipse(dx*sc, dy*sc, 5, 5);
  //translate(dx, dy, dz);
  strokeWeight(4);
  point(dx, dy, dz);
  t +=0.04; 
}

You had your popMatrix before drawing the point, that’s why it didn’t rotate.

  • In fact, you don’t need pushMatrix and popMatrix here (Matrix is reseted at start of draw() anyway and no other things are drawn after point()), so I deleted them.
  • But again, this results in rotate() still being in place when we draw the point; before, rotate weren’t working when we “stopped it” with popMatrix before drawing the point.

Actually, this project is not as easy as you think.

Let me explain in steps:

Without background() at the start of draw(), everything is drawn on top of each other (which looks great by the way), so you can’t really see the graph because each point gets rotated differently.

So each point is effected by the formula and by the rotation for it.

float dx, dy, dz, t; 
float ry; 
float r_step;
float sc;

void setup() {
  size(1000, 1000, P3D);
  dx = 0;
  dy = 0;
  dz = 0;
  t=0;
  ry = 0;
  r_step = 0.02;
  sc = 1.5;
  background(100);
  color(255);
  //noStroke();
}
void draw() {
  // background(100);

  // rotate scene 
  translate(width/2, height/2);
  rotateY(ry);
  ry += r_step;

  // calc a graph 
  dx = sin(t/5)*100+cos(t/8)*100+sin(t/15)*100;
  dy = cos(t/3)*100+sin(t/15)*100+cos(t/8)*100;
  dz = cos(t/15)*100+cos(t/4)*100+sin(t/3)*100;
  t +=0.04;

  //display graph
  strokeWeight(4);
  point(dx, dy, dz);
}

OR you use background then you’ll see only one point all the time. Bad.

float dx, dy, dz, t; 
float ry; 
float r_step;
float sc;

void setup() {
  size(1000, 1000, P3D);
  dx = 0;
  dy = 0;
  dz = 0;
  t=0;
  ry = 0;
  r_step = 0.02;
  sc = 1.5;
  background(100);
  color(255);
  //noStroke();
}
void draw() {
  background(100);

  // rotate scene 
  translate(width/2, height/2);
  rotateY(ry);
  ry += r_step;

  // calc a graph 
  dx = sin(t/5)*100+cos(t/8)*100+sin(t/15)*100;
  dy = cos(t/3)*100+sin(t/15)*100+cos(t/8)*100;
  dz = cos(t/15)*100+cos(t/4)*100+sin(t/3)*100;
  t +=0.04;

  //display graph
  strokeWeight(4);
  point(dx, dy, dz);
}

Because of this you need a while loop that draws your ENTIRE graph every time from the beginning to see it developing.

You can stop the rotation when you hold a key

float dx, dy, dz, t;
int max_i=0; 

float ry; 
float r_step;
float sc;

void setup() {
  size(1000, 1000, P3D);
  dx = 0;
  dy = 0;
  dz = 0;
  t=0;
  ry = 0;
  r_step = 0.02;
  sc = 1.5;
  background(100);
  color(255);
  //noStroke();
}
void draw() {
  background(100);
  //lights();

  // rotate scene 
  translate(width/2, height/2);
  rotateY(ry);
  if (!keyPressed) 
    ry += r_step;

  // calc a graph 
  t=0;
  int i=0; 
  while (i<max_i) {
    dx = sin(t/5)*100+cos(t/8)*100+sin(t/15)*100;
    dy = cos(t/3)*100+sin(t/15)*100+cos(t/8)*100;
    dz = cos(t/15)*100+cos(t/4)*100+sin(t/3)*100;

    //display graph
    strokeWeight(4);
    point(dx, dy, dz);

    t +=0.04;
    i++;
  }
  max_i++;
}

This is getting slowly because he’s calculating everything again and again every time.
And sin and cos are relatively slow.

Remark

To avoid this you could make an ArrayList of PVector, move the dx,dy,dz into it and display the ArrayList (using background of course):

  • ArrayList<PVector> listPV = new ArrayList();
  • list.add(new PVector(dx,dy,dz));
  • for (PVector pv : list) point(pv.x, pv.y, pv.z);

You can pre-calculate for example 1000 values in setup() or add slowly in draw().

It’s a fantastic formula, what’s it called?

Warm regards,

Chrisir

Hi Chrisir
You are amazing. This is exactly what I wanted :slight_smile:
There is no name for this equation, I just made it up lol
Lets call it “Squiddy_3D”

I am going to work on it a little more and refine it further with ArrayList<> and add some color to it.
Will post the update soon.

1 Like
  • Library peasyCam would allow you to rotate freely with the mouse

  • when you use sphere (decrease sphereDetail please, see reference) instead of point() you could use lights() and additionally make your points red (or even gradient based on your variable t, with something like lerpColor(), see reference).

  • Because: Everything looks better with a small lights().

pushMatrix
translate(....
sphere(....
popMatrix();

Thanks Chris, That’s exactly what I ended up doing :slight_smile:
I just posted the code here:

Thanks a lot for your help. Have attributed this thread and your profile :smiley:

3 Likes

Did you use lights ()?

Did you consider:

have a camera going through the figure?

Like going vertical up rotating around itself looking outward?

Or Following the line itself?

I made some changes

Important: The way you do it you still use the sin / cos formula EVERY time for ALL particles. Bad. Instead calc those only once in the constructor and then just use the RESULT in display. Much faster.

You need to say lights or directionallight AFTER background at start of draw to have effect

  • AND I improved the color bit

This is enough one in setup imho, not throughout: (saves a bit time)

  sphereDetail(8);
  noStroke();

It’s getting slow because lights and sphere are heavy

To reduce the numbers of spheres in the ArrayList you could increase the value you add to t or only add values to the ArrayList that have a certain distance to the previous entry

here


/*
Author: 
 With help from: Chris (https://discourse.processing.org/u/chrisir/summary)
 Processing forum discussion: https://discourse.processing.org/t/how-can-i-rotate-the-sketch-in-3d-while-its-drawing/25389
 */

ArrayList<Particle> particles = new ArrayList<Particle>();

float dx, dy, dz, t;
int max_i=0; 
float ry; 
float r_step;
float sc;
color c;
int variableName;

float a1 = random(3, 4);
float a2 = random(5, 7);
float a3 = random(4, 8);
float a4 = random(10, 12);
float a5 = random(12, 15);

void setup() {
  size(1000, 1000, P3D);
  t=0;
  ry = 0;
  r_step = 0.02;
  sc = 1.5;
  //  colorMode(HSB);
  sphereDetail(8);
  noStroke();
}

void draw() {
  background(0, 0, 0);
  lights();
  //  directionalLight(51, 102, 126, -1, 0, 0);

  // rotate scene 
  translate(width/2, height/2);
  rotateY(ry);
  if (!keyPressed) 
    ry += r_step;

  // Add 1 particle to array list
  particles.add(new Particle(t, c, a1, a2, a3, a4, a5));
  t += 0.04;

  // Display ALL particles
  for ( Particle part : particles ) {
    part.display();
  }
}

void mouseReleased() {
  // Reset and draw a new graph on mouse click
  reDraw();
}

void reDraw() {
  // Reset background
  // background(100);

  // Clear the ArrayList
  particles.clear();
  a1 = random(3, 4);
  a2 = random(5, 7);
  a3 = random(4, 8);
  a4 = random(10, 12);
  a5 = random(12, 15);
  variableName = 0;
  t=0;
}

// ================================================================================

class Particle {
  float dx, dy, dz, t;
  float x1, y1, z1; 
  int grains = 64;
  color c;    
  float a1;
  float a2;
  float a3;
  float a4;
  float a5;

  Particle(float tt, color cc, float aa1, float aa2, float aa3, float aa4, float aa5) {
    t = tt;
    c = cc;
    c=lerpColor( color(255, 0, 0), color(0, 255, 0), map(t, 0, 200, 0, 1)); 
    a1 = aa1;
    a2 = aa2;
    a3 = aa3;
    a4 = aa4;
    a5 = aa5;

    // Set x,y,z coordinates
    dx = sin(t/a2)*100+cos(t/a3)*100+sin(t/a5)*100;
    dy = cos(t/a1)*100+sin(t/a5)*100+cos(t/a3)*100;
    dz = cos(t/a5)*100+cos(t/a2)*100+sin(t/a1)*100;

    x1=dx;
    y1=dy;
    z1=dz;
  }

  public void display() {
    // Draw sphere
    pushMatrix();
    fill(c);
    translate(x1, y1, z1);
    sphere(7);
    popMatrix();
  }//method
  //
}//class
//

Thanks,
That looks really nice :slight_smile:

1 Like