Capstone — Building a Small 2D/3D Geometry Toolkit

Geometry & Trigonometry

Chapter 10 · Capstone — Building a Small 2D/3D Geometry Toolkit

One continuous project: authoring, locating, lighting, animating, orienting, rendering, and finally letting a player click on a single game object — a treasure chest — following it through every chapter this course built, in the order a real object actually moves through a real engine's pipeline. Every step below directly reuses that chapter's own already-verified numbers, rather than re-deriving them, exactly the way a real engineer reuses a formula they've already trusted and tested.

StepTaskChapter(s) used
1Author the chest's rotation and convert unitsCh.2
2Triangulate the chest's distance on the minimapCh.3
3Light the chest and check which side of the fence it's onCh.4
4Animate the chest's idle spin around its own centerCh.5
5Let the player freely orient the chest — and hit gimbal lockCh.6
6Fix it with quaternionsCh.7
7Place and view the chest through the scene cameraCh.8
8Let the player click the chest, and check a tooltip boxCh.9

Step 1 — Authoring the Chest's Rotation

Ch.2

The chest's designer sets its authored rotation to 45° in the level editor. The engine's own math library works entirely in radians.

Verified directly
45° = π/4 = 0.7853981633974483 radians — confirmed two independent ways (math.radians(45) and math.pi/4 agree exactly). As the chest idly spins every frame afterward, its accumulated rotation angle gets wrapped back into [0,2π) every frame — Chapter 2's own verified 2,000,000-frame experiment showed doing this keeps sin()/cos() accurate to ≈4.54×10⁻¹¹ relative error, versus ≈3.15×10⁻⁷ if the angle were ever left to grow unbounded.

Step 2 — Triangulating the Chest's Position on the Minimap

Ch.3

Two scouts stand 100m apart and each report the angle to the chest: 60° and 70°.

Verified directly — reusing Chapter 3's own triangulation exactly
Law of Sines gives the chest's distance from each scout: ≈122.67m and ≈113.05m. Feeding those two distances back through the Law of Cosines recovers the original 100m baseline almost exactly (100.00000000000001) — the same cross-check discipline confirming the minimap's triangulation is self-consistent before trusting it.

Step 3 — Lighting the Chest, and Checking the Fence Line

Ch.4

The chest's lid is a triangle with vertices (0,0,0), (2,0,0), (0,3,1). The scene also has a fence running from (0,0) to (4,0), and the game needs to know which side of it the chest sits on.

Verified directly — reusing Chapter 4's own normal, lighting, and side-test numbers
The lid's unit normal, (0, −0.3162, 0.9487), verified perpendicular to both edges and unit length. Lit from the front: brightness ≈0.6069. Lit from directly behind (impossible for a real light, but a useful stress test): brightness ≈−0.6069, correctly clamped to 0. The chest, sitting at (2,3) relative to the fence, gives a cross-product side value of +12 — the same sign as a known "inside the yard" reference point, confirming it's on the correct side.

Step 4 — The Chest's Idle Spin

Ch.5

The chest spins slowly in place as an idle animation — rotating around its own center, not the world origin.

Verified directly — reusing Chapter 5's own pivot rotation and composition findings
A marker point on the chest's lid, (5,5), rotated 90° around the chest's own center (2,2), lands at exactly (−1,5) — confirming the arbitrary-pivot formula, not the origin, is what the idle-spin code actually uses. Composing two 30° and 45° spin increments matches a single 75° rotation to within ≈10⁻¹⁶. But updating the chest's rotation matrix this way every single frame, for a very long play session, is exactly the scenario Chapter 5 verified drifts — after 200,000 frame updates, the matrix's determinant creeps to 1.0000000000188298 instead of exactly 1, subtly distorting the chest's own shape over time if left uncorrected.

Step 5 — Free Orientation Control, and Gimbal Lock

Ch.6

In the player's inventory screen, the chest can be freely rotated with three sliders: yaw, pitch, and roll. A tester reports that at one specific pitch value, the yaw and roll sliders "stop doing different things."

Verified directly — reusing Chapter 6's own gimbal-lock finding exactly
At pitch=90°, four different (yaw,roll) combinations that all share yaw−roll=20°(30°,10°), (40°,20°), (25°,5°), (100°,80°) — produce the identical orientation matrix. The tester's bug report is genuine, reproducible, and exactly this: at that one pitch value, the yaw and roll sliders really have collapsed into controlling the same thing.

Step 6 — Fixing It With Quaternions

Ch.7

The inventory screen's orientation control is switched from Euler-angle sliders to an internal quaternion representation, driven by a virtual trackball instead.

