rotationX/rotationY getting really slow

the rotation is gradually getting slower and really laggy, anyone know why this is happening?
Many thanks, Callum

// ------------------------------------START------------------------------------
// ~variables & imports
import peasy.*;

ArrayList<PVector> points = new ArrayList<PVector>();

float u;
float v;
float tau;
static final int NUM_SHOW = 2;

// ------------------------------------SETUP------------------------------------
void setup() {
  size(800, 800, P3D);
  //background(20);
  colorMode(HSB);
}
// -----------------------------------------------------------------------------
void draw() {
  background(20);
  for (float u = -TAU; u <= TAU; u += 0.04) {
    for (float v = -1; v <= 1; v += 0.5) {
      points.add(new PVector(hyperX(u, v, 2), hyperY(u, v, 2), hyperZ(u, v)));
    }
  }
  showData();
}
// -----------------------------------------------------------------------------
void showData() {
  
  translate(width/2, height/2, 0);
  float t;
  for (t = -TAU; t <= TAU; t+=0.1) {
    float angleX = map(mouseX++, 0, width, t++, -TAU/4);
    float angleY = map(mouseY++, 0, width, t++, TAU/4);
    rotateY(angleY * 10);
    rotateX(angleX);
  }
  
  noFill();
  

  beginShape();
  for (int i = 0; i < NUM_SHOW; i++) {
    stroke(i, 180, 200);
    for (PVector v : points) {
      strokeWeight(2);
      point(400 * v.x + i/10, 400 * v.y + i/100, 200 * v.z + i*10);
    }
  }

  endShape();
}
// -----------------------------------------------------------------------------
// Parametric equations for hyperbolic helicoid
float hyperX(float u, float v, float tau) {
  return (float)((Math.sinh(v) * cos(tau * u)) / (1 + Math.cosh(u) * Math.cosh(v)));
} 

float hyperY(float u, float v, float tau) {
  return (float)((Math.sinh(v) * sin(tau * u)) / (1 + Math.cosh(u) * Math.cosh(v)));
}

float hyperZ(float u, float v) {
  return (float)((Math.cosh(v) * Math.sinh(u)) / (1 + Math.cosh(u) * Math.cosh(v)));
}
// -------------------------------------END-------------------------------------
1 Like

In my opinion you are adding points and points to the ArrayList 60 times per second.

Consider to move these lines from draw() into setup() please

Remark

In showData


for (t = -TAU; t <= TAU; t+=0.1) {
    float angleX = map(mouseX++, 0, width, t++, -TAU/4);
    float angleY = map(mouseY++, 0, width, t++, TAU/4);
    rotateY(angleY * 10);
    rotateX(angleX);
  }

This doesn’t do anything but is very time consuming…

Remark

Also in showData

