An interactive 3D studio for seeing the geometry of vectors and Ordinary Least Squares — column space, projection, residuals and the orthogonality that ties them together.
Watch how Ordinary Least Squares projects the data vector y onto the column space Col(X). The residual e = y − ŷ is what's left over — always perpendicular to the fit.
y,x rows to make the scene your own regressionA free playground for 3D vector algebra. Spawn vectors, feed them into operations — add, subtract, cross product, projection — and watch results update live as you drag.
Each collapses to its header. The lesson step that teaches a card opens it and marks it as the current subject.
y,x rows. With one regressor the scene is your data, at any sample size, and you can drag a point.Enter VR appears when a headset is present; Enter AR when it supports passthrough, which puts the model in your room. Grab the amber y arrow with the trigger or a pinch. The left stick moves θ and tilt, the right rotates and scales. A floating panel carries the lesson, the toggles and a tab for each feature.
WebXR needs HTTPS. Opening the file directly, or over plain http://, will show “VR not supported”.
The scene, the sandbox, your quiz answers and tutorial progress are saved to this browser and restored when you return. Add ?fresh to the address to start clean.
Every observation is a dimension, so y is one point in Rⁿ and the design matrix X spans a k-dimensional subspace of it. OLS asks the only sensible question: which point of that subspace is nearest? The answer is the perpendicular projection, which is why e ⊥ Col(X) — and every OLS identity follows from that single fact.
ŷ = Py with P = X(X′X)⁻¹X′, e = My with M = I − P, ∥y∥² = ∥ŷ∥² + ∥e∥², and R² = cos²θ.
A statistic is an angle whenever it has the shape
stat = (∥Pₐv∥²/q) ÷ (∥Pᴸv∥²/d) = (d/q)·cot²θ
with A and B orthogonal. Cotangent decreases, so a large statistic is a small angle: you reject when v lies close to A. The boundary θ = θcrit is a cone, so the acceptance region is literally a cone you can look at.
A test only has to declare three things — the vector it examines, what the null already explains, and the directions the alternative adds. The geometry follows.
This is where it earns its keep. Breusch–Pagan is not about y: heteroskedasticity is a claim about the size of the errors, so the vector is ê² and the plane is the auxiliary regressors. White is the same vector and space with a wider plane. Breusch–Godfrey moves again, to the residuals against their own lags. The app names the space each time, because reading those pictures as “y and Col(X)” is the commonest mistake students make with diagnostics.
For these, LM = n·cos²θ, so the critical angle is acos√(χ²/n) — it widens with the sample, and a weaker lean suffices to convict.
The F and t cones are exact under normality. The LM cones are exact as a description of the statistic but their critical value is asymptotic, and the app says so on every one of them. Jarque–Bera is deliberately absent: skewness and kurtosis are not quadratic forms, so there is no angle to draw.
Critical values come from the regularised incomplete beta — a Lentz continued fraction with a Lanczos log-gamma, then bisection — so there are no tables and no library. χ² is taken as the limiting case of F. Projections use modified Gram–Schmidt, which drops rank-deficient columns rather than returning NaN.
One HTML file. No build step, no bundler, no framework, nothing to install. Open it on a static host and it runs; the only things fetched at runtime are Three.js and the fonts.
immersive-vr and immersive-ar, controllers and hand trackingA publish/subscribe bus carries ols:update, drag, mode and workspace events, so features observe the app rather than editing its hot paths. The geometry runs through one column-space frame, which is why the regressors can move at all. window.__studio is the hand-off surface for tests and scripted demos.
Some work is withheld from public builds pending an IP review. Those features live in js/*.js, load only behind a flag, and are simply absent when the folder is not deployed — the import fails and is swallowed.
Open tests/ on the same host. It runs the real app in a frame and asserts against it — geometry, distributions against published tables, the Monte Carlo size and power of every diagnostic, serialization, the session, the lessons, the VR panel layout, contrast ratios and hit targets.
It measures layout, not just state. A regression that left every feature card inside a hidden container passed every state check and still showed nothing on screen.
ES-module imports mean it must be served over HTTP, not opened from disk: python -m http.server 8000, then localhost:8000. For a headset, host it anywhere with HTTPS and open that address in the headset’s browser.
Any current browser with WebGL2. VR and AR need a WebXR runtime — the Meta Quest browser is what it was built against. Everything degrades quietly when a capability is missing.
Designed and built as a teaching instrument for the geometry of ordinary least squares and the tests built on it — first for the desktop, then for the headset. Bug reports, teaching feedback and feature requests are welcome by email.
Inspired by ImDat and MathVR by Matt Cabanag, UNSW — presented at the SIGGRAPH Asia Educator’s Forum, 2023.
The geometric treatment of least squares owes its shape to the standard econometric literature, where the projection picture and the Frisch–Waugh–Lovell theorem are long established.
Three.js, under its own MIT licence. Roboto and Roboto Condensed via Google Fonts, under Apache 2.0. The Monash M-device and the Monash palette are used under the university’s identity guidelines.
© 2026 Nazirul Hazim A. Khalim. All rights reserved.
This is proprietary software. It may not be copied, modified, redistributed or used commercially without written permission. Viewing it here grants no right in it. See LICENSE for the full terms.
Commercial and institutional licences are available — get in touch.
Three.js (MIT) and the Roboto fonts (Apache 2.0) remain under their own licences. The Monash M-device and palette are Monash University trade marks, used under its brand guidelines and not licensed as part of this software.
© 2026 Nazirul Hazim A. Khalim · Monash University Malaysia.
All rights reserved · nazirul.hazim@gmail.com
Version 2.0 — August 2026.