docs: split Phase 9a into 9a.1 (CPEuclidean) + 9a.2 (InversiveDistance)

Audit during Phase 9a preparation revealed:

* The Java repo `varylab/conformallab` does NOT contain
  `InversiveDistanceFunctional.java`.  The original roadmap mention
  was based on a misreading.
* The closest existing Java class is `CPEuclideanFunctional.java`
  (260 lines, with FunctionalTest), implementing the Bobenko-Pinkall-
  Springborn 2010 face-based circle-packing functional.

These two functionals are mathematically distinct (face-dual vs vertex-
based) but related: BPS-CP generalises inversive-distance via the
intersection angle parameter θ_e (I_ij = cos θ_e for orthogonal
limit, I_ij = 1 for tangential).

The roadmap is now split into:
- 9a.1  CPEuclideanFunctional  (Java port + test, BPS 2010 reference)
- 9a.2  InversiveDistanceFunctional  (from-literature, Luo 2004
        + Glickenstein 2011)

Both belong in Phase 9a; cross-validation between them in the
tangential limit (θ=0 ⇔ I=1) becomes a Phase 9a acceptance test.

The tutorial `doc/tutorials/add-inversive-distance.md` is corrected:
it no longer claims `InversiveDistanceFunctional.java` exists upstream,
and cites Luo 2004 + Glickenstein 2011 + Bowers-Stephenson 2004 instead.
Updated edge-length formula from incorrect hyperbolic cosh form to
the correct Luo §3 Euclidean form:
  ℓ_ij² = exp(2u_i) + exp(2u_j) + 2 I_ij exp(u_i + u_j)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Tarik Moussa
2026-05-19 23:18:57 +02:00
parent e435e143c6
commit 48e6d2131e
2 changed files with 121 additions and 17 deletions

View File

@@ -1,8 +1,16 @@
# Tutorial: Porting the Inversive-Distance Functional (Phase 9a)
# Tutorial: Porting the Inversive-Distance Functional (Phase 9a.2)
This is a complete, step-by-step example of how to add a new functional
to conformallab++. It ports `InversiveDistanceFunctional.java` from the
Java reference implementation (Luo 2004).
to conformallab++.
> **Note:** This tutorial implements the **vertex-based** inversive-distance
> circle packing of Luo (2004) and Glickenstein (2011). Despite an earlier
> draft of this document, the Java reference repository `varylab/conformallab`
> does **not** contain an `InversiveDistanceFunctional.java`. This is a
> from-the-literature implementation, validated by cross-checking against
> the **face-based** circle-packing functional `CPEuclideanFunctional.java`
> (Bobenko-Pinkall-Springborn 2010, see Phase 9a.1) in the tangential
> limit `I_ij = 1` ⇔ `θ_e = 0`.
**Prerequisite:** Read [doc/api/extending.md](../api/extending.md) first
for the general pattern. This tutorial fills in every detail for one
@@ -12,22 +20,50 @@ specific case.
## Mathematical background
Inversive distance (Luo 2004) uses a different edge-length update formula:
Inversive distance circle packing parametrises each vertex by a circle of
radius `r_i = exp(u_i)`. For each edge, the *inversive distance* `I_ij`
between the two adjacent circles is a fixed constant of the edge, computed
once from the initial geometry:
```
Given inversive distances I_{ij} ∈ for each edge {i,j}:
cosh(l̃_{ij}) = I_{ij} · cosh((u_i + u_j) / 2)
+ (cosh²((u_i - u_j) / 2) - 1) · ...
I_ij = (_ij² r_i² r_j²) / (2 r_i r_j) (Bowers-Stephenson)
```
For the Euclidean version the angle formula is the same law of cosines,
but the log-lengths Λ̃ are computed differently from the u-vector.
| Range of `I_ij` | Geometric meaning |
|---|---|
| `I_ij = 1` | Tangential circles (Koebe-style) |
| `I_ij = cos φ ∈ (0,1)` | Overlapping circles with intersection angle φ |
| `I_ij = 0` | Orthogonal circles |
| `I_ij ∈ (1, 0)` | Disjoint circles (inversive-distance > 1) |
**Reference:** Luo, F. (2004). *Combinatorial Yamabe Flow on Surfaces*.
Communications in Contemporary Mathematics, 6(5), 765780.
The edge length is then determined by the radii via:
**Java source:** `de.varylab.discreteconformal.functional.InversiveDistanceFunctional`
```
_ij(u)² = exp(2 u_i) + exp(2 u_j) + 2 I_ij exp(u_i + u_j) (Luo 2004 §3)
```
The angle formula is the same law of cosines (numerically stable
half-tangent form) as the Euclidean functional — only the edge-length
mapping changes. The gradient
```
∂E/∂u_i = Θ_i Σ_{T ∋ i} α_i(T)
```
is the standard Yamabe-flow gradient (Luo 2004 Lemma 3.1).
**Primary references:**
- Luo, F. (2004). *Combinatorial Yamabe Flow on Surfaces*.
Communications in Contemporary Mathematics, 6(5), 765780.
- Bowers, P. L. & Stephenson, K. (2004). *Uniformizing dessins and
Belyĭ maps via circle packing*. Memoirs of the AMS 170(805).
- Glickenstein, D. (2011). *Discrete conformal variations and scalar
curvature on piecewise flat manifolds*. J. Differential Geometry
87(2), 201238 (analytic Hessian, eq. 4.6).
**Java source:** none — this functional is implemented from the
above papers. See [doc/roadmap/phases.md](../roadmap/phases.md) §9a for
the historical clarification.
---