for (int i = 0; i < NUM_SHOW; i++) {

not needed

Why beginning a new discussion…?

FULL CODE

with mouse steering (instead of peasyCam)


// ------------------------------------START------------------------------------
// ~variables & imports
// import peasy.*;

ArrayList<PVector> points = new ArrayList<PVector>();

float u;
float v;
float tau;
static final int NUM_SHOW = 2;

float angleX, angleY;

// ------------------------------------SETUP------------------------------------
void setup() {
  size(800, 800, P3D);
  //background(20);
  colorMode(HSB);

  for (float u = -TAU; u <= TAU; u += 0.04) {
    for (float v = -1; v <= 1; v += 0.5) {
      points.add(new PVector(hyperX(u, v, 2), hyperY(u, v, 2), hyperZ(u, v)));
    }
  }
}
// -----------------------------------------------------------------------------
void draw() {
  background(20);

  showData();
}
// -----------------------------------------------------------------------------
void showData() {

  lights(); 

  translate(width/2, height/2, 0);

  angleY = map(mouseX, 0, width, 0, TWO_PI);
  angleX = map(mouseY, 0, height, 0, TWO_PI);
  rotateY(angleY * 10);
  rotateX(angleX);


  beginShape(QUAD_STRIP);
  int i = 2; 
  fill(i, 180, 200);
  noStroke(); 
  for (PVector v : points) {
    strokeWeight(2);
    vertex(400 * v.x + i/10, 
      400 * v.y + i/100, 
      200 * v.z + i*10);
  }

  endShape();
}
// -----------------------------------------------------------------------------
// Parametric equations for hyperbolic helicoid
float hyperX(float u, float v, float tau) {
  return (float)((Math.sinh(v) * cos(tau * u)) / (1 + Math.cosh(u) * Math.cosh(v)));
} 

float hyperY(float u, float v, float tau) {
  return (float)((Math.sinh(v) * sin(tau * u)) / (1 + Math.cosh(u) * Math.cosh(v)));
}

float hyperZ(float u, float v) {
  return (float)((Math.cosh(v) * Math.sinh(u)) / (1 + Math.cosh(u) * Math.cosh(v)));
}
// -------------------------------------END----------------------------------
2 Likes

Hello,

You kept adding points to your array and it got quite large!

Some mods I added to your code below:

  • Added points.clear() to clear the array before you filled it and filled it and filled it…
  • Added println() statement for debugging; try this to see the size of array with\without points.clear()
  • Removed your rotation code (overcooked) and replaced with a simplified one that rotates each draw cycle.
// ------------------------------------START------------------------------------
// ~variables & imports
import peasy.*;

ArrayList<PVector> points = new ArrayList<PVector>();

float u;
float v;
float tau;
static final int NUM_SHOW = 2;

// ------------------------------------SETUP------------------------------------
void setup() {
  size(800, 800, P3D);
  //background(20);
  colorMode(HSB);
}
// -----------------------------------------------------------------------------

float angleX = 0;
float angleY = 0;

void draw() {
  background(20);
  points.clear();           //GLV added
  for (float u = -TAU; u <= TAU; u += 0.04) 
    {
    for (float v = -1; v <= 1; v += 0.5) 
      {
      points.add(new PVector(hyperX(u, v, 2), hyperY(u, v, 2), hyperZ(u, v)));
      }
    }
  println(points.size());   //GLV added
 
  showData();
}

// -----------------------------------------------------------------------------
void showData() {
  
  translate(width/2, height/2, 0);
  
  // GLV commented:
  //float t;
  //for (t = -TAU; t <= TAU; t+=0.001) {
  //  float angleX = map(mouseX++, 0, width, t++, -TAU/4);
  //  float angleY = map(mouseY++, 0, width, t++, TAU/4);
  //  rotateY(angleY * 10);
  //  rotateX(angleX);
  //}
  
  angleX += TAU/800;        // GLV 
  angleY += TAU/800;        // GLV
  rotateY(angleY * 10);     // GLV     
  rotateX(angleX);          // GLV
  
  noFill();
  

  beginShape();                        
  for (int i = 0; i < NUM_SHOW; i++) {
    stroke(i, 180, 200);
    for (PVector v : points) {
      strokeWeight(2);
      point(400 * v.x + i/10, 400 * v.y + i/100, 200 * v.z + i*10);
    }
  }
  endShape();                          
}
// -----------------------------------------------------------------------------
// Parametric equations for hyperbolic helicoid
float hyperX(float u, float v, float tau) {
  return (float)((Math.sinh(v) * cos(tau * u)) / (1 + Math.cosh(u) * Math.cosh(v)));
} 

float hyperY(float u, float v, float tau) {
  return (float)((Math.sinh(v) * sin(tau * u)) / (1 + Math.cosh(u) * Math.cosh(v)));
}

float hyperZ(float u, float v) {
  return (float)((Math.cosh(v) * Math.sinh(u)) / (1 + Math.cosh(u) * Math.cosh(v)));
}

I like your use of TAU.
Nice to see working shape!

:)

2 Likes

Thanks for the help guys! Just curious how to remove the random point in above the shape? Last question I promise lol

// ------------------------------------START------------------------------------
// ~variables & imports
import peasy.*;
PeasyCam cam;

ArrayList<PVector> points = new ArrayList<PVector>();

float              u;
float              v;
float              tau;
final static int   NUM_SHOW = 2;

