public static void half_diff_coords_to_std_coords(double _ThetaHalf, double _PhiHalf, double _ThetaDiff, double _PhiDiff, out double _ThetaIn, out double _PhiIn, out double _ThetaOut, out double _PhiOut) { double SinTheta_half = Math.Sin(_ThetaHalf); Half.Set(Math.Cos(_PhiHalf) * SinTheta_half, Math.Sin(_PhiHalf) * SinTheta_half, Math.Cos(_ThetaHalf)); // Build the 2 vectors representing the frame in which we can use the diff angles Vector3 OrthoX; Half.Cross(ref Normal, out OrthoX); if (OrthoX.LengthSq() < 1e-6) { OrthoX.Set(1, 0, 0); } else { OrthoX.Normalize(); } Vector3 OrthoY; Half.Cross(ref OrthoX, out OrthoY); // Rotate using diff angles to retrieve incoming direction Half.Rotate(ref OrthoX, -_ThetaDiff, out Temp); Temp.Rotate(ref Half, _PhiDiff, out In); // We can get the outgoing vector either by rotating the incoming vector half a circle // Temp.Rotate( ref Half, _PhiDiff + Math.PI, out Out ); // ...or by mirroring in "Half tangent space" double MirrorX = -In.Dot(ref OrthoX); double MirrorY = -In.Dot(ref OrthoY); double z = In.Dot(ref Half); Out.Set( MirrorX * OrthoX.x + MirrorY * OrthoY.x + z * Half.x, MirrorX * OrthoX.y + MirrorY * OrthoY.y + z * Half.y, MirrorX * OrthoX.z + MirrorY * OrthoY.z + z * Half.z ); // CHECK // Vector3 CheckHalf = new Vector3() { x = In.x+Out.x, y = In.y+Out.y, z = In.z+Out.z }; // CheckHalf.Normalize(); // Is this Half ??? // CHECK // Finally, we can retrieve the angles we came here to look for... _ThetaIn = Math.Acos(In.z); _PhiIn = Math.Atan2(In.y, In.x); _ThetaOut = Math.Acos(Out.z); _PhiOut = Math.Atan2(Out.y, Out.x); }
public static void half_diff_coords_to_std_coords(double _ThetaHalf, double _PhiHalf, double _ThetaDiff, double _PhiDiff, ref Vector3 _In, ref Vector3 _Out) { double SinTheta_half = Math.Sin(_ThetaHalf); Half.Set(Math.Cos(_PhiHalf) * SinTheta_half, Math.Sin(_PhiHalf) * SinTheta_half, Math.Cos(_ThetaHalf)); // Build the 2 vectors representing the frame in which we can use the diff angles Vector3 OrthoX; Half.Cross(ref Normal, out OrthoX); if (OrthoX.LengthSq() < 1e-6) { OrthoX.Set(1, 0, 0); } else { OrthoX.Normalize(); } Vector3 OrthoY; Half.Cross(ref OrthoX, out OrthoY); // Rotate using diff angles to retrieve incoming direction Half.Rotate(ref OrthoX, -_ThetaDiff, out Temp); Temp.Rotate(ref Half, _PhiDiff, out _In); // ...or by mirroring in "Half tangent space" double MirrorX = -_In.Dot(ref OrthoX); double MirrorY = -_In.Dot(ref OrthoY); double z = _In.Dot(ref Half); _Out.Set( MirrorX * OrthoX.x + MirrorY * OrthoY.x + z * Half.x, MirrorX * OrthoX.y + MirrorY * OrthoY.y + z * Half.y, MirrorX * OrthoX.z + MirrorY * OrthoY.z + z * Half.z ); // if ( _In.z < -0.5 || _Out.z < -0.5 ) // throw new Exception( "RHA MAIS MERDE!" ); }