Not yet made into a routine but this section of code did work quite well.
It calculates the y rot of a vector 4096 long, its start point (current_mid) being somewhere on the surface of an imaginary sphere with a radius of 4096 and then continuing tangentially from the spheres surface to it's end point (current_t).
The y rot calulated is quit an exotic y rotation specification.... it is the y rotation relative to the XY plane. There has to be a compromise when the startpoint is towards the min or max z --- then 0 y is when the vector points to the poles (min or max y).
// (c) Jon P 2001
dx = current_mid.vx;
if ( dx < 0 ) dx *= -1;
dy = current_mid.vy;
if ( dy < 0 ) dy *= -1;
dz = current_mid.vz;
if ( dz < 0 ) dz *= -1;
dx2 = current_t.vx - current_mid.vx;
dy2 = current_t.vy - current_mid.vy;
dz2 = current_t.vz - current_mid.vz;
FntPrint( "\n" );
if ( dz <= 2896 )
{
if ( dx <= 2896 )
{ // TOP or BOTTOM section....
// Find-out how much to adjust the Z values to effectively unrotate them
// about the X axis (undoing any foreshortening)...
temp = ( dz << 10 ) / dy;
temp2 = temp * temp;
temp2 /= 2750;
temp2 += 1024;
temp *= 43;
temp2 += temp >> 10;
FntPrint( "TOP zs=%4d ", temp2 );
// Make the adjustments to Z...
dz2 = ( dz2 * temp2 ) >> 10;
// Find-out how much to adjust the X values to effectively unrotate them
// about the Z axis (undoing any foreshortening)...
temp = ( dx << 10 ) / dy;
temp2 = temp * temp;
temp2 /= 2750;
temp2 += 1024;
temp *= 43;
temp2 += temp >> 10;
FntPrint( "xs=%4d ", temp2 );
// Make the adjustments to X...
dx2 = ( dx2 * temp2 ) >> 10;
// see if we're doing the TOP or BOTTOM section...
if ( current_mid.vy < 0 )
temp = auto_arc_tan( dx2, dz2 ); // TOP section
else
temp = auto_arc_tan( dx2, -dz2 ); // BOTTOM section
FntPrint( "ang=%d ", temp );
}
else
{ // The LEFT or RIGHT section...
// Find-out how much to adjust the Z values to effectively unrotate them
// about the Y axis (undoing any foreshortening)...
temp = ( dz << 10 ) / dx;
temp2 = temp * temp;
temp2 /= 2750;
temp2 += 1024;
temp *= 43;
temp2 += temp >> 10;
FntPrint( "RGT zs=%4d ", temp2 );
// Make the adjustments to Z...
dz2 = ( dz2 * temp2 ) >> 10;
// Find-out how much to adjust the Y values to effectively rotate them
// about the Z axis (undoing any foreshortening)...
temp = ( dy << 10 ) / dx;
temp2 = temp * temp;
temp2 /= 2750;
temp2 += 1024;
temp *= 43;
temp2 += temp >> 10;
FntPrint( "ys=%4d ", temp2 );
// Make the adjustments to Y...
dy2 = ( dy2 * temp2 ) >> 10;
// see if we're doing the RIGHT or LEFT section...
if ( current_mid.vx > 0 )
temp = auto_arc_tan( dy2, dz2 );
else
temp = auto_arc_tan( dy2, -dz2 );
FntPrint( "ang=%d ", temp );
}
}
else
{ // The FRONT or REAR section...
// Find-out how much to adjust the Y values to effectively rotate them
// about the X axis (undoing any foreshortening)...
temp = ( dy << 10 ) / dz;
temp2 = temp * temp;
temp2 /= 2750;
temp2 += 1024;
temp *= 43;
temp2 += temp >> 10;
FntPrint( "FNT ys=%4d ", temp2 );
// Make the adjustments to Y...
dy2 = ( dy2 * temp2 ) >> 10;
// Find-out how much to adjust the X values to effectively unrotate them
// about the Y axis (undoing any foreshortening)...
temp = ( dx << 10 ) / dz;
temp2 = temp * temp;
temp2 /= 2750;
temp2 += 1024;
temp *= 43;
temp2 += temp >> 10;
FntPrint( "xs=%4d ", temp2 );
// Make the adjustments to X...
dx2 = ( dx2 * temp2 ) >> 10;
// see if we're doing the RIGHT or LEFT section...
if ( current_mid.vz > 0 )
temp = auto_arc_tan( dx2, dy2 );
else
temp = auto_arc_tan( dx2, -dy2 );
FntPrint( "ang=%d ", temp );
}
FntPrint( "\n" );