I am trying to build a random walker in three-dimensional space. So far it works, check the code below. However, in the next step I would like to rotate the entire structure around its own Z axis. I have tried different ideas. Firstly, rotating the camera - with PeasyCam, which unfortunately I didn't get set up correctly. Secondly, to work with a PGraphics layer on which the random walker runs - later I rotate it... but here the image always becomes unintentionally flat. What thought have I overlooked? How could the whole structure be combined and rotated?
float x;
float y;
float z;
void setup() {
size(600, 600, P3D);
x = width/2;
y = height/2;
z = -height/4;
//background(255);
}
void draw() {
x += random(-10, 10);
y += random(-10, 10);
z += random(-10, 10);
//rotateZ(radians(mouseX));
pushMatrix();
rotateX(radians(45));
push();
translate(x, y, z);
push();
rotateX(radians(90));
rect(0, 0, 10, 10);
pop();
pop();
popMatrix();
}
There are a couple of gotchas with your what you're trying to do:
(x,y,z)
: if you want to draw the 'trails' of this walker you would need to remember them (store changing values in an array (or ArrayList
). (You were sort of on the right track with PGraphics, but that is simply a flat layer to render into. If you store the values in an array you can then reuse them to render however you'd like).rotateX()
, translate()
, etc.). This is where modelX()
, modelY()
, modelZ()
Here's an example using the above notes (converting from local to global coordinates (using modelX,Y,Z) and storing to an array):
import peasy.*;
float x;
float y;
float z;
int numSteps = 300;
PVector[] steps = new PVector[numSteps];
// index of the current step
int currentStep = 0;
void setup() {
size(600, 600, P3D);
x = width/2;
y = height/2;
z = -height/4;
// init walker steps (memory)
for(int i = 0 ; i < numSteps; i++){
steps[i] = new PVector(x, y, z);
}
new PeasyCam(this, 400);
}
void updateWalker(){
x += random(-10, 10);
y += random(-10, 10);
z += random(-10, 10);
//rotateZ(radians(mouseX));
pushMatrix();
rotateX(radians(45));
pushMatrix();
translate(x, y, z);
pushMatrix();
rotateX(radians(90));
//rect(0, 0, 10, 10);
// use modelX(), modelY(), modelZ() to convert from the local model transformations to global
steps[currentStep].set(modelX(x, y, z),
modelY(x, y, z),
modelZ(x, y, z));
popMatrix();
popMatrix();
popMatrix();
//increment step index (looping over back to 0 at the end (%))
currentStep = (currentStep + 1) % numSteps;
}
void drawWalker(){
for(int i = 0 ; i < numSteps; i++){
PVector step = steps[i];
pushMatrix();
translate(step.x, step.y, step.z);
box(10);
popMatrix();
}
}
void draw() {
background(255);
updateWalker();
drawWalker();
}
Feel free to switch from an array to an ArrayList
.
(It might make adding/removing elements easier in case you want to also update them in a certain order).