static void std_coords_to_half_diff_coords( double _ThetaIn, double _PhiIn, double _ThetaOut, double _PhiOut,
out double _ThetaHalf, out double _PhiHalf, out double _ThetaDiff, out double _PhiDiff )
{
// compute in vector
double in_vec_z = Math.Cos(_ThetaIn);
double proj_in_vec = Math.Sin(_ThetaIn);
double in_vec_x = proj_in_vec*Math.Cos(_PhiIn);
double in_vec_y = proj_in_vec*Math.Sin(_PhiIn);
In.Set( in_vec_x, in_vec_y, in_vec_z );
// compute out vector
double out_vec_z = Math.Cos(_ThetaOut);
double proj_out_vec = Math.Sin(_ThetaOut);
double out_vec_x = proj_out_vec*Math.Cos(_PhiOut);
double out_vec_y = proj_out_vec*Math.Sin(_PhiOut);
Out.Set( out_vec_x, out_vec_y, out_vec_z );
// compute halfway vector
Half.Set( in_vec_x + out_vec_x, in_vec_y + out_vec_y, in_vec_z + out_vec_z );
Half.Normalize();
// compute _ThetaHalf, _PhiHalf
_ThetaHalf = Math.Acos( Half.z );
_PhiHalf = Math.Atan2( Half.y, Half.x );
// Compute diff vector
In.Rotate( ref Normal, -_PhiHalf, out Temp );
Temp.Rotate( ref BiTangent, -_ThetaHalf, out Diff );
// Compute _ThetaDiff, _PhiDiff
_ThetaDiff = Math.Acos( Diff.z );
_PhiDiff = Math.Atan2( Diff.y, Diff.x );
}