Have a better lookat() ?

Brent Bates ViGYAN AAD/TAB blbates at AERO36.LARC.NASA.GOV
Mon Mar 25 23:13:38 AEST 1991


  A while back Stefan Farestam <farestam at orion.cerfacs.fr> posted some
equations for finding the proper twist angle and I just recently added
them to something I'm working on.  Here is part of his note:

 >* view_point is the point you are looking from
 >
 >* ref_point is the point you are looking towards
 >
 >* up_vec is a vector that represents the direction up (i.e. if you would
 >  plot up_vec after lookat was applied it would be a vertical vector
 >  pointing upwards on the screen)
 >
 >* v = view_point - ref_point
 >
 >* w = (up_vec) x (v)   where 'x' signifies the vector product
 >
 >* v and w are normalized
 >
 >then the twist angle used in lookat can be calculated by:
 >
 >   swy = (int) copysign(1.0, wy) ;
 >
 >   twist = swy * acos((wx*vz - wz*vx) / sqrt(vx*vx         + vz*vz)
 >                                      / sqrt(wx*wx + wy*wy + wz*wz)) ;
 >
 >and the call to lookat would look like:
 >
 >   lookat(view_point->x, view_point->y, view_point->z,
 >           ref_point->x,  ref_point->y,  ref_point->z, twist * 180/PI * 10) ;

   Below is my implemention in C:

/* I am looking from origin to a point in space, however the look vector is
   in opposite direction */
      look_x=(-x);
      look_y=(-y);
      look_z=(-z);

/* Non ambiguous direction vector in same x/y direction as REAL look vector */
      ra_x=x;
      ra_y=y;
      ra_z=0.0;

/* up_vec = look_vec X (unit_z_vec X ra_vec)
   (unit_z_vec X ra_vec) creates a vector perpendicular to look vector with
   the general "up" direction I want. */
      up_x=(-ra_x*z);
      up_y=(-ra_y*z);
      up_z=x*ra_x+y*ra_y;
/* Now up vector is perpendicular to look vector */

/* w_vec = up_vec X look_vec */
      w_x=up_y*look_z-up_z*look_y;
      w_y=up_z*look_x-up_x*look_z;
      w_z=up_x*look_y-up_y*look_x;
      mag=sqrt(look_x*look_x+look_y*look_y+look_z*look_z);
      look_x=look_x/mag;
      look_y=look_y/mag;
      look_z=look_z/mag;
      mag=sqrt(w_x*w_x+w_y*w_y+w_z*w_z);
      w_x=w_x/mag;
      w_y=w_y/mag;
      w_z=w_z/mag;
      swy=copysign(1.0,w_y);
      twist=(Angle) (swy*acos((w_x*look_z-w_z*look_x)/
                     sqrt(look_x*look_x+look_z*look_z)/
                     sqrt(w_x*w_x+w_y*w_y+w_z*w_z))*1800.0/pi);
      lookat(0.0,0.0,0.0,(Coord) x,(Coord) y,(Coord) z,twist);

   The important thing to note is that the up vector MUST be perpendicular
to the look vector.  I kept getting incorrect results until did this.
This seems to work for all look vectors.  I have tried various look vectors
that could give problems and the results were still correct.  Hope this
helps.

	Brent L. Bates
	NASA-Langley Research Center
	M.S. 361
	Hampton, Virginia  23665-5225
	Phone:(804) 864-2854          FAX:(804) 864-6792
	E-mail: blbates at aero36.larc.nasa.gov or blbates at aero8.larc.nasa.gov



More information about the Comp.sys.sgi mailing list