FAQ
Cover
This is the archive Discourse for the Processing (ALPHA) software.
Please visit the new Processing forum for current information.

   Processing 1.0 _ALPHA_
   Programming Questions & Help
   Programs
(Moderators: fry, REAS)
   Math for 3D rotation
« Previous topic | Next topic »

Pages: 1 
   Author  Topic: Math for 3D rotation  (Read 4385 times)
pitaru

WWW Email
Math for 3D rotation
« on: Feb 13th, 2003, 8:06pm »

In the following example: http://www.pitaru.com/proce55ing/rotation_q/, you can  
 
rotate the cube in 3D space by dragging the mouse.
 
In my code (see source at above link), i'm only changing rotateX() and rotateY(). In return, the interaction is a bit strange when rotateZ() <> 0.  
 
My question, how do i integrate the Z zxis into the code?
 
Glen Murphy

WWW Email
Re: Math for 3D rotation
« Reply #1 on: Feb 13th, 2003, 11:40pm »

You shouldn't need to - you can rotate anything to any angle using only two axes.
 
What you would want to do is to rotate the object before the rotateX, rotateY in a similar way to how
 
fry


WWW
Re: Math for 3D rotation
« Reply #2 on: Feb 14th, 2003, 2:07am »

this is a common problem for 3d graphics, because rotation is so unintuitive. usually it's solved with math around 'quaternions' (sorry, you just got through all that other matrix math and i gotta throw that out).  
 
a common, more intuitive way to move/rotate things in 3d is to move the object with a virtual trackball. part of which can be found in this goofy applet:
http://acg.media.mit.edu/projects/treehouse/3d/
(hold down shift for the rotation of the object).
 
i'll be posting code soon for the trackball, i just have to clean up some wiring...
 
pitaru

WWW Email
Re: Math for 3D rotation
« Reply #3 on: Feb 14th, 2003, 4:07am »

'quaternions' . off course
 
actually, i found this nice link to bring me up to speed: http://www.geocities.com/SiliconValley/2151/matrices.html
 
Still, i'm having a hard time writing down my specific problem. it's as if the X/Y axis aren't 'refreshing' after every rotation (on mouse-up). Try rotating just the X, then just the Y. While the Y rotates, you'll notice that the object is still rotating around the original X value.  
 
i'm very curious to see the 'trackball' source. It may solve the whole problem.
 
Glen Murphy

WWW Email
Re: Math for 3D rotation
« Reply #4 on: Feb 14th, 2003, 4:43am »

This board is quite weird - I didn't mean to post that, but I think my Ctrl-W posts it.
 
Anyway, I think you've got what I was originally going to say, before I decided that I wasn't any good at explaining it.
 
PS fry, that applet you posted didn't seem to acknowledge any of my keypresses. Bit weird.
 
Gosh it's hot in here.
 
Martin

122417302122417302martingomez_listsmg1ph WWW Email
Re: Math for 3D rotation
« Reply #5 on: Feb 14th, 2003, 5:58am »

hmm... ben's treehouse applet works on mine. what do you do? i make it work this way: click on a shape from the left panel. click and drag your mouse on the canvas... while keeping the mouse pressed, simultaneously hold 'shift' to rotate the shape or 'control' to move the shape. once the shape is there, you can't do anything to it anymore... though, you can delete the shapes via their layers using 'backspace'... hmm... that's about it.
 
currently working on a ths applet where you can move the shapes around even if they're already drawn.
 
and i really have to get some sleep.
 
Katrin Lang
Guest
Email
Re: Math for 3D rotation
« Reply #6 on: Jun 28th, 2003, 1:51pm »

I encountered exactly this problem these days
first:  
writing a virtual trackball is actually quite easy, it's basically four lines of code:
You define a virtual sphere with a certain radius, see
where the mouseX position intersects (Pythagoras) with that sphere and then you get the x angle simply using atan2 of the the point thus defined. Same with y.Of course there are still some extra goodies like continuing the rotation when the mouse leaves the screen and so on, but basically that's it.
 
