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/experiments.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 '')
| -rw-r--r-- | src/experiments.ts | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/src/experiments.ts b/src/experiments.ts index 6045a88..d4d2bc2 100644 --- a/src/experiments.ts +++ b/src/experiments.ts @@ -1,3 +1,4 @@ +import { getLanguage, word } from './i18n'; import { electricField, type Charge } from './physics/electricField'; import { capacitor, conductor, forceOn, gaussianFlux, pairEnergy, potential, semiconductor } from './physics/models'; @@ -31,7 +32,15 @@ export function format(value: number, digits = 2): string { if (Math.abs(value) < 0.01 || Math.abs(value) >= 1e5) return value.toExponential(2); return value.toLocaleString('en', { maximumFractionDigits: digits }); } -const metric = (label: string, value: number, unit: string): Measurement => ({ label, value: format(value), unit }); +export function formatDisplay(value: number, digits = 2): string { + if (getLanguage() !== 'da') return format(value, digits); + if (!Number.isFinite(value)) return 'Udefineret'; + if (value === 0) return '0'; + const locale = 'da-DK'; + if (Math.abs(value) < 0.01 || Math.abs(value) >= 1e5) return value.toLocaleString(locale, { notation: 'scientific', maximumFractionDigits: 2 }); + return value.toLocaleString(locale, { maximumFractionDigits: digits }); +} +const metric = (label: string, value: number, unit: string): Measurement => ({ label, value: formatDisplay(value), unit }); const textbook = (page: string) => ({ title: 'OpenStax · University Physics', url: `https://openstax.org/books/university-physics-volume-2/pages/${page}` }); export function chargePair(p: Parameters): Charge[] { const half = number(p, 'separation') / 2; @@ -68,7 +77,7 @@ export const experiments: Experiment[] = [ const charges = chargePair(p); const e = electricField({ x: 0, y: 0, z: 0 }, charges); const f = forceOn(charges[1], [charges[0]]); - return [metric('|E| at origin', Math.hypot(e.x, e.y, e.z), 'N/C'), metric('|Force on right charge|', Math.hypot(f.x, f.y, f.z) * 1e9, 'nN'), { label: 'Interaction', value: p.configuration === 'like' ? 'Repulsive' : 'Attractive', unit: '' }]; + return [metric('|E| at origin', Math.hypot(e.x, e.y, e.z), 'N/C'), metric('|Force on right charge|', Math.hypot(f.x, f.y, f.z) * 1e9, 'nN'), { label: 'Interaction', value: word(p.configuration === 'like' ? 'Repulsive' : 'Attractive'), unit: '' }]; }, }, { @@ -85,7 +94,7 @@ export const experiments: Experiment[] = [ measure: p => { const q = { x: number(p, 'position'), y: 0, z: 0, coulombs: number(p, 'charge') * 1e-9 }; const flux = gaussianFlux([q], number(p, 'radius')); - return [metric('Net electric flux', flux, 'N·m²/C'), metric('Enclosed charge', Number.isNaN(flux) ? NaN : Math.abs(q.x) < number(p, 'radius') ? q.coulombs * 1e9 : 0, 'nC'), { label: 'Source location', value: Number.isNaN(flux) ? 'On surface' : Math.abs(q.x) < number(p, 'radius') ? 'Inside' : 'Outside', unit: '' }]; + return [metric('Net electric flux', flux, 'N·m²/C'), metric('Enclosed charge', Number.isNaN(flux) ? NaN : Math.abs(q.x) < number(p, 'radius') ? q.coulombs * 1e9 : 0, 'nC'), { label: 'Source location', value: word(Number.isNaN(flux) ? 'On surface' : Math.abs(q.x) < number(p, 'radius') ? 'Inside' : 'Outside'), unit: '' }]; }, }, { |