Skip to content

Commit b2713b5

Browse files
committed
Updated the remaining tables in README.md—non-functional requirements, front-end stack, algorithms, error-handling, testing plan, and build/deployment—into narrative bullet lists that keep every original detail intact
1 parent cc47e0e commit b2713b5

1 file changed

Lines changed: 25 additions & 37 deletions

File tree

README.md

Lines changed: 25 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -73,70 +73,58 @@ All stored data (ray origins/directions, quality score, error estimate) is kept
7373

7474
## 4. Non-Functional Requirements
7575

76-
| Category | Specification |
77-
| ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
78-
| **Performance** | Target ≥ 30 fps on mid-range devices with 20+ lines. Use frustum culling & unlit materials. |
79-
| **Orientation** | `screen.orientation.lock('portrait')`. |
80-
| **Accessibility** | WCAG-AA contrast for banners & modals. No additional colour-blind accommodations in v1. |
81-
| **Privacy** | No analytics, cookies, or external calls (except CDN modules). Camera feed stays on-device. |
82-
| **Security** | Must run over HTTPS; service-worker restricted to origin scope. |
83-
| **Supported Platforms** | Any browser that returns `navigator.xr.isSessionSupported('immersive-ar') == true` (e.g., Chrome ≥ 94 Android, iOS Safari ≥ 15, Samsung Internet, Vision Pro Safari). Others receive overlay. |
76+
- **Performance:** Target ≥ 30 fps on mid-range devices with 20+ lines. Use frustum culling and unlit materials.
77+
- **Orientation:** Lock to portrait via `screen.orientation.lock('portrait')`.
78+
- **Accessibility:** Maintain WCAG-AA contrast for banners and modals; no additional colour-blind accommodations in v1.
79+
- **Privacy:** Avoid analytics, cookies, or external calls (CDN modules only). Keep camera feed on-device.
80+
- **Security:** Serve over HTTPS with service-worker scoped to the origin.
81+
- **Supported Platforms:** Require `navigator.xr.isSessionSupported('immersive-ar')` to return true (Chrome ≥ 94 Android, iOS Safari ≥ 15, Samsung Internet, Vision Pro Safari). Otherwise show the unsupported overlay.
8482

8583
---
8684

8785
## 5. Technical Architecture
8886

8987
### 5.1 Front-end Stack
9088