// ------------------------------------SETUP------------------------------------
void setup() {
  size(800, 800, P3D);
  //background(20);
  colorMode(HSB);
}
// -----------------------------------------------------------------------------

float angleX = 0;
float angleY = 0;

void draw() {
  background(20);
  points.clear();
  for (float u = -TAU; u <= TAU; u += 0.04) {
    for (float v = -1; v <= 1; v += 0.5) {
      points.add(new PVector(hyperX(u, v, 2), hyperY(u, v, 2), hyperZ(u, v)));
    }
  }
  showData();
}
// -----------------------------------------------------------------------------
// plots, rotates and colourises hyperbolic helicoid.
void showData() {
  lights();
  float hu = 0;
  noFill         ();
  translate      (width/2, height/2, 0);
  strokeWeight   (2);
  
  angleX += TAU/800;
  angleY += TAU/800;
    
  rotateY(angleY * 10);
  rotateX(angleX);
  
  noFill();
  
  beginShape();    
  for (int i = 0; i < NUM_SHOW; i++) {
    stroke(i, 180, 200);
    for (PVector v : points) {
      stroke(hu+=0.1, 180, 150);
      point(400 * v.x + i/10, 400 * v.y + i/100, 200 * v.z + i*10);

      if(hu > 255) { hu = 0; }
    }
    scale(2);
  }
  
  endShape();            
}
// -----------------------------------------------------------------------------
// Parametric equations for hyperbolic helicoid.
float hyperX(float u, float v, float tau) {
  return (float)((Math.sinh(v) * cos(tau * u)) / (1 + Math.cosh(u) * Math.cosh(v)));
} 

float hyperY(float u, float v, float tau) {
  return (float)((Math.sinh(v) * sin(tau * u)) / (1 + Math.cosh(u) * Math.cosh(v)));
}

float hyperZ(float u, float v) {
  return (float)((Math.cosh(v) * Math.sinh(u)) / (1 + Math.cosh(u) * Math.cosh(v)));
}
// -----------------------------------------------------------------------------
// Reduce clipping (greater area in view of 'cam').
void avoidClipping() { 
  perspective(PI/3.0, (float) width/height, 1, 1000000); 
}
// -------------------------------------END-------------------------------------

Hello,

These are just hints and tips for you to try:

  • subtract from limit in loops; in this case, NUM_SHOW is related to shapes so would try that.
    I tried this and also had to change scale() back to 1; this seemed to work and also got rid of double image.

Let me know why the above worked after you sort this out.

Keep at it!

I change size of sketch for this screen grab:

1 Like

Fixed the scaling issue. Just used ‘j’ from NUM_SHOW for loop to multiply the vectors and stroke/strokeweight.

/** 
  TITLE:           Hyperbolic Helicoid
  LAST UPDATED:    Thursday 2nd April 2020
  
  DESC:            Draws a wireframe hyperbolic helicoid (Java).
*/
// ------------------------------------START------------------------------------
// ~variables
ArrayList<PVector> points = new ArrayList();

float              u;
float              v;
float              tau;
float              angleX       = 0;
float              angleY       = 0;

final static int   NUM_SHOW     = 3; // number of hyperbolic helicoids
// -----------------------------------------------------------------------------
void setup() {
  size       (800, 800, P3D);
  colorMode  (HSB);
  for (float u = -TAU; u <= TAU; u += 0.037) {
    for (float v = -1; v <= 1; v += 0.09) // or v += 0.5
    { 
      points.add(new PVector( // 1/v also works here.
      hyperX(u, v, 2) * 2, 
      hyperY(u, v, 2) * 2, 
      hyperZ(u, v   ) * 2 
      ));
    }
  }
}
// -----------------------------------------------------------------------------
void draw() {
  background  (28);  
  showData    ();
}
// -----------------------------------------------------------------------------
// plots, rotates and colourises hyperbolic helicoid.
void showData() {
  
  noFill         ();
  lights         ();
  translate      (width/2, height/2, 0);
  
  angleX +=     -TAU/800;
  angleY +=      TAU/800;
    
  rotateY        (sin(angleX) * 10);
  rotateX        (sin(angleY) );
  
  float          hu = 0;
  
  beginShape();   
  for (int j = 1; j < NUM_SHOW; j++ ) {
    for (PVector v : points) 
    {
      stroke(hu+=0.1 * (j * 0.1), 140, 160); // colour of object changes over time (hu).

      strokeWeight   (2 * 2/j);
      point // or 'point'
      (
        (400 * v.x) * j/2,
        (400 * v.y) * j/2,
        (200 * v.z) * j/2 
      ); 
      
      if  (hu > 255) { hu = 0; }
    }
  }
  endShape();  
}
// -----------------------------------------------------------------------------
// Parametric equations for hyperbolic helicoid.
float hyperX(float u, float v, float tau) {
  return (float)
  ((Math.sinh(v) * cos(tau * u))  /  (1 + Math.cosh(u) * Math.cosh(v)));
} 

