A progressive web app to display the angle bisector of two angles given by zodiac sign, degrees and minutes.
fork

Configure Feed

Select the types of activity you want to include in your feed.

Make it work

Signed-off-by: Release-Candidate <rec@gmx.at>

+204 -9
+1 -1
.eslintrc.json
··· 203 203 ] 204 204 } 205 205 ], 206 - "no-mixed-operators": "error", 206 + "no-mixed-operators": "off", 207 207 "no-multi-assign": "error", 208 208 "no-multi-spaces": "error", 209 209 "no-multi-str": "error",
+109 -7
src/App.tsx
··· 18 18 * The app's main entry point. 19 19 * @returns {JSX.Element} Main app component. 20 20 */ 21 + // eslint-disable-next-line max-lines-per-function 21 22 function App(): JSX.Element { 22 - const [count, setCount] = createSignal(0); 23 + const [z1, setZ1] = createSignal(0); 24 + const [z2, setZ2] = createSignal(0); 25 + const [deg1, setDeg1] = createSignal(0); 26 + const [deg2, setDeg2] = createSignal(0); 27 + const [min1, setMin1] = createSignal(0); 28 + const [min2, setMin2] = createSignal(0); 29 + const angle: z.ZodiacAngle = { 30 + z: z1() as z.Zodiacs, 31 + degrees: 15, 32 + minutes: 20, 33 + }; 34 + const angle2: z.ZodiacAngle = { 35 + z: z.Zodiacs.Cancer, 36 + degrees: 8, 37 + minutes: 45, 38 + }; 23 39 24 40 return ( 25 41 <> 26 42 <h1>Bisectriz</h1> 27 - {circle} 43 + <p> 44 + <label for="zodiac1">Zvieratník:</label> 45 + <select 46 + name="zodiac1" 47 + id="zodiac1" 48 + onChange={(e) => setZ1(Number(e.target.value))}> 49 + <option value="0">baran</option> 50 + <option value="1">býk</option> 51 + <option value="2">bliženci</option> 52 + <option value="3">rak</option> 53 + <option value="4">lev</option> 54 + <option value="5">panna</option> 55 + <option value="6">váhy</option> 56 + <option value="7">škorpion</option> 57 + <option value="8">strelec</option> 58 + <option value="9">kozorožec</option> 59 + <option value="10">vodnár</option> 60 + <option value="11">ryby</option> 61 + </select> 62 + 63 + <label for="zodiac1-deg"> deg: </label> 64 + <input 65 + type="number" 66 + name="zodiac1-deg" 67 + id="zodiac1-deg" 68 + value="0" 69 + min="0" 70 + max="29" 71 + onChange={(e) => setDeg1(Number(e.target.value))} 72 + /> 73 + 74 + <label for="zodiac1-min"> min: </label> 75 + <input 76 + type="number" 77 + name="zodiac1-min" 78 + id="zodiac1-min" 79 + value="0" 80 + min="0" 81 + max="59" 82 + onChange={(e) => setMin1(Number(e.target.value))} 83 + /> 84 + </p> 85 + <p> 86 + <label for="zodiac2">Zvieratník:</label> 87 + <select 88 + name="zodiac2" 89 + id="zodiac2" 90 + onChange={(e) => setZ2(Number(e.target.value))}> 91 + <option value="0">baran</option> 92 + <option value="1">býk</option> 93 + <option value="2">bliženci</option> 94 + <option value="3">rak</option> 95 + <option value="4">lev</option> 96 + <option value="5">panna</option> 97 + <option value="6">váhy</option> 98 + <option value="7">škorpion</option> 99 + <option value="8">strelec</option> 100 + <option value="9">kozorožec</option> 101 + <option value="10">vodnár</option> 102 + <option value="11">ryby</option> 103 + </select> 104 + 105 + <label for="zodiac2-deg"> deg: </label> 106 + <input 107 + type="number" 108 + name="zodiac2-deg" 109 + id="zodiac2-deg" 110 + value="0" 111 + min="0" 112 + max="29" 113 + onChange={(e) => setDeg2(Number(e.target.value))} 114 + /> 115 + 116 + <label for="zodiac2-min"> min: </label> 117 + <input 118 + type="number" 119 + name="zodiac2-min" 120 + id="zodiac2-min" 121 + value="0" 122 + min="0" 123 + max="59" 124 + onChange={(e) => setMin2(Number(e.target.value))} 125 + /> 126 + </p> 28 127 <div class="card m-4 bg-orange-200"> 29 - <button class="" onClick={() => setCount((cnt) => cnt + 1)}> 30 - count is {count()} 31 - </button> 32 128 <p> 33 - Edit <code>src/App.tsx</code> and save to test HMR{" "} 34 - {z.zodiacSymbol(z.Zodiacs.Cancer)} 129 + Bisectriz:{" "} 130 + {z.zodiacAngleString( 131 + z.bisectZodiacAngle( 132 + { z: z1(), degrees: deg1(), minutes: min1() }, 133 + { z: z2(), degrees: deg2(), minutes: min2() }, 134 + ), 135 + )} 35 136 </p> 36 137 </div> 138 + {circle} 37 139 </> 38 140 ); 39 141 }
+94 -1
src/zodiacs.ts
··· 28 28 } 29 29 30 30 /** 31 + * Constant to multiply the zodiac index with to get the angle in degrees. 32 + * Starting with Aries at 0°. 33 + */ 34 + const zodiacDegreeFactor = 30; 35 + 36 + /** 37 + * Return the angle in degrees of the given zodiac, starting with aries at 0. 38 + * @param z The zodiac to get the angle of. 39 + * @returns The angle in degrees of the given zodiac, starting with aries at 0. 40 + */ 41 + export function zodiacDegrees(z: Zodiacs): number { 42 + return z * zodiacDegreeFactor; 43 + } 44 + 45 + /** 31 46 * The name of the 12 zodiac sign in slovak. 32 47 */ 33 48 const zodiacSlovak = [ ··· 57 72 /** 58 73 * The Unicode symbols of the 12 zodiac signs. 59 74 */ 60 - export const zodiacSymbols = [ 75 + const zodiacSymbols = [ 61 76 "♈", 62 77 "♉", 63 78 "♊", ··· 80 95 export function zodiacSymbol(z: Zodiacs): string { 81 96 return zodiacSymbols[z]; 82 97 } 98 + 99 + /** 100 + * A angle given in zodiac signs, degrees and minutes. 101 + * `z` is angle in as a zodiac sign, the angle in 30° increments, 102 + * `degrees` is the remainder of the angle in degrees should be between 0 and 30 103 + * (exclusive), 104 + * `minutes` is the remainder of the angle in minutes. 105 + */ 106 + export type ZodiacAngle = { 107 + // eslint-disable-next-line lines-around-comment 108 + /** 109 + * The zodiac sign of the angle. This is a angle in 30° increments. 110 + */ 111 + z: Zodiacs; 112 + 113 + /** 114 + * The part of the angle in degrees, should be between 0 and 30 (exclusive). 115 + */ 116 + degrees: number; 117 + 118 + /** 119 + * The part of the angle in minutes, should be between 0 and 59 (exclusive). 120 + * A minute is 1/60 of a degree. 121 + */ 122 + minutes: number; 123 + }; 124 + 125 + /** 126 + * Return a string representation of the given `ZodiacAngle`. 127 + * @param a The `ZodiacAngle` to convert to a string. 128 + * @returns The string representation of the given `ZodiacAngle`. 129 + */ 130 + export function zodiacAngleString(a: ZodiacAngle): string { 131 + return `${zodiacString(a.z)} ${a.degrees}°${a.minutes}'`; 132 + } 133 + 134 + /** 135 + * Return the angle in degrees of the given `ZodiacAngle`. 136 + * @param a The `ZodiacAngle` to convert to degrees. 137 + * @returns The angle in degrees of the given `ZodiacAngle`. 138 + */ 139 + export function zodiacAngle2Deg(a: ZodiacAngle): number { 140 + // eslint-disable-next-line no-magic-numbers 141 + return (a.z * zodiacDegreeFactor + a.degrees + a.minutes / 60) % 360; 142 + } 143 + 144 + /** 145 + * Return the `ZodiacAngle` of the given angle in degrees. 146 + * @param angle The angle in degrees to convert to a `ZodiacAngle`. 147 + * @returns The `ZodiacAngle` of the given angle in degrees. 148 + */ 149 + export function deg2ZodiacAngle(angle: number): ZodiacAngle { 150 + // eslint-disable-next-line no-magic-numbers 151 + const z = Math.floor(angle / zodiacDegreeFactor) % 12; 152 + const degrees = Math.floor(angle % zodiacDegreeFactor); 153 + // Round two times, once to a factor of ten and then round again after / 10. 154 + const minutes = Math.round( 155 + // eslint-disable-next-line no-magic-numbers, @typescript-eslint/no-extra-parens 156 + Math.round(((angle - (z * zodiacDegreeFactor + degrees)) * 600) % 600) * 157 + // eslint-disable-next-line no-magic-numbers 158 + 0.1, 159 + ); 160 + return { z, degrees, minutes }; 161 + } 162 + 163 + /** 164 + * Return the bisection of the angle between the two given `ZodiacAngle`s. 165 + * @param a The first `ZodiacAngle` of the angle to bisect. 166 + * @param b The second `ZodiacAngle` of the angle to bisect. 167 + * @returns The bisection of the angle between the two given `ZodiacAngle`s. 168 + */ 169 + export function bisectZodiacAngle(a: ZodiacAngle, b: ZodiacAngle): ZodiacAngle { 170 + const aDeg = zodiacAngle2Deg(a); 171 + const bDeg = zodiacAngle2Deg(b); 172 + // eslint-disable-next-line no-magic-numbers 173 + const cDeg = (aDeg + bDeg) * 0.5; 174 + return deg2ZodiacAngle(cDeg); 175 + }