diff --git a/code/include/euclidean_hessian.hpp b/code/include/euclidean_hessian.hpp index 5918c79..83f473d 100644 --- a/code/include/euclidean_hessian.hpp +++ b/code/include/euclidean_hessian.hpp @@ -17,18 +17,21 @@ // │ side lengths lij = exp(Λ̃ij/2): │ // │ │ // │ t12 = −l12+l23+l31, t23 = l12−l23+l31, t31 = l12+l23−l31 │ -// │ denom2 = 2·sqrt(t12·t23·t31·l123) = 8·Area │ +// │ l123 = l12+l23+l31, denom2 = 2·sqrt(t12·t23·t31·l123) = 8·Area │ // │ │ -// │ cot_k = (t_adj1·l123 − t_adj2·t_opp) / denom2 │ -// │ = cotangent of the angle αk at vertex k │ +// │ Cotangent at vertex k (opposite t_opp, adjacent t_a and t_b): │ +// │ cot_k = (t_opp · l123 − t_a · t_b) / denom2 │ // │ │ -// │ Hessian contributions per face: │ -// │ H[vi, vi] += cot_vj + cot_vk (diagonal, both non-opp angles) │ -// │ H[vi, vj] -= cot_vk (off-diagonal, for variable vi,vj│ +// │ Assignment (k ↔ opposite edge ↔ opposite t-value): │ +// │ cot1 (v1, opp l23): t_opp=t23, t_a=t12, t_b=t31 │ +// │ cot2 (v2, opp l31): t_opp=t31, t_a=t12, t_b=t23 │ +// │ cot3 (v3, opp l12): t_opp=t12, t_a=t23, t_b=t31 │ // │ │ -// │ This is exactly the cotangent-Laplace operator from Pinkall–Polthier. │ +// │ Hessian contributions per face (Pinkall–Polthier ½ factor): │ +// │ H[vi, vi] += (cot_vj + cot_vk) / 2 (diagonal) │ +// │ H[vi, vj] −= cot_vk / 2 (off-diagonal, variable pairs) │ // │ │ -// │ Pinned vertices (v_idx = −1) contribute to diagonal of neighbours but │ +// │ Pinned vertices (v_idx = −1) contribute to diagonal of neighbours but │ // │ do not create a column/row in H themselves. │ // └──────────────────────────────────────────────────────────────────────────┘ // @@ -54,7 +57,11 @@ namespace conformallab { // Given three Euclidean SIDE LENGTHS l12, l23, l31 (already exp(Λ̃/2)), // return the three cotangent weights (cot1, cot2, cot3). // -// cot_k = (t_adj·l123 − t_opp·t_other) / (8·Area) +// cot_k = (t_opp · l123 − t_a · t_b) / (8·Area) +// +// where t_opp is the t-value of the edge OPPOSITE vertex k, and t_a, t_b are +// the t-values of the two edges ADJACENT to vertex k. See the box comment at +// the top of this file for the explicit assignment of t_opp/t_a/t_b per vertex. // // Returns {0,0,0} for degenerate faces (triangle inequality violated or Area=0). /// Three Euclidean cotangent weights `(cot1, cot2, cot3)` for the @@ -85,9 +92,10 @@ inline EuclCotWeights euclidean_cot_weights(double l12, double l23, double l31) // denom2 = 2·sqrt(t12·t23·t31·l123) = 8·Area const double denom2 = 2.0 * std::sqrt(denom2_sq); - // cot at v1 (opposite l23): adjacent t-values are t12 and t31. - // cot at v2 (opposite l31): adjacent t-values are t12 and t23. - // cot at v3 (opposite l12): adjacent t-values are t23 and t31. + // Formula: cot_k = (t_opp · l123 − t_a · t_b) / denom2 + // cot1: t_opp=t23, t_a=t12, t_b=t31 (v1 opposite l23) + // cot2: t_opp=t31, t_a=t12, t_b=t23 (v2 opposite l31) + // cot3: t_opp=t12, t_a=t23, t_b=t31 (v3 opposite l12) return { (t23 * l123 - t31 * t12) / denom2, // cot1 (t31 * l123 - t12 * t23) / denom2, // cot2 diff --git a/doc/reviewer/external-audit-2026-05-30.md b/doc/reviewer/external-audit-2026-05-30.md index b76245c..16bdedc 100644 --- a/doc/reviewer/external-audit-2026-05-30.md +++ b/doc/reviewer/external-audit-2026-05-30.md @@ -701,7 +701,7 @@ index. Add a comment: |----|------|-------|------|----------|--------| | A | `hyper_ideal_functional.hpp` | 319–344 | Bug | Critical (mixed config) | ✅ Fixed 2026-05-30 | | B | `gauss_bonnet.hpp` | 87–88, 128–134 | API error | Medium | ✅ Fixed 2026-05-31 | -| C | `euclidean_hessian.hpp` | 26–27, 57–58 | Doc error | Medium | 🟡 Open | +| C | `euclidean_hessian.hpp` | 26–27, 57–58 | Doc error | Medium | ✅ Fixed 2026-05-31 | | D | `euclidean_functional.hpp` + 2 others | 97–107 | Doc error | Medium | 🟡 Open | | E | `cp_euclidean_functional.hpp` | 338–349, 373–387 | Inconsistency | Medium | 🟡 Open | | F | test files | — | Test gap | Medium | 🟠 Open |