The page is available here.
A workspace for visualizing the behavior of autonomous systems in the browser. Use the tabs at the top of the page to switch between 1D / 2D / 3D.
1D dx/dt = f(x) — Given any function f(x) as a string, it draws
the graph of f(x), the phase line (direction of flow), the stability of fixed points, and the time series x(t).
The behavior of solutions can be understood entirely on the phase line:
- Points where
f(x) = 0are fixed points (equilibria). - On intervals where
f(x) > 0, x increases (→); wheref(x) < 0, it decreases (←). - The slope at a fixed point determines stability:
f'(x*) < 0is stable (●),f'(x*) > 0is unstable (○).
2D dx/dt = f(x,y), dy/dt = g(x,y) — On the phase plane it draws
the vector field, nullclines (f=0 / g=0), fixed points (classified by the eigenvalues of the Jacobian), and trajectories,
and can also play an animation of particles flowing along the field.
3D dx/dt = f(x,y,z), dy/dt = g(x,y,z), dz/dt = h(x,y,z) — In phase space it draws
trajectories (numerically integrated) and fixed points (classified by the eigenvalues of the 3×3 Jacobian).
You can rotate the viewpoint by dragging, and play an animation of particles flowing (examples: Lorenz, Rössler, Chen, Thomas, Halvorsen).
| Crate | Kind | Role | Dependencies |
|---|---|---|---|
dyn-core |
lib | Expression parser, fixed-point detection, stability classification, RK4 integration | zero deps |
dyn-wasm |
cdylib | Exposes dyn-core to WebAssembly (the compute engine for the browser version) |
wasm-bindgen |
dyn-cli |
bin | Equation → PNG / animated GIF | plotters |
dyn-core depends only on the standard library — a thin numeric core that even has no_std use / embedded repurposing in view.
The 1D browser version and the CLI are both thin presentation layers consuming this same core; the essential logic
(expression parsing, fixed-point detection, RK4 integration) runs in Rust (WASM), and only the rendering (canvas) and UI are JavaScript.
The 2D and 3D tabs are implemented as self-contained in-browser JavaScript (their own parser + RK4 + Jacobian-based
fixed-point classification; the 3D one adds a 3×3 Jacobian eigenvalue solver and a rotating projection) and do not depend on
the Rust crates (inside web/index.html).
./run.shThis single command does everything:
- Auto-installs the wasm target and
wasm-bindgen-cli(same version asCargo.lock) if missing - Rebuilds the WebAssembly if it hasn't been built / the source has changed
- Starts a local HTTP server and opens the page in your default browser (Ctrl-C to stop and clean up)
The port is chosen automatically (specify with ./run.sh 8080). Entering an equation (or clicking an example button) redraws
immediately. For expressions containing the parameters p q r (e.g. r - x^2, r*x*(1 - x/q), p + r*x - x^3),
only the parameters that appear get a slider on a dedicated row, and you can move them to observe bifurcations
(creation/annihilation of fixed points). For expressions with parameters, a bifurcation diagram is also shown automatically
(plotting the fixed points x* against the swept parameter — stable = green / unstable = red, with the current value drawn as a
vertical line; when there are multiple parameters you can choose which one to sweep).
▶ アニメーション再生 shows particles flowing along the phase line and converging to stable fixed points.
All computation (parsing, fixed points, integration) is done in Rust (WASM); rendering is canvas.
If you only want to build / serve, use ./build-web.sh (--serve serves on port 8000).
Opening directly via
file://fails because fetching the ES module / WASM is blocked by CORS, so HTTP serving is required.web/pkg/is generated bybuild-web.sh(=cargo build --target wasm32-unknown-unknown+wasm-bindgen).
Use the tabs at the top of the page to switch between 1D / 2D / 3D. 2D is the phase plane of the autonomous system
dx/dt = f(x,y), dy/dt = g(x,y), drawing the vector field, nullclines, fixed points
(classified by the eigenvalues of the Jacobian), and trajectories (examples: damped pendulum, Van der Pol, Lotka-Volterra).
3D is the phase space of dx/dt = f(x,y,z), dy/dt = g(x,y,z), dz/dt = h(x,y,z), drawing trajectories and fixed points
(classified by the eigenvalues of the 3×3 Jacobian), and can be rotated by dragging (examples: Lorenz, Rössler, Chen, Thomas, Halvorsen).
The 2D and 3D sides are self-contained JS added without touching the 1D code.
# still image
cargo run -p dyn-cli -- "x - x^3"
# with parameters (saddle-node bifurcation)
cargo run -p dyn-cli -- "r - x^2" --r 1 -o saddle.png
cargo run -p dyn-cli -- "r*x*(1 - x/q)" --r 1.2 --q 0.8 # multiple parameters p/q/r
# animated GIF
cargo run -p dyn-cli -- "x*(1-x)" --gif -o logistic.gif --frames 120Main options: --xmin/--xmax (x range), --tmax (integration time), --n (number of trajectories),
--p/--q/--r (parameters), --size WxH, --gif, --frames. Use -h for the full list.
- Operators:
+ - * /, exponent^, parentheses, implicit multiplication2x/x(1-x) - Functions:
sin cos tan asin acos atan sinh cosh tanh exp log(=ln) log10 log2 sqrt cbrt abs sign floor ceil round pow(a,b) atan2 min max mod - Constants:
pi e tau; variable:x; parameters:pqr(only those appearing in the expression are adjustable)
Expressions in the 2D tab use variables x, y; in the 3D tab x, y, z (neither supports parameters).
Operators, functions, constants, and implicit multiplication are the same as in 1D.
cargo test --workspacedyn-core: verifies the parser (unary minus, exponent precedence, implicit multiplication, multiple parameters), fixed-point detection, the saddle-node bifurcation, that RK4 matches the analytic solutione^{-t}, and more.
Logistic x(1-x) |
Bistable x - x³ |
Saddle-node r - x² (r=1) |
sin(x) |
Output examples (PNG / GIF) are under gallery/.
- Builds on stable Rust (local development can use nightly too).
- plotters' default
ttf/font-kit backend breaks on the latest nightly (pathfinder_simd), so we use the pure-Rustab_glyphfont backend and register a system TTF at runtime (crates/dyn-cli/src/font.rs). - The browser version uses
wasm-bindgen. Thewasm-bindgencrate and CLI versions must match (this repo uses0.2.125). We don't usetrunk/wasm-pack(which need extra CLIs); instead a minimal setup callswasm-bindgendirectly (build-web.sh). Rendering and UI are done with HTML/CSS+canvas because Japanese text displays as-is and it's lightweight (all heavy computation is in Rust/WASM).