second:
i tried to write an algorithm which allows you to
create 3dimensional lines with assigned line strength
(using boxes) which can then also be lighted and smoothed, quite nice actually.
So... thing is you actually have to consider the third axis as well. I mean, you still have to rotate only about two axes, but the rotation has to behave differently depending on whether the third axis is positive or negative.
Complicated?
I still have to sort some little things out, but I think I can post the codes these days if it helps.
 
Katrin
 
pitaru

WWW Email
Re: Math for 3D rotation
« Reply #7 on: Jun 28th, 2003, 2:04pm »

Thanks Kartin,
 
Since posting this question (February), I've learned about the wonders of arcball/quaternions
 
check out this post:
http://proce55ing.net/discourse/yabb/board_Tools_action_display__num_1054894944.html
 
and this one:  
http://proce55ing.net/discourse/yabb/board_Tools_action_display__num_1056320689.html
 
katrin

Email
Re: Math for 3D rotation
« Reply #8 on: Jul 31st, 2003, 8:23pm »

Uuh, I'm so sorry!
 
I know i promised to post this a month ago..
But now i finished my exams and got back to work.
So, this is my code for the virtual trackball and 3D rotation. It's part of a project on the 4-dimensional cube I've done at UdK Berlin.
 
Besides it would be so much nicer if I could call the
mouse events from inside the "update"-method.
Can anybody help?
 
The applet is online at http://user.cs.tu-berlin.de/~langk/
 
 
--just ignore all the smileys
 
virtualTrackball vt;
 
void setup() {
  size(300, 300);
  background(0);
  fill(255);
  stroke(255);  
  lights();
  smooth();  
  vt = new virtualTrackball(150, 150, 150);
  }
   
 
 
