' Pattern Diagram Rotation.
' Rotation calculation.
'
' FF Table : step 1 deg.
'
' Author : F5FOD Jean-Pierre Waymel, with the DG7YBN Hartmut Klüver's advices and suggestions.
' Date : november 2016 - february 2017
'
' Program name : step1_phi1_theta1_generator_V2-0.bas
' Version 2.0
' From V1.2.
' The 3 cases where x1 = y1 = 0 are solved directly with conditions on the specific values
' of (phi, theta) :
' (phi, theta) = (0, alpha) => (phi1, theta1) = (0, 0),
' (phi, theta) = (180, 180 – alpha) => (phi1, theta1) = (0, 180),
' (phi, theta) = (360, alpha) => (phi1, theta1) = (0, 0).
' sin(theta=180), cos(theta=90), sin(phi=180or360), cos(phi=90or270) and cos(alpha=90) forced to 0.
' x1 computed in 2 times : x_cos and z_sin then x_cos - z_sin.
' z1 computed in 2 times : x_sin and z_cos then x_sin + z_cos.
' "_V2-0" added to the output file name which becomes "FFstep1_phi1_theta1_basic_**_V2-0.txt"
'
'
' The points M and M1 are situated on a sphere the radius of which is equal to 1 :
' (phi , theta ) : point M, before the rotation ;
' (phi1, theta1) : point M1, directly after a rotation of an angle alpha around OY, towards OZ.
'
' For each pair (phi, theta) before the rotation, a pair (phi1, theta1) is calculated.
'
' The pairs (phi, theta) are sorted by increasing phi by increasing theta ;
' phi runs from 0 deg. to 360 deg. step 1 deg.
' theta runs from 0 deg. to 180 deg. step 1 deg.
' Then the (phi, theta) pairs are :
' (0, 0), (0, 1),..., (0, 180),
' (1, 0), (1, 1),..., (1, 180),
' ...,
' ..., (360, 180).
'
' There are 181 x 361 = 65341 pairs (phi, theta).
'
' Due to the sorting, due to the range and the step of phi's and theta's, the value of
' a pair (phi, theta) is "hidden" in an index :
' phi is the result of an euclidian division "\" => (index - 1)\181 ;
' theta is the rest of this division ;
' "- 1" is due to the fact that the index begins at "1" (as the line numbering in Excel)
' when phi and theta begin at "0".
'
' Reversely, index = 181 * phi + theta + 1.
'
' Example for index = 7534 :
' phi = (7534 - 1)\181 = 41 deg.
' theta = [(7534 - 1) - (41 x 181)] = 112 deg.
'
' An index is a simplified way to give a pair (phi, theta).
'
' This program delivers an output file named "FFstep1_phi1_theta1_basic_**_V2-0.txt"
' with "**" being the value of the rotation angle alpha.
' The format of this file is : ;;, with phi1 and theta1 in deg.
'
format3_18$ = "###.##################"
format5_0$ = "#####"
'
DIM index AS LONG
DIM alpha_rad AS DOUBLE
DIM phi_rad AS DOUBLE
DIM theta_rad AS DOUBLE
DIM sin_theta AS DOUBLE
DIM cos_theta AS DOUBLE
DIM sin_phi AS DOUBLE
DIM cos_phi AS DOUBLE
DIM cos_alpha AS DOUBLE
DIM x AS DOUBLE
DIM y AS DOUBLE
DIM z AS DOUBLE
DIM x_cos AS DOUBLE
DIM z_sin AS DOUBLE
DIM x_sin AS DOUBLE
DIM z_cos AS DOUBLE
DIM x1 AS DOUBLE
DIM y1 AS DOUBLE
DIM z1 AS DOUBLE
DIM phi1_rad AS DOUBLE
DIM theta1_rad AS DOUBLE
DIM phi1 AS DOUBLE
DIM theta1 AS DOUBLE
'
'
' PART 1
' Entering alpha value
'
alpha_entry:
CLS
PRINT " Rotation angle value, in degrees"
PRINT " (any integer value between 1 and 90, step 1) "; ' alpha = 0 => no rotation !
INPUT alpha%
IF alpha% < 1% OR alpha% > 90% THEN GOTO alpha_entry
IF alpha% < 10% THEN alpha$ = "0" + LTRIM$(STR$(alpha%)) ELSE alpha$ = LTRIM$(STR$(alpha%))
'
'
' PART 2
' Rotation : calculating the pairs (phi1, theta1)
alpha_rad = alpha% * _PI/180%
'
CLOSE 1%
OPEN "FFstep1_phi1_theta1_basic_" + alpha$ + "_V2-0.txt" FOR OUTPUT AS #1%
'
FOR phi% = 0% TO 360%
IF phi% = 90% THEN SOUND 440%, 18%
IF phi% = 180% THEN SOUND 540%, 18%
IF phi% = 270% THEN SOUND 640%, 18%
IF phi% = 360% THEN SOUND 740%, 18%
FOR theta% = 0% TO 180%
index = 181% * phi% + theta% + 1%
phi_rad = phi% * _PI/180%
theta_rad = theta% * _PI/180%
'
sin_theta = SIN(theta_rad)
IF theta% = 180% THEN sin_theta = 0%
'
cos_theta = COS(theta_rad)
IF theta% = 90% THEN cos_theta = 0%
'
sin_phi = SIN(phi_rad)
IF phi% = 180% THEN sin_phi = 0%
IF phi% = 360% THEN sin_phi = 0%
'
cos_phi = COS(phi_rad)
IF phi% = 90% THEN cos_phi = 0%
IF phi% = 270% THEN cos_phi = 0%
'
cos_alpha = COS(alpha_rad)
IF alpha% = 90% THEN cos_alpha = 0%
'
x = sin_theta * cos_phi
y = sin_theta * sin_phi
z = cos_theta
'
x_cos = x * cos_alpha
z_sin = z * SIN(alpha_rad)
x1 = x_cos - z_sin
y1 = y
x_sin = x * SIN(alpha_rad)
z_cos = z * cos_alpha
z1 = x_sin + z_cos
'
phi1_rad = _ATAN2(y1, x1) ' (y1, x1) : QB64 _ATAN2 format
' _ATAN2(0, 0) is undefined and the function
' returns 0 instead of a division error.
theta1_rad = _ACOS(z1)
IF z1 >= 1% THEN theta1_rad = 0%
IF z1 <= -1% THEN theta1_rad = _PI
phi1 = phi1_rad * 180%/_PI
IF phi1 < 0% THEN phi1 = 360% + phi1
IF phi1 = -0% THEN phi1 = 0%
theta1 = theta1_rad * 180%/_PI
'
IF phi% = 0% AND theta% = alpha% THEN ' When x1 = y1 = 0
phi1 = 0%
theta1 = 0%
ENDIF
IF phi% = 180% AND theta% = 180% - alpha% THEN ' When x1 = y1 = 0
phi1 = 0%
theta1 = 180%
ENDIF
IF phi% = 360% AND theta% = alpha% THEN ' When x1 = y1 = 0
phi1 = 0%
theta1 = 0%
ENDIF
'
PRINT USING format5_0$; index;
PRINT ";";
PRINT USING format3_18$;phi1;
PRINT ";";
PRINT USING format3_18$;theta1
'
PRINT #1%, USING format5_0$; index;
PRINT #1%,";";
PRINT #1%, USING format3_18$;phi1;
PRINT #1%,";";
PRINT #1%, USING format3_18$;theta1
NEXT theta%
NEXT phi%
'
CLOSE 1%
'
' PART 3
' New alpha value ?
PRINT " Another alpha value (Y for 'Yes' or for 'No') ";
INPUT A$
IF A$ = "Y" OR A$ = "y" THEN GOTO alpha_entry
'
'
END