in the ref find:
https://processing.org/reference/PVector_rotate_.html
only work 2D,
now to rotate a PVector in 3D it still can be used / hacked
try:
// file: sketch_3D_PVector_rotate
// using mouseWheel Plus PLus for rotation
PVector a, atx, aty, atz, at;
int along = 50;
float angbx=0, angby=0, angbz=0;
boolean axprint = true, axline = true;
void setup() {
size(600, 600, P3D);
a = new PVector(along, along, along);
info_print(); // Tab ptz
println("here add: key [x] [y] [z] rotation axis / key [r] reset AND turn MouseWheel");
}
void draw () {
background(200, 200, 0);
PTZ();
}
//_____________________________________________________
void draw_object() { // called by / from inside ptz
axis();
trans();
show_vector();
}
void rotatePVX(float angbx) {
//______________________________________________ step 1 rotate a ( by x )
atx = new PVector(a.y, a.z); // create a 2D vector
atx.rotate(angbx); // rotate 2D original angle + MWPP angle
atx.set(a.x, atx.x, atx.y); // restore to 3D
atx.sub(a); // get the move vector only
at.add(atx); // by x
}
void rotatePVY(float angby) {
//______________________________________________ step 2 rotate a ( by y )
aty = new PVector(a.x, a.z);
aty.rotate(angby);
aty.set(aty.x, a.y, aty.y);
aty.sub(a);
at.add(aty); // by y
}
void rotatePVZ(float angbz) {
//______________________________________________ step 3 rotate a ( by z )
atz = new PVector(a.x, a.y);
atz.rotate(angbz);
atz.set(atz.x, atz.y, a.z);
atz.sub(a);
at.add(atz); // by z
}
void trans() {
at = a.copy(); // copy from original
rotatePVX(angbx);
rotatePVY(angby);
rotatePVZ(angbz);
}
void axis() {
int max = 100;
stroke(200, 0, 0);
strokeWeight(1);
line(0, 0, 0, max, 0, 0);
strokeWeight(0.3);
line(0, 0, 0, -max, 0, 0);
fill(200, 0, 0);
text("x", max, 0);
stroke(0, 200, 0);
strokeWeight(1);
line(0, 0, 0, 0, max, 0);
strokeWeight(0.3);
line(0, 0, 0, 0, -max, 0);
fill(0, 200, 0);
text("y", 0, max);
stroke(0, 0, 200);
strokeWeight(1);
line(0, 0, 0, 0, 0, max);
strokeWeight(0.3);
line(0, 0, 0, 0, 0, -max);
fill(0, 0, 200);
text("z", 0, 0, max);
fill(100, 100, 0, 10); // transparent not work
noStroke();
//max = 20; // so make it small
//rect(-max, -max, 2*max, 2*max); // xy plane
}
void show_vector() {
fill(200, 0, 200);
noStroke();
push();
translate(a.x, a.y, a.z);
sphere(3);
pop();
stroke(200, 0, 200);
strokeWeight(3);
line(a.x, a.y, a.z, 0, 0, 0);
if ( axline ) {
//show axis components
stroke(80);
strokeWeight(0.5);
line(a.x, a.y, a.z, a.x, 0, 0);
line(a.x, a.y, a.z, 0, a.y, 0);
line(a.x, a.y, a.z, 0, 0, a.z);
}
// show rotated vector
fill(0, 200, 200);
noStroke();
push();
translate(at.x, at.y, at.z);
sphere(3);
pop();
stroke(0, 200, 200);
strokeWeight(3);
line(at.x, at.y, at.z, 0, 0, 0);
if ( axline ) {
//show axis components
stroke(80);
strokeWeight(0.5);
line(at.x, at.y, at.z, at.x, 0, 0);
line(at.x, at.y, at.z, 0, at.y, 0);
line(at.x, at.y, at.z, 0, 0, at.z);
// show the at_i components
push();
stroke(0, 200, 200);
strokeWeight(0.5);
translate(a.x, a.y, a.z);
line(0, 0, 0, atx.x, atx.y, atx.z);
translate(atx.x, atx.y, atx.z);
line(0, 0, 0, aty.x, aty.y, aty.z);
translate(aty.x, aty.y, aty.z);
line(0, 0, 0, atz.x, atz.y, atz.z);
pop();
}
}
void main_keyPressed(float e) { // called from pts void mouseWheel(MouseEvent event) {
float speed = 0.056;
if ( keyPressed && key == 'x' ) {
angbx += e * speed;
if ( abs(angbx) > TAU ) angbx = 0;
println(" key x: angbx "+int(degrees(angbx)));
}
if ( keyPressed && key == 'y' ) {
angby += e * speed;
if ( abs(angby) > TAU ) angby = 0;
println(" key y: angby "+int(degrees(angby)));
}
if ( keyPressed && key == 'z' ) {
angbz += e * speed;
if ( abs(angbz) > TAU ) angbz = 0;
println(" key z: angbz "+int(degrees(angbz)));
}
if ( keyPressed && key == 'r' ) {
angbx=angby=angbz=0;
println("reset");
}
if ( axprint ) {
println("a"+a);
println("atx"+atx);
println("aty"+aty);
println("atz"+atz);
println("at"+at);
}
}
// tab ptz
int mode = 0;
float Zmag = 2;
int Zaxis=-100;
float Xmag, Ymag = 0;
float newXmag, newYmag = 0;
int newZmag = 0;
float newxpos, newypos = 0; // for PAN
float xposd, yposd = 0; // for PAN
//_________________________________________________________________ ROTATE / TILDE and MOVE / PAN
void mousePressed() {
if (mouseButton == LEFT) mode=1; // ORBIT
else if (mouseButton == RIGHT) mode=2; // PAN
// else if (mouseButton == CENTER) mode=3; // zoom mouse wheel
}
//_________________________________________________________________ mouse PT end
void mouseReleased() {
mode = 0;
}
//_________________________________________________________________ mouseWheel ZOOM
void mouseWheel(MouseEvent event) {
float e = event.getCount();
//println(e);
if ( !keyPressed ) {
float newZmag = event.getCount()/3.0;
Zmag += newZmag;
//println("mouse event: "+newZmag+" Zmag "+Zmag);
}
main_keyPressed(e); // from main
}
//_______________________________________________ OPERATION
void keyPressed() {
if ( keyCode == UP ) Ymag -= 0.1 ;
if ( keyCode == DOWN ) Ymag += 0.1 ;
if ( keyCode == RIGHT) Xmag -= 0.1 ;
if ( keyCode == LEFT ) Xmag += 0.1 ;
if ( keyCode == 16 ) Zmag -= 0.2 ; // [Page Down]
if ( keyCode == 11 ) Zmag += 0.2 ; // [Page Up ]
//println("key: "+key); println("keyCode: "+keyCode);
}
//_______________________________________________
void keyReleased() {
}
//________________________________________________ Pan Tilde Zoom
void PTZ() {
pushMatrix();
translate(width/2, height/2, Zaxis);
// get new mouse operation
if ( mode == 2 ) { // PAN ( right mouse button pressed)
xposd = (mouseX-float(width/2));
yposd = (mouseY-float(height/2));
}
newxpos = xposd;// xposd=0;
newypos = yposd;// yposd = 0;
translate(newxpos, newypos, 0); // move object
if ( mode == 1 ) { // ORBIT ( left mouse button pressed)
newXmag = mouseX/float(width) * TWO_PI;
newYmag = mouseY/float(height) * TWO_PI;
float diff = Xmag-newXmag;
if (abs(diff) > 0.01) Xmag -= diff/4.0;
diff = Ymag-newYmag;
if (abs(diff) > 0.01) Ymag -= diff/4.0;
}
rotateX(-Ymag);
rotateY(-Xmag);
scale(Zmag);
draw_object(); // THE OBJECT
popMatrix();
}
//_______________________________________________ SETUP PRINT INFO
void info_print() {
println("PTZ info:");
println("key UP DOWN RIGHT LEFT -> rotate // key PAGE UP DOWN -> zoom");
println("mouse LEFT press drag up down right left -> rotate");
println("mouse RIGHT press -> move ");
println("mouse WHEEL turn -> zoom");
}
//_______________________________________________
yes, the code is lengthy,
but the rotation part not,
- only the axis / axis components / move vector / part
- MouseWheel Plus Plus operation ( x y z invisible slider )
- and the Pan-tilt-zoom (PTZ) operation/show makes it long.
same trick used here Intersection between point and plane in 3D or more already