Skip to content

Commit f8e27ec

Browse files
authored
Update index.html
1 parent e340ba5 commit f8e27ec

1 file changed

Lines changed: 277 additions & 0 deletions

File tree

index.html

Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,253 @@ <h4 style="font-size:160%;margin:7px">Trigonometry</h4>
624624
<br>
625625
<br>
626626
<br>
627+
<div>
628+
<script>
629+
630+
// ---- Trigonometry ----
631+
// A lightweight approximation-based lookup function
632+
633+
634+
// The lookup table
635+
636+
const trig = {
637+
"rad(1.6)": {
638+
"sin": "1"
639+
"cos": "0"
640+
"tan": "undefined"
641+
"deg": "90.0"
642+
},
643+
644+
645+
"rad(1.467)": {
646+
"sin": "0.991"
647+
"cos": "0.131"
648+
"tan": "7.596"
649+
"deg": "82.5"
650+
651+
}
652+
653+
}
654+
655+
// Helper: Finds closest rad(x) match for given function (sin or cos)
656+
function findClosestRad(value, funcType) {
657+
let closestKey = null;
658+
let minDiff = Infinity;
659+
660+
for (const key in trig) {
661+
if (!trig[key][funcType]) continue;
662+
const keyMatch = key.match(/rad\(([\d.]+)\)/);
663+
if (!keyMatch) continue;
664+
665+
const radVal = parseFloat(keyMatch[1]);
666+
const diff = Math.abs(radVal - value);
667+
668+
if (diff < minDiff) {
669+
minDiff = diff;
670+
closestKey = key;
671+
}
672+
673+
674+
if (closestKey) {
675+
const approxVal = trig[closestKey][funcType].value?.approx ?? trig[closestKey][funcType].value;
676+
return `${funcType}(${closestKey}) ≈ ${approxVal}`;
677+
}
678+
}
679+
680+
function querySin(input) {
681+
// Normalize input: remove spaces, handle cases like "sin 0533" or "sin(0.533)"
682+
const match = input.match(/sin\s*\(?([0-9.]+)\)?/i);
683+
if (!match) return "Invalid input. Format: sin 0.533 or sin(0.533)";
684+
685+
const x = parseFloat(match[1]);
686+
const radKey = `rad(${x.toFixed(3)})`;
687+
688+
// Case 1: Exact match
689+
if ([radKey] && [radKey].sin) {
690+
return `sin(${x}) ≈ ${trig[radKey].sin.value?.approx ?? trig[radKey].sin.value}`;
691+
}
692+
693+
// Case 2A: 1.6 > x > 0.8 OR 0.1 > x > 0
694+
if ((x > 0.8 && x < 1.6) || (x > 0 && x < 0.1)) {
695+
// Find closest match in trig table
696+
const closest = findClosestRad(x, 'sin');
697+
return `sin(${x}) ≈ ${closest}`;
698+
}
699+
700+
// Case 2B: 0.8 > x > 0.1 → Reflect to cosine
701+
if (x > 0.1 && x < 0.8) {
702+
const reflected = (1.6 - x).toFixed(3);
703+
const reflectedKey = `rad(${reflected})`;
704+
if (trig[reflectedKey] && trig[reflectedKey].cos) {
705+
return `sin(${x}) ≈ cos(${reflected}) ≈ ${trig[reflectedKey].cos.value?.approx ?? trig[reflectedKey].cos.value}`;
706+
}
707+
const closest = findClosestRad(reflected, 'cos');
708+
return `sin(${x}) ≈ cos(${reflected}) ≈ ${closest}`;
709+
}
710+
711+
}
712+
713+
function queryCos(input) {
714+
// Normalize and extract the value from input like "cos 0.533" or "cos(0.533)"
715+
const match = input.match(/cos\s*\(?([0-9.]+)\)?/i);
716+
if (!match) return; // Invalid input format
717+
718+
const x = parseFloat(match[1]);
719+
const radKey = `rad(${x.toFixed(3)})`;
720+
721+
// Case 1: Exact match
722+
if (trig[radKey] && trig[radKey].cos) {
723+
return `cos(${x}) ≈ ${trig[radKey].cos.value?.approx ?? trig[radKey].cos.value}`;
724+
}
725+
726+
// Case 2A: 1.6 > x > 0.8 OR 0.1 > x > 0
727+
if ((x > 0.8 && x < 1.6) || (x > 0 && x < 0.1)) {
728+
const closest = findClosestRad(x, 'cos');
729+
return `cos(${x}) ≈ ${closest}`;
730+
}
731+
732+
// Case 2B: 0.8 > x > 0.1 → Reflect to sin(1.6 - x)
733+
if (x > 0.1 && x < 0.8) {
734+
const reflected = (1.6 - x).toFixed(3);
735+
const reflectedKey = `rad(${reflected})`;
736+
737+
if (trig[reflectedKey] && trig[reflectedKey].sin) {
738+
return `cos(${x}) ≈ sin(${reflected}) ≈ ${trig[reflectedKey].sin.value?.approx ?? trig[reflectedKey].sin.value}`;
739+
}
740+
741+
const closest = findClosestRad(reflected, 'sin');
742+
return `cos(${x}) ≈ sin(${reflected}) ≈ ${closest}`;
743+
}
744+
}
745+
746+
function queryTan(input) {
747+
// Normalize and extract the value from input like "tan 0.533" or "tan(0.533)"
748+
const match = input.match(/tan\s*\(?([0-9.]+)\)?/i);
749+
if (!match) return; // Invalid input format
750+
751+
const x = parseFloat(match[1]);
752+
const radKey = `rad(${x.toFixed(3)})`;
753+
754+
// Case 1: Exact match
755+
if (trig[radKey] && trig[radKey].tan) {
756+
return `tan(${x}) ≈ ${trig[radKey].tan.value?.approx ?? trig[radKey].tan.value}`;
757+
}
758+
759+
// Case 2A: 1.6 > x > 0.8 OR 0.1 > x > 0
760+
if ((x > 0.8 && x < 1.6) || (x > 0 && x < 0.1)) {
761+
const closest = findClosestRad(x, 'tan');
762+
return `tan(${x}) ≈ ${closest}`;
763+
}
764+
765+
// Case 2B: 0.8 > x > 0.1 → Reflect
766+
if (x > 0.1 && x < 0.8) {
767+
const reflected = (1.6 - x).toFixed(3);
768+
const reflectedKey = `rad(${reflected})`;
769+
770+
if (trig[reflectedKey] && trig[reflectedKey].tan) {
771+
const reflectedTan = parseFloat(trig[reflectedKey].tan.value?.approx ?? trig[reflectedKey].tan.value);
772+
return `tan(${x}) ≈ 1 / tan(${reflected})`;
773+
}
774+
775+
const fallback = findClosestRad(reflected, 'tan');
776+
return `tan(${x}) ≈ 1 / tan(${reflected}) ≈ 1 / (${fallback})`;
777+
}
778+
}
779+
780+
function findClosestValueMatch(value, funcType) {
781+
let bestMatch = null;
782+
let minDiff = Infinity;
783+
784+
for (const key in trig) {
785+
const approx = trig[key][funcType]?.value?.approx ?? trig[key][funcType]?.value;
786+
if (!approx) continue;
787+
788+
const diff = Math.abs(parseFloat(approx) - value);
789+
if (diff < minDiff) {
790+
minDiff = diff;
791+
bestMatch = { angle: key, approx };
792+
}
793+
}
794+
795+
return bestMatch;
796+
}
797+
798+
799+
function queryAsin(input) {
800+
// Normalize and extract the value: "asin 0.5" or "asin(0.5)"
801+
const match = input.match(/asin\s*\(?([0-9./\s-]+)\)?/i);
802+
if (!match) return; // Invalid format
803+
804+
const inputStr = match[1].trim();
805+
const x = parseFloat(eval(inputStr.replace(/(\d+)/g, 'Math.sqrt($1)'))); // handles √2 etc.
806+
807+
if (isNaN(x) || x <= 0 || x >= 1) return; // asin(x) only defined for 0 < x < 1
808+
809+
// Case A: x > 0.707 or x < 0.1 → search sin column directly
810+
if (x > 0.707 || x < 0.1) {
811+
const bestMatch = findClosestValueMatch(x, 'sin');
812+
if (bestMatch) return `asin(${inputStr}) ≈ ${bestMatch.angle}`;
813+
}
814+
815+
// Case B: 0.1 < x < 0.707 → search cos column and reflect
816+
const bestCosMatch = findClosestValueMatch(x, 'cos');
817+
if (bestCosMatch) {
818+
const angleMatch = bestCosMatch.angle;
819+
const angleNum = parseFloat(angleMatch.match(/[\d.]+/)[0]);
820+
const reflected = (1.6 - angleNum).toFixed(3);
821+
return `asin(${inputStr}) ≈ 1.6 - ${angleMatch} ≈ rad(${reflected})`;
822+
}
823+
}
824+
825+
function queryAcos(input) {
826+
// Normalize and extract the value: "acos 0.5" or "acos(0.5)"
827+
const match = input.match(/acos\s*\(?([0-9./\s-]+)\)?/i);
828+
if (!match) return; // Invalid format
829+
830+
const inputStr = match[1].trim();
831+
const x = parseFloat(eval(inputStr.replace(/(\d+)/g, 'Math.sqrt($1)')));
832+
833+
if (isNaN(x) || x <= 0 || x >= 1) return; // acos(x) only defined for 0 < x < 1
834+
835+
// Case A: x < 0.707 or x > 0.996 → match cos directly
836+
if (x < 0.707 || x > 0.996) {
837+
const bestMatch = findClosestValueMatch(x, 'cos');
838+
if (bestMatch) return `acos(${inputStr}) ≈ ${bestMatch.angle}`;
839+
}
840+
841+
// Case B: 0.707 < x < 0.996 → reflect from sin column
842+
const bestSinMatch = findClosestValueMatch(x, 'sin');
843+
if (bestSinMatch) {
844+
const angleNum = parseFloat(bestSinMatch.angle.match(/[\d.]+/)[0]);
845+
const reflected = (1.6 - angleNum).toFixed(3);
846+
return `acos(${inputStr}) ≈ 1.6 - ${bestSinMatch.angle} ≈ rad(${reflected})`;
847+
}
848+
}
849+
850+
function queryAtan(input) {
851+
// Normalize and extract the value: "atan 0.5" or "atan(0.5)"
852+
const match = input.match(/atan\s*\(?([0-9./\s-]+)\)?/i);
853+
if (!match) return; // Invalid format
854+
855+
const inputStr = match[1].trim();
856+
const x = parseFloat(eval(inputStr.replace(/(\d+)/g, 'Math.sqrt($1)')));
857+
858+
if (isNaN(x) || x <= 0 || x >= 7.6) return; // Domain cutoffs from your spec
859+
860+
// Case A: x > 1 or x < 0.089 → direct match
861+
if (x > 1 || x < 0.089) {
862+
const bestMatch = findClosestValueMatch(x, 'tan');
863+
if (bestMatch) return `atan(${inputStr}) ≈ ${bestMatch.angle}`;
864+
}
865+
866+
// Case B: 0.089 < x < 1 → invert to 1/x and search tan table
867+
const reciprocal = 1 / x;
868+
const bestMatch = findClosestValueMatch(reciprocal, 'tan');
869+
if (bestMatch) return `atan(${inputStr}) ≈ ${bestMatch.angle}`;
870+
}
871+
872+
</script>
873+
</div>
627874
<div>
628875
<p style="margin:12px;">Area of a triangle:
629876
<br>
@@ -1978,6 +2225,36 @@ <h6 style="font-size:160%;margin:7px">Area of a circle</h6>
19782225
<br>
19792226
<br>
19802227
<br>
2228+
<label style="margin:12px;" for="test1">test1:</label>
2229+
<input id="test1" type="number" value="1" step="any" />
2230+
<br>
2231+
<label style="margin:12px;" for="test2">test2:</label>
2232+
<input id="test2" type="number" value="1" step="any" />
2233+
2234+
<script>
2235+
function test(test1, test2) {
2236+
return test1 + test2 * test3 ;
2237+
}
2238+
2239+
function updateTestVolume() {
2240+
const test1 = parseFloat(document.getElementById('test1').value);
2241+
const test2 = parseFloat(document.getElementById('test2').value);
2242+
const test3 = queryTan(1.2);
2243+
2244+
if (isNaN(test1) || isNaN(test2)) {
2245+
document.getElementById('test-volume').innerText = '';
2246+
return;
2247+
}
2248+
2249+
document.getElementById('test-volume').innerText =
2250+
`Volume: ${testVolume(test1, test2).toFixed(5)} cubic units`;
2251+
}
2252+
2253+
document.getElementById('test1').addEventListener('input', updateTestVolume);
2254+
document.getElementById('test2').addEventListener('input', updateTestVolume);
2255+
</script>
2256+
<p style="margin:12px;" id="test-volume"></p>
2257+
</div>
19812258
<div>
19822259
<h17 style="font-size:160%;margin:7px">Geometry Calculator Android App</h17>
19832260
<br>

0 commit comments

Comments
 (0)