diff options
| author | LalleSX | 2026-10-24 14:58:21 +0200 |
|---|---|---|
| committer | LalleSX | 2026-10-24 14:58:21 +0200 |
| commit | 73b09270c54acab810c10a80bed1d77c1a7bb2ab (patch) | |
| tree | e5bae1180c9a76345cc7779a24988875542d2dd9 /src/i18n/narrate.ts | |
| parent | Add tests for math rendering and interactive scenes; update navigation and viewport handling (diff) | |
| download | 3D-Electrophysics-73b09270c54acab810c10a80bed1d77c1a7bb2ab.tar.gz 3D-Electrophysics-73b09270c54acab810c10a80bed1d77c1a7bb2ab.zip | |
Diffstat (limited to 'src/i18n/narrate.ts')
| -rw-r--r-- | src/i18n/narrate.ts | 41 |
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}`; +} |