// file: sketch_3D_PVector_rotate // using mouseWheel Plus PLus for rotation // using PTZ for operation show // publish // https://discourse.processing.org/t/pvector-rotate-use-for-3d/10958 // use already here https://discourse.processing.org/t/intersection-between-point-and-plane-in-3d-or-more/10780/7 // add a mag slider // http://kll.engineering-news.org/kllfusion01/articles.php?article_id=154#here22 PVector a, atx, aty, atz, atm, at; int along = 50; float angbx=0, angby=0, angbz=0; float amag0,amag; boolean axprint = true, axline = true, axvec = true; void setup() { size(600, 600, P3D); a = new PVector(along, along, along); amag0=amag = a.mag(); info_print(); // Tab ptz println("here add: key [x] [y] [z] rotation axis / key [m] mag / key [r] reset \nAND 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); atm = at.copy(); atm.setMag(amag); } 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 / magnified vector fill(0, 200, 200); noStroke(); push(); translate(atm.x, atm.y, atm.z); sphere(3); pop(); stroke(0, 200, 200); strokeWeight(3); line(atm.x, atm.y, atm.z, 0, 0, 0); strokeWeight(0.5); line(at.x, at.y, at.z, 0, 0, 0); if ( axline ) { //show axis components stroke(80); strokeWeight(0.5); line(atm.x, atm.y, atm.z, atm.x, 0, 0); line(atm.x, atm.y, atm.z, 0, atm.y, 0); line(atm.x, atm.y, atm.z, 0, 0, atm.z); } if ( axvec ) { // 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; amag = amag0; println("reset"); } if ( keyPressed && key == 'm' ) { amag += e; println(" key m: amag "+int(amag)); } if ( axprint ) { println("a"+a); println("atx"+atx); println("aty"+aty); println("atz"+atz); println("at"+at); println("atm"+atm); } } // 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"); } //_______________________________________________