# 3D Scissors Congruence

Interactive Three.js demonstrations of the Conway–Radin–Sadun dissection,
including rhombohedra, Hill tetrahedra, prism assembly, and rectangle dissections.
The main viewer is `index.html`; pages in `demos/` explore and debug individual steps.
The pages load pinned Three.js versions from CDNs and require an internet connection.

## Source layout

```text
index.html               Main browser entrypoint
demos/                   Supporting demo and debugging HTML pages
src/
  viewer/                Main scene orchestration and stage catalog
  animation/             Shared frame clock, stage playback, controls, and motion
  demos/                 Standalone demo entry modules
  geometry/              Pure geometry, dissections, and vector calculations
  rendering/             Shared pieces, dissections, block assembly, and reshaping
styles/                  Stylesheets for all pages
experiments/             Python geometry checks and visualization prototypes
construction/            Separate Python-only exact construction interface
docs/
  geometry/              Mathematical derivations and component notes
  references/            Reference PDFs
  research/              Fabrication/search proposals and measured baselines
  plans/                 Historical implementation and refactor plans
tests/                   Node, Python, and browser checks
```

Browse the [notes webpage](docs/index.html) for the dated list of notes
and reference papers, or use the [Markdown index](docs/README.md).
After adding or renaming notes, run `uv run --extra docs python scripts/build_notes_index.py` to
refresh the index and browser-readable note pages. The Markdown files remain the
authoritative source; do not hand-edit generated `docs/index.html` or `docs/read/`.
Links between notes open their HTML versions, and relative images and data links
are preserved. Equations use MathJax when online; note text works without JavaScript.
Entries are sorted by their latest Git update, newest first (filesystem date for
new, untracked notes); same-day entries are alphabetical.
The root also contains this README and the Python project configuration and
lockfile. All application JavaScript and CSS lives in `src/` and `styles/`.

Page entrypoints own scene composition and stage visuals. Geometry modules have
no DOM or Three.js dependency; rendering modules consume geometry data. The
viewer and prism demo compute the shared Hill dissection once per tetrahedron
and use the same animation and block-assembly builders, with page-specific wire
opacity. `block_assembly.mjs` handles rotation into the block frame and movement
into a slot. `rect_prism_reshape.mjs` handles the three rectangle-reshaping
stages; each stage supplies dimensions, colors, and its reshape plane.

The original three-polyhedron-to-cube viewer is the animation reference.
Its `steps.mjs` defines navigation labels and speeds. Every page uses the clock
in `src/animation/loop.mjs`, and every dissection uses `animation/playback.mjs`
for stage navigation, easing, reverse motion, and input locking. Speeds retain
the original viewer's 60 Hz pacing but now use elapsed time, so refresh rate
does not change animation duration. Large tab-resume gaps are capped.

`animation/controls.mjs` connects the shared controller to previous/next,
playback, and stage-selection controls. The Hill and prism explorers keep
their focused step buttons and slider as adapters to that same controller.
Pages supply geometry-specific stage visuals; renderers consume eased progress
and never run their own clocks. `animation/motion.mjs` owns the reference
rectangle motion path, used by the main viewer, both canvas demos, and the
batched truncated-icosidodecahedron renderer. Batching changes rendering cost,
not the cuts, pivots, or paths. No build step is required.

## Supporting demos

- [Saved eight-piece construction](demos/guarded_eight_pieces.html) — select paired pieces and inspect recorded removal sequences.

- [Truncated icosidodecahedron → cube (v0)](demos/truncated_icosidodecahedron.html)
- [Hill tetrahedron](demos/ht.html)
- [Prism assembly](demos/pr.html)
- [Rhombic triacontahedron](demos/rt.html)
- [Rectangle dissection](demos/rect2rect.html)
- [Combining prisms](demos/comb_prisms_step1a.html)
- [Orientation debugging](demos/debug_orient.html)

The main viewer's **Demos & explorers** menu links to every page; every demo
links back to the main viewer. The new truncated-icosidodecahedron demo shows
eight states from the 385-tile zonotope dissection to a cube, with stage
navigation, playback, and individual tile inspection during the grid-cut and
box-to-slab steps. Both cube viewers share the Conway viewer's perspective
camera, lighting, saturated materials, and control styles. The first explosion
translates every tile 2.5 units outward without scaling it. The camera stays
fixed throughout forward/reverse playback, including stage boundaries.
**Fit view** explicitly reframes the current model; stage jumps and individual
tile selection also frame the requested view. Use this for the wide tile grid
and long column, which can extend outside the current view. All dimensions
remain to scale; no continuous auto-zoom is applied.

