aboutsummaryrefslogtreecommitdiff
path: root/src/scene/experiments.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/scene/experiments.ts')
-rw-r--r--src/scene/experiments.ts22
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;
}