aboutsummaryrefslogtreecommitdiff
path: root/src/i18n/narrate.ts
diff options
context:
space:
mode:
authorLalleSX2026-10-24 14:58:21 +0200
committerLalleSX2026-10-24 14:58:21 +0200
commit73b09270c54acab810c10a80bed1d77c1a7bb2ab (patch)
treee5bae1180c9a76345cc7779a24988875542d2dd9 /src/i18n/narrate.ts
parentAdd tests for math rendering and interactive scenes; update navigation and viewport handling (diff)
download3D-Electrophysics-main.tar.gz
3D-Electrophysics-main.zip
Tilføj danskHEADmain
Diffstat (limited to '')
-rw-r--r--src/i18n/narrate.ts41
1 files changed, 41 insertions, 0 deletions
diff --git a/src/i18n/narrate.ts b/src/i18n/narrate.ts
new file mode 100644
index 0000000..e112b42
--- /dev/null
+++ b/src/i18n/narrate.ts
@@ -0,0 +1,41 @@
+import { formatDisplay, number, type Parameters, type TestId } from '../experiments';
+import { assemblyState, centralState, conservationState, motionState, rotationState } from '../test4';
+
+const n = (value: number) => formatDisplay(value);
+
+export function narrate(id: TestId, p: Parameters): string {
+ if (id === 'test-work') {
+ const work = n(motionState(p).work * 1e9);
+ const route = p.path === 'curved'
+ ? 'Den krumme rute tilføjer bevægelse på tværs, men det endelige arbejde forbliver det samme.'
+ : 'Den rette rute gør skalarproduktet mellem kraft og forskydning let at se.';
+ return `${route} Ved b udfører feltet ${work} nJ arbejde; $U$ falder med det beløb.`;
+ }
+ if (id === 'test-conservation') {
+ const s = conservationState(p);
+ return String.raw`Ved $r$ = ${n(s.r)} m er $U$ = ${n(s.u * 1e9)} nJ og $K$ = ${n(s.kinetic * 1e9)} nJ. Summen forbliver ${n(s.total * 1e9)} nJ. Det hidtidige arbejde er stigningen i $K$.`;
+ }
+ if (id === 'test-central') {
+ const s = centralState(p);
+ return s.rb === Infinity
+ ? String.raw`I det uendelige er $U_b=0$ eksakt. $W_{a\infty}=U_a$ = ${n(s.work * 1e9)} nJ. Diagrammets kant er kun en visuel fortsættelse mod uendelighed.`
+ : String.raw`Feltet udfører ${n(s.work * 1e9)} nJ arbejde fra $r_a$ = ${s.ra} m til $r_b$ = ${s.rb} m. Skift af fortegn på en af ladningerne vender $U$ og $W$.`;
+ }
+ if (id === 'test-assembly') {
+ const s = assemblyState(p);
+ return String.raw`Trin ${s.stage}: ${s.stage * (s.stage - 1) / 2} forskellige par er til stede. $U_{123}$ = ${n(s.base * 1e9)} nJ; tilføjelse af $q_0$ ændrer den med ${n(s.extra * 1e9)} nJ. Negativ parenergi betyder modsatte fortegn.`;
+ }
+ if (id === 'test-uniform') {
+ const m = motionState(p);
+ return String.raw`$\alpha = ${number(p, 'angle')}^\circ$ projicerer $s$ = ${m.s} m over på $\Delta x$ = ${n(m.dx)} m. $W$ = ${n(m.work * 1e9)} nJ og $U_b$ = ${n(-m.work * 1e9)} nJ med $U_a=0$.`;
+ }
+ const s = rotationState(p);
+ const degrees = s.theta * 180 / Math.PI;
+ if (s.field === 0) return String.raw`$E=0$: begge kræfter, kraftmomentet, rotationsarbejdet og dipolens vekselvirkningsenergi forsvinder. Der er ingen foretrukken orientering.`;
+ if (degrees < 0.01) return String.raw`Indrettet ved $0^\circ$: $U$ er minimum, og kraftmomentet er nul. Det er stabil ligevægt; en lille drejning giver et tilbageførende kraftmoment.`;
+ if (degrees > 179.99) return String.raw`Modsat ved $180^\circ$: $U$ er maksimum, og kraftmomentet er nul. Det er ustabil ligevægt; en lille drejning fører den væk fra denne position.`;
+ const follow = Math.abs(degrees - 90) < 0.01
+ ? String.raw`Ved $90^\circ$ er $U=0$ per valg, men kraftmomentet er størst: det er ikke ligevægt.`
+ : 'Følg punktet på energikurven, mens du drejer.';
+ return String.raw`Ved $\theta = ${n(degrees)}^\circ$ er $\tau_z$ = ${n(s.torqueZ * 1e9)} nN·m. Den negative z-retning mindsker $\theta$ mod indretning. ${follow}`;
+}