From 002b807c50be89901f50e324afdfb18871603dfa Mon Sep 17 00:00:00 2001 From: POUGET Marc Date: Mon, 9 Sep 2024 18:07:11 +0200 Subject: [PATCH] hopefully last revision for 1st review round --- ...yperbolic_surface_triangulation_2_demo.cpp | 4 +- .../Hyperbolic_fundamental_domain_factory_2.h | 11 ++--- .../CGAL/Hyperbolic_surface_triangulation_2.h | 11 +++-- .../Hyperbolic_surface_triangulation_2.txt | 40 +++++++++--------- .../hyperbolic_surface_triangulation.cpp | 4 +- .../Hyperbolic_fundamental_domain_factory_2.h | 16 ++++--- .../CGAL/Hyperbolic_surface_triangulation_2.h | 11 ++++- .../hs_test_circular_kernel.cpp | 4 +- .../hs_test_factory.cpp | 4 +- .../hs_test_lazy_exact_nt | Bin 216856 -> 216896 bytes .../hs_test_lazy_exact_nt.cpp | 4 +- 11 files changed, 62 insertions(+), 47 deletions(-) diff --git a/Hyperbolic_surface_triangulation_2/demo/Hyperbolic_surface_triangulation_2/Hyperbolic_surface_triangulation_2_demo.cpp b/Hyperbolic_surface_triangulation_2/demo/Hyperbolic_surface_triangulation_2/Hyperbolic_surface_triangulation_2_demo.cpp index 57a8e8c47cf..35d1c8aa40b 100644 --- a/Hyperbolic_surface_triangulation_2/demo/Hyperbolic_surface_triangulation_2/Hyperbolic_surface_triangulation_2_demo.cpp +++ b/Hyperbolic_surface_triangulation_2/demo/Hyperbolic_surface_triangulation_2/Hyperbolic_surface_triangulation_2_demo.cpp @@ -35,8 +35,8 @@ typedef Hyperbolic_surface_triangulation_2 Triangul int main(int argc, char** argv){ // 1. Generate the triangulation - Factory factory = Factory(time(NULL)); - Domain domain = factory.generate_domain_g2(); + Factory factory; + Domain domain = factory.make_hyperbolic_fundamental_domain_g2(time(NULL)); Triangulation triangulation = Triangulation(domain); triangulation.make_Delaunay(); diff --git a/Hyperbolic_surface_triangulation_2/doc/Hyperbolic_surface_triangulation_2/CGAL/Hyperbolic_fundamental_domain_factory_2.h b/Hyperbolic_surface_triangulation_2/doc/Hyperbolic_surface_triangulation_2/CGAL/Hyperbolic_fundamental_domain_factory_2.h index 8d0eb869a78..92ee475c7c4 100644 --- a/Hyperbolic_surface_triangulation_2/doc/Hyperbolic_surface_triangulation_2/CGAL/Hyperbolic_fundamental_domain_factory_2.h +++ b/Hyperbolic_surface_triangulation_2/doc/Hyperbolic_surface_triangulation_2/CGAL/Hyperbolic_fundamental_domain_factory_2.h @@ -13,17 +13,18 @@ class Hyperbolic_fundamental_domain_factory_2{ /// \name Creation /// @{ /*! - Constructor, the seed is used for generation. + Constructor. */ - Hyperbolic_fundamental_domain_factory_2(unsigned int seed); + Hyperbolic_fundamental_domain_factory_2(); /// @} - /// \name Generation of a domain + /// \name Generation of a domain in genus 2. /// @{ /*! - randomly generates a convex domain of a closed orientable hyperbolic surface of genus two. + randomly generates a convex domain of a closed orientable hyperbolic surface + of genus two from a seed. */ - Hyperbolic_fundamental_domain_2 generate_domain_g2(); + Hyperbolic_fundamental_domain_2 make_hyperbolic_fundamental_domain_g2(unsigned int seed); /// @} }; diff --git a/Hyperbolic_surface_triangulation_2/doc/Hyperbolic_surface_triangulation_2/CGAL/Hyperbolic_surface_triangulation_2.h b/Hyperbolic_surface_triangulation_2/doc/Hyperbolic_surface_triangulation_2/CGAL/Hyperbolic_surface_triangulation_2.h index c95b200fdc1..9c2f9e274ef 100644 --- a/Hyperbolic_surface_triangulation_2/doc/Hyperbolic_surface_triangulation_2/CGAL/Hyperbolic_surface_triangulation_2.h +++ b/Hyperbolic_surface_triangulation_2/doc/Hyperbolic_surface_triangulation_2/CGAL/Hyperbolic_surface_triangulation_2.h @@ -117,8 +117,15 @@ class Hyperbolic_surface_triangulation_2{ \pre is_valid() && has_anchor() */ Anchor& anchor(); + /*! + constant version of the getter. + + \pre is_valid() && has_anchor() + */ + const Anchor& const_anchor(); /// @} + /// \name Delaunay flip algorithm /// @{ /*! @@ -190,9 +197,7 @@ class Hyperbolic_surface_triangulation_2{ /*! reads the triangulation from a stream. The format of the input should be the same as the format of the output of the '<<' operator. - - \pre is_valid() - */ + */ std::istream& operator>>(std::istream& s, Hyperbolic_surface_triangulation_2& triangulation); /// @} }; diff --git a/Hyperbolic_surface_triangulation_2/doc/Hyperbolic_surface_triangulation_2/Hyperbolic_surface_triangulation_2.txt b/Hyperbolic_surface_triangulation_2/doc/Hyperbolic_surface_triangulation_2/Hyperbolic_surface_triangulation_2.txt index cf7a2252710..f143ecac512 100644 --- a/Hyperbolic_surface_triangulation_2/doc/Hyperbolic_surface_triangulation_2/Hyperbolic_surface_triangulation_2.txt +++ b/Hyperbolic_surface_triangulation_2/doc/Hyperbolic_surface_triangulation_2/Hyperbolic_surface_triangulation_2.txt @@ -1,5 +1,5 @@ -\page Chapter_Hyperbolic_Surface_Triangulations Triangulations of hyperbolic surfaces +\page Chapter_Hyperbolic_Surface_Triangulations Triangulations of Hyperbolic Surfaces namespace CGAL { /*! @@ -19,30 +19,30 @@ Functionalities are offered such as the Delaunay flip algorithm, and the constru A triangulation of a surface can be generated from a convex fundamental domain of the surface. A method is offered that generates such domains in genus two. -\section Section_Hyperbolic_Surface_Triangulations_Background Hyperbolic surfaces +\section Section_Hyperbolic_Surface_Triangulations_Background Hyperbolic Surfaces We assume some familiarity with basic notions from covering space theory, and from the theory of hyperbolic surfaces. -The Poincaré disk \f$ \mathbb{D} \f$ is a model of the hyperbolic plane whose point set is the open unit disk of the complex plane \f$ \mathbb{C} \f$. +The Poincaré disk \f$ \mathbb{D} \f$ is a model of the hyperbolic plane whose point set is the open unit disk of the complex plane \f$ \mathbb{C} \f$. In this package, every hyperbolic surface \f$ S \f$ is closed (compact, and without boundary) and orientable: this is without further mention. The Poincaré disk \f$ \mathbb{D} \f$ is a universal covering space for \f$ S \f$, whose projection map \f$ \pi: \mathbb{D} \to S \f$ is a (local) isometry. -The pre-image set \f$ \pi^{-1}(x) \f$ of a point \f$ x \in S \f$ is infinite, its points are the lifts of \f$ x \f$. +The pre-image set \f$ \pi^{-1}(x) \f$ of a point \f$ x \in S \f$ is infinite, its points are the lifts of \f$ x \f$. We usually denote by \f$ \widetilde x \f$ a lift of \f$ x \f$. Paths and triangulations of \f$ S \f$ can also be lifted in \f$ \mathbb{D} \f$. -\subsection Section_Hyperbolic_Surface_Triangulations_domains Fundamental domains and triangulations +\subsection Section_Hyperbolic_Surface_Triangulations_domains Fundamental Domains and Triangulations Let \f$ S \f$ be a hyperbolic surface. For representing \f$ S \f$ on a computer, we cut \f$ S \f$ into "manageable" pieces. -A graph \f$ G \f$ embedded on \f$ S \f$ is a cellular decomposition of \f$ S \f$ if every face (every connected component of \f$ S \setminus G \f$ ) is a topological disk. +A graph \f$ G \f$ embedded on \f$ S \f$ is a cellular decomposition of \f$ S \f$ if every face (every connected component of \f$ S \setminus G \f$ ) is a topological disk. In this document, every edge of a graph \f$ G \f$ embedded on \f$ S \f$ is a geodesic on \f$ S \f$. We consider two types of cellular decompositions of \f$ S \f$:
  • We consider cellular decompositions \f$ G \f$ of \f$ S \f$ that have only one face. -Cutting \f$ S \f$ open at the edges of \f$ G \f$ results in a hyperbolic polygon \f$ P \f$, which is a fundamental domain for \f$ S \f$. +Cutting \f$ S \f$ open at the edges of \f$ G \f$ results in a hyperbolic polygon \f$ P \f$, which is a fundamental domain for \f$ S \f$. The edges of \f$ P \f$ are paired, so that every edge of \f$ G \f$ is cut into two edges that are paired in \f$ P \f$. -Every hyperbolic surface admits a fundamental domain \f$ P \f$ that is convex, in that the interior angles of \f$ P \f$ do not exceed \f$ \pi \f$. +Every hyperbolic surface admits a fundamental domain \f$ P \f$ that is convex, in that the interior angles of \f$ P \f$ do not exceed \f$ \pi \f$. -
  • Also, we consider triangulations of \f$ S \f$. +
  • Also, we consider triangulations of \f$ S \f$. A cellular decomposition \f$ T \f$ of \f$ S \f$ is a triangulation if every face of \f$ T \f$ is a "triangle": it admits three incidences with edges of \f$ T \f$. Observe that this definition allows for triangulations with only one vertex.
@@ -50,7 +50,7 @@ Observe that this definition allows for triangulations with only one vertex. A triangulation of \f$ S \f$ can be obtained from a convex fundamental domain \f$ P \f$ of \f$ S \f$ by triangulating the interior of \f$ P \f$, and by gluing back the boundary edges that are paired in \f$ P \f$. The assumption that \f$ P \f$ is convex ensures that the interior of \f$ P \f$ can be triangulated naively by insertion of any maximal set of pairwise-disjoint arcs of \f$ P \f$. -\subsection Section_Hyperbolic_Surface_Triangulations_generation Generation of convex fundamental domains +\subsection Section_Hyperbolic_Surface_Triangulations_generation Generation of Convex Fundamental Domains This package can generate a convex fundamental domain \f$ P \f$ of a surface of genus two, with eight vertices \f$ z_0, \dots, z_7 \in \mathbb{C} \f$, whose side pairings are \f$ A B C D \overline{A} \overline{B} \overline{C} \overline{D} \f$. The vertices and the side pairings are in counter-clockwise order, the side between \f$ z_0 \f$ and \f$ z_1 \f$ is \f$ A \f$, and the side between \f$ z_4 \f$ and \f$ z_5 \f$ is \f$ \overline{A} \f$. @@ -63,7 +63,7 @@ Such octagons are described in \cgalCite{aigon2005hyperbolic}. \section Subsection_Hyperbolic_Surface_Triangulations_Representation Representation -\subsection Subsection_Hyperbolic_Surface_Triangulations_DS_Domains Data structure for domains +\subsection Subsection_Hyperbolic_Surface_Triangulations_DS_Domains Data Structure for Domains We represent every domain as a polygon in the Poincaré disk, given by the list of its vertices, and by the list of its side pairings. Concerning the generation of domains, in order to perform fast and exact @@ -72,11 +72,11 @@ Under this constraint, it is not known how to generate domains of surfaces of ge In genus two, this package generates domains whose vertices belong to \f$ \mathbb{Q} + i \mathbb{Q} \f$ (their real and imaginary parts are rational numbers). The exact generation process can be found in \cgalCite{despre2022experimental}, together with a proof that the surfaces that can be generated in this way are dense in the space of surfaces genus two. -\subsection Subsection_Hyperbolic_Surface_Triangulations_DS_Triangulations Data structure for triangulations +\subsection Subsection_Hyperbolic_Surface_Triangulations_DS_Triangulations Data Structure for Triangulations Let \f$ T \f$ be a triangulation of a hyperbolic surface. We represent \f$ T \f$ by an instance of CGAL::Combinatorial_map whose edges are decorated with complex numbers. -The complex number \f$ R_T(e) \in \mathbb{C} \f$ decorating an edge \f$ e \f$ of \f$ T \f$ is the cross ratio of \f$ e \f$ in \f$ T \f$, defined as follows. +The complex number \f$ R_T(e) \in \mathbb{C} \f$ decorating an edge \f$ e \f$ of \f$ T \f$ is the cross ratio of \f$ e \f$ in \f$ T \f$, defined as follows. Consider the lift \f$ \widetilde T \f$ of \f$ T \f$ in the Poincaré disk \f$ \mathbb{D} \f$. In \f$ \widetilde T \f$, let \f$ \widetilde e \f$ be a lift of \f$ e \f$. Orient \f$ \widetilde e \f$ arbitrarily, and let \f$ z_0 \in \mathbb{D} \f$ and \f$ z_2 \in \mathbb{D} \f$ be respectively the first and second vertices of \f$ \widetilde e \f$. @@ -95,18 +95,18 @@ The anchor is used when building a portion of the lift of \f$ T \f$ in the Poinc It contains a lift \f$ t \f$ of a triangle of \f$ T \f$ in \f$ \mathbb{D} \f$: \f$ t \f$ is represented by its three vertices in \f$ \mathbb{D} \f$, and by a dart of the corresponding triangle in the combinatorial map of \f$ T \f$. -\subsection Subsection_Hyperbolic_Surface_Triangulations_Delaunay Delaunay flip algorithm +\subsection Subsection_Hyperbolic_Surface_Triangulations_Delaunay Delaunay Flip Algorithm -Let \f$ T \f$ be a triangulation of a hyperbolic surface. An edge \f$ e \f$ of \f$ T \f$ satisfies the Delaunay criterion if the imaginary part of its cross ratio \f$R_T(e)\f$ is non-positive. +Let \f$ T \f$ be a triangulation of a hyperbolic surface. An edge \f$ e \f$ of \f$ T \f$ satisfies the Delaunay criterion if the imaginary part of its cross ratio \f$R_T(e)\f$ is non-positive. This definition is equivalent to the usual "empty disk" formulation. -Then \f$ T \f$ is a Delaunay triangulation if every edge of \f$ T \f$ satisfies the Delaunay criterion. +Then \f$ T \f$ is a Delaunay triangulation if every edge of \f$ T \f$ satisfies the Delaunay criterion. If an edge \f$e \f$ of \f$ T \f$ does not satisfy the Delaunay criterion, then the two triangles incident to \f$ e \f$ form a strictly convex quadrilateron, so \f$ e \f$ can be deleted from \f$ T \f$ and replaced by the other diagonal of the quadrilateron. -This operation is called a Delaunay flip. +This operation is called a Delaunay flip. When a flip occurs, the cross ratios of the involved edges are modified via simple formulas. -The Delaunay flip algorithm flips edges that do not satisfy the Delaunay criterion as long as possible, with no preference on the order of the flips. +The Delaunay flip algorithm flips edges that do not satisfy the Delaunay criterion as long as possible, with no preference on the order of the flips. This algorithm terminates, and outputs a Delaunay triangulation of \f$ S \f$ \cgalCite{despre2020flipping}. -\section Section_Hyperbolic_Surface_Triangulations_Software_Design Software design +\section Section_Hyperbolic_Surface_Triangulations_Software_Design Software Design The package contains three main classes: @@ -129,7 +129,7 @@ Also, the concept `ComplexWithoutSqrt` describes a complex number type that does The example below generates a convex fundamental domain of a surface of genus two, triangulates the domain, applies the Delaunay flip algorithm to the resulting triangulation, saves and prints the Delaunay triangulation. \cgalExample{Hyperbolic_surface_triangulation_2/hyperbolic_surface_triangulation.cpp} -\section Section_Hyperbolic_Surface_Implementation_History Design and implementation history +\section Section_Hyperbolic_Surface_Implementation_History Design and Implementation History This package implements the Delaunay flip algorithm described in the hyperbolic setting by Vincent Despré, Jean-Marc Schlenker, and Monique Teillaud in \cgalCite{despre2020flipping} (with a different data structure for representing triangulations, see \cgalCite{despre2022experimental}). It also implements the generation of domains described by Vincent Despré, Loïc Dubois, Benedikt Kolbe, and Monique Teillaud in \cgalCite{despre2022experimental}, based on results of Aline Aigon-Dupuy, Peter Buser, Michel Cibils, Alfred F Künzle, and Frank Steiner \cgalCite{aigon2005hyperbolic}. diff --git a/Hyperbolic_surface_triangulation_2/examples/Hyperbolic_surface_triangulation_2/hyperbolic_surface_triangulation.cpp b/Hyperbolic_surface_triangulation_2/examples/Hyperbolic_surface_triangulation_2/hyperbolic_surface_triangulation.cpp index 61babd60268..236d3adb09e 100644 --- a/Hyperbolic_surface_triangulation_2/examples/Hyperbolic_surface_triangulation_2/hyperbolic_surface_triangulation.cpp +++ b/Hyperbolic_surface_triangulation_2/examples/Hyperbolic_surface_triangulation_2/hyperbolic_surface_triangulation.cpp @@ -17,8 +17,8 @@ typedef CGAL::Hyperbolic_surface_triangulation_2 Triangulati int main(){ // Generates the domain: - Factory factory = Factory(time(NULL)); - Domain domain = factory.generate_domain_g2(); + Factory factory = Factory(); + Domain domain = factory.make_hyperbolic_fundamental_domain_g2(time(NULL)); // Triangulates the domain: Triangulation triangulation = Triangulation(domain); diff --git a/Hyperbolic_surface_triangulation_2/include/CGAL/Hyperbolic_fundamental_domain_factory_2.h b/Hyperbolic_surface_triangulation_2/include/CGAL/Hyperbolic_fundamental_domain_factory_2.h index 6e5441e8f66..eb74b565e8c 100644 --- a/Hyperbolic_surface_triangulation_2/include/CGAL/Hyperbolic_fundamental_domain_factory_2.h +++ b/Hyperbolic_surface_triangulation_2/include/CGAL/Hyperbolic_fundamental_domain_factory_2.h @@ -24,7 +24,10 @@ namespace CGAL { /* -Factory class, whose only purpose is to construct random domains of genus 2 closed orientable hyperbolic surfaces, via its method generate_domain_g2. +Factory class, whose only purpose is to construct random fundamental domains of +closed orientable hyperbolic surfaces. The method +make_hyperbolic_fundamental_domain_g2 constructs such a domain for a surface of +genus 2. */ template class Hyperbolic_fundamental_domain_factory_2{ @@ -36,8 +39,8 @@ class Hyperbolic_fundamental_domain_factory_2{ Random _random; public: - Hyperbolic_fundamental_domain_factory_2(unsigned int seed); - Hyperbolic_fundamental_domain_2 generate_domain_g2(); + Hyperbolic_fundamental_domain_factory_2(); + Hyperbolic_fundamental_domain_2 make_hyperbolic_fundamental_domain_g2(unsigned int seed); private: float random_positive_float(); // returns number in [0,1] @@ -60,15 +63,14 @@ class Hyperbolic_fundamental_domain_factory_2{ //////////////////////////////////////////////////////////////////////////////// template -Hyperbolic_fundamental_domain_factory_2::Hyperbolic_fundamental_domain_factory_2(unsigned int seed){ - _random = Random(seed); -} + Hyperbolic_fundamental_domain_factory_2::Hyperbolic_fundamental_domain_factory_2(){} //////////////////////////////////////////////////////////////////////////////// template -Hyperbolic_fundamental_domain_2 Hyperbolic_fundamental_domain_factory_2::generate_domain_g2(){ +Hyperbolic_fundamental_domain_2 Hyperbolic_fundamental_domain_factory_2::make_hyperbolic_fundamental_domain_g2(unsigned int seed){ + _random = Random(seed); bool is_domain_generated = false; _Cmplx exact_z0, exact_z1, exact_z2, exact_z3; diff --git a/Hyperbolic_surface_triangulation_2/include/CGAL/Hyperbolic_surface_triangulation_2.h b/Hyperbolic_surface_triangulation_2/include/CGAL/Hyperbolic_surface_triangulation_2.h index 29d1c4d7993..c2205accf68 100644 --- a/Hyperbolic_surface_triangulation_2/include/CGAL/Hyperbolic_surface_triangulation_2.h +++ b/Hyperbolic_surface_triangulation_2/include/CGAL/Hyperbolic_surface_triangulation_2.h @@ -83,7 +83,8 @@ class Hyperbolic_surface_triangulation_2{ Combinatorial_map_with_cross_ratios& combinatorial_map(); bool has_anchor() const; Anchor& anchor(); - + const Anchor& const_anchor(); + void to_stream(std::ostream& s) const; void from_stream(std::istream& s); @@ -241,10 +242,16 @@ bool Hyperbolic_surface_triangulation_2::has_anchor() const template typename Hyperbolic_surface_triangulation_2::Anchor& -Hyperbolic_surface_triangulation_2::anchor(){ +Hyperbolic_surface_triangulation_2::anchor() { return _anchor; } + template +const typename Hyperbolic_surface_triangulation_2::Anchor& + Hyperbolic_surface_triangulation_2::const_anchor(){ + return _anchor; +} + //////////////////////////////////////////////////////////////////////////////// template diff --git a/Hyperbolic_surface_triangulation_2/test/Hyperbolic_surface_triangulation_2/hs_test_circular_kernel.cpp b/Hyperbolic_surface_triangulation_2/test/Hyperbolic_surface_triangulation_2/hs_test_circular_kernel.cpp index 377a541130f..65129a18c8a 100644 --- a/Hyperbolic_surface_triangulation_2/test/Hyperbolic_surface_triangulation_2/hs_test_circular_kernel.cpp +++ b/Hyperbolic_surface_triangulation_2/test/Hyperbolic_surface_triangulation_2/hs_test_circular_kernel.cpp @@ -24,8 +24,8 @@ typedef Hyperbolic_surface_triangulation_2 typedef typename Traits::Hyperbolic_point_2 Point; int main() { - Factory factory (3459); - Domain domain = factory.generate_domain_g2(); + Factory factory; + Domain domain = factory.make_hyperbolic_fundamental_domain_g2(3459); Triangulation triangulation0 = Triangulation(domain); assert( triangulation0.is_valid() ); diff --git a/Hyperbolic_surface_triangulation_2/test/Hyperbolic_surface_triangulation_2/hs_test_factory.cpp b/Hyperbolic_surface_triangulation_2/test/Hyperbolic_surface_triangulation_2/hs_test_factory.cpp index c38b32e872f..fc60b1611c6 100644 --- a/Hyperbolic_surface_triangulation_2/test/Hyperbolic_surface_triangulation_2/hs_test_factory.cpp +++ b/Hyperbolic_surface_triangulation_2/test/Hyperbolic_surface_triangulation_2/hs_test_factory.cpp @@ -22,8 +22,8 @@ typedef typename Traits::Complex Complex; int main() { - Factory factory (3459); - Domain domain = factory.generate_domain_g2(); + Factory factory; + Domain domain = factory.make_hyperbolic_fundamental_domain_g2(3459); std::vector vertices; Point z0 = Point(FT("4881/5000"),FT("0")); diff --git a/Hyperbolic_surface_triangulation_2/test/Hyperbolic_surface_triangulation_2/hs_test_lazy_exact_nt b/Hyperbolic_surface_triangulation_2/test/Hyperbolic_surface_triangulation_2/hs_test_lazy_exact_nt index 99514d0aa9fc96d659d64f84a1080cdb06628c39..4d8562b54866355f3a8307c2fb373b3281aef079 100755 GIT binary patch delta 13503 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 Triangul typedef typename Traits::Hyperbolic_point_2 Point; int main() { - Factory factory (3459); - Domain domain = factory.generate_domain_g2(); + Factory factory; + Domain domain = factory.make_hyperbolic_fundamental_domain_g2(3459); Triangulation triangulation0 = Triangulation(domain); assert( triangulation0.is_valid() );