We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpPrograms › Perpendicular to Camera vector
Page Index Toggle Pages: 1
Perpendicular to Camera vector (Read 1832 times)
Perpendicular to Camera vector
Feb 6th, 2007, 8:40pm
 
I am using camera() to look around and travel through a 3D environment.  I want to be able to simulate spheres by drawing simple circles and having them always be perpendicular to the where the camera is pointing.

How do I rotateX, rotateY, and rotateZ the circles so that they are always being viewed face-on?

Re: Perpendicular to Camera vector
Reply #1 - Feb 6th, 2007, 10:30pm
 
Hello,

Code:

class Camera {
float distance;
float dEcranOeil;
float dEcranRepere;
Vecteur oeil,posRegard;
Vecteur camX,camY,camZ,camX0,camY0,camZ0,vectEyeMouse,vectImpact ;
//++++++++++++++++++++++++++++++++++++++++++++++++++
//
//++++++++++++++++++++++++++++++++++++++++++++++++++
public Camera(){
vectImpact=new Vecteur(0,0,-rayon);
camZ0=new Vecteur(0,0,1);
camZ=camZ0.cloner();
camY0=new Vecteur(0,1,0);
camY=camY0.cloner();
camX0=new Vecteur(1,0,0);
camX=camX0.cloner();
distance=1000;
this.posRegard =new Vecteur(0,0,0);
oeil=posRegard.ajouter(camZ0,-distance);
dEcranOeil=height/(2*tan(PI/6));
dEcranRepere=distance-dEcranOeil;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++
//
//++++++++++++++++++++++++++++++++++++++++++++++++++
void placercamera(){
oeil=posRegard.ajouter(camZ,-distance);
camera(oeil.x,oeil.y,oeil.z,posRegard.x,posRegard.y,posRegard.z,camY.x,camY.y,camY.z);
}
//++++++++++++++++++++++++++++++++++++++++++++++++++
//
//++++++++++++++++++++++++++++++++++++++++++++++++++
void tournerCam(Quat lequa){
camZ=lequa.tourner(camZ0);
camY=lequa.tourner(camY0);
camX=lequa.tourner(camX0);
}}

.....and
void draw(){
background(140,120,200);

......
pushMatrix();
applyMatrix( cam.camX.x,cam.camY.x,cam.camZ.x,0,
cam.camX.y,cam.camY.y,cam.camZ.y,0,
cam.camX.z,cam.camY.z,cam.camZ.z,0,
0,0,0,1);
dessinerCercle();
popMatrix();

}




http://www.alcys.com/p5/Alcys_essai/applet/index.html
Re: Perpendicular to Camera vector
Reply #2 - Feb 7th, 2007, 3:01am
 
Thanks alcys for the code.  Was hoping for an easier solution.  Anyone have suggestions that dont involve incorporating a Vector and Quat class?

-robert
Re: Perpendicular to Camera vector
Reply #3 - Feb 7th, 2007, 11:10am
 
I think it may go something like...

Code:

float eyeX,eyeY,eyeZ,midX,midY,midZ; //eye position, and lookAt position.
//assuming you've got them pre-computed

float deltaX=eyeX-midX;
float deltaY=eyeY-midY;
float deltaZ=eyeZ-midZ;

float angleZ=atan2(deltaY,deltaX);
float hyp=sqrt(sq(deltaX)+sq(deltaY));
float angleY=atan2(deltaZ,hyp);

rotateZ(angleZ);
rotateY(angleY);



That's off the top of my head an dshould be right, but may have thigns rotating in the wrong direction, so you may need to use -angleZ/y or reverse the terms in the atan2 functions.
Re: Perpendicular to Camera vector
Reply #4 - Feb 7th, 2007, 7:52pm
 
Did the trick!  I flipped the two values in the last atan2, but otherwise, exactly what I needed.

Yay!
Re: Perpendicular to Camera vector
Reply #5 - Jan 10th, 2008, 4:06pm
 
I'm trying to implement this algorithm but so far there's a quirk, at lower camera angles the objects start twisting. I don't understand the logic of it therefore I can't fix it.. Is it missing a rotateX call?
Here's a simple sketch to isolate the problem:

Code:

import processing.opengl.*;

float[][] circles_arr;

void setup() {
size(400, 400, OPENGL);

// build array of random coords for circles
int num = 100;
circles_arr = new float[num][];
for ( int i=0; i<num; i++ ) {
circles_arr[i] = new float[3];
circles_arr[i][0] = random(-100,100);
circles_arr[i][1] = random(-100,100);
circles_arr[i][2] = random(-100,100);
}
}

void draw() {
background(0);
lights();

float eyeX = 30;
float eyeY = mouseY;
float eyeZ = 220;
float midX = 0;
float midY = 0;
float midZ = 0;

camera(eyeX, eyeY, eyeZ, midX, midY, midZ, 0.0, 1.0, 0.0);

fill(150);
box(50);

rotate_to_cam_perpendicular(eyeX, eyeY, eyeZ, midX, midY, midZ);
// place circles
fill(255,255,00);
for ( int i=0; i<circles_arr.length; i++ ) {
pushMatrix();
float[] circle = circles_arr[i];
translate(circle[0],circle[1],circle[2]);
ellipse(0, 0, 10, 10);
popMatrix();
};
}

void rotate_to_cam_perpendicular(float eyeX, float eyeY, float eyeZ, float midX, float midY, float midZ){
float deltaX=eyeX-midX;
float deltaY=eyeY-midY;
float deltaZ=eyeZ-midZ;

float angleZ=atan2(deltaY,deltaX);
float hyp=sqrt(sq(deltaX)+sq(deltaY));
float angleY=atan2(hyp,deltaZ);

rotateZ(angleZ);
rotateY(angleY);
}

Re: Perpendicular to Camera vector
Reply #6 - Jan 13th, 2008, 6:11pm
 
In order to avoid that weirdness, you should do the rotation to make the plane face the camera on a per-circle basis. The reason things start spinning is that your camera is turning to face midX, midY, midZ as you move around that point.

You are drawing all the circles on a single plane right now, which prevents them from moving 'realistically' in space. The plane is the one you rotated your drawing environment to. When the plane rotates to face the camera, all the circles rotate with it.

Make your transformation to place each circle and then rotate that circle to face the camera.

Modified snippet from your draw loop:
// place circles
 fill(255,255,00);
 for ( int i=0; i<circles_arr.length; i++ ) {
   pushMatrix();
   float[] circle = circles_arr[i];
   translate(circle[0],circle[1],circle[2]);
   rotate_to_cam_perpendicular(eyeX, eyeY, eyeZ, midX, midY, midZ);
   ellipse(0, 0, 10, 10);
   popMatrix();
 };


As an optimization, since you are drawing each circle at the origin, you could calculate your rotations once (avoiding repeated trig calls), and then simply reapply them.

//code begins inside draw loop
//calculate normal angle to camera from origin
 float angleZ = getAngleZ( eyeX, eyeY, eyeZ );
 float angleY = getAngleY( eyeX, eyeY, eyeZ );
 
 fill(150);
 box(50);
 
 // place circles
 fill(255,255,00);
 for ( int i=0; i<circles_arr.length; i++ ) {
   pushMatrix();
   float[] circle = circles_arr[i];
   translate(circle[0],circle[1],circle[2]);
   rotateZ(angleZ);
   rotateY(angleY);
   ellipse(0, 0, 10, 10);
   popMatrix();
 };
} //close draw loop

float getAngleY( float eyeX, float eyeY, float eyeZ ){
 float hyp=sqrt(sq(eyeX)+sq(eyeY));
 float angleY=atan2(hyp,eyeZ);
 return angleY;
}

float getAngleZ( float eyeX, float eyeY, float eyeZ ){
 float angleZ=atan2(eyeY,eyeX);
 return angleZ;
}
Page Index Toggle Pages: 1