float hyperY(float u, float v, float tau) {
  return (float)
  ((Math.sinh(v) * sin(tau * u))  /  (1 + Math.cosh(u) * Math.cosh(v)));
}

float hyperZ(float u, float v) {
  return (float)
  ((Math.cosh(v) * Math.sinh(u))  /  (1 + Math.cosh(u) * Math.cosh(v)));
}
// -------------------------------------END-------------------------------------

3 Likes

Very nice work!

Also a nice distraction for me.

This topic will be added to my bookmarks to revisit another day.

Stay well!

:)

1 Like

try to make a closed surface now…

1 Like

Just tried to optimize your code a little but failed! :expressionless:
But gonna leave my attempt posted here anyways. :woozy_face:
At least it is now compatible w/ Pjs if deployed for the web. :spider_web:

/** 
 TITLE:           Hyperbolic Helicoid
 LAST UPDATED:    Thursday 2nd April 2020
 
 DESC:            Draws a wireframe hyperbolic helicoid (Java).
 */

import java.util.List;

static final boolean OFFLINE = 1/2 != 1/2.;
static final int NUM_SHOW = 3; // number of hyperbolic helicoids

PVector[] points;

float angleX, angleY;
boolean paused;

void setup() {
  size(800, 600, P3D);
  colorMode(HSB);

  final List<PVector> vecs = new ArrayList<PVector>();  

  for (float u = -TAU; u <= TAU; u += .037)  for (float v = -1; v <= 1; v += .09) {
    final PVector vec = new PVector(hyperX(u, v, 2), hyperY(u, v, 2), hyperZ(u, v));
    vec.mult(2);
    vecs.add(vec);
  }

  points = vecs.toArray(new PVector[vecs.size()]);
}

void draw() {
  background(040);  
  showData();
  if (OFFLINE)  surface.setTitle("FPS: " + round(frameRate));
}

void mousePressed() {
  if (paused ^= true)  noLoop();
  else                 loop();
}

void showData() { // plots, rotates and colourises hyperbolic helicoid.
  translate(width >> 1, height >> 1);

  rotateY(sin(angleX -= TAU / width) * 10);
  rotateX(sin(angleY += TAU / height));

  float hu = 0;

  for (int j = 1; j < NUM_SHOW; j++) {
    final int point_j = j * 200, point_half_j = j * 100;
    strokeWeight(4 / j);

    for (final PVector v : points) {
      if (hu > 0xff)  hu = 0;
      stroke(hu += .01 * j, 140, 160);
      point(point_j * v.x, point_j * v.y, point_half_j * v.z);
    }
  }
}

// Parametric equations for hyperbolic helicoid:

static final float hyperX(final float u, final float v, final float tau) {
  return (float) ((Math.sinh(v) * cos(tau * u)) / (Math.cosh(u) * Math.cosh(v) + 1));
} 

static final float hyperY(final float u, final float v, final float tau) {
  return (float) ((Math.sinh(v) * sin(tau * u)) / (Math.cosh(u) * Math.cosh(v) + 1));
}

static final float hyperZ(final float u, final float v) {
  return (float) ((Math.cosh(v) * Math.sinh(u)) / (Math.cosh(u) * Math.cosh(v) + 1));
}
3 Likes