Appearance
Quaternions
Problem
i want to render 3D data as 2D perspective. Rotatable objects, rotatable sub-objects. Euler angles cause gimbal lock—two axes align and you lose a degree of freedom. Not acceptable.
Goal
- Learn quaternions and the 3D→2D projection pipeline
- Build a proof-of-concept with gl-matrix + Canvas 2D
- Rotate objects smoothly, no gimbal lock
- Render wireframe with proper perspective
- Apply color and clipping
Approach
Stack:
gl-matrixfor quaternions, matrices, projection math- Canvas 2D API for line drawing
- Svelte + Vite + TypeScript
Pipeline:
- Define 3D vertices + edges
- Model matrix: quaternion → rotation matrix → transform vertices
- View matrix: camera position (
mat4.lookAt) - Projection matrix: perspective (
mat4.perspective) - Perspective divide: clip space → NDC → screen coordinates
- Draw edges as 2D lines
Milestones
- [x] Static cube with perspective projection
- [x] Mouse-drag rotation via quaternions
- [x] Nested transforms (object within object)
- [x] Create a VSCode project, in ~/GitHub/di
- [x] Line styling (depth-based opacity)
- [x] create github repo
- [x] add Svelte
Resume Points
- 2025-01-04: Created
experiments/quaternion-poc/index.htmlin webseriously. Working cube with quaternion rotation + perspective. Drag to rotate. Uses gl-matrix + Canvas 2D. - 2025-01-05: Created Vite+TS project in
~/GitHub/di. Runyarn && yarn devto start. - 2025-01-05: Refactored—moved app logic to
src/lib/ts/guts.ts,main.tsis now just boilerplate. - 2025-01-05: Implemented manager pattern. Scene, Camera, Render, Input, Animation in
src/lib/ts/managers/. Classes are simple names, exports are lowercase singletons. Split architecture docs intoproject.md,managers.md,types.md,files.md. - 2025-01-05: Rewrote all md files using voice.md guidelines—less machine-like, more human.
- 2025-01-05: Moved
types.tstotypes/index.ts. - 2025-01-05: Moved types to
types/Interfaces.ts;index.tsre-exports. - 2025-01-05: Added
Angle.ts(quadrants, orientations) andCoordinates.ts(Point, Size, Rect, Polar) to types. - 2025-01-05: Added migration plan to
types.mdfor converting x/y to Point and width/height to Size. - 2025-01-05: Phase 1 done—Render now uses
Sizeinstead of separate width/height. - 2025-01-05: Phase 2 done—Input now uses
Pointfor last_position and delta. Updated test.ts caller. - 2025-01-05: Applied style.md naming—snake_case for variables/methods,
T_prefix for types. Updated all managers and test.ts. - 2025-01-05: Phase 3 done—Camera.init() now takes
Size. Phase 5 callers updated. Migration complete (skipping Phase 4 per plan). - 2025-01-05: Renamed
SceneObjecttoO_Scene. AddedO_prefix to style.md for data object interfaces. - 2025-01-05: Created GitHub repo
design.intuition, pushed. - 2025-01-05: Added
Point3,Size3,Blockto Coordinates.ts. Replacedverticesarrays withPoint3[]in O_Scene, Scene, Render, test.ts. - 2025-01-05: Added Svelte. Created App.svelte, updated vite.config.ts, tsconfig.json. Run
yarnto install new deps. - 2025-01-05: Fixed circular dependency hell—use
import typefor type-only imports (Interfaces.ts, Input.ts, Scene.ts, Render.ts). Sanitized webseriously imports in Extensions.ts, Testworthy_Utilities.ts, S_Mouse.ts. - 2025-01-05: Moved Enumerations.ts from common/ to types/.