I am a beginner with p5js and graphics in general. I’ve done a few 2D sketches, and while they were becoming more complex, I read about createGraphics() and how I can use this as a buffer to improve performance.
A few days ago, I tried sketching my first 3d animation, one of a complex sinusoid.
The link is here: p5.js Web Editor
The code looks like this:
const r = 60;
let vC, vR, mP;
let angl;
let reset;
let f;
let points = [];
function setup() {
createCanvas(800, 500, WEBGL);
frameRate(20);
push();
translate(0,0,0);
f = 0.03;
angl = PI/2;
vC = createVector(0, 0);
vR = createVector(0, 0);
mp = createVector(0, 0, 0);
pop();
}
function draw() {
background(255);
orbitControl();
translate(vC.x, vC.y, 0);
// rotateX(frameCount * 0.01);
// rotateY(angl);
// orbitControl(1, 1, 0.1, vC.x, vC.y, 0);
// Draw the first plane
push();
smooth();
translate(vC.x, vC.y, 0);
fill(255, 255, 255);
vR.x = sin(angl) * r;
vR.y = cos(angl) * r;
stroke('red');
line(-width, 0, 0, width, 0, 0); // x
stroke('blue');
line(0, -height, 0, 0, height, 0); // y
stroke('green');
line(0, 0, -2000, 0, 0, 2000); // z
push();
stroke('black');
translate(0, 0, PI/2 * r);
circle(0, 0, 3);
translate(0, 0, PI/2 * r);
circle(0, 0, 3);
translate(0, 0, PI/2 * r);
circle(0, 0, 3);
translate(0, 0, PI/2 * r);
circle(0, 0, 3);
translate(0, 0, PI/2 * r);
circle(0, 0, 3);
translate(0, 0, PI/2 * r);
circle(0, 0, 3);
translate(0, 0, PI/2 * r);
circle(0, 0, 3);
pop();
push();
translate(0, 0, TWO_PI * r);
stroke('black')
circle(0, 0, 3);
pop();
stroke('black');
line(0, 0, 0, vR.x, vR.y, 0);
circle(vR.x, vR.y, 3);
mp.x = vR.x;
mp.y = vR.y;
mp.z += f*r;
points.push([vR.x, mp.y, mp.z]);
stroke('gray');
for(let i = 1; i < points.length; i++) {
// main moving point
line(points[i-1][0], points[i-1][1], points[i-1][2], points[i][0], points[i][1], points[i][2]);
// cosinus moving point
push();
translate(2*r, 0, 0);
rotateY(PI/2);
line(-points[i][2], points[i][1], -points[i-1][2], points[i-1][1]);
// point(-points[i][2], points[i][1]);
pop();
// sinus moving point
push();
translate(0, 2*r, 0);
rotateX(PI/2);
line(points[i][0], points[i][2], points[i-1][0], points[i-1][2]);
pop();
}
line(vR.x, vR.y, 0, mp.x, mp.y, mp.z);
fill('black');
point(mp.x, mp.y, mp.z);
noFill()
circle(0, 0, 2*r);
pop();
push();
translate(2*r, 0, 0);
rotateY(PI/2);
fill('lightgray');
plane(r * 3 * TWO_PI, 2*r);
pop();
push();
translate(0, 2*r, 0);
rotateX(PI/2);
fill('lightgray');
plane(2*r, r * 3 * TWO_PI);
pop();
angl+=f;
if (angl>2*TWO_PI) {
angl=PI/2;
mp = createVector(0,0,0);
console.log(points.length);
points = [];
}
}
function drawPoint(x, y, z) {
push();
translate(x, y, z);
pop();
}
The animation works well, but computers struggle a little because of that for loop inside the drawing function. Is there a way I could incrementally update the helix (spiral), without adding all points repeatedly? Something similar to a createGraphics() in 2d, but this time in 3d?
In short, how can I draw the complex sinusoid incrementally without having to redraw all existing points?