Make one vector perpendicular to a second vector.
Strewth! I can't for the life of me remember what all this is about or why I wrote it... I can't think what you'd use it for but here it is...
#includevoid extend_to_perpendicular( VECTOR *p_line1, VECTOR *p_line2, long *p_squared_dis ) { // V1.0 // (c) Jon P 2001 // // MAKE TWO LINES PERPENDICULAR TO EACH OTHER IN THEIR EXISTING PLANE. // // *p_line1 and *p_line2 are end points of two lines that have an origin of 0,0,0. // Each line must have a length of 4096. // *** Note: the two lines must already be at least 45 degrees appart and not // more than 90 degrees. // // *p_line2 is changed so that its line becomes perpendicular to *p_line1 in the // same plane. *p_line1 is not changed. // // *p_suared_dis is the distance between *p_line1 and *p_line2 squared. // If *p_suared_dis is passed as 0 then this routine will calculate it and return // the answer in that parameter incase it might prove useful in the calling code. // Thus p_suared_dis must be a valid read-writable address if specified as zero. // Eplaination:- // Take two lines (and pass them as *p_line1 and *p_line2) , both 4096 in length, // with the same origin of 0,0,0 ... then calculate the squared distance between // the two end points and pass it as as *p_squared_dis. // This length is effectively a squared chord length of a circle with a 4096 radius // and with the two end points being points on its circumference // (see NOTES12# for examples). // // The squared length is then used to calculate two multipliers... // the first is applied to *p_line2 to shorten it (relative to 0,0,0) to where it // intersects a new chord (which is a chord as if the two lines are perpendicular). // The second multiplier is then used to extend the new point in *p_line2 (relative // to point *p_line1) into the final perpendicular position // // register long temp, temp2; if ( *p_squared_dis == 0 ) { // squared chord length not supplied so calculate it. temp = p_line1->vx - p_line2->vx; temp *= temp; temp2 = p_line1->vy - p_line2->vy; temp += temp2 * temp2; temp2 = p_line1->vz - p_line2->vz; temp += temp2 * temp2; *p_squared_dis = temp; } if ( *p_squared_dis <= 22943587 ) { temp = *p_squared_dis >> 13; // /8192 temp += temp * temp / 7984; temp += ( 33554432 - *p_squared_dis ) / 6369; temp -= 2208; p_line2->vx *= temp; p_line2->vx >>= 12; p_line2->vy *= temp; p_line2->vy >>= 12; p_line2->vz *= temp; p_line2->vz >>= 12; temp = ( *p_squared_dis / 9077 ) + 1823; } else { temp = *p_squared_dis >> 13; temp = -( temp - 422 ) * ( 6458 - temp ); temp /= 4551; temp += 3327; temp += *p_squared_dis / 12559; p_line2->vx *= temp; p_line2->vx >>= 12; p_line2->vy *= temp; p_line2->vy >>= 12; p_line2->vz *= temp; p_line2->vz >>= 12; temp = *p_squared_dis >> 13; temp = temp * temp / 6177; temp += 3071; } p_line2->vx = ( p_line2->vx - p_line1->vx ) * 5793 / temp + p_line1->vx; p_line2->vy = ( p_line2->vy - p_line1->vy ) * 5793 / temp + p_line1->vy; p_line2->vz = ( p_line2->vz - p_line1->vz ) * 5793 / temp + p_line1->vz; }