aboutsummaryrefslogtreecommitdiff

Fieldwork ยท Electrophysics

An interactive 3D learning lab built with TypeScript, Vite, Three.js, and KaTeX. PLAN.md controls the subject scope. The only implemented subject is Electric flux and charge.

Run locally

Use Node 22 (at least 22.12.0), as specified in .nvmrc.

npm install
npm run dev

Open the local URL printed by Vite. npm run build type-checks and builds the app into dist/; npm run preview serves that build. npm run typecheck runs TypeScript separately.

No test scripts or test files were created for this implementation. The pre-existing test commands and dependencies in package.json are retained, but there is no test suite in the current working tree.

The experiment

  • Change a point charge from โˆ’5 to +5 nC and move it along the x-axis.
  • Choose a sphere or cube and change its radius or half side length.
  • Compare enclosed charge, surface area, and exact net flux.
  • Try positive, negative, and external-charge presets.
  • Toggle the surface, field lines, and outward normals.
  • Drag to orbit; scroll to zoom. Focus the canvas and use arrow keys to orbit, +/โˆ’ to zoom, and Home to reset. All other controls are native keyboard-operable inputs.

The model assumes a stationary ideal point charge in vacuum. The imaginary Gaussian surface is centered at the origin. Geometry uses metres, physics uses SI units, and the interface presents charge in nanocoulombs. A nonzero charge exactly on the surface produces an undefined enclosed-charge/flux result because its field is singular there. The visible marker's radius does not change the point-charge model. Sampled lines and fixed-size arrows illustrate field direction; total flux is calculated analytically, never by counting those lines.

Reference: docs/theory/3Electric flux and charge.pdf, sections 3.2โ€“3.4. Lesson copy and graphics are original, based on these definitions.

Add another 3D model

  1. Enable its subject in PLAN.md first.
  2. Create src/models/<model-id>/ with separate physics, state, scene, and view modules.
  3. Implement ModelDefinition from src/core/model.ts. mount(host, { i18n }) renders into its host and returns a ModelInstance whose dispose() releases listeners, GPU resources, and observers.
  4. Add its title, controls, explanations, accessibility text, and messages to src/i18n/en.ts.
  5. Register a lazy-loading definition in src/models/registry.ts. The current shell mounts its first entry. Add model selection to the shell when a second enabled model is implemented; each model's physics and scene remain independent.

src/models/electric-flux/physics.ts has no dependency on DOM, Three.js, or translations. Rendering consumes physical field directions; it does not own the equations or measurement state. Scenes render only when controls, state, or viewport size changes.

Add a language

English (en) is the default and fallback. User-facing copy is in src/i18n/en.ts, accessed through stable typed keys. Messages accept named parameters and numbers use Intl.NumberFormat.

To support another language, add its catalog and register its BCP 47 locale in src/i18n/index.ts. Pass that locale to createI18n in the shell. Missing messages fall back to English. No physics or model components need rewriting. Add a language selector only once another language has been requested and supplied.

Layout

src/core/                    Shared model lifecycle contract
src/i18n/                    English catalog, locale registry, formatting
src/models/registry.ts       Enabled, lazy-loaded models
src/models/electric-flux/    Pure physics, state, Three.js scene, lesson view
src/ui/                      Shared interface graphics
src/main.ts                  Application shell
src/style.css                Responsive presentation