diff options
Diffstat (limited to 'src/scene/experiments.ts')
| -rw-r--r-- | src/scene/experiments.ts | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/src/scene/experiments.ts b/src/scene/experiments.ts index 67d0322..f48c984 100644 --- a/src/scene/experiments.ts +++ b/src/scene/experiments.ts @@ -3,13 +3,14 @@ import { chargePair, carrierModel, number, plateModel, wireModel, type Experimen import { electricField, type Charge, type Point } from '../physics/electricField'; import { forceOn, pairEnergy, potential } from '../physics/models'; import { arrow, box, colours, grid, label, line, sphere } from './primitives'; +import { buildTestScene } from './test4'; export type Animate = (delta: number) => void; const still: Animate = () => {}; function signedCharge(group: THREE.Group, charge: Charge) { const colour = charge.coulombs >= 0 ? colours.positive : colours.negative; sphere(group, charge, 0.2, colour); - label(group, `${charge.coulombs >= 0 ? '+' : '−'}${Math.abs(charge.coulombs * 1e9).toFixed(1)} nC`, { ...charge, y: charge.y + 0.55 }, colour, 1.25); + label(group, String.raw`$${charge.coulombs >= 0 ? '+' : '-'}${Math.abs(charge.coulombs * 1e9).toFixed(1)}\,\mathrm{nC}$`, { ...charge, y: charge.y + 0.55 }, colour, 1.25); } function compressedFieldArrow(group: THREE.Group, position: Point, direction: Point, colour = colours.field) { const strength = Math.hypot(direction.x, direction.y, direction.z); @@ -28,7 +29,7 @@ function fieldScene(group: THREE.Group, p: Parameters) { } const force = forceOn(charges[1], [charges[0]]); arrow(group, { ...charges[1], y: 0.8 }, force, 1.3, colours.gold); - label(group, 'F on right charge', { x: charges[1].x, y: 1.5, z: 0 }, colours.gold, 2); + label(group, String.raw`$\vec F$ on right charge`, { x: charges[1].x, y: 1.5, z: 0 }, colours.gold, 2); sphere(group, { x: 0, y: 0, z: 0 }, 0.06, colours.gold); label(group, 'Origin', { x: 0, y: 0, z: 0.45 }, colours.muted, 0.9); } @@ -71,9 +72,9 @@ function energyScene(group: THREE.Group, p: Parameters) { line(group, [{ x: -2.5, y: 0, z: -1.5 }, { x: 3.5, y: 0, z: -1.5 }], colours.muted); line(group, [{ x: -3, y: -5.5, z: -1.5 }, { x: -3, y: 5.5, z: -1.5 }], colours.muted, 0.5); sphere(group, { x: -3 + r, y: pairEnergy(3e-9, q, r) * 1e9 / 20, z: -1.5 }, 0.12, colours.gold); - label(group, 'U(r) · 20 nJ per height unit', { x: 0, y: 5.7, z: -1.5 }, colours.field, 3.9); + label(group, String.raw`$U(r)$ · 20 nJ per height unit`, { x: 0, y: 5.7, z: -1.5 }, colours.field, 3.9); label(group, '0 energy', { x: 4, y: 0, z: -1.5 }, colours.muted, 1.5); - label(group, `r = ${r.toFixed(2)} m`, { x: 0, y: -0.65, z: 1.5 }, colours.muted, 2); + label(group, String.raw`$r = ${r.toFixed(2)}\,\mathrm m$`, { x: 0, y: -0.65, z: 1.5 }, colours.muted, 2); } function potentialScene(group: THREE.Group, p: Parameters) { @@ -154,8 +155,8 @@ function plateScene(group: THREE.Group, p: Parameters, dielectric: boolean) { } } line(group, [{ x: -halfGap, y: -side, z: 0 }, { x: halfGap, y: -side, z: 0 }], colours.muted); - label(group, `d = ${number(p, 'gap').toFixed(1)} mm (gap ×50)`, { x: 0, y: -side - 0.45, z: 0 }, colours.muted, 2.5); - label(group, `${c.voltage.toFixed(2)} V · ${p.connection === 'isolated' ? 'isolated' : 'supply connected'}`, { x: 0, y: side + 0.8, z: 0 }, colours.field, 3); + label(group, String.raw`$d = ${number(p, 'gap').toFixed(1)}\,\mathrm{mm}$ (gap $\times50$)`, { x: 0, y: -side - 0.45, z: 0 }, colours.muted, 2.5); + label(group, String.raw`$${c.voltage.toFixed(2)}\,\mathrm V$ · ${p.connection === 'isolated' ? 'isolated' : 'supply connected'}`, { x: 0, y: side + 0.8, z: 0 }, colours.field, 3); grid(group, -3.2); } @@ -183,7 +184,7 @@ function currentScene(group: THREE.Group, p: Parameters): Animate { arrow(group, { x: -Math.sign(model.current) * 1.1, y: radius + 0.8, z: 0 }, { x: model.current, y: 0, z: 0 }, 2.2, colours.field); label(group, model.current === 0 ? 'No net current' : 'Conventional current', { x: 0, y: radius + 1.5, z: 0 }, colours.field, 2.8); arrow(group, { x: -Math.sign(model.electronDrift) * 1.1, y: -radius - 0.65, z: 0 }, { x: model.electronDrift, y: 0, z: 0 }, 2.2, colours.negative); - label(group, 'Electron drift · displayed ×600', { x: 0, y: -radius - 1.1, z: 0 }, colours.negative, 3.3); + label(group, String.raw`Electron drift · displayed $\times600$`, { x: 0, y: -radius - 1.1, z: 0 }, colours.negative, 3.3); const velocity = model.electronDrift * 600 * 3; return delta => { for (const electron of carriers) { @@ -201,11 +202,11 @@ function semiconductorScene(group: THREE.Group, p: Parameters): Animate { box(group, { x: 0, y: -bandEdge - 0.4, z: 0 }, { x: 7, y: 0.8, z: 3 }, colours.positive, 0.12); line(group, [{ x: -3.5, y: 0, z: 1.6 }, { x: 3.5, y: 0, z: 1.6 }], colours.muted, 0.7); line(group, [{ x: -3.6, y: s.fermiShift * 3, z: 1.65 }, { x: 3.6, y: s.fermiShift * 3, z: 1.65 }], colours.gold); - label(group, 'EF', { x: 4, y: s.fermiShift * 3, z: 1.65 }, colours.gold, 0.7); - label(group, 'Ei ≈ midgap', { x: -4.4, y: 0, z: 1.65 }, colours.muted, 1.7); + label(group, String.raw`$E_F$`, { x: 4, y: s.fermiShift * 3, z: 1.65 }, colours.gold, 0.7); + label(group, String.raw`$E_i\approx\text{midgap}$`, { x: -4.4, y: 0, z: 1.65 }, colours.muted, 1.7); label(group, 'Conduction band', { x: 0, y: bandEdge + 1.1, z: 0 }, colours.negative, 2.8); label(group, 'Valence band', { x: 0, y: -bandEdge - 1.1, z: 0 }, colours.positive, 2.8); - label(group, 'Eg = 1.12 eV', { x: 4.1, y: 0, z: -1.3 }, colours.muted, 1.8); + label(group, String.raw`$E_g=1.12\,\mathrm{eV}$`, { x: 4.1, y: 0, z: -1.3 }, colours.muted, 1.8); line(group, [{ x: 3.8, y: -bandEdge, z: -1.3 }, { x: 3.8, y: bandEdge, z: -1.3 }], colours.muted); const particles: { mesh: THREE.Mesh; base: THREE.Vector3; phase: number }[] = []; for (const [density, sign] of [[s.electrons, 1], [s.holes, -1]]) { @@ -240,6 +241,7 @@ export function buildExperiment(group: THREE.Group, id: ExperimentId, p: Paramet case 'dielectric': plateScene(group, p, true); break; case 'current': return currentScene(group, p); case 'semiconductor': return semiconductorScene(group, p); + default: return buildTestScene(group, id, p); } return still; } |