91-
| Layer | Choice | Rationale |
92-
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------- |
93-
| 3-D / AR | **Three.js 0.165** ES-modules + WebXR API | Familiar ecosystem, matches sample. |
94-
| UI | **Vanilla JS + Tailwind CSS CDN** | Zero build step, quick to load. |
95-
| PWA | Minimal `manifest.json` (name, short_name, icons, start_url, display = standalone, orientation = portrait, theme_color #000000). | |
96-
| Service-Worker | Hand-written `sw.js` using Cache API: precache **index.html**, `main.js`, `styles.css`, icon set; runtime network-first for CDN modules with cache-fallback. | |
89+
- **3-D / AR:** **Three.js 0.165** ES-modules paired with the WebXR API for scene rendering.
90+
- **UI:** **Vanilla JS + Tailwind CSS CDN**, keeping the setup build-free and fast to load.
91+
- **PWA:** Minimal `manifest.json` covering name, short_name, icons, start_url, standalone display, portrait orientation, and theme colour `#000000`.
92+
- **Service-worker:** Hand-written `sw.js` using the Cache API to precache `index.html`, `main.js`, `styles.css`, and icons; runtime is network-first with cache fallback for CDN modules.
9793

9894
---
9995

10096
## 6. Algorithms & Key Methods
10197

102-
| Concern | Approach |
103-
| ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
104-
| Hit-testing | `session.requestReferenceSpace('viewer')``requestHitTestSource`. Use first result each frame; reticle shows `visible = result.length > 0`. |
105-
| Distance calc | `distance = p1.distanceTo(p2)` (metres).<br>• Metric: ≥ 1 m → metres (toFixed 2); < 1 m → centimetres (Math.round).<br>• Imperial: totalInches = metres×39.3701; feet = Math.floor(totalInches/12); inchesDec = (totalInches % 12).toFixed(2). |
106-
| Colour generator | Keep HSL saturation = 80%, lightness = 55%.<br>`nextHue = (prevHue + 137) % 360` ensures contrast. |
107-
| Triangulation | Build normalized view rays from tap NDC + inverse PV per pose. Solve closest segment between `o₁+t₁d₁` and `o₂+t₂d₂`; midpoint = anchor, miss = `\|p₁−p₂\|`. Require ≥0.30 m baseline. Quality buckets: Green (θ ≥ 8°, miss ≤ 1.5 cm), Yellow (θ ≥ 4° or miss ≤ 3 cm), Red otherwise. Error bar = combined miss of both endpoints. |
98+
- **Hit-testing:** Call `session.requestReferenceSpace('viewer')` then `requestHitTestSource`; consume the first result each frame and toggle the reticle via `visible = result.length > 0`.
99+
- **Distance calculation:** Compute `distance = p1.distanceTo(p2)` in metres. Metric display uses metres with two decimals when ≥ 1 m, otherwise centimetres rounded to integers. Imperial display converts to inches (`metres × 39.3701`), splits into feet (`Math.floor(totalInches / 12)`) and decimal inches (`(totalInches % 12).toFixed(2)`).
100+
- **Colour generator:** Fix HSL saturation at 80% and lightness at 55%, advancing hue with `nextHue = (prevHue + 137) % 360` to guarantee contrast.
101+
- **Triangulation:** Normalize view rays from tap NDC using the inverse projection-view matrices per pose. Solve the closest segment between `o₁ + t₁d₁` and `o₂ + t₂d₂`; take the midpoint as the anchor and miss distance `‖p₁ − p₂‖`. Enforce a ≥ 0.30 m baseline and classify quality as Green (θ ≥ 8° and miss ≤ 1.5 cm), Yellow (θ ≥ 4° or miss ≤ 3 cm), or Red otherwise. The error bar reflects the combined miss of both endpoints.
108102

109103
---
110104

111105
## 7. Error-Handling Strategy
112106

113-
| Scenario | UI Response |
114-
| ------------------------ | --------------------------------------------------------------------------------------------- |
115-
| Camera permission denied | Replace AR canvas with overlay: “Camera access is required. Enable it in browser settings.” |
116-
| WebXR session init fails | Same overlay with error code. |
117-
| Unhandled JS error | Console .log only (no remote logging). |
118-
| CDN file missing | Service-worker returns cached copy; if absent, overlay: “Connection lost—reload when online.” |
107+
- **Camera permission denied:** Replace the AR canvas with the overlay “Camera access is required. Enable it in browser settings.”
108+
- **WebXR session init fails:** Show the same overlay, including the specific error code.
109+
- **Unhandled JS error:** Log details to the console only; do not send remote telemetry.
110+
- **CDN file missing:** Let the service-worker serve the cached asset; if unavailable, display “Connection lost—reload when online.”
119111

120112
---
121113

122114
## 8. Testing Plan
123115

124-
| Layer | Tooling & Scope |
125-
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
126-
| **Unit Tests** | **Jest** (Node) for: distance calculation, metric↔imperial conversion, colour generator non-collision, random-hue cycle. |
127-
| **Manual Exploratory** | Checklist for: placement (hit-test + triangulation), baseline guidance ring, quality chip colours, redo/undo actions, list copy/delete, unit toggle, haptic feedback, loss-tracking banner, PWA install/open offline. Test on at least: Pixel 8 (Android 15 Chrome), iPhone 14 (iOS 17 Safari), Galaxy S22 (Samsung Internet), Vision Pro simulator. |
128-
| **CI** | GitHub Actions: `npm ci``npm test`. Failures block merge. |
116+
- **Unit tests:** Run **Jest** (Node) against distance calculations, metric↔imperial conversion, colour generator non-collision, and the random-hue cycle.
117+
- **Manual exploratory:** Follow a checklist covering placement (hit-test and triangulation), baseline guidance ring, quality chip colours, redo/undo actions, list copy/delete, unit toggle, haptic feedback, loss-tracking banner, and PWA install/open offline. Exercise on Pixel 8 (Android 15 Chrome), iPhone 14 (iOS 17 Safari), Galaxy S22 (Samsung Internet), and the Vision Pro simulator.
118+
- **CI:** Execute GitHub Actions workflow `npm ci` then `npm test`; treat failures as merge blockers.
129119

130120
---
131121

132122
## 9. Build & Deployment
133123

134-
| Stage | Detail |
135-
| -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
136-
| **Build** | None. All scripts/styles loaded via `<script type="module">` / Tailwind CDN. Icons generated once (512 × 512 source → smaller sizes via real-favicongenerator). |
137-
| **Deployment** | Manual: push `main` branch; GitHub Pages serves root `/pocket-tape-ar/`. |
138-
| **Versioning** | Git tags `vMAJOR.MINOR.PATCH`. |
139-
| **License** | **GPL v3**. Include `LICENSE` file. |
124+
- **Build:** No build step; load scripts with `<script type="module">` and styles from the Tailwind CDN. Generate icons once (512 × 512 source exported to smaller sizes via real-favicongenerator).
125+
- **Deployment:** Push the `main` branch manually and let GitHub Pages serve from `/pocket-tape-ar/`.
126+
- **Versioning:** Tag releases as `vMAJOR.MINOR.PATCH`.
127+
- **License:** Ship under **GPL v3** with the `LICENSE` file included.
140128

141129
---
142130

0 commit comments

Comments
 (0)