Verified directly — reusing Chapter 7's own quaternion findings exactly
Quaternion composition reproduces Chapter 6's own matrix results exactly — the internal representation genuinely changed, the rotations themselves didn't. Composing rotations through the exact orientation that broke the slider UI stays numerically smooth, with no coordinate singularity. The one honest limit still applies: if the UI ever needs to display numeric yaw/pitch/roll values again (say, in a debug overlay), converting the quaternion back still collapses (30°,10°) and (40°,20°) to the identical displayed numbers — switching representations fixed the control scheme, not the underlying geometric fact about that orientation.

Step 7 — Placing and Viewing the Chest Through the Camera

Ch.8

The chest, at world position (5,2) rotated 30°, needs to be drawn from the scene's camera, sitting at world position (10,10) rotated −45°.

Verified directly — reusing Chapter 8's own full pipeline exactly
The chest's local forward-marker (1,0) transforms to world position (5.866025403784438, 2.5), then into camera space at (2.380139..., −8.226462...) — matching exactly whether computed as two separate steps or as one precomputed combined matrix (0.0 difference). The camera's own inverse transform, checked against its forward transform, multiplies back out to the exact identity matrix — confirming the whole pipeline is self-consistent before a single pixel gets drawn.

Step 8 — The Player Clicks the Chest

Ch.9

The player clicks on the chest. The engine casts a ray from the camera through the click point and tests it against the chest's bounding sphere — and separately checks whether the same click also landed inside a nearby tooltip box.

Verified directly — reusing Chapter 9's own ray-sphere and point-in-polygon findings exactly
The ray-sphere test, set up exactly as Chapter 9 verified (a=1, b=−100000, c=1 — a ray originating far from a large bounding volume, a completely ordinary real setup), shows the naive quadratic formula's near-hit-point relative error at ≈3.38×10⁻⁷ versus the stable formula's ≈1.14×10⁻¹⁶ — confirming the pick-testing code must use the stable reformulation, not the textbook one, to reliably report exactly where the click landed on the chest's surface. Separately, the same click point tested against the tooltip's boundary box reuses Chapter 9's own boundary-case finding: a click landing exactly on the tooltip's edge needs a small tolerance, not strict inequality, to behave predictably.

What This Course Doesn't Cover

As stated honestly back in Chapter 1: formal proof-based Euclidean geometry, projective and non-Euclidean geometry, and differential geometry/manifolds were all named as deliberately out of scope, and stayed out of scope through all ten chapters. This capstone built and picked one simple object; a real engine repeats exactly this pipeline for every object in a scene, every frame — the underlying mathematics doesn't change with scale, only the bookkeeping does.

Where This Course Connects

Linear Algebra Fundamentals' own vectors, dot/cross products, and its brief rotation-matrix introduction underwrote nearly every chapter here directly. Numerical Methods & Floating-Point Computation's own catastrophic-cancellation and stable-quadratic-formula material was reused explicitly and by name in Chapters 4 and 9 — this course's own capstone (Step 8) is a direct, concrete application of that course's own capstone lesson, applied to a genuinely different problem. Calculus & Optimization's derivative and chain-rule material underlies the smooth interpolation (SLERP) briefly mentioned in Chapter 7, a natural next step beyond this course's own scope.

Hands-On Exercises

Exercise 1

Using this chapter's own Step 3 lighting numbers, explain what would happen to the chest's rendered lid if the game's lighting code forgot the max(0, ...) clamp verified back in Chapter 4, in a scene with two lights, one in front of the chest and one behind it.

📄 View solution
Exercise 2

Using this chapter's own Step 5 and Step 6, explain why switching the inventory screen's orientation control from Euler-angle sliders to a quaternion-driven trackball fixes the tester's bug report, but would not fix a hypothetical second bug report about a debug overlay that displays the chest's numeric yaw/pitch/roll values.

📄 View solution
Exercise 3

Using this chapter's own Step 8, explain in your own words why the engine needs both the numerically stable ray-sphere formula and a boundary tolerance for the tooltip check — that is, why fixing only one of the two would still leave a real, user-visible bug in the picking system.

📄 View solution

Chapter 10 Quick Reference

  • Full worked project: author + convert units (Ch.2) → triangulate position (Ch.3) → light + side-test (Ch.4) → idle-spin around own pivot (Ch.5) → free orientation + gimbal lock (Ch.6) → fix with quaternions (Ch.7) → full render pipeline (Ch.8) → mouse-pick with a stable ray-sphere test + tolerant boundary check (Ch.9)
  • Every step directly reused that chapter's own already-verified numbers, rather than re-deriving them from scratch — exactly how a real engineer builds on trusted, tested formulas
  • The one recurring theme across all eight steps: geometry code is only as reliable as its numerical foundations — a correct formula used carelessly (naive quadratic roots, exact-equality boundary checks, unwrapped angles, un-renormalized rotations) still produces real, user-visible bugs
  • Out of scope: formal proof-based Euclidean geometry, projective/non-Euclidean geometry, differential geometry/manifolds
  • Course complete — Geometry & Trigonometry, 10 chapters, from a single naive heading-subtraction bug to a fully picked, rendered, and orientable game object