|
 |
Worked it out by hand.
Tested.
Works for all but the edge cases where X and Z are 0.
Fair notice: There's a weird hack or two in there.
:)
#declare MA_Deg2Vector_RA_Offset = 180;
// Forward: (RA, Dec, Radius) -> <x, y, z>
#local E = 1E-6;
#macro Sign (N)
select (N, -1, 0, 1)
#end
#macro MA_Deg2Vector (S_RA, S_Dec, S_Radius)
#local S_RA = S_RA + MA_Deg2Vector_RA_Offset;
#local S_Rect = radians(S_RA);
#local S_Dec = S_Dec + 180;
#local S_DecRad = radians(S_Dec);
#local S_DecRad = S_DecRad/2;
#local S_X = S_Radius * sin(S_DecRad) * cos(S_Rect);
#local S_Y = S_Radius * cos(S_DecRad);
#local S_Z = S_Radius * sin(S_DecRad) * sin(S_Rect);
#local V_Out = <S_X, -S_Y, S_Z>;
V_Out
#end
#macro MA_Vector2Deg (V_In)
// Undo the original Y inversion
#local S_X = V_In.x;
#local S_Y = -V_In.y;
#local S_Z = V_In.z;
#local Radius = sqrt(S_X*S_X + S_Y*S_Y + S_Z*S_Z);
// Handle the degenerate zero-length vector
#if (Radius < 1e-12)
#local Result = <0, 0, 0>;
#else
//#if (abs(S_Z) < E) S_Z = 0 #end
#local PreDecRad = S_Y / Radius;
// Clamp for numeric safety
#local PreDecRad = max (min (PreDecRad, 1), -1);
#local DecRad1 = acos (PreDecRad);
#local DecRad = DecRad1 * 2;
#local Dec = degrees (DecRad);
#local Dec = Dec - 180;
// Try to fix edge cases
//====================================================
#if (abs(S_X) < E)
#local FF = E;
#local S_X2 = FF*Sign(S_X);
#local S_Y2 = S_Y + FF*Sign(S_X);
#local S_Z2 = FF*Sign(S_X);
#local PreDecRad = S_Y2 / Radius;
#local PreDecRad = max (min (PreDecRad, 1), -1);
#local DecRad1 = acos (PreDecRad);
#else
#local S_X2 = S_X;
#local S_Y2 = S_Y;
#local S_Z2 = S_Z;
#end
//====================================================
#local SinDecRad1 = sin (DecRad1);
#if (abs(SinDecRad1) < E)
#local SinDecRad1 = 1;
#end
#local PreRect = S_Z2 / (Radius * SinDecRad1);
#local PreRect = max (min (PreRect, 1), -1);
#local Rect = asin (PreRect);
#local RectDeg = degrees (Rect);
#local RA = RectDeg - MA_Deg2Vector_RA_Offset;
#if (abs(RA) < E) #local RA = 0; #end
#while (RA < 0)
#local RA = RA + 180;
#end
#if (S_X <= 0 & S_Z >=0)
#local RA = 360 - RA;
#end
#if (S_X > 0 & S_Z >=0)
#local RA = RA + 180;
#end
#if (S_X <= 0 & S_Z <=0)
#local RA = 180 - RA;
#end
#if (S_X < 0 & S_Z =0)
#local RA = 180 + RA;
#end
#local Result = <RA, Dec, Radius>;
#end
Result
#end
// Example round-trip test
#for (RA, 0, 360, 10)
#for (Dec, -180, 180, 18)
#local V = <RA, Dec, 10>;
#debug concat("RA = ", str(V.x,0,3), ", Dec = ", str(V.y,0,3), ", R = ",
str(V.z,0,3), " -----> ")
#declare V1 = MA_Deg2Vector (V.x, V.y, V.z);
#debug concat("X = ", str(V1.x,0,8), ", Y = ", str(V1.y,0,8), ", Z = ",
str(V1.z,0,3), " -----> ")
#declare P1 = MA_Vector2Deg (V1); // P1 = <RA, Dec, R>
#debug concat("RA = ", str(P1.x,0,3), ", Dec = ", str(P1.y,0,3), ", R = ",
str(P1.z,0,3),"\n")
#end
#debug "\n"
#end
#error "No objects in scene"
Post a reply to this message
|
 |