docs: Doxygen-API + Validierungsprotokoll + Porting-Tutorial
All checks were successful
C++ Tests / test-fast (push) Successful in 2m15s
C++ Tests / test-cgal (push) Has been skipped

Für einen Mathematiker der unabhängig validieren und eigene Forschung
einbringen möchte.

Doxygen-Kommentare (code/include/):
  newton_solver.hpp — newton_euclidean(), newton_spherical(), newton_hyper_ideal()
    je mit \param, \return, \note, \see inkl. mathematischer Begründung
    (Konvexität, Vorzeichenkonvention, SparseQR-Fallback-Erklärung)
  layout.hpp — euclidean_layout(), spherical_layout(), hyper_ideal_layout()
    mit vollständiger Parameter-Doku, halfedge_uv-Semantik, Poincaré-Disk-Note

Neues Dokument:
  doc/math/validation-protocol.md
    7 reproduzierbare Checks mit konkreten Befehlen und erwartetem Output:
    0. 170 Tests, 1 Skip
    1. Gauss–Bonnet exakt (1e-10)
    2. FD-Gradientencheck < 1e-6 für alle 3 Geometrien
    3. Newton-Konvergenz < 50 Iterationen
    4. τ ∈ SL(2,ℤ)-Fundamentaldomäne (3 Invarianten)
    5. Möbius-Arithmetik (Inverse, Compose, from_three)
    6. End-to-End-Pipeline
    7. Manueller τ-Check für torus_4x4.off (Codebeispiel)

Neues Tutorial:
  doc/tutorials/add-inversive-distance.md
    Vollständiger Step-by-Step-Port von Phase 9a (Luo 2004):
    Header anlegen, Energie/Gradient implementieren, FD-Check,
    Newton-Wrapper, CMakeLists, Java-Referenzvergleich, Checkliste.

doc/getting-started.md:
  Abschnitt "Known issues": macOS-Finder-Duplikate (rm-Befehl),
  Warnung "First build 30–90s" (Tarball-Extraktion)

README.md:
  Zwei neue Links in der Dokumentationstabelle (validation-protocol,
  tutorial)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Tarik Moussa
2026-05-18 01:19:44 +02:00
parent e28aee7051
commit b235666725
6 changed files with 571 additions and 18 deletions

View File

@@ -452,6 +452,29 @@ inline void set_root_huv_2d(
} // namespace detail
// ── Euclidean layout ──────────────────────────────────────────────────────────
/// Embed the mesh in ℝ² using the Euclidean metric encoded in x.
///
/// Runs priority-BFS trilateration: places vertices in order of BFS depth
/// from the root face (largest 3D area), so errors accumulate last.
/// For closed genus-g surfaces a CutGraph must be supplied — otherwise
/// the layout will have a seam discontinuity (Layout2D::has_seam = true).
///
/// \param mesh Input surface mesh. Must have lambda0 and v_idx set in maps.
/// \param x DOF vector returned by newton_euclidean().
/// \param maps EuclideanMaps (lambda0, v_idx, e_idx).
/// \param cut Optional cut graph (compute_cut_graph()). Pass nullptr for
/// open meshes or if seams are acceptable.
/// \param holonomy If non-null and cut != nullptr, receives the lattice
/// translations ω_i ∈ per cut edge.
/// Pass to compute_period_matrix() for the conformal modulus τ.
/// \param normalise If true, calls normalise_euclidean() on the result:
/// centroid → origin, major axis → x-axis (PCA).
/// \return Layout2D with .uv[v] (per-vertex UV) and
/// .halfedge_uv[h] (per-halfedge UV for texture atlasing).
///
/// \note halfedge_uv differs from uv at seam edges: the two sides of a cut
/// carry different UV coordinates for proper GPU texture atlasing.
inline Layout2D euclidean_layout(
ConformalMesh& mesh,
const std::vector<double>& x,
@@ -571,6 +594,20 @@ inline Layout2D euclidean_layout(
}
// ── Spherical layout ──────────────────────────────────────────────────────────
/// Embed the mesh on the unit sphere S² using the spherical metric encoded in x.
///
/// Runs priority-BFS trilateration using the spherical law of cosines.
/// Typical use: genus-0 (sphere-like) surfaces after newton_spherical().
///
/// \param mesh Input genus-0 surface mesh.
/// \param x DOF vector returned by newton_spherical().
/// \param maps SphericalMaps.
/// \param cut Optional cut graph (rarely needed for genus-0).
/// \param holonomy If non-null, receives rotational holonomies (spherical).
/// \param normalise If true, calls normalise_spherical(): rotates the centroid
/// to the north pole (Rodrigues rotation formula).
/// \return Layout3D with .xyz[v] ∈ S² ⊂ ℝ³ for each vertex.
inline Layout3D spherical_layout(
ConformalMesh& mesh,
const std::vector<double>& x,
@@ -670,6 +707,29 @@ inline Layout3D spherical_layout(
}
// ── HyperIdeal layout (Poincaré disk) — exact trilateration ──────────────────
/// Embed the mesh in the Poincaré disk (H²) using the hyperbolic metric encoded in x.
///
/// Runs priority-BFS trilateration using exact Möbius-isometric placement:
/// each new vertex is located by solving the hyperbolic law of cosines and
/// applying a Möbius map to position it in the disk.
/// For closed genus-g surfaces (g ≥ 1) a CutGraph is required.
///
/// \param mesh Input genus-g surface mesh (g ≥ 1).
/// \param x DOF vector returned by newton_hyper_ideal()
/// (vertex b_v and edge a_e variables).
/// \param maps HyperIdealMaps (lambda0, v_idx, e_idx).
/// \param cut CutGraph from compute_cut_graph(). Required for closed surfaces.
/// \param holonomy If non-null, receives the Möbius maps T_i ∈ SU(1,1) per cut edge.
/// Pass to compute_period_matrix() for holonomy analysis.
/// \param normalise If true, calls normalise_hyperbolic(): iterative face-area-weighted
/// Möbius centring (Fréchet mean, 30 iterations) → disk origin.
/// \return Layout2D with .uv[v] ∈ Poincaré disk (|uv| < 1) for each vertex,
/// and .halfedge_uv[h] for seam-aware texture atlasing.
///
/// \note All vertex positions satisfy |uv[v]| < 1 (inside the Poincaré disk)
/// if the metric is hyperbolic. Points on or outside the boundary indicate
/// a non-hyperbolic metric (GaussBonnet violation).
inline Layout2D hyper_ideal_layout(
ConformalMesh& mesh,
const std::vector<double>& x,