' 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