void loop() {  
   
 
translate(150, 150);
vt.update();  
 
 
  //horizontal  
  fakeLine3D(-75, -25, 75, 25, -25, 75, 2.;
  fakeLine3D(-75, 75, 75, 25, 75, 75, 2.;
  fakeLine3D(-75, -25, -25, 25, -25, -25, 2.;
  fakeLine3D(-75, 75, -25, 25, 75, -25, 2.;
  fakeLine3D(-25, 25, 25, 75, 25, 25, 2.;
  fakeLine3D(-25, -75, 25, 75, -75, 25, 2.;
  fakeLine3D(-25, 25, -75, 75, 25, -75, 2.;
  fakeLine3D(-25, -75, -75, 75, -75, -75, 2.;
   
  //vertical  
  fakeLine3D(-75, 75, 75, -75, -25, 75, 2.;
  fakeLine3D(25, 75, 75, 25, -25, 75, 2.;
  fakeLine3D(-75, 75, -25, -75, -25, -25, 2.;
  fakeLine3D(25, 75, -25, 25, -25, -25, 2.;
  fakeLine3D(-25, 25, 25, -25, -75, 25, 2.;
  fakeLine3D(75, 25, 25, 75, -75, 25, 2.;
  fakeLine3D(-25, 25, -75, -25, -75, -75, 2.;
  fakeLine3D(75, 25, -75, 75, -75, -75, 2.;
     
  //depth  
  fakeLine3D(-75, -25, 75, -75, -25, -25, 2.;
  fakeLine3D(-75, 75, 75, -75, 75, -25, 2.;
  fakeLine3D(25, -25, 75, 25, -25, -25, 2.;
  fakeLine3D(25, 75, 75, 25, 75, -25, 2.;
  fakeLine3D(-25, 25, 25, -25, 25, -75, 2.;
  fakeLine3D(-25, -75, 25, -25, -75, -75, 2.;  
  fakeLine3D(75, 25, 25, 75, 25, -75, 2.;
  fakeLine3D(75, -75, 25, 75, -75, -75, 2.;
   
  //diagonal
  fakeLine3D(-75, -25, 75, -25, -75, 25, 2.;
  fakeLine3D(-75, 75, 75, -25, 25, 25, 2.;
  fakeLine3D(25, -25, 75, 75, -75, 25, 2.;
  fakeLine3D(25, 75, 75, 75, 25, 25, 2.;
  fakeLine3D(-75, -25, -25, -25, -75, -75, 2.;
  fakeLine3D(-75, 75, -25, -25, 25, -75, 2.;
  fakeLine3D(25, -25, -25, 75, -75, -75, 2.;
  fakeLine3D(25, 75, -25, 75, 25, -75, 2.;
   
  }  
 
 
void fakeLine3D (float x1, float y1, float z1, float x2, float y2, float z2, float lineStrength) {
  //points defining a 3d vector
  float px= x2-x1;
  float py= y2-y1;
  float pz= z2-z1;
  //angles for rotation  
  float xy, xz;
  //length of line (needed only for linestrength)
  float length= sqrt(sq(px) + sq(py) + sq(pz));
   
  if(px > 0) {
    xz= atan2(pz, -px);
    xy= -atan2(py, sqrt(sq(px) + sq(pz)));
    }
  else{
   xz= atan2(-pz, px);
   xy= atan2(-py, -sqrt(sq(px) + sq(pz))) ;
   };
   
   
  push();
  translate(x1 + px/2, y1 + py/2, z1 + pz/2);
  rotateY(xz);
  rotateZ(xy);
  scale(length/lineStrength, 1, 1);
  box(lineStrength);
  pop();
  }
   
class virtualTrackball {
 
boolean over = false;    
float xangle = 0.0;
float yangle = 0.0;
float initx, inity, initxangle, inityangle;
float radius; // radius of trackball
float xpos;  // horizontal position of trackball
float ypos;  // vertical position of trackball
 
virtualTrackball(int x, int y, int rad) {
  xpos = x;  
  ypos = y;  
  radius = rad;  
  }
   
void update() {
   
  rotateX(yangle);
  rotateY(xangle);  
  }  
}
   
 
 
 
void mousePressed() {
  vt.initx= mouseX-vt.xpos;
  vt.inity= mouseY-vt.xpos;
  if(-vt.radius <= vt.initx && vt.initx<= vt.radius && -vt.radius <= vt.inity && vt.inity <= vt.radius) {
    vt.initxangle = vt.xangle;
    vt.inityangle = vt.yangle;
    vt.over = true;
    }  
  }  
 
                           
void mouseDragged() {
   
  if(vt.over == true){
    float xpos = mouseX-vt.xpos;
    float ypos = mouseY-vt.ypos;
     
    float x = xpos%vt.radius;
    float y = ypos%vt.radius;
    float xsgn = (xpos-x)/vt.radius;
    float ysgn = (ypos-y)/vt.radius;    
 
 
    float xz = (sqrt(sq(vt.radius)-sq(x)));
    vt.xangle = xsgn*PI/2 + (atan2(x-vt.initx, xz))+vt.initxangle;  
 
    float yz= (sqrt(sq(vt.radius)-sq(y)));  
    vt.yangle = -(ysgn*PI/2)-(atan2(y-vt.inity, yz))+vt.inityangle;
    }
  }    
   
void mouseReleased() {    
  vt.over = false;
  }    
   
 
 
mKoser

WWW Email
Re: Math for 3D rotation
« Reply #9 on: Jul 31st, 2003, 8:40pm »

to avoid smileys you can clip in code like this:
 
[ code ]
 
// this is my code
// bla bla bla
// code stuff
 
[/ code ]
 
...if you remove the spaces within the brackets, the code is represented like this:
 
Code:

 
// this is my code
// bla bla bla
// code stuff
 

 
 

mikkel crone koser | www.beyondthree.com | http://processing.beyondthree.com
katrin

Email
Re: Math for 3D rotation
« Reply #10 on: Jul 31st, 2003, 9:20pm »

Thanks
 
Pages: 1 

« Previous topic | Next topic »