This is a stagewise v0: each operation uses actual cuts and rigid motions, but
earlier seams are hidden at stage boundaries. It does not yet propagate a common
refinement (one persistent set of final fragments) through the entire sequence,
and animation paths are not collision-free. The pure geometry module computes
the construction in the browser; the renderer batches each stage into two draw
calls. See the [derivation](docs/geometry/truncated_icosidodecahedron_to_cube.md).

## Python experiments

The separate [exact construction prototype](construction/README.md) provides
geometric planes, checked rigid motions, and partition histories that export
replayable certificates. Start with its
[design and working example](docs/research/geometric_construction_language.md).
It needs only Python and the existing exact kernel; it does not use the Rust
search backend.

The goal is a complete, fabricatable TI-to-cube puzzle, with a soft preference
for fewer, manageable pieces and no mandatory central core. The best coverage
result is an exact **95.0668% partial construction with 45 physical groups**.
The more promising assembly control is the guarded retry: eight exactly replayed
pieces covering 26.9957%, with numerical removal checks at both endpoints.
Neither result is a complete or physically validated puzzle.

Start with [current status and next experiment](docs/research/STATUS.md), the
[full evidence review](docs/research/experimental_review_2026_09_21.md), and the
[research tool guide](experiments/README.md). Superseded campaigns and their
failure evidence are preserved in the [archive](docs/research/archive/README.md)
and local Git tag `research-before-cleanup-2026-09-21`.

Run the guarded control into a fresh directory:

```sh
uv run --with scipy python -m experiments.baseline \
  --seconds 30 --seeds 31 47 83 --output .research-cache/guarded-new
```

The [optional Rust kernel](native/README.md) accelerates numerical geometry;
exact certification remains independent. With it installed, use `uv run --extra
native` instead of `uv run --with scipy`. Budgeted motion audits and exact replay
run after numerical search; reports separate all three results.

The independent numerical triacontahedron check is `uv run python -m
experiments.rt_decomp_fixed`. `experiments/rt.py` retains the Viser prototype.
Browser demos do not depend on these Python tools.

## Exact certificates

The [exact checker](docs/research/certificates/README.md) verifies cut trees and
rigid motions independently of floating search geometry, using only Python's
standard library. It distinguishes complete and partial exact constructions;
the TI search remains incomplete and its full numerical result is not certified.

```sh
uv run python -m experiments.certification verify \
  docs/research/certificates/brick_to_cube.json --require-complete
uv run python -m experiments.certification verify \
  docs/research/certificates/ti_common_region_partial.json --expect-ti
```

Numerical proposals require separate exact reconstruction. They are not
certificates of the original rounded mesh. The checker is not Lean-verified,
and exact endpoint geometry does not certify physical assembly or fabrication.

## Local development

From the workspace's `site-pipeline/` directory, run:

```sh
uv run sideprojects-dashboard
```

Open http://localhost:8010 and select this project. The dashboard serves all
pages and local modules through one port and reloads pages when source changes.
Its `--no-reload` option is intended for controlled automation.

## Checks

From this project directory:

```sh
node --test tests/*.mjs tests/*.js
uv run --with scipy python -m unittest discover -s tests -p 'test_*.py'
```

The Node checks cover playback commands and boundaries, rectangle coverage,
prism face orientation, closed hulls, coordinate transforms, stage definitions, and volume conservation
through the shared Hill dissection for all 20 RT rhombohedra. The Python check
covers centered and uncentered rhombic triacontahedron decompositions.

For browser checks, use installed Google Chrome on macOS. On other platforms,
install Playwright Chromium once. Then run:

```sh
uv run --with playwright python tests/browser_smoke.py
```

An existing compatible Chromium executable can be supplied with
`--browser-executable /path/to/chromium`. The browser check starts a temporary
loopback server, checks all eight pages, exercises all 35 main-viewer
stages and playback controls, and verifies the prism half-turn, assembled block
bounds, and reshape endpoints in both planes. It also exercises forward/reverse
controls on every animated demo and compares the new batched rectangle motions
against the reference renderer at intermediate poses. It controls the
animation clock explicitly; it does not replace the development server.

The eight-piece widget uses a compact export of the preserved numerical geometry
and assembly audit. Rebuild it with `python3 scripts/build_guarded_eight_display.py`.
Its explanatory page is included in the notes index by `scripts/build_notes_index.py`.
