๐ Reference
This is the API surface of Helion as exported from src/index.js. Import via ES modules โ no build step required:
import { Simulation, Vec3, DiscreteScalarField, SurfaceVisualization, GaussianImpulse, SchrodingerSolver} from "helion";// or via importmap in the browserimport { Simulation } from "../../../src/index.js";See also: Architecture for concepts (State / apply / evolve / bind) and Getting Started for a first simulation.
1. Core โ Simulation, Binding, Registry
Section titled โ1. Core โ Simulation, Binding, RegistryโSimulation
Section titled โSimulationโFactory: Simulation.with(options) โ Simulation instance. All methods are chainable.
| Option | Type | Default | Description |
|---|---|---|---|
htmlDivId | string | auto-created | Container div id |
viewport.aspectRatio | string | "1 / 1" | CSS aspect-ratio for wrapper |
camera.position | Vec3 | (3,3,3) | Initial camera position |
camera.target | Vec3 | (0,0,0) | OrbitControls target |
camera.fieldOfView | number | 50 | Perspective FOV |
camera.orthographic | boolean | false | Orthographic disables rotate/pan (only zoom) |
camera.controls | boolean | true | OrbitControls enabled |
scene.background | ThreeJsScene.Background | TRANSPARENT | PLAIN, FOG, TRANSPARENT, STARS |
scene.backgroundColor | hex | 0x0088ff | Used with PLAIN |
scene.scale | number | 1 | Physics โ world mapping |
lighting.enabled / shadows | boolean | true / false | Three.js lights/shadows |
headUpDisplay.enabled | boolean | true | HUD overlay (simulation.setLatexTitle renders via renderMath in titleDiv) |
infoPanel.text | string | "" | Info panel HTML |
parameterMenuCollapsed | boolean | true | Controls collapsed |
Chaining API:
Simulation.with({ htmlDivId: "container", scale: 1e-9, headUpDisplay: true }) .runsEvery(0.016) // wall-clock step .advancesBy(0.01) // simulated time per step .atSpeed(1) // timeScale multiplier .substeps(1) // steps per clock tick .onStep((clock, dt) => { // fixed-step mode field.evolve(solver, dt); }) // or: .maxOutCpu((clock) => field.evolve(solver, dt), 30, 10) .onFrame((t) => {}) .bind(model.alwaysWith(view)) // continuous sync .bind(model.onceWith(view)) // one-shot sync .append(new Slider("k").withRange(...)) // controls .provideAxesAround(view) // axes + AxesUI .frameSceneOn(view, { padding: 1.2 }) .setOrthographic(true) // switch to orthographic top-down for 2D .removeAxes() / setAxesVisible(false) // hide axes for 2D .setLatexTitle("\\phi = n\\cdot137.5\\pi/180") // MathJax/KaTeX via renderMath in titleDiv .setTextTitle("plain text") .clearTitle() .setupGraphWith({ dataDefinition, title }) .plot([t, value]) .withMouseClickEventListener() // click โ start/pause/reset .appendStartStopResetUI() .onReset(() => field.reset()) .start() // .stop(), .reset(), .isRunningrunsEvery vs advancesBy: scheduling interval vs simulated time. maxOutCpu(fn, minFrameRate=30, iterationsPerFrame=10) is the adaptive alternative to onStep.
MathPhysicsModelBehavior / Binding / Transformation
Section titled โMathPhysicsModelBehavior / Binding / Transformationโclass Transformation { applyTo(model) {} }
model.apply(transformation) // โ transformation.applyTo(model)model.and(other) // โ BodyPairmodel.alwaysWith(view) // โ Binding(ALWAYS)model.onceWith(view) // โ Binding(ONCE)simulation.bind(binding) // checks view.canBindTo(model)Registry
Section titled โRegistryโnew Registry({ id, label, entries: { Key: () => value } })registry.get(name); registry.names; registry.label; registry.idUsed for ColorMappers, ColorLayers, ShapesFactory.
2. Math primitives
Section titled โ2. Math primitivesโVec3(x=0, y=0, z=0) / Vec2(x=0, y=0)
Section titled โVec3(x=0, y=0, z=0) / Vec2(x=0, y=0)โMutable vectors: clone(), set, copy, add, sub, addScaledVector, cross, dot, length, normalize, multiplyScalar, distanceTo, projectOnVector, random().
Complex(re, im)
Section titled โComplex(re, im)โclone(), phase, abs/magnitude/absSquared, multiply(c).
Interval(from=-Infinity, to=Infinity)
Section titled โInterval(from=-Infinity, to=Infinity)โrange, normalize(value), scaleUnitParameter(u) โ maps [0,1] โ interval, shrinkTo(value).
Range(from, to, stepSize=0.1)
Section titled โRange(from, to, stepSize=0.1)โIterable: for (const x of new Range(0,10,0.5)). count.
Domain(xRange=[-0.5,0.5], yRange=[-0.5,0.5])
Section titled โDomain(xRange=[-0.5,0.5], yRange=[-0.5,0.5])โHolds xRange: Interval, yRange: Interval.
Helpers
Section titled โHelpersโlinspace(start, stop, num), meshgrid(x, y), factorial(n), degToRad, toCartesian(r,theta,phi), generateUUID(), normalDistribution(mu,sigma), uniform(min,max), randomInt(min,max).
3. Fields and Surfaces
Section titled โ3. Fields and SurfacesโField โ abstract
Section titled โField โ abstractโsample(u, v, target) โ duck-typed target (number, Complex, Vec3).
DiscreteScalarField({ nx=100, ny=100 })
Section titled โDiscreteScalarField({ nx=100, ny=100 })โfield.nx; field.ny; field.data; // Float32Arrayfield.index(x,y); field.valueAt(x,y); field.setValueAt(x,y,v);field.reset(); // fill 0field.evolve(solver, dt); // โ solver.step(this, dt)field.sample(u,v,target); // bilinear (stub, uses index())DiscreteComplexField({ nx=128, ny=128, real, imag })
Section titled โDiscreteComplexField({ nx=128, ny=128, real, imag })โfield.nx; field.ny; field.size; field.real; field.imag; // Float32Arrayfield.index(x,y); field.valueAt(i,j,target); // writes Complexfield.reset(); field.evolve(solver, dt);RealFunction({ domain=new Interval(-1,1), func=x=>0 })
Section titled โRealFunction({ domain=new Interval(-1,1), func=x=>0 })โconst f = new RealFunction({ domain:new Interval(-3,3), func:x=>Math.sin(x)/x });f.domain; // Intervalf.evaluate(x); // numberf.sample(u, target=new Vec2()); // uโ[0,1] โ Vec2(x,y)f.setFunction(newFunc); // for Taylor/Fourier demosVectorField / DiscreteScalarField sampling
Section titled โVectorField / DiscreteScalarField samplingโVectorField.sample(positionVector, target). Continuous vs discrete is a data-access detail: field.sample(u,v,target) vs field.valueAt(i,j,target) + field.nx/ny.
Surface โ abstract
Section titled โSurface โ abstractโframeAt(u, v, target: DifferentialFrame) via DifferentialGeometry. sampleSpacing(resolution).
ParametricSurface({ domain, x=(u,v)=>u, y=(u,v)=>v, z=(u,v)=>0 })
Section titled โParametricSurface({ domain, x=(u,v)=>u, y=(u,v)=>v, z=(u,v)=>0 })โsample maps [0,1]ยฒ โ Domain โ Vec3(x, z, y) (Y-up).
ScalarFieldSurface({ domain, func }) / DiscreteFieldSurface({ field })
Section titled โScalarFieldSurface({ domain, func }) / DiscreteFieldSurface({ field })โScalarFieldSurface embeds a continuous MultivariateFunction/ComplexFunction as height. DiscreteFieldSurface adapts a DiscreteScalarField via valueAt + central-difference normals โ enables SurfaceVisualization for raster fields without manual conversion.
4. Bodies and Lattices
Section titled โ4. Bodies and LatticesโBody({ position, velocity, mass=1, charge=0, fixed=false, orientation })
Section titled โBody({ position, velocity, mass=1, charge=0, fixed=false, orientation })โposition/velocity/acceleration/mass/charge/force/state, reset(), integrate(dt, integrator), fieldAt(point), positionVectorTo(other), kineticEnergy, momentum.
RadialSymmetricBody({ position, velocity, mass, radius=1, charge, fixed })
Section titled โRadialSymmetricBody({ position, velocity, mass, radius=1, charge, fixed })โAdds radius.
AxialSymmetricBody({ position, velocity, axis, radius, mass, charge, fixed })
Section titled โAxialSymmetricBody({ position, velocity, axis, radius, mass, charge, fixed })โAdds axis: Vec3.
Block({ position, velocity, size=Vec3(1,1,1), mass, charge, fixed })
Section titled โBlock({ position, velocity, size=Vec3(1,1,1), mass, charge, fixed })โAdds size: Vec3.
Lattice({ k=100, damping=0, bodySize=0.075, bondRadius })
Section titled โLattice({ k=100, damping=0, bodySize=0.075, bondRadius })โSpring network: addBody(body), connect(body1, body2, {k, restLength, damping}), bodyAt(i)/bondAt(i), bodyCount/bondCount, integrate(dt), fixateBodyAt(i), applyToBodies(transformation).
ChainTopology({ count=100, length=20, bondRestLength, totalMass=0.025 })
Section titled โChainTopology({ count=100, length=20, bondRestLength, totalMass=0.025 })โapplyTo(lattice) โ builds a 1D chain.
CubicLatticeTopology({ nx=4, ny=4, nz=4, spacing=0.3, totalMass=1 })
Section titled โCubicLatticeTopology({ nx=4, ny=4, nz=4, spacing=0.3, totalMass=1 })โapplyTo(lattice), index(i,j,k).
PointCloud / Gas
Section titled โPointCloud / GasโPointCloud (particleStateAt(i) โ {position, color, size}) for the legacy PointCloudView / ParticleCloudView pattern. Gas โ 2D/3D kinetic gas used in examples/thermodynamics (Gas + ParticleView2D or PointCloudView). Discrete fields (DiscreteScalarField) are now visualized directly via DiscreteFieldSurfaceView/TiledPlane without an intermediate PointCloud.
5. Forces and Interactions
Section titled โ5. Forces and InteractionsโAll forces extend Transformation and accumulate into body.force until body.integrate() consumes it.
| Class | Constructor | Description |
|---|---|---|
Force | โ | Base; _calculateForceOn(body) |
FieldForce | (field) | Samples field at body.position |
CoulombForce.in(field) | (electricField) | F = qยทE |
LorentzForce.in(field) | (magneticField) | F = q vรB |
DragForce | (dragCoefficient=-5) | F = cยทv_y |
UniformGravitationalForce | () | F = mยทg downward |
GravitationalForce | () | Pair: Gยทm1ยทm2/rยฒ via BodyPair |
SpringForce | ({k=200, restLength, damping=0}) | Pair: Hooke + damping |
CoulombPairForce | () | Pair: kยทq1ยทq2/rยณยทr |
SphereSphereCollision | () | Pair: elastic collision + penetration resolve |
Usage:
body.apply(new DragForce(-2));bodyA.and(bodyB).apply(new GravitationalForce());lattice.connect(a, b, { k: 200, restLength: 1, damping: 0.1 });Constants: G = 6.67e-11, K = 9e9, EC = 1.602e-19, g = 9.81.
6. Operators
Section titled โ6. OperatorsโAll extend Transformation (applyTo(field)). Use declaratively: field.reset().apply(op1).apply(op2).
| Operator | Options | Notes |
|---|---|---|
GaussianImpulse | {centerX=100, centerY=100, amplitude=1, sigma=3} | Adds Gaussian in ยฑ5px window |
GaussianImpulseComplex2D | {wavePacketEnergy=0.05, packetWidth=48} | Plane wave exp(i kยทr)ยทexp(-rยฒ/wยฒ) |
DiamondSquareOperator | {roughness=1, amplitude=100} | Fractal terrain; nx-1 must be power of 2 |
PerlinNoiseOperator | {scale=50, frequency=0.02, octaves=6, persistence=0.5, z=0} | Fractal Perlin via three/ImprovedNoise |
DoubleSlitOperator | {wavelength=525, positionSlit1, positionSlit2} | Interference factor cosยฒ |
SineImpulseOperator | {wavelengthInPixels=10, amplitude=1, periods=1} | Also has .ui() |
FFT2D | () | Forward 2D FFT (rows โ cols) |
FFTShift2D | () | Shift zero-frequency to center |
Potential | (shapeConfiguration, reflectionStrength=0.1) | Sets potential where shape samples true |
ShapeMask | (shapeConfiguration) | Sets 1 where shape samples true |
ComplexShapeMask | (shapeConfiguration) | Sets real to 1 |
Softness | {softness=0} | Blur by averaging 4-neighbors |
ComplexSoftness | {softness=0} | Same on real channel |
LaplaceOperator | static only | LaplaceOperator.at(field,i,j) |
Shapes // { SingleSlit, DoubleSlit, Grating, Circle, Square, Line, Step }new ShapeConfiguration({ defaultSize=40, defaultShape=Shapes.DoubleSlit })shapeConfig.size; shapeConfig.shape; shapeConfig.ui() // Dropdown + SliderShapesFactory.create(shapeConfig).sample(x, y, field) // โ boolean7. Equations, Solvers, Integrators
Section titled โ7. Equations, Solvers, IntegratorsโBarrierWaveEquation({ obstacleField, velocity=1, damping=0.1 })
Section titled โBarrierWaveEquation({ obstacleField, velocity=1, damping=0.1 })โdamping, acceleration(field,i,j) โ (1-obstacle)ยทvยฒยทLaplacian, .ui() โ damping slider.
WaveEquationSolver(equation)
Section titled โWaveEquationSolver(equation)โnew WaveEquationSolver(equation)solver.step(field, dt) // field: DiscreteScalarFieldsolver.reset()field.evolve(solver, dt)SchrodingerSolver(potential)
Section titled โSchrodingerSolver(potential)โnew SchrodingerSolver(potentialField) // potential.datasolver.initialize(psi, dt) // stagger imag by 0.5 dtsolver.step(psi, dt) // psi: DiscreteComplexFieldsolver.reset()psi.evolve(solver, dt)Integrators (static)
Section titled โIntegrators (static)โBody.integrate(dt, Integrators.symplecticEulerStep)Integrators.eulerStep(state, dt)Integrators.symplecticEulerStep(state, dt)Integrators.rk2Step(state, dt, derivativeFn)Integrators.rk4Step(state, dt)state: { position, velocity, acceleration, clone() }.
8. Views โ 3D primitives
Section titled โ8. Views โ 3D primitivesโAll extend Renderable3D (Object3D). Contract: canBindTo(model), initialize(model), synchronizeWith(model), reset(), dispose(), boundingBox.
| View | Options | Binds to |
|---|---|---|
Sphere | {color=0xffff00, opacity=1, wireframe, segments=24, castShadow} | body.position && body.radius |
Box | {color=0xff0000, opacity, castShadow} | body.position && body.size && body.orientation |
Cylinder | {color, opacity, segments=24, radiusFunction=body=>body.radius} | body.position && body.axis |
Arrow | {color, size=1, opacity, round, magnitudeMap, colorMap} | body.position && body.axis |
VectorView | {vectorProperty=body=>body.velocity, color, size, round} | body.position && vectorProperty |
Ring | {color, thickness=0.1} | body.position && body.axis && body.radius |
Helix | {color, coils=20, thickness=0.05, radiusFunction} | BodyPair |
Trail | {maxPoints=200, trailStep=1, color} | body.position |
Label | {text, color, size} | body.position |
Floor/Aquarium/Ceiling | โ | decorations |
Visibility: prefer
particle.visibleon the model (e.g.get visible(){return index < n}inFlowerParticle) โParticleView2Dhides via child meshes and keepsview.visible=truesoBinding.synchronize()stays active. Settingview.visible=falseskips synchronization (seesrc/core/helion.js:103guard) and requiresforceSynchronize()to recover.
Composite
Section titled โCompositeโ| View | Options | Notes |
|---|---|---|
PointCloudView | {material} | pointCloud.positionAt etc. |
LatticeView | {bodyViewFactory, bondViewFactory} | Lattice โ new LatticeView({bodyViewFactory:()=>new Sphere(), bondViewFactory:()=>new SwitchableBondView()}) |
DiatomicMolecule | {bondType, bondColor, atom1Color, atom2Color} | BodyPair |
SwitchableBondView | {bondType="Spring"/"Cylinder", color, coils} | delegates to Helix/Cylinder |
ArrowField | {xRange, yRange, zRange, scaleFactor, magnitudeMap, colorMap} | VectorField |
ElectromagneticWave | {electricFieldColor, magneticFieldColor, numArrows=100} | Wave.valueAt |
OneDimensionalComplexPlaneWave3D | {size, numArrows=70} | ComplexWave.valueAt |
Surface visualization
Section titled โSurface visualizationโnew SurfaceVisualization({ resolution: new SurfaceResolution(100,100), colorLayer: new HeightLayer(), // or GaussianCurvatureLayer etc. colorMapper: colorLayer.preferredColorMapper(), normalizer: new AdaptiveSymmetricNormalizer(0.05), // or FixedIntervalNormalizer(range) opacity: 1, display: SurfaceVisualization.Display.Surface, // "surface"|"glyphs"|"none" glyphType: GlyphLayer.GlyphTypes.BOXES, glyphScale: 0.8})vis.canBindTo(model) // โ model.frameAtvis.addOverlayLayer(new ContoursLayer({}))vis.display(SurfaceVisualization.Display.Glyphs)vis.ui() // Color map + opacityvis.colorLayerUI() // Color layer dropdownSurfaceResolution(u=50, v=50)FixedIntervalNormalizer(interval: Interval)โnormalize(v)viainterval.normalizeAdaptiveSymmetricNormalizer(smoothing=0.05)โ EMA ofmaxAbsColorLayersregistry:Height,PrincipalCurvature1/2,GaussianCurvature,MeanCurvature,ShapeIndex,Curvedness- Layers:
SurfaceLayer,GlyphLayer(BOXES|CAPSULES|CYLINDERS|CONES|ICOSAHEDRONS|TILES|SPHERES),ContoursLayer,PrincipalDirectionsLayer,NormalsLayer
3D discrete-field views
Section titled โ3D discrete-field viewsโnew DiscreteFieldBoxView({ width=200, height=200, heightScale=100, color:0xff0033, opacity:0.35 })// Instanced BoxGeometry per texel; canBindTo: field.valueAt && field.nx && field.nynew DiscreteFieldSurfaceView({ colorMapper, opacityFunction }) // 2D DataTexture plane (also listed under 2D)Complex field views (2D/3D)
Section titled โComplex field views (2D/3D)โimport { ComplexFunction, ComplexSurfaceView2D, ComplexSurfaceView3D, WaveFunctionSurface3D } from "helion";// 3D: ComplexFieldViewable base โ ComplexSurfaceView3D (tanh height) / WaveFunctionSurface3D (log height, shader + alpha)// 2D: ComplexFieldViewable2D base โ ComplexSurfaceView2D (DataTexture, world 4x4 or nx*ny)const view3D = new ComplexSurfaceView3D({ defaultResolution:new SurfaceResolution(400,400), maxHeight:4 });const view2D = new ComplexSurfaceView2D({ defaultResolution:new SurfaceResolution(400,400), brightnessFunction:m=>Math.exp(-0.5*m) });view3D.colorMapper = view2D.colorMapper = ComplexColorMappers.get(ComplexColorMappers.Hsl); // shared control- Both share
sample(u,v, ComplexFunctionSample{input,output})/valueAtcontract andresolution()logic;valueAtis used for discrete grids (performance) without interpolation. - 2D uses
brightnessFunctionto modulate RGB (kept opaque) to avoid old-frame shine-through.
2D views โ rasters, fields and particles
Section titled โ2D views โ rasters, fields and particlesโnew PixelRasterView({ width=512, height=512, transparent }) // DataTexture + PlaneGeometry, canBindTo: pixelAt/pixelsnew DiscreteFieldSurfaceView({ colorMapper:new WavelengthColorMapper(525), opacityFunction:v=>Math.sqrt(v) })new FieldEdgeIntensityPixelRaster({ edgeHeight:100, colorMapper, opacityFunction })new ComplexSurfaceView2D({ showPhaseColour, brightnessFunction:m=>m>1?1:m, colorMapper:ComplexColorMappers.get(ComplexColorMappers.Hsv) })new ParticleView2D({ segments:16, colorFunction:p=>number, colorMapper:new HueColorMapper(), hasBorder:false, borderColor:Colour.Yellow, visible:true })// ParticleView2D replaces the legacy InstancedMesh ParticleCloudView; visibility via particle.visible (model) keeps Binding.synchronize() active; hasBorder adds CircleGeometry(1.15) outline1D โ CurveView (LineSegmentsView subclass)
Section titled โ1D โ CurveView (LineSegmentsView subclass)โimport { RealFunction, Interval, CurveView } from "helion";const f = new RealFunction({ domain:new Interval(-3,3), func:x=>Math.sin(x) });const curve = new CurveView({ resolution:200, lineWidth:3, colorMapper:ColorMappers.get(ColorMappers.Uniform) });simulation.bind(f.alwaysWith(curve)).frameSceneOn(curve);// update function later: f.setFunction(x=>Math.cos(x));RealFunctionis sampled viasample(u, Vec2);CurveViewhandlesvalueAtfast-path vssamplelike the 2D/3D complex views.- Used in
examples/mathematics/scenes/taylor_expansion.jsandfourier_transform.js(migrated fromFunctionGraph).
Color mappers
Section titled โColor mappersโColorMappers registry: Gradient, Inferno, RdYlBu, Seismic, Scientific, Terrain, Uniform, Viridis, Water, WaterAlternative. WavelengthColorMapper(lambda=590).
9. Controls
Section titled โ9. Controlsโnew Slider("Label").withRange(new Range(0,1,0.01)).withValue(0.5).withUnits("m")new Checkbox("Label").checked(true)new DropdownMenu().for(registry) // registry: Registrynew RadioGroup().add("Label", cb).checked(0)new Button().withText("Run").addEventListener("click", cb)new CompoundControl().add(controlA).add(controlB)control.togetherWith(other) // same rowcontrol.addEventListener("input", cb) // also calls simulation.onUserInteractioncontrol.append(div).to(simulation)simulation.append(control) // โ details panelRange(from,to,stepSize) used for Slider.withRange. AxesUI(axes).ui() โ Frame/Annotations/XY/XZ/YZ checkboxes.
10. Import and build
Section titled โ10. Import and buildโ// Browser (examples use Vite + importmap)import { Simulation, Vec3 } from "../../../src/index.js";
// NPMimport { Simulation } from "helion";Build:
npm run build:examples # Vite builds examples/*npm --prefix docs run build # Astro Starlight โ dist/Public texture assets: src/textures/; shaders in src/textures/shaders/*.glsl.
This reference mirrors src/index.js exports. For implementation details see source files under src/core, src/model, src/view and the example scenes in examples/.