mirror of https://github.com/CGAL/cgal
Misc code cleaning
This commit is contained in:
parent
c672ed6fc1
commit
33ed6b6482
|
|
@ -1,4 +1,4 @@
|
||||||
cmake_minimum_required(VERSION 3.12...3.29)
|
cmake_minimum_required(VERSION 3.12...3.31)
|
||||||
|
|
||||||
project( Triangulation_on_hyperbolic_surface_2_Demo )
|
project( Triangulation_on_hyperbolic_surface_2_Demo )
|
||||||
|
|
||||||
|
|
@ -9,35 +9,25 @@ include_directories(${CMAKE_BINARY_DIR})
|
||||||
# Instruct CMake to run moc automatically when needed.
|
# Instruct CMake to run moc automatically when needed.
|
||||||
set(CMAKE_AUTOMOC ON)
|
set(CMAKE_AUTOMOC ON)
|
||||||
|
|
||||||
|
|
||||||
# CGAL and its components
|
# CGAL and its components
|
||||||
find_package(CGAL REQUIRED COMPONENTS Core Qt6)
|
find_package(CGAL REQUIRED COMPONENTS Core Qt6)
|
||||||
|
|
||||||
find_package(Qt6 QUIET COMPONENTS Widgets)
|
find_package(Qt6 QUIET COMPONENTS Widgets)
|
||||||
|
|
||||||
if ( NOT CGAL_FOUND )
|
if ( NOT CGAL_FOUND )
|
||||||
|
|
||||||
message(STATUS "This project requires the CGAL library, and will not be compiled.")
|
message(STATUS "This project requires the CGAL library, and will not be compiled.")
|
||||||
return()
|
return()
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if ( NOT CGAL_Qt6_FOUND OR NOT Qt6_FOUND)
|
if ( NOT CGAL_Qt6_FOUND OR NOT Qt6_FOUND)
|
||||||
|
|
||||||
message(STATUS "This project requires the Qt6 library, and will not be compiled.")
|
message(STATUS "This project requires the Qt6 library, and will not be compiled.")
|
||||||
return()
|
return()
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Boost and its components
|
# Boost and its components
|
||||||
find_package( Boost REQUIRED )
|
find_package( Boost REQUIRED )
|
||||||
|
|
||||||
if ( NOT Boost_FOUND )
|
if ( NOT Boost_FOUND )
|
||||||
|
|
||||||
message(STATUS "This project requires the Boost library, and will not be compiled.")
|
message(STATUS "This project requires the Boost library, and will not be compiled.")
|
||||||
|
|
||||||
return()
|
return()
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# ui files, created with Qt Designer
|
# ui files, created with Qt Designer
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <CGAL/Exact_rational.h>
|
#include <CGAL/Exact_rational.h>
|
||||||
#include <CGAL/Simple_cartesian.h>
|
#include <CGAL/Simple_cartesian.h>
|
||||||
|
|
||||||
#include <CGAL/Hyperbolic_Delaunay_triangulation_traits_2.h>
|
#include <CGAL/Hyperbolic_Delaunay_triangulation_traits_2.h>
|
||||||
#include <CGAL/Hyperbolic_surface_traits_2.h>
|
#include <CGAL/Hyperbolic_surface_traits_2.h>
|
||||||
#include <CGAL/Hyperbolic_fundamental_domain_factory_2.h>
|
#include <CGAL/Hyperbolic_fundamental_domain_factory_2.h>
|
||||||
|
|
@ -20,7 +21,8 @@ typedef Triangulation_on_hyperbolic_surface_2<Traits> Triangul
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
int main(int argc, char** argv){
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
// 1. Generate the triangulation
|
// 1. Generate the triangulation
|
||||||
Factory factory;
|
Factory factory;
|
||||||
Domain domain = factory.make_hyperbolic_fundamental_domain_g2(time(NULL));
|
Domain domain = factory.make_hyperbolic_fundamental_domain_g2(time(NULL));
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,9 @@
|
||||||
|
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
|
|
||||||
DemoWindowItem::DemoWindowItem() : CGAL::Qt::GraphicsItem(){
|
DemoWindowItem::DemoWindowItem()
|
||||||
|
: CGAL::Qt::GraphicsItem()
|
||||||
|
{
|
||||||
// Clear
|
// Clear
|
||||||
_edges.clear();
|
_edges.clear();
|
||||||
|
|
||||||
|
|
@ -28,9 +30,15 @@ DemoWindowItem::DemoWindowItem() : CGAL::Qt::GraphicsItem(){
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void DemoWindowItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
|
void DemoWindowItem::paint(QPainter *painter,
|
||||||
|
const QStyleOptionGraphicsItem *option,
|
||||||
|
QWidget *widget)
|
||||||
|
{
|
||||||
// 1. Draw the poincaré disk
|
// 1. Draw the poincaré disk
|
||||||
QRectF circle_rect = QRectF(-_poincare_disk_radius_in_pixels-3, -_poincare_disk_radius_in_pixels-3, 2*_poincare_disk_radius_in_pixels+6, 2*_poincare_disk_radius_in_pixels+6);
|
QRectF circle_rect = QRectF(-_poincare_disk_radius_in_pixels-3,
|
||||||
|
-_poincare_disk_radius_in_pixels-3,
|
||||||
|
2*_poincare_disk_radius_in_pixels+6,
|
||||||
|
2*_poincare_disk_radius_in_pixels+6);
|
||||||
painter->setPen(_poincare_disk_pen);
|
painter->setPen(_poincare_disk_pen);
|
||||||
painter->setBrush(QBrush());
|
painter->setBrush(QBrush());
|
||||||
painter->drawEllipse(circle_rect);
|
painter->drawEllipse(circle_rect);
|
||||||
|
|
@ -38,26 +46,32 @@ void DemoWindowItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *op
|
||||||
// 2. Draw the edges
|
// 2. Draw the edges
|
||||||
painter->setBrush(QBrush());
|
painter->setBrush(QBrush());
|
||||||
painter->setPen(_edges_pen);
|
painter->setPen(_edges_pen);
|
||||||
for (int i=0; i<_edges.size(); i++){
|
for (int i=0; i<_edges.size(); i++) {
|
||||||
draw_edge(painter, _edges[i].first, _edges[i].second);
|
draw_edge(painter, _edges[i].first, _edges[i].second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QRectF DemoWindowItem::boundingRect() const{
|
QRectF DemoWindowItem::boundingRect() const {
|
||||||
return QRectF(-_poincare_disk_radius_in_pixels-3, -_poincare_disk_radius_in_pixels-3, _poincare_disk_radius_in_pixels+6, _poincare_disk_radius_in_pixels+6);
|
return QRectF(-_poincare_disk_radius_in_pixels-3,
|
||||||
|
-_poincare_disk_radius_in_pixels-3,
|
||||||
|
_poincare_disk_radius_in_pixels+6,
|
||||||
|
_poincare_disk_radius_in_pixels+6);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DemoWindowItem::modelChanged(){} // Only used by Qt : we don't need to fill it
|
void DemoWindowItem::modelChanged() {} // Only used by Qt : we don't need to fill it
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void DemoWindowItem::draw_triangulation(Triangulation& triangulation){
|
void DemoWindowItem::draw_triangulation(Triangulation& triangulation)
|
||||||
typedef std::vector<std::tuple<typename Triangulation::Combinatorial_map_with_cross_ratios::Dart_const_handle,Point,Point,Point>> RealizationVector;
|
{
|
||||||
|
typedef std::vector<std::tuple<typename Triangulation::Combinatorial_map_with_cross_ratios::Dart_const_handle,
|
||||||
|
Point, Point, Point> > RealizationVector;
|
||||||
|
|
||||||
RealizationVector realized_triangles;
|
RealizationVector realized_triangles;
|
||||||
realized_triangles = triangulation.lift();
|
realized_triangles = triangulation.lift();
|
||||||
|
|
||||||
Point point_1, point_2, point_3;
|
Point point_1, point_2, point_3;
|
||||||
for (typename RealizationVector::iterator it = realized_triangles.begin(); it != realized_triangles.end(); ++it){
|
for (typename RealizationVector::iterator it = realized_triangles.begin(); it != realized_triangles.end(); ++it) {
|
||||||
point_1 = std::get<1>(*it);
|
point_1 = std::get<1>(*it);
|
||||||
point_2 = std::get<2>(*it);
|
point_2 = std::get<2>(*it);
|
||||||
point_3 = std::get<3>(*it);
|
point_3 = std::get<3>(*it);
|
||||||
|
|
@ -70,7 +84,8 @@ void DemoWindowItem::draw_triangulation(Triangulation& triangulation){
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void DemoWindowItem::draw_point(QPainter* painter, Point position){
|
void DemoWindowItem::draw_point(QPainter* painter, Point position)
|
||||||
|
{
|
||||||
// First convert the point in doubles, well-scaled
|
// First convert the point in doubles, well-scaled
|
||||||
double point_x = _poincare_disk_radius_in_pixels * CGAL::to_double(position.x());
|
double point_x = _poincare_disk_radius_in_pixels * CGAL::to_double(position.x());
|
||||||
double point_y = _poincare_disk_radius_in_pixels * CGAL::to_double(position.y());
|
double point_y = _poincare_disk_radius_in_pixels * CGAL::to_double(position.y());
|
||||||
|
|
@ -78,10 +93,10 @@ void DemoWindowItem::draw_point(QPainter* painter, Point position){
|
||||||
// Then draw a small circle
|
// Then draw a small circle
|
||||||
QRectF circle_rect = QRectF(point_x-1, point_y-1, 3, 3);
|
QRectF circle_rect = QRectF(point_x-1, point_y-1, 3, 3);
|
||||||
painter->drawEllipse(circle_rect);
|
painter->drawEllipse(circle_rect);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DemoWindowItem::draw_edge(QPainter* painter, Point source, Point target){
|
void DemoWindowItem::draw_edge(QPainter* painter, Point source, Point target)
|
||||||
|
{
|
||||||
// First convert the points coordinates to doubles
|
// First convert the points coordinates to doubles
|
||||||
|
|
||||||
double src_x = CGAL::to_double(source.x());
|
double src_x = CGAL::to_double(source.x());
|
||||||
|
|
@ -91,9 +106,10 @@ void DemoWindowItem::draw_edge(QPainter* painter, Point source, Point target){
|
||||||
double tar_y = CGAL::to_double(target.y());
|
double tar_y = CGAL::to_double(target.y());
|
||||||
|
|
||||||
// 0. If src and tar are too colinear or too close from each other then draw a line
|
// 0. If src and tar are too colinear or too close from each other then draw a line
|
||||||
|
|
||||||
double determinant = src_x*tar_y - src_y*tar_x; // determinant of the matrix whose columns are the vectors src and tar : indicates colinearity
|
double determinant = src_x*tar_y - src_y*tar_x; // determinant of the matrix whose columns are the vectors src and tar : indicates colinearity
|
||||||
double distance_squared = (src_x-tar_x)*(src_x-tar_x) + (src_y-tar_y)*(src_y-tar_y);
|
double distance_squared = (src_x-tar_x)*(src_x-tar_x) + (src_y-tar_y)*(src_y-tar_y);
|
||||||
if ((std::abs(determinant) < computation_treshold_squared) || (distance_squared < computation_treshold_squared)){
|
if ((std::abs(determinant) < computation_treshold_squared) || (distance_squared < computation_treshold_squared)) {
|
||||||
// src and tar are too colinear or too close from each other
|
// src and tar are too colinear or too close from each other
|
||||||
draw_line(painter, src_x, src_y, tar_x, tar_y);
|
draw_line(painter, src_x, src_y, tar_x, tar_y);
|
||||||
return;
|
return;
|
||||||
|
|
@ -102,7 +118,7 @@ void DemoWindowItem::draw_edge(QPainter* painter, Point source, Point target){
|
||||||
// 1. Compute the center of the circle supporting the geodesic between src and tar
|
// 1. Compute the center of the circle supporting the geodesic between src and tar
|
||||||
|
|
||||||
// 1.a Inverse src and tar with respect to the unit circle and find the euclidean midpoints of the segments between respectively
|
// 1.a Inverse src and tar with respect to the unit circle and find the euclidean midpoints of the segments between respectively
|
||||||
// src and it's inversion, and tar and it's inversion
|
// src and its inversion, and tar and its inversion
|
||||||
|
|
||||||
double src_norm_2 = src_x*src_x + src_y*src_y; // Can't be too close to zero because determinant was not
|
double src_norm_2 = src_x*src_x + src_y*src_y; // Can't be too close to zero because determinant was not
|
||||||
double tar_norm_2 = tar_x*tar_x + tar_y*tar_y; // Can't be too close to zero because determinant was not
|
double tar_norm_2 = tar_x*tar_x + tar_y*tar_y; // Can't be too close to zero because determinant was not
|
||||||
|
|
@ -118,10 +134,9 @@ void DemoWindowItem::draw_edge(QPainter* painter, Point source, Point target){
|
||||||
double tar_mid_x = (tar_x + tar_inv_x) / 2;
|
double tar_mid_x = (tar_x + tar_inv_x) / 2;
|
||||||
double tar_mid_y = (tar_y + tar_inv_y) / 2;
|
double tar_mid_y = (tar_y + tar_inv_y) / 2;
|
||||||
|
|
||||||
// 1.b Solve a system to find the intersection (center_x, center_y) of the bisectors of the two segments [src, src_inv] and [tar, tar_inv] :
|
// 1.b Solve a system to find the intersection (center_x, center_y) of the bisectors of the two segments [src, src_inv] and [tar, tar_inv]:
|
||||||
// (center_x \\ center y) = (a & b \\ c & d)^{-1} \times (u_x \\ u_y)
|
// (center_x \\ center y) = (a & b \\ c & d)^{-1} \times (u_x \\ u_y)
|
||||||
|
|
||||||
|
|
||||||
// 1.b.i define the system
|
// 1.b.i define the system
|
||||||
|
|
||||||
double a = src_x;
|
double a = src_x;
|
||||||
|
|
@ -141,9 +156,10 @@ void DemoWindowItem::draw_edge(QPainter* painter, Point source, Point target){
|
||||||
draw_arc(painter, src_x, src_y, tar_x, tar_y, center_x, center_y);
|
draw_arc(painter, src_x, src_y, tar_x, tar_y, center_x, center_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DemoWindowItem::draw_line(QPainter* painter,
|
||||||
void DemoWindowItem::draw_line(QPainter* painter, double point_1_x, double point_1_y, double point_2_x, double point_2_y){
|
double point_1_x, double point_1_y,
|
||||||
|
double point_2_x, double point_2_y)
|
||||||
|
{
|
||||||
// Convert to doubles and scale by the radius of the poincaré disk
|
// Convert to doubles and scale by the radius of the poincaré disk
|
||||||
double src_x = _poincare_disk_radius_in_pixels * point_1_x;
|
double src_x = _poincare_disk_radius_in_pixels * point_1_x;
|
||||||
double src_y = _poincare_disk_radius_in_pixels * point_1_y;
|
double src_y = _poincare_disk_radius_in_pixels * point_1_y;
|
||||||
|
|
@ -155,9 +171,11 @@ void DemoWindowItem::draw_line(QPainter* painter, double point_1_x, double point
|
||||||
painter->drawLine(line);
|
painter->drawLine(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DemoWindowItem::draw_arc(QPainter* painter,
|
||||||
void DemoWindowItem::draw_arc(QPainter* painter, double point_1_x, double point_1_y,
|
double point_1_x, double point_1_y,
|
||||||
double point_2_x, double point_2_y, double center_x, double center_y){
|
double point_2_x, double point_2_y,
|
||||||
|
double center_x, double center_y)
|
||||||
|
{
|
||||||
// Draws the arc supported by the circle whose center is (center_x, center_y) and whose extremities are src and tar
|
// Draws the arc supported by the circle whose center is (center_x, center_y) and whose extremities are src and tar
|
||||||
|
|
||||||
// 1. Scale by the radius of the poincaré disk
|
// 1. Scale by the radius of the poincaré disk
|
||||||
|
|
@ -183,7 +201,7 @@ void DemoWindowItem::draw_arc(QPainter* painter, double point_1_x, double point_
|
||||||
// If the source and the target are too close from each other (less than 10 pixels) or if the circle is very big then just draw a line
|
// If the source and the target are too close from each other (less than 10 pixels) or if the circle is very big then just draw a line
|
||||||
double dist_sq = (src_x-tar_x)*(src_x-tar_x) + (src_y - tar_y)*(src_y-tar_y);
|
double dist_sq = (src_x-tar_x)*(src_x-tar_x) + (src_y - tar_y)*(src_y-tar_y);
|
||||||
double rad_sq = (xM-xc)*(xM-xc) + (yM-yc)*(yM-yc);
|
double rad_sq = (xM-xc)*(xM-xc) + (yM-yc)*(yM-yc);
|
||||||
if ( (dist_sq < 100) || (rad_sq > 1000 * dist_sq) ){
|
if ((dist_sq < 100) || (rad_sq > 1000 * dist_sq)) {
|
||||||
QLineF line (src_x, src_y, tar_x, tar_y);
|
QLineF line (src_x, src_y, tar_x, tar_y);
|
||||||
painter->drawLine(line);
|
painter->drawLine(line);
|
||||||
return;
|
return;
|
||||||
|
|
@ -211,15 +229,16 @@ void DemoWindowItem::draw_arc(QPainter* painter, double point_1_x, double point_
|
||||||
painter->drawArc(bbox_rect, src_angle*16, sweep_angle*16);
|
painter->drawArc(bbox_rect, src_angle*16, sweep_angle*16);
|
||||||
}
|
}
|
||||||
|
|
||||||
double DemoWindowItem::deg_angle(double x, double y){
|
double DemoWindowItem::deg_angle(double x, double y)
|
||||||
|
{
|
||||||
// To avoid problems when further division by x (ok since x^2 + y^2 not too small) :
|
// To avoid problems when further division by x (ok since x^2 + y^2 not too small) :
|
||||||
if (x*x < computation_treshold_squared){
|
if (x*x < computation_treshold_squared) {
|
||||||
if (y>0) return 90;
|
if (y>0) return 90;
|
||||||
return -90;
|
return -90;
|
||||||
}
|
}
|
||||||
|
|
||||||
double angle = 180. * std::atan(y / x) / M_PI;
|
double angle = 180. * std::atan(y / x) / M_PI;
|
||||||
if (x < 0){
|
if (x < 0) {
|
||||||
return angle + 180.;
|
return angle + 180.;
|
||||||
}
|
}
|
||||||
return angle;
|
return angle;
|
||||||
|
|
@ -229,7 +248,8 @@ double DemoWindowItem::deg_angle(double x, double y){
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
DemoWindow::DemoWindow() : DemosMainWindow(){
|
DemoWindow::DemoWindow() : DemosMainWindow()
|
||||||
|
{
|
||||||
setupUi(this); // Method automatically generated by the ui file and here inherited from Ui::MainWindow. Builds the window and the contents for us...
|
setupUi(this); // Method automatically generated by the ui file and here inherited from Ui::MainWindow. Builds the window and the contents for us...
|
||||||
this->graphicsView->setScene(&_scene); // ... in particular graphicsView is already constructed : we just put our scene in it and then do things within the scene
|
this->graphicsView->setScene(&_scene); // ... in particular graphicsView is already constructed : we just put our scene in it and then do things within the scene
|
||||||
_scene.setItemIndexMethod(QGraphicsScene::NoIndex);
|
_scene.setItemIndexMethod(QGraphicsScene::NoIndex);
|
||||||
|
|
@ -241,7 +261,8 @@ DemoWindow::DemoWindow() : DemosMainWindow(){
|
||||||
setWindowTitle("Hyperbolic surfaces triangulation 2 Demo");
|
setWindowTitle("Hyperbolic surfaces triangulation 2 Demo");
|
||||||
}
|
}
|
||||||
|
|
||||||
DemoWindowItem& DemoWindow::item(){
|
DemoWindowItem& DemoWindow::item()
|
||||||
|
{
|
||||||
return *_item;
|
return *_item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
#include <CGAL/Exact_rational.h>
|
#include <CGAL/Exact_rational.h>
|
||||||
#include <CGAL/Simple_cartesian.h>
|
#include <CGAL/Simple_cartesian.h>
|
||||||
|
|
||||||
#include <CGAL/Hyperbolic_Delaunay_triangulation_traits_2.h>
|
#include <CGAL/Hyperbolic_Delaunay_triangulation_traits_2.h>
|
||||||
#include <CGAL/Hyperbolic_surface_traits_2.h>
|
#include <CGAL/Hyperbolic_surface_traits_2.h>
|
||||||
#include <CGAL/Triangulation_on_hyperbolic_surface_2.h>
|
#include <CGAL/Triangulation_on_hyperbolic_surface_2.h>
|
||||||
|
|
@ -33,13 +34,14 @@ typedef CGAL::Hyperbolic_surface_traits_2<ParentTraits>
|
||||||
typedef Traits::Hyperbolic_point_2 Point;
|
typedef Traits::Hyperbolic_point_2 Point;
|
||||||
typedef CGAL::Triangulation_on_hyperbolic_surface_2<Traits> Triangulation;
|
typedef CGAL::Triangulation_on_hyperbolic_surface_2<Traits> Triangulation;
|
||||||
|
|
||||||
class DemoWindowItem :
|
class DemoWindowItem
|
||||||
public CGAL::Qt::GraphicsItem
|
: public CGAL::Qt::GraphicsItem
|
||||||
{
|
{
|
||||||
Q_OBJECT // Qt macro for Qt objects
|
Q_OBJECT // Qt macro for Qt objects
|
||||||
// (Q_OBJECT does not support templates)
|
// (Q_OBJECT does not support templates)
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef CGAL::Bbox_2 Bbox_2; // "Bounding box" : just a box type used for drawing
|
typedef CGAL::Bbox_2 Bbox_2; // "Bounding box": just a box type used for drawing
|
||||||
|
|
||||||
// Edges to draw
|
// Edges to draw
|
||||||
std::vector<std::pair<Point,Point>> _edges;
|
std::vector<std::pair<Point,Point>> _edges;
|
||||||
|
|
@ -50,7 +52,9 @@ private:
|
||||||
|
|
||||||
// radius of the poincaré disk
|
// radius of the poincaré disk
|
||||||
const int _poincare_disk_radius_in_pixels = 600;
|
const int _poincare_disk_radius_in_pixels = 600;
|
||||||
// Approximation treshold : used to decide when to simplify a computation (ex : draw a line instead of an arc if an hyperbolic segment is very small)
|
|
||||||
|
// Approximation treshold: used to decide when to simplify a computation (ex: draw a line
|
||||||
|
// instead of an arc if an hyperbolic segment is very small)
|
||||||
const double computation_treshold = 0.001;
|
const double computation_treshold = 0.001;
|
||||||
const double computation_treshold_squared = computation_treshold*computation_treshold;
|
const double computation_treshold_squared = computation_treshold*computation_treshold;
|
||||||
|
|
||||||
|
|
@ -81,11 +85,13 @@ private:
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
class DemoWindow :
|
class DemoWindow
|
||||||
public CGAL::Qt::DemosMainWindow, public Ui::MainWindow
|
: public CGAL::Qt::DemosMainWindow,
|
||||||
|
public Ui::MainWindow
|
||||||
{
|
{
|
||||||
Q_OBJECT // Qt macro for Qt objects
|
Q_OBJECT // Qt macro for Qt objects
|
||||||
// (Q_OBJECT does not support templates)
|
// (Q_OBJECT does not support templates)
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QGraphicsScene _scene;
|
QGraphicsScene _scene;
|
||||||
DemoWindowItem* _item;
|
DemoWindowItem* _item;
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
namespace CGAL{
|
namespace CGAL {
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\ingroup PkgHyperbolicSurfaceTriangulation2MainClasses
|
\ingroup PkgHyperbolicSurfaceTriangulation2MainClasses
|
||||||
|
|
||||||
\cgalModels{ComplexNumber}
|
\cgalModels{ComplexNumber}
|
||||||
|
|
||||||
\tparam FT is the field type and must be a model of `FieldNumberType`.
|
\tparam FT is the field type and must be a model of `FieldNumberType`.
|
||||||
*/
|
*/
|
||||||
template <class FT>
|
template <class FT>
|
||||||
class Complex_number {
|
class Complex_number {
|
||||||
};
|
};
|
||||||
|
|
||||||
}; // namespace CGAL
|
} // namespace CGAL
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,34 @@
|
||||||
namespace CGAL{
|
namespace CGAL {
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\ingroup PkgHyperbolicSurfaceTriangulation2MainClasses
|
\ingroup PkgHyperbolicSurfaceTriangulation2MainClasses
|
||||||
|
|
||||||
represents a fundamental domain of a closed orientable hyperbolic surface.
|
represents a fundamental domain of a closed orientable hyperbolic surface.
|
||||||
The domain is given as a polygon \f$ P \f$ represented by the list of its vertices in the Poincaré disk model,
|
The domain is given as a polygon \f$ P \f$ represented by the list of its vertices in the Poincaré disk model,
|
||||||
together with a pairing of the sides of \f$ P \f$.
|
together with a pairing of the sides of \f$ P \f$.
|
||||||
The \f$ n \f$-th side of \f$ P \f$ is the side between the \f$ n \f$-th and the \f$ (n+1) \f$-th vertex, where indices are modulo the number of vertices of \f$ P \f$.
|
The \f$ n \f$-th side of \f$ P \f$ is the side between the \f$ n \f$-th and the \f$ (n+1) \f$-th vertex, where indices are modulo the number of vertices of \f$ P \f$.
|
||||||
The side pairings are represented by a list of integers, such that if the \f$ n \f$-th integer of the list is \f$ m \f$, then the \f$ n \f$-th side is paired to the \f$ m \f$-th side.
|
The side pairings are represented by a list of integers, such that if the \f$ n \f$-th integer of the list is \f$ m \f$, then the \f$ n \f$-th side is paired to the \f$ m \f$-th side.
|
||||||
|
|
||||||
\tparam Traits must be a model of `HyperbolicSurfaceTraits_2`.
|
\tparam Traits must be a model of `HyperbolicSurfaceTraits_2`.
|
||||||
|
|
||||||
\sa `Hyperbolic_fundamental_domain_factory_2`
|
\sa `Hyperbolic_fundamental_domain_factory_2`
|
||||||
*/
|
*/
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
class Hyperbolic_fundamental_domain_2 {
|
class Hyperbolic_fundamental_domain_2
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
/// \name Types
|
/// \name Types
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Point type.
|
Point type.
|
||||||
*/
|
*/
|
||||||
typedef typename Traits::Hyperbolic_point_2 Point;
|
typedef typename Traits::Hyperbolic_point_2 Point;
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
/// \name Creation
|
/// \name Creation
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Default constructor
|
Default constructor
|
||||||
*/
|
*/
|
||||||
|
|
@ -32,8 +36,9 @@ public:
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Constructor from vertices and pairings ranges.
|
Constructor from vertices and pairings ranges.
|
||||||
@tparam PointRange a model of the concepts `RandomAccessContainer` whose `value_type` is `Point`.
|
|
||||||
@tparam PairingRange a model of the concepts `RandomAccessContainer` whose `value_type` is `std::size_t`.
|
\tparam PointRange a model of the concepts `RandomAccessContainer` whose `value_type` is `Point`.
|
||||||
|
\tparam PairingRange a model of the concepts `RandomAccessContainer` whose `value_type` is `std::size_t`.
|
||||||
*/
|
*/
|
||||||
template<class PointRange, class PairingRange>
|
template<class PointRange, class PairingRange>
|
||||||
Hyperbolic_fundamental_domain_2(PointRange & vertices, PairingRange & pairings);
|
Hyperbolic_fundamental_domain_2(PointRange & vertices, PairingRange & pairings);
|
||||||
|
|
@ -41,6 +46,7 @@ public:
|
||||||
|
|
||||||
/// \name Access Functions
|
/// \name Access Functions
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
returns the number of vertices (equivalently, the number of sides) of the domain.
|
returns the number of vertices (equivalently, the number of sides) of the domain.
|
||||||
|
|
||||||
|
|
@ -68,24 +74,28 @@ public:
|
||||||
\pre <code> is_valid() </code>
|
\pre <code> is_valid() </code>
|
||||||
*/
|
*/
|
||||||
Hyperbolic_isometry_2<Traits> side_pairing(std::size_t i) const;
|
Hyperbolic_isometry_2<Traits> side_pairing(std::size_t i) const;
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/// @{
|
|
||||||
/// \name Validity
|
/// \name Validity
|
||||||
|
/// @{
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
checks that the number of vertices is even, that there are as many side pairings as vertices, and that the vertices all lie within the open unit disk.
|
checks that the number of vertices is even, that there are as many side pairings as vertices,
|
||||||
|
and that the vertices all lie within the open unit disk.
|
||||||
*/
|
*/
|
||||||
bool is_valid() const;
|
bool is_valid() const;
|
||||||
/// @}
|
|
||||||
|
|
||||||
|
/// @}
|
||||||
};
|
};
|
||||||
|
|
||||||
}; // namespace CGAL
|
} // namespace CGAL
|
||||||
|
|
||||||
/// \name Input/Output
|
/// \name Input/Output
|
||||||
/// @{
|
/// @{
|
||||||
/*!
|
|
||||||
inserts the domain in a stream.
|
/*!
|
||||||
|
\brief inserts the domain in a stream.
|
||||||
|
|
||||||
The format of the output is the following.
|
The format of the output is the following.
|
||||||
The first line prints the number \f$n\f$ of vertices of the domain.
|
The first line prints the number \f$n\f$ of vertices of the domain.
|
||||||
|
|
@ -93,13 +103,14 @@ public:
|
||||||
For \f$ i=0 \f$ to \f$ n-1 \f$ the i-th vertex is printed on a separate line.
|
For \f$ i=0 \f$ to \f$ n-1 \f$ the i-th vertex is printed on a separate line.
|
||||||
|
|
||||||
\pre <code> is_valid() </code>
|
\pre <code> is_valid() </code>
|
||||||
*/
|
*/
|
||||||
std::ostream& operator<<(std::ostream& s, const Hyperbolic_fundamental_domain_2<Traits>& domain);
|
std::ostream& operator<<(std::ostream& s, const Hyperbolic_fundamental_domain_2<Traits>& domain);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
extracts the domain from a stream.
|
\brief extracts the domain from a stream.
|
||||||
|
|
||||||
The format of the input must be the same as the format of the output of 'operator<<()'.
|
The format of the input must be the same as the format of the output of 'operator<<()'.
|
||||||
*/
|
*/
|
||||||
std::istream& operator>>(std::istream& s, Hyperbolic_fundamental_domain_2<Traits>& domain);
|
std::istream& operator>>(std::istream& s, Hyperbolic_fundamental_domain_2<Traits>& domain);
|
||||||
/// @}
|
|
||||||
|
/// @}
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,23 @@
|
||||||
namespace CGAL{
|
namespace CGAL {
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\ingroup PkgHyperbolicSurfaceTriangulation2MainClasses
|
\ingroup PkgHyperbolicSurfaceTriangulation2MainClasses
|
||||||
|
|
||||||
Factory class, whose only purpose is to construct random fundamental domains of
|
Factory class, whose only purpose is to construct random fundamental domains of
|
||||||
closed orientable hyperbolic surfaces.
|
closed orientable hyperbolic surfaces.
|
||||||
|
|
||||||
The function `make_hyperbolic_fundamental_domain_g2()` constructs such a domain for
|
The function `make_hyperbolic_fundamental_domain_g2()` constructs such a domain for
|
||||||
a surface of genus two.
|
a surface of genus two.
|
||||||
|
|
||||||
\tparam Traits must be a model of `HyperbolicSurfaceTraits_2`.
|
\tparam Traits must be a model of `HyperbolicSurfaceTraits_2`.
|
||||||
*/
|
*/
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
class Hyperbolic_fundamental_domain_factory_2{
|
class Hyperbolic_fundamental_domain_factory_2
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
/// \name Creation
|
/// \name Creation
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Constructor.
|
Constructor.
|
||||||
*/
|
*/
|
||||||
|
|
@ -24,13 +26,13 @@ public:
|
||||||
|
|
||||||
/// \name Generation of a domain in genus two.
|
/// \name Generation of a domain in genus two.
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
randomly generates a convex domain of a closed orientable hyperbolic surface
|
randomly generates a convex domain of a closed orientable hyperbolic surface of genus two from a seed.
|
||||||
of genus two from a seed.
|
|
||||||
*/
|
*/
|
||||||
Hyperbolic_fundamental_domain_2<Traits> make_hyperbolic_fundamental_domain_g2(unsigned int seed);
|
Hyperbolic_fundamental_domain_2<Traits> make_hyperbolic_fundamental_domain_g2(unsigned int seed);
|
||||||
/// @}
|
|
||||||
|
|
||||||
|
/// @}
|
||||||
};
|
};
|
||||||
|
|
||||||
}; // namespace CGAL
|
} // namespace CGAL
|
||||||
|
|
|
||||||
|
|
@ -1,40 +1,50 @@
|
||||||
namespace CGAL{
|
namespace CGAL {
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\ingroup PkgHyperbolicSurfaceTriangulation2MainClasses
|
\ingroup PkgHyperbolicSurfaceTriangulation2MainClasses
|
||||||
|
|
||||||
represents an isometry in the Poincaré disk model.
|
represents an isometry in the Poincaré disk model.
|
||||||
The isometry \f$ f \f$ is represented by a list \f$ (c_0, c_1, c_2, c_3) \f$ of complex numbers,
|
The isometry \f$ f \f$ is represented by a list \f$ (c_0, c_1, c_2, c_3) \f$ of complex numbers,
|
||||||
so that \f$ f(z) = (c_0 z + c_1) / (c_2 z + c_3) \f$ holds on every complex \f$ z \f$ in the open unit disk.
|
so that \f$ f(z) = (c_0 z + c_1) / (c_2 z + c_3) \f$ holds on every complex \f$ z \f$ in the open unit disk.
|
||||||
|
|
||||||
Functionalities are offered to compose isometries, and apply an isometry to a point.
|
Functionalities are offered to compose isometries, and apply an isometry to a point.
|
||||||
|
|
||||||
\tparam Traits must be a model of `HyperbolicSurfaceTraits_2`.
|
\tparam Traits must be a model of `HyperbolicSurfaceTraits_2`.
|
||||||
*/
|
*/
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
class Hyperbolic_isometry_2{
|
class Hyperbolic_isometry_2
|
||||||
public:
|
{
|
||||||
|
public:
|
||||||
/// \name Types
|
/// \name Types
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Complex number type.
|
Complex number type.
|
||||||
*/
|
*/
|
||||||
typedef typename Traits::Complex Complex_number;
|
typedef typename Traits::Complex Complex_number;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Point type.
|
Point type.
|
||||||
*/
|
*/
|
||||||
typedef typename Traits::Hyperbolic_point_2 Point;
|
typedef typename Traits::Hyperbolic_point_2 Point;
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/// \name Creation
|
/// \name Creation
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Default constructor to the identity.
|
Default constructor to the identity.
|
||||||
*/
|
*/
|
||||||
Hyperbolic_isometry_2();
|
Hyperbolic_isometry_2();
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Constructor from coefficients.
|
Constructor from coefficients.
|
||||||
*/
|
*/
|
||||||
Hyperbolic_isometry_2(const Complex_number& c0, const Complex_number& c1, const Complex_number& c2, const Complex_number& c3);
|
Hyperbolic_isometry_2(const Complex_number& c0,
|
||||||
|
const Complex_number& c1,
|
||||||
|
const Complex_number& c2,
|
||||||
|
const Complex_number& c3);
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
@ -44,47 +54,52 @@ class Hyperbolic_isometry_2{
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
sets the coefficients of the isometry.
|
sets the coefficients of the isometry.
|
||||||
\warning The implementation does not check that the
|
|
||||||
resulting transformation is an isometry.
|
|
||||||
|
|
||||||
|
\warning The implementation does not check that the resulting transformation is an isometry.
|
||||||
*/
|
*/
|
||||||
void set_coefficients(const Complex_number& c0, const Complex_number& c1, const Complex_number& c2, const Complex_number& c3);
|
void set_coefficients(const Complex_number& c0,
|
||||||
|
const Complex_number& c1,
|
||||||
|
const Complex_number& c2,
|
||||||
|
const Complex_number& c3);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
sets a particular coefficient of the isometry.
|
sets a particular coefficient of the isometry.
|
||||||
\warning The implementation does not check that the
|
|
||||||
resulting transformation is an isometry.
|
|
||||||
|
|
||||||
|
\warning The implementation does not check that the resulting transformation is an isometry.
|
||||||
*/
|
*/
|
||||||
void set_coefficient(int index, const Complex_number& coefficient);
|
void set_coefficient(int index, const Complex_number& coefficient);
|
||||||
|
|
||||||
/// \name Access Functions
|
/// \name Access Functions
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
returns the index-th coefficient.
|
returns the index-th coefficient.
|
||||||
*/
|
*/
|
||||||
const Complex_number& get_coefficient(int index) const;
|
const Complex_number& get_coefficient(int index) const;
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/// \name Operations
|
/// \name Operations
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
evaluates the isometry at point \f$ p \f$.
|
evaluates the isometry at point \f$ p \f$.
|
||||||
*/
|
*/
|
||||||
Point evaluate(const Point& p) const;
|
Point evaluate(const Point& p) const;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
evaluates the isometry at point \f$ p \f$.
|
evaluates the isometry at point \f$ p \f$.
|
||||||
*/
|
*/
|
||||||
Point operator()(const Point& p) const;
|
Point operator()(const Point& p) const;
|
||||||
|
|
||||||
/// @{
|
|
||||||
/*!
|
/*!
|
||||||
returns the composition of two isometries.
|
returns the composition of two isometries.
|
||||||
*/
|
*/
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
Hyperbolic_isometry_2<Traits> operator*(const Hyperbolic_isometry_2<Traits>& iso1, const Hyperbolic_isometry_2<Traits>& iso2);
|
Hyperbolic_isometry_2<Traits> operator*(const Hyperbolic_isometry_2<Traits>& iso1,
|
||||||
/// @}
|
const Hyperbolic_isometry_2<Traits>& iso2);
|
||||||
|
|
||||||
|
/// @}
|
||||||
};
|
};
|
||||||
|
|
||||||
}; // namespace CGAL
|
} // namespace CGAL
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
namespace CGAL{
|
namespace CGAL {
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\ingroup PkgHyperbolicSurfaceTriangulation2TraitsClasses
|
\ingroup PkgHyperbolicSurfaceTriangulation2TraitsClasses
|
||||||
|
|
||||||
\tparam HyperbolicTraits must be a model of `HyperbolicDelaunayTriangulationTraits_2`.
|
\tparam HyperbolicTraits must be a model of `HyperbolicDelaunayTriangulationTraits_2`.
|
||||||
|
|
||||||
\cgalModels{HyperbolicSurfaceTraits_2}
|
\cgalModels{HyperbolicSurfaceTraits_2}
|
||||||
*/
|
*/
|
||||||
template<class HyperbolicTraits>
|
template<class HyperbolicTraits>
|
||||||
class Hyperbolic_surface_traits_2 : public HyperbolicTraits {};
|
class Hyperbolic_surface_traits_2 : public HyperbolicTraits {};
|
||||||
|
|
||||||
}; // namespace CGAL
|
} // namespace CGAL
|
||||||
|
|
|
||||||
|
|
@ -1,97 +1,110 @@
|
||||||
namespace CGAL{
|
namespace CGAL {
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\ingroup PkgHyperbolicSurfaceTriangulation2MainClasses
|
\ingroup PkgHyperbolicSurfaceTriangulation2MainClasses
|
||||||
|
|
||||||
|
This item defines attributes of edges that are of type `Complex_number` reprensenting cross-ratios.
|
||||||
|
|
||||||
This item defines attributes of edges that are of type
|
\tparam Traits must be a model of `HyperbolicSurfaceTraits_2`.
|
||||||
`Complex_number` reprensenting cross-ratios.
|
|
||||||
|
|
||||||
\tparam Traits must be a model of `HyperbolicSurfaceTraits_2`.
|
\cgalModels{GenericMapItems}
|
||||||
|
|
||||||
\cgalModels{GenericMapItems}
|
|
||||||
*/
|
*/
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
struct Combinatorial_map_with_cross_ratios_item{
|
struct Combinatorial_map_with_cross_ratios_item
|
||||||
|
{
|
||||||
template <class CMap>
|
template <class CMap>
|
||||||
struct Dart_wrapper{
|
struct Dart_wrapper
|
||||||
typedef Cell_attribute<CMap, Complex_number<typename Traits::FT>> Edge_attrib;
|
{
|
||||||
typedef std::tuple<void,Edge_attrib,void> Attributes;
|
typedef Cell_attribute<CMap, Complex_number<typename Traits::FT> > Edge_attrib;
|
||||||
|
typedef std::tuple<void, Edge_attrib, void> Attributes;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\ingroup PkgHyperbolicSurfaceTriangulation2MainClasses
|
\ingroup PkgHyperbolicSurfaceTriangulation2MainClasses
|
||||||
|
|
||||||
represents a triangulation of a closed orientable hyperbolic surface.
|
represents a triangulation of a closed orientable hyperbolic surface.
|
||||||
|
|
||||||
The class provides functions such as the generation of the triangulation from a convex fundamental domain,
|
The class provides functions such as the generation of the triangulation from a convex fundamental domain,
|
||||||
the Delaunay flip algorithm, and the construction of a portion of the lift of the triangulation in the hyperbolic plane.
|
the Delaunay flip algorithm, and the construction of a portion of the lift of the triangulation in the hyperbolic plane.
|
||||||
|
|
||||||
\tparam Traits must be a model of `HyperbolicSurfaceTraits_2`.
|
\tparam Traits must be a model of `HyperbolicSurfaceTraits_2`.
|
||||||
|
\tparam Attributes must be a model of `GenericMapItems` whose edges are
|
||||||
\tparam Attributes must be a model of `GenericMapItems` whose edges are
|
decorated with complex numbers to represent cross ratios.
|
||||||
decorated with complex numbers to represent cross ratios.
|
|
||||||
*/
|
*/
|
||||||
template<class Traits, class Attributes = Combinatorial_map_with_cross_ratios_item<Traits>>
|
template<class Traits, class Attributes = Combinatorial_map_with_cross_ratios_item<Traits> >
|
||||||
class Triangulation_on_hyperbolic_surface_2
|
class Triangulation_on_hyperbolic_surface_2
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// \name Types
|
/// \name Types
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Type of combinatorial map whose edges are decorated with complex numbers.
|
Type of combinatorial map whose edges are decorated with complex numbers.
|
||||||
*/
|
*/
|
||||||
typedef Combinatorial_map<2, Attributes> Combinatorial_map_with_cross_ratios;
|
typedef Combinatorial_map<2, Attributes> Combinatorial_map_with_cross_ratios;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Combinatorial map dart descriptor type.
|
Combinatorial map dart descriptor type.
|
||||||
*/
|
*/
|
||||||
typedef typename Combinatorial_map_with_cross_ratios::Dart_descriptor Dart_descriptor;
|
typedef typename Combinatorial_map_with_cross_ratios::Dart_descriptor Dart_descriptor;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Combinatorial map dart const descriptor type.
|
Combinatorial map dart const descriptor type.
|
||||||
*/
|
*/
|
||||||
typedef typename Combinatorial_map_with_cross_ratios::Dart_const_descriptor Dart_const_descriptor;
|
typedef typename Combinatorial_map_with_cross_ratios::Dart_const_descriptor Dart_const_descriptor;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Range of one dart for each vertex (that is 0-cell) of the combinatorial map.
|
Range of one dart for each vertex (that is 0-cell) of the combinatorial map.
|
||||||
*/
|
*/
|
||||||
typedef typename Combinatorial_map_with_cross_ratios::template One_dart_per_cell_range<0> Vertex_range;
|
typedef typename Combinatorial_map_with_cross_ratios::template One_dart_per_cell_range<0> Vertex_range;
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Range of one dart for each edge (that is 1-cell) of the combinatorial map.
|
Range of one dart for each edge (that is 1-cell) of the combinatorial map.
|
||||||
*/
|
*/
|
||||||
typedef typename Combinatorial_map_with_cross_ratios::template One_dart_per_cell_range<1> Edge_range;
|
typedef typename Combinatorial_map_with_cross_ratios::template One_dart_per_cell_range<1> Edge_range;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Range of one dart for each face (that is 2-cell) of the combinatorial map.
|
Range of one dart for each face (that is 2-cell) of the combinatorial map.
|
||||||
*/
|
*/
|
||||||
typedef typename Combinatorial_map_with_cross_ratios::template One_dart_per_cell_range<2> Face_range;
|
typedef typename Combinatorial_map_with_cross_ratios::template One_dart_per_cell_range<2> Face_range;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Range of one dart for each vertex (that is 0-cell) of the combinatorial map.
|
Range of one dart for each vertex (that is 0-cell) of the combinatorial map.
|
||||||
*/
|
*/
|
||||||
typedef typename Combinatorial_map_with_cross_ratios::template One_dart_per_cell_const_range<0> Vertex_const_range;
|
typedef typename Combinatorial_map_with_cross_ratios::template One_dart_per_cell_const_range<0> Vertex_const_range;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Range of one dart for each edge (that is 1-cell) of the combinatorial map.
|
Range of one dart for each edge (that is 1-cell) of the combinatorial map.
|
||||||
*/
|
*/
|
||||||
typedef typename Combinatorial_map_with_cross_ratios::template One_dart_per_cell_const_range<1> Edge_const_range;
|
typedef typename Combinatorial_map_with_cross_ratios::template One_dart_per_cell_const_range<1> Edge_const_range;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Range of one dart for each face (that is 2-cell) of the combinatorial map.
|
Range of one dart for each face (that is 2-cell) of the combinatorial map.
|
||||||
*/
|
*/
|
||||||
typedef typename Combinatorial_map_with_cross_ratios::template One_dart_per_cell_const_range<2> Face_const_range;
|
typedef typename Combinatorial_map_with_cross_ratios::template One_dart_per_cell_const_range<2> Face_const_range;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Point type.
|
Point type.
|
||||||
*/
|
*/
|
||||||
typedef typename Traits::Hyperbolic_point_2 Point;
|
typedef typename Traits::Hyperbolic_point_2 Point;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
stores a dart \f$ d \f$ of the combinatorial map, belonging to a triangle \f$ t \f$, and stores the three vertices of a lift of \f$ t \f$ in the hyperbolic plane.
|
stores a dart \f$ d \f$ of the combinatorial map, belonging to a triangle \f$ t \f$,
|
||||||
|
and stores the three vertices of a lift of \f$ t \f$ in the hyperbolic plane.
|
||||||
*/
|
*/
|
||||||
struct Anchor{
|
struct Anchor
|
||||||
|
{
|
||||||
typename Combinatorial_map_with_cross_ratios::Dart_descriptor dart;
|
typename Combinatorial_map_with_cross_ratios::Dart_descriptor dart;
|
||||||
typename Traits::Hyperbolic_point_2 vertices[3];
|
typename Traits::Hyperbolic_point_2 vertices[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/// \name Creation
|
/// \name Creation
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Default constructor.
|
Default constructor.
|
||||||
*/
|
*/
|
||||||
|
|
@ -110,18 +123,22 @@ public:
|
||||||
Constructor from a decorated combinatorial map and an anchor.
|
Constructor from a decorated combinatorial map and an anchor.
|
||||||
*/
|
*/
|
||||||
Triangulation_on_hyperbolic_surface_2(Combinatorial_map_with_cross_ratios& cmap, Anchor& an_anchor);
|
Triangulation_on_hyperbolic_surface_2(Combinatorial_map_with_cross_ratios& cmap, Anchor& an_anchor);
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/// \name Assignment
|
/// \name Assignment
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\pre <code> other.is_valid() </code>
|
\pre <code> other.is_valid() </code>
|
||||||
*/
|
*/
|
||||||
Triangulation_on_hyperbolic_surface_2& operator=(Triangulation_on_hyperbolic_surface_2 other);
|
Triangulation_on_hyperbolic_surface_2& operator=(Triangulation_on_hyperbolic_surface_2 other);
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/// \name Access Functions
|
/// \name Access Functions
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
returns the decorated combinatorial map.
|
returns the decorated combinatorial map.
|
||||||
*/
|
*/
|
||||||
|
|
@ -129,54 +146,60 @@ public:
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
returns whether the triangulation has an anchor or not.
|
returns whether the triangulation has an anchor or not.
|
||||||
|
|
||||||
\pre <code> is_valid() </code>
|
\pre <code> is_valid() </code>
|
||||||
*/
|
*/
|
||||||
bool has_anchor() const;
|
bool has_anchor() const;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
returns the anchor.
|
returns the anchor.
|
||||||
|
|
||||||
\pre <code> is_valid() && has_anchor() </code>
|
\pre <code> is_valid() && has_anchor() </code>
|
||||||
*/
|
*/
|
||||||
Anchor& anchor();
|
Anchor& anchor();
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
returns the anchor.
|
returns the anchor.
|
||||||
|
|
||||||
\pre <code> is_valid() && has_anchor() </code>
|
\pre <code> is_valid() && has_anchor() </code>
|
||||||
*/
|
*/
|
||||||
const Anchor& anchor() const;
|
const Anchor& anchor() const;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
returns the range of vertices.
|
returns the range of vertices.
|
||||||
*/
|
*/
|
||||||
Vertex_range vertices_range();
|
Vertex_range vertices_range();
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
returns the range of edges.
|
returns the range of edges.
|
||||||
*/
|
*/
|
||||||
Edge_range edges_range();
|
Edge_range edges_range();
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
returns the range of faces.
|
returns the range of faces.
|
||||||
*/
|
*/
|
||||||
Face_range faces_range();
|
Face_range faces_range();
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
returns the range of vertices.
|
returns the range of vertices.
|
||||||
*/
|
*/
|
||||||
Vertex_const_range vertices_const_range() const;
|
Vertex_const_range vertices_const_range() const;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
returns the range of edges.
|
returns the range of edges.
|
||||||
*/
|
*/
|
||||||
Edge_const_range edges_const_range() const;
|
Edge_const_range edges_const_range() const;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
returns the range of faces.
|
returns the range of faces.
|
||||||
*/
|
*/
|
||||||
Face_const_range faces_const_range() const;
|
Face_const_range faces_const_range() const;
|
||||||
/// @}
|
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
/// \name Delaunay Flip Algorithm
|
/// \name Delaunay Flip Algorithm
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
returns whether the edge supported by the dart is Delaunay flippable or not. An edge \f$ e \f$ is Delaunay flippable if the imaginary part of its cross ratio is positive.
|
returns whether the edge supported by the dart is Delaunay flippable or not. An edge \f$ e \f$
|
||||||
|
is Delaunay flippable if the imaginary part of its cross ratio is positive.
|
||||||
|
|
||||||
\pre <code> is_valid() </code>
|
\pre <code> is_valid() </code>
|
||||||
*/
|
*/
|
||||||
|
|
@ -196,16 +219,18 @@ Face_const_range faces_const_range() const;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
applies the Delaunay flip algorithm: flips Delaunay-flippable edges until there is no such edge anymore.
|
applies the Delaunay flip algorithm: flips Delaunay-flippable edges until there is no such edge anymore.
|
||||||
|
|
||||||
\pre <code> is_valid() </code>
|
\pre <code> is_valid() </code>
|
||||||
*/
|
*/
|
||||||
int make_Delaunay();
|
int make_Delaunay();
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/// \name Lifting
|
/// \name Lifting
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
lifts the triangulation in the hyperbolic plane.
|
lifts the triangulation in the hyperbolic plane.
|
||||||
|
|
||||||
Returns, for every triangle \f$ t \f$ of the triangulation, one of the darts of \f$ t \f$ in the combinatorial map of the triangulation, together with a triple \f$ p,q,r \f$ of points in the hyperbolic plane.
|
Returns, for every triangle \f$ t \f$ of the triangulation, one of the darts of \f$ t \f$ in the combinatorial map of the triangulation, together with a triple \f$ p,q,r \f$ of points in the hyperbolic plane.
|
||||||
The points \f$ p,q,r \f$ are the vertices of a lift of \f$ t \f$ in the hyperbolic plane.
|
The points \f$ p,q,r \f$ are the vertices of a lift of \f$ t \f$ in the hyperbolic plane.
|
||||||
If the center parameter is set to true, then one of the vertices of the anchor is translated to the origin \f$ 0 \f$.
|
If the center parameter is set to true, then one of the vertices of the anchor is translated to the origin \f$ 0 \f$.
|
||||||
|
|
@ -213,17 +238,21 @@ Face_const_range faces_const_range() const;
|
||||||
\pre <code> is_valid() && has_anchor() </code>
|
\pre <code> is_valid() && has_anchor() </code>
|
||||||
*/
|
*/
|
||||||
std::vector<std::tuple<Dart_const_descriptor, Point, Point, Point>> lift(bool center=true) const;
|
std::vector<std::tuple<Dart_const_descriptor, Point, Point, Point>> lift(bool center=true) const;
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/// \name Validity
|
/// \name Validity
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
checks that the underlying combinatorial map \f$ M \f$ has no boundary and calls the is_valid method of \f$ M \f$.
|
checks that the underlying combinatorial map \f$ M \f$ has no boundary and calls the is_valid method of \f$ M \f$.
|
||||||
If there is an anchor, then checks that the dart descriptor of the anchor does indeed point to a dart of \f$ M \f$, and checks that the three vertices of the anchor lie within the open unit disk.
|
|
||||||
|
If there is an anchor, then checks that the dart descriptor of the anchor does indeed point to a dart of \f$ M \f$,
|
||||||
|
and checks that the three vertices of the anchor lie within the open unit disk.
|
||||||
*/
|
*/
|
||||||
bool is_valid() const;
|
bool is_valid() const;
|
||||||
/// @}
|
|
||||||
|
|
||||||
|
/// @}
|
||||||
};
|
};
|
||||||
|
|
||||||
}; // namespace CGAL
|
} // namespace CGAL
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,37 @@
|
||||||
namespace CGAL{
|
namespace CGAL {
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\ingroup PkgHyperbolicSurfaceTriangulation2InputOutput
|
\ingroup PkgHyperbolicSurfaceTriangulation2InputOutput
|
||||||
|
|
||||||
inserts the triangulation in a stream.
|
inserts the triangulation in a stream.
|
||||||
|
|
||||||
The format of the output is the following.
|
The format of the output is the following.
|
||||||
Each dart of the triangulation is given an index between \f$ 0 \f$ and \f$ n-1 \f$, where \f$ n \f$ is the number of darts of the triangulation.
|
Each dart of the triangulation is given an index between \f$ 0 \f$ and \f$ n-1 \f$, where \f$ n \f$
|
||||||
|
is the number of darts of the triangulation.
|
||||||
The first line contains the number \f$ n \f$ of darts.
|
The first line contains the number \f$ n \f$ of darts.
|
||||||
The next line contains either 'yes' or 'no' and tells whether the triangulation has an anchor.
|
The next line contains either 'yes' or 'no' and tells whether the triangulation has an anchor.
|
||||||
If the triangulation has an anchor, then the four next lines print the index of the dart of the anchor, and the three vertices of the anchor.
|
If the triangulation has an anchor, then the four next lines print the index of the dart of the anchor,
|
||||||
|
and the three vertices of the anchor.
|
||||||
Then, for every triangle \f$ t \f$, the indices of the three darts of \f$ t \f$ are printed on three distinct lines.
|
Then, for every triangle \f$ t \f$, the indices of the three darts of \f$ t \f$ are printed on three distinct lines.
|
||||||
Finally, for every edge \f$ e \f$, the indices of the two darts of \f$ e \f$ are printed on two distinct lines, followed by a third line on which the cross ratio of \f$ e \f$ is printed.
|
Finally, for every edge \f$ e \f$, the indices of the two darts of \f$ e \f$ are printed on two distinct lines, followed by a third line on which the cross ratio of \f$ e \f$ is printed.
|
||||||
|
|
||||||
\pre <code> Triangulation_on_hyperbolic_surface_2<Traits>::is_valid() </code>
|
\pre <code> Triangulation_on_hyperbolic_surface_2<Traits>::is_valid() </code>
|
||||||
*/
|
*/
|
||||||
std::ostream& operator<<(std::ostream& s, const Triangulation_on_hyperbolic_surface_2<Traits>& triangulation);
|
std::ostream& operator<<(std::ostream& s, const Triangulation_on_hyperbolic_surface_2<Traits>& triangulation);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\ingroup PkgHyperbolicSurfaceTriangulation2InputOutput
|
\ingroup PkgHyperbolicSurfaceTriangulation2InputOutput
|
||||||
|
|
||||||
extracts the triangulation from a stream.
|
extracts the triangulation from a stream.
|
||||||
|
|
||||||
The format of the input should be the same as the format of the output of
|
The format of the input should be the same as the format of the output of
|
||||||
the '<<' operator for Triangulation_on_hyperbolic_surface_2.
|
the '<<' operator for Triangulation_on_hyperbolic_surface_2.
|
||||||
*/
|
*/
|
||||||
std::istream& operator>>(std::istream& s, Triangulation_on_hyperbolic_surface_2<Traits>& triangulation);
|
std::istream& operator>>(std::istream& s, Triangulation_on_hyperbolic_surface_2<Traits>& triangulation);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\ingroup PkgHyperbolicSurfaceTriangulation2InputOutput
|
\ingroup PkgHyperbolicSurfaceTriangulation2InputOutput
|
||||||
|
|
||||||
inserts the domain in a stream.
|
inserts the domain in a stream.
|
||||||
|
|
||||||
The format of the output is the following.
|
The format of the output is the following.
|
||||||
|
|
@ -33,22 +40,24 @@ namespace CGAL{
|
||||||
For \f$ i=0 \f$ to \f$ n-1 \f$ the i-th vertex is printed on a separate line.
|
For \f$ i=0 \f$ to \f$ n-1 \f$ the i-th vertex is printed on a separate line.
|
||||||
|
|
||||||
\pre <code> Hyperbolic_fundamental_domain_2< Traits >::is_valid() </code>
|
\pre <code> Hyperbolic_fundamental_domain_2< Traits >::is_valid() </code>
|
||||||
*/
|
*/
|
||||||
std::ostream& operator<<(std::ostream& s, const Hyperbolic_fundamental_domain_2<Traits>& domain);
|
std::ostream& operator<<(std::ostream& s, const Hyperbolic_fundamental_domain_2<Traits>& domain);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\ingroup PkgHyperbolicSurfaceTriangulation2InputOutput
|
\ingroup PkgHyperbolicSurfaceTriangulation2InputOutput
|
||||||
|
|
||||||
extracts the domain from a stream.
|
extracts the domain from a stream.
|
||||||
|
|
||||||
The format of the input must be the same as the format of the output of
|
The format of the input must be the same as the format of the output of
|
||||||
the '<<' operator for Hyperbolic_fundamental_domain_2.
|
the '<<' operator for Hyperbolic_fundamental_domain_2.
|
||||||
*/
|
*/
|
||||||
std::istream& operator>>(std::istream& s, Hyperbolic_fundamental_domain_2<Traits>& domain);
|
std::istream& operator>>(std::istream& s, Hyperbolic_fundamental_domain_2<Traits>& domain);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\ingroup PkgHyperbolicSurfaceTriangulation2InputOutput
|
\ingroup PkgHyperbolicSurfaceTriangulation2InputOutput
|
||||||
inserts the isometry in a stream.
|
|
||||||
*/
|
|
||||||
std::ostream& operator<<(std::ostream& s, const Hyperbolic_isometry_2<Traits>& isometry);
|
|
||||||
|
|
||||||
}; // namespace CGAL
|
inserts the isometry in a stream.
|
||||||
|
*/
|
||||||
|
std::ostream& operator<<(std::ostream& s, const Hyperbolic_isometry_2<Traits>& isometry);
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
|
||||||
|
|
@ -1,29 +1,31 @@
|
||||||
// Copyright (c) 2024 INRIA Nancy - Grand Est (France). LIGM Marne-la-Vallée (France)
|
|
||||||
// All rights reserved.
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\ingroup PkgHyperbolicSurfaceTriangulation2Concepts
|
\ingroup PkgHyperbolicSurfaceTriangulation2Concepts
|
||||||
\cgalConcept
|
\cgalConcept
|
||||||
|
|
||||||
Describes a complex number type over a `FieldNumberType` for its real and
|
Describes a complex number type over a `FieldNumberType` for its real and imaginary parts.
|
||||||
imaginary parts.
|
|
||||||
|
|
||||||
\cgalRefines{Field}
|
\cgalRefines{Field}
|
||||||
|
|
||||||
\cgalHasModelsBegin
|
\cgalHasModelsBegin
|
||||||
\cgalHasModels{CGAL::Complex_number}
|
\cgalHasModels{CGAL::Complex_number}
|
||||||
\cgalHasModelsEnd
|
\cgalHasModelsEnd
|
||||||
*/
|
*/
|
||||||
class ComplexNumber {
|
class ComplexNumber
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
/// \name Types
|
/// \name Types
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Number type for real and imaginary parts: must be a model of `FieldNumberType`.
|
Number type for real and imaginary parts: must be a model of `FieldNumberType`.
|
||||||
*/
|
*/
|
||||||
typedef unspecified_type FT;
|
typedef unspecified_type FT;
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
/// \name Creation
|
/// \name Creation
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Default constructor, sets the both the real part and the imaginary part to \f$ 0 \f$.
|
Default constructor, sets the both the real part and the imaginary part to \f$ 0 \f$.
|
||||||
*/
|
*/
|
||||||
|
|
@ -46,10 +48,12 @@ public:
|
||||||
*/
|
*/
|
||||||
template<class U,class V>
|
template<class U,class V>
|
||||||
ComplexNumber(U&& real_part, V&& imaginary_part);
|
ComplexNumber(U&& real_part, V&& imaginary_part);
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/// \name Get and Set
|
/// \name Getter and Setter
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
sets the real part to <code> real_part </code>.
|
sets the real part to <code> real_part </code>.
|
||||||
*/
|
*/
|
||||||
|
|
@ -69,86 +73,32 @@ public:
|
||||||
returns the imaginary part.
|
returns the imaginary part.
|
||||||
*/
|
*/
|
||||||
FT imag() const;
|
FT imag() const;
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/// \name Operations
|
/// \name Operations
|
||||||
/// @{
|
/// @{
|
||||||
/* /\*! */
|
|
||||||
/* returns +z. */
|
|
||||||
/* *\/ */
|
|
||||||
/* //ComplexNumber operator+(const ComplexNumber& z) const; */
|
|
||||||
|
|
||||||
/* /\*! */
|
|
||||||
/* returns -z. */
|
|
||||||
/* *\/ */
|
|
||||||
/* //ComplexNumber operator-(const ComplexNumber& z) const; */
|
|
||||||
|
|
||||||
/* /\*! */
|
|
||||||
/* Unary complex addition. */
|
|
||||||
/* *\/ */
|
|
||||||
/* //ComplexNumber operator+=(const ComplexNumber& other) const; */
|
|
||||||
|
|
||||||
/* /\*! */
|
|
||||||
/* Unary complex substraction. */
|
|
||||||
/* *\/ */
|
|
||||||
/* //ComplexNumber operator-=(const ComplexNumber& other) const; */
|
|
||||||
|
|
||||||
/* /\*! */
|
|
||||||
/* Unary complex multiplication. */
|
|
||||||
/* *\/ */
|
|
||||||
/* //ComplexNumber operator*=(const ComplexNumber& other) const; */
|
|
||||||
|
|
||||||
/* /\*! */
|
|
||||||
/* Unary complex division. */
|
|
||||||
/* *\/ */
|
|
||||||
/* //ComplexNumber operator/=(const ComplexNumber& other) const; */
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Copy operator.
|
Copy operator.
|
||||||
*/
|
*/
|
||||||
ComplexNumber operator=(const ComplexNumber& other) const;
|
ComplexNumber operator=(const ComplexNumber& other) const;
|
||||||
|
|
||||||
/* /\*! */
|
|
||||||
/* Equality test. */
|
|
||||||
/* *\/ */
|
|
||||||
/* //bool operator==(const ComplexNumber& z1, const ComplexNumber& z2); */
|
|
||||||
/* /\*! */
|
|
||||||
/* Inequality test. */
|
|
||||||
/* *\/ */
|
|
||||||
/* // bool operator!=(const ComplexNumber& z1, const ComplexNumber& z2); */
|
|
||||||
|
|
||||||
/* /\*! */
|
|
||||||
/* Binary complex addition. */
|
|
||||||
/* *\/ */
|
|
||||||
/* //ComplexNumber operator+(const ComplexNumber& z1, const ComplexNumber& z2); */
|
|
||||||
|
|
||||||
/* /\*! */
|
|
||||||
/* Binary complex substraction. */
|
|
||||||
/* *\/ */
|
|
||||||
/* //ComplexNumber operator-(const ComplexNumber& z1, const ComplexNumber& z2); */
|
|
||||||
|
|
||||||
/* /\*! */
|
|
||||||
/* Binary complex multiplication. */
|
|
||||||
/* *\/ */
|
|
||||||
/* //ComplexNumber operator*(const ComplexNumber& z1, const ComplexNumber& z2); */
|
|
||||||
|
|
||||||
/* /\*! */
|
|
||||||
/* Binary complex division. */
|
|
||||||
/* *\/ */
|
|
||||||
/* //ComplexNumber operator/(const ComplexNumber& z1, const ComplexNumber& z2); */
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
writes the complex in a stream.
|
writes the complex in a stream.
|
||||||
*/
|
*/
|
||||||
std::ostream& operator<<(std::ostream& s, const ComplexNumber& z);
|
std::ostream& operator<<(std::ostream& s, const ComplexNumber& z);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
reads the complex from a stream.
|
reads the complex from a stream.
|
||||||
*/
|
*/
|
||||||
void operator>>(std::istream& s, ComplexNumber& z);
|
void operator>>(std::istream& s, ComplexNumber& z);
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/// \relates ComplexNumber
|
/// \relates ComplexNumber
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
returns the square of the modulus.
|
returns the square of the modulus.
|
||||||
*/
|
*/
|
||||||
|
|
@ -158,5 +108,6 @@ public:
|
||||||
returns the conjugate.
|
returns the conjugate.
|
||||||
*/
|
*/
|
||||||
ComplexNumber conj(ComplexNumber z) const;
|
ComplexNumber conj(ComplexNumber z) const;
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,26 @@
|
||||||
/*!
|
/*!
|
||||||
\ingroup PkgHyperbolicSurfaceTriangulation2Concepts
|
\ingroup PkgHyperbolicSurfaceTriangulation2Concepts
|
||||||
\cgalConcept
|
\cgalConcept
|
||||||
|
|
||||||
This traits class must have a type for complex numbers.
|
This traits class must have a type for complex numbers.
|
||||||
|
|
||||||
\cgalRefines{HyperbolicDelaunayTriangulationTraits_2}
|
\cgalRefines{HyperbolicDelaunayTriangulationTraits_2}
|
||||||
|
|
||||||
\cgalHasModelsBegin
|
\cgalHasModelsBegin
|
||||||
\cgalHasModels{CGAL::Hyperbolic_surface_traits_2}
|
\cgalHasModels{CGAL::Hyperbolic_surface_traits_2}
|
||||||
\cgalHasModelsEnd
|
\cgalHasModelsEnd
|
||||||
*/
|
*/
|
||||||
class HyperbolicSurfaceTraits_2 {
|
class HyperbolicSurfaceTraits_2
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
/// \name Types
|
/// \name Types
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
represents a complex number, model of
|
represents a complex number, model of `ComplexNumber`,
|
||||||
`ComplexNumber`, over the field `HyperbolicSurfaceTraits_2::FT` for its real and
|
over the field `HyperbolicSurfaceTraits_2::FT` for its real and imaginary parts.
|
||||||
imaginary parts.
|
|
||||||
*/
|
*/
|
||||||
typedef unspecified_type Complex;
|
typedef unspecified_type Complex;
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@
|
||||||
/// \defgroup PkgHyperbolicSurfaceTriangulation2InputOutput Input/Output Functions
|
/// \defgroup PkgHyperbolicSurfaceTriangulation2InputOutput Input/Output Functions
|
||||||
/// \ingroup PkgHyperbolicSurfaceTriangulation2Ref
|
/// \ingroup PkgHyperbolicSurfaceTriangulation2Ref
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\addtogroup PkgHyperbolicSurfaceTriangulation2Ref
|
\addtogroup PkgHyperbolicSurfaceTriangulation2Ref
|
||||||
|
|
||||||
|
|
@ -26,7 +25,7 @@
|
||||||
\cgalPkgSummaryEnd
|
\cgalPkgSummaryEnd
|
||||||
|
|
||||||
\cgalPkgShortInfoBegin
|
\cgalPkgShortInfoBegin
|
||||||
\cgalPkgSince{6}
|
\cgalPkgSince{6.1}
|
||||||
\cgalPkgDependsOn{\ref PkgCombinatorialMaps}
|
\cgalPkgDependsOn{\ref PkgCombinatorialMaps}
|
||||||
\cgalPkgBib{cgal:y-t2}
|
\cgalPkgBib{cgal:y-t2}
|
||||||
\cgalPkgLicense{\ref licensesGPL "GPL"}
|
\cgalPkgLicense{\ref licensesGPL "GPL"}
|
||||||
|
|
@ -35,7 +34,6 @@
|
||||||
|
|
||||||
\cgalPkgDescriptionEnd
|
\cgalPkgDescriptionEnd
|
||||||
|
|
||||||
|
|
||||||
\cgalClassifedRefPages
|
\cgalClassifedRefPages
|
||||||
|
|
||||||
\cgalCRPSection{Concepts}
|
\cgalCRPSection{Concepts}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,10 @@
|
||||||
cmake_minimum_required(VERSION 3.12...3.29)
|
cmake_minimum_required(VERSION 3.12...3.31)
|
||||||
|
|
||||||
project( Triangulation_on_hyperbolic_surface_2_Examples )
|
project( Triangulation_on_hyperbolic_surface_2_Examples )
|
||||||
|
|
||||||
# CGAL and its components
|
# CGAL and its components
|
||||||
find_package( CGAL REQUIRED )
|
find_package( CGAL REQUIRED )
|
||||||
|
|
||||||
include_directories(../../include/)
|
|
||||||
|
|
||||||
# create a target per cppfile
|
# create a target per cppfile
|
||||||
file(
|
file(
|
||||||
GLOB cppfiles
|
GLOB cppfiles
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ typedef CGAL::Hyperbolic_fundamental_domain_2<Traits> Domain;
|
||||||
typedef CGAL::Hyperbolic_fundamental_domain_factory_2<Traits> Factory;
|
typedef CGAL::Hyperbolic_fundamental_domain_factory_2<Traits> Factory;
|
||||||
typedef CGAL::Triangulation_on_hyperbolic_surface_2<Traits> Triangulation;
|
typedef CGAL::Triangulation_on_hyperbolic_surface_2<Traits> Triangulation;
|
||||||
|
|
||||||
int main(){
|
int main() {
|
||||||
// Generates the domain:
|
// Generates the domain:
|
||||||
Factory factory = Factory();
|
Factory factory = Factory();
|
||||||
Domain domain = factory.make_hyperbolic_fundamental_domain_g2(time(NULL)); // get a random seed with time(NULL)
|
Domain domain = factory.make_hyperbolic_fundamental_domain_g2(time(NULL)); // get a random seed with time(NULL)
|
||||||
|
|
|
||||||
|
|
@ -10,21 +10,23 @@
|
||||||
//
|
//
|
||||||
// Author(s) : Vincent Despré, Loïc Dubois, Marc Pouget, Monique Teillaud
|
// Author(s) : Vincent Despré, Loïc Dubois, Marc Pouget, Monique Teillaud
|
||||||
|
|
||||||
// This file contains the declaration and the implementation of the class Complex_number
|
|
||||||
|
|
||||||
#ifndef CGAL_COMPLEX_NUMBER_H
|
#ifndef CGAL_COMPLEX_NUMBER_H
|
||||||
#define CGAL_COMPLEX_NUMBER_H
|
#define CGAL_COMPLEX_NUMBER_H
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Templated by a field FT. Represents a complex number over FT.
|
Templated by a field FT. Represents a complex number over FT.
|
||||||
*/
|
*/
|
||||||
template <class FT>
|
template <class FT>
|
||||||
class Complex_number {
|
class Complex_number
|
||||||
|
{
|
||||||
typedef Complex_number<FT> _Self;
|
typedef Complex_number<FT> _Self;
|
||||||
|
|
||||||
FT _real, _imag;
|
FT _real, _imag;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -33,8 +35,8 @@ public:
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Complex_number(const FT& real_part, const FT& imaginary_part)
|
Complex_number(const FT& real_part, const FT& imaginary_part)
|
||||||
: _real(real_part)
|
: _real(real_part),
|
||||||
, _imag(imaginary_part)
|
_imag(imaginary_part)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Complex_number()
|
Complex_number()
|
||||||
|
|
@ -43,15 +45,15 @@ public:
|
||||||
|
|
||||||
template<class U,class V>
|
template<class U,class V>
|
||||||
Complex_number(U&& real_part, V&& imaginary_part)
|
Complex_number(U&& real_part, V&& imaginary_part)
|
||||||
: _real(std::forward<U>(real_part))
|
: _real(std::forward<U>(real_part)),
|
||||||
, _imag(std::forward<V>(imaginary_part))
|
_imag(std::forward<V>(imaginary_part))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void real(const FT& real_part){
|
void real(const FT& real_part) {
|
||||||
_real = real_part;
|
_real = real_part;
|
||||||
}
|
}
|
||||||
|
|
||||||
void imag(const FT& imaginary_part){
|
void imag(const FT& imaginary_part) {
|
||||||
_imag = imaginary_part;
|
_imag = imaginary_part;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -89,7 +91,7 @@ public:
|
||||||
return !operator==(z1, z2);
|
return !operator==(z1, z2);
|
||||||
}
|
}
|
||||||
|
|
||||||
friend _Self operator+(const _Self& z1, const _Self& z2){
|
friend _Self operator+(const _Self& z1, const _Self& z2) {
|
||||||
return _Self(z1._real+z2._real, z1._imag+z2._imag);
|
return _Self(z1._real+z2._real, z1._imag+z2._imag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -101,50 +103,53 @@ public:
|
||||||
return _Self(z1._real*z2._real-z1._imag*z2._imag, z1._real*z2._imag+z1._imag*z2._real);
|
return _Self(z1._real*z2._real-z1._imag*z2._imag, z1._real*z2._imag+z1._imag*z2._real);
|
||||||
}
|
}
|
||||||
|
|
||||||
friend _Self operator/(const _Self& z1, const _Self& z2){
|
friend _Self operator/(const _Self& z1, const _Self& z2) {
|
||||||
FT m2 = norm(z2);
|
FT m2 = norm(z2);
|
||||||
return _Self(z1._real/m2, z1._imag/m2)*conj(z2);
|
return _Self(z1._real/m2, z1._imag/m2)*conj(z2);
|
||||||
}
|
}
|
||||||
|
|
||||||
friend std::ostream& operator<<(std::ostream& s, const _Self& z){
|
friend std::ostream& operator<<(std::ostream& s, const _Self& z) {
|
||||||
s << z._real << std::endl << z._imag << std::endl;
|
s << z._real << std::endl << z._imag << std::endl;
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
friend void operator>>(std::istream& s, _Self& z){
|
friend void operator>>(std::istream& s, _Self& z) {
|
||||||
FT ft;
|
FT ft;
|
||||||
s >> ft;
|
s >> ft;
|
||||||
z.real(ft);
|
z.real(ft);
|
||||||
s >> ft;
|
s >> ft;
|
||||||
z.imag(ft);
|
z.imag(ft);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
template<class FT>
|
template<class FT>
|
||||||
Complex_number<FT>& Complex_number<FT>::operator+=(const Complex_number<FT>& other) {
|
Complex_number<FT>& Complex_number<FT>::operator+=(const Complex_number<FT>& other)
|
||||||
|
{
|
||||||
_real += other.real();
|
_real += other.real();
|
||||||
_imag += other.imag();
|
_imag += other.imag();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class FT>
|
template<class FT>
|
||||||
Complex_number<FT>& Complex_number<FT>::operator-=(const Complex_number<FT>& other) {
|
Complex_number<FT>& Complex_number<FT>::operator-=(const Complex_number<FT>& other)
|
||||||
|
{
|
||||||
_real -= other.real();
|
_real -= other.real();
|
||||||
_imag -= other.imag();
|
_imag -= other.imag();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class FT>
|
template<class FT>
|
||||||
Complex_number<FT>& Complex_number<FT>::operator*=(const Complex_number<FT>& other) {
|
Complex_number<FT>& Complex_number<FT>::operator*=(const Complex_number<FT>& other)
|
||||||
|
{
|
||||||
_real = _real*other.real() - _imag*other.imag();
|
_real = _real*other.real() - _imag*other.imag();
|
||||||
_imag = _real*other.imag() + _imag*other.real();
|
_imag = _real*other.imag() + _imag*other.real();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class FT>
|
template<class FT>
|
||||||
Complex_number<FT>& Complex_number<FT>::operator/=(const Complex_number<FT>& other) {
|
Complex_number<FT>& Complex_number<FT>::operator/=(const Complex_number<FT>& other)
|
||||||
|
{
|
||||||
FT m2 = norm(other);
|
FT m2 = norm(other);
|
||||||
_real /= m2;
|
_real /= m2;
|
||||||
_imag /= m2;
|
_imag /= m2;
|
||||||
|
|
@ -153,12 +158,14 @@ Complex_number<FT>& Complex_number<FT>::operator/=(const Complex_number<FT>& oth
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class FT>
|
template<class FT>
|
||||||
FT norm(const Complex_number<FT>& z) {
|
FT norm(const Complex_number<FT>& z)
|
||||||
|
{
|
||||||
return z.real()*z.real() + z.imag()*z.imag();
|
return z.real()*z.real() + z.imag()*z.imag();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class FT>
|
template<class FT>
|
||||||
Complex_number<FT> conj(const Complex_number<FT>& z) {
|
Complex_number<FT> conj(const Complex_number<FT>& z)
|
||||||
|
{
|
||||||
return Complex_number<FT>(z.real(), -z.imag());
|
return Complex_number<FT>(z.real(), -z.imag());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,18 +10,17 @@
|
||||||
//
|
//
|
||||||
// Author(s) : Vincent Despré, Loïc Dubois, Marc Pouget, Monique Teillaud
|
// Author(s) : Vincent Despré, Loïc Dubois, Marc Pouget, Monique Teillaud
|
||||||
|
|
||||||
// This file contains the declaration and the implementation of the class Hyperbolic_fundamental_domain_2
|
|
||||||
|
|
||||||
#ifndef CGAL_HYPERBOLIC_FUNDAMENTAL_DOMAIN_2_H
|
#ifndef CGAL_HYPERBOLIC_FUNDAMENTAL_DOMAIN_2_H
|
||||||
#define CGAL_HYPERBOLIC_FUNDAMENTAL_DOMAIN_2_H
|
#define CGAL_HYPERBOLIC_FUNDAMENTAL_DOMAIN_2_H
|
||||||
|
|
||||||
#include <CGAL/license/Triangulation_on_hyperbolic_surface_2.h>
|
#include <CGAL/license/Triangulation_on_hyperbolic_surface_2.h>
|
||||||
|
|
||||||
#include <CGAL/Hyperbolic_isometry_2.h>
|
#include <CGAL/Hyperbolic_isometry_2.h>
|
||||||
#include <CGAL/basic.h>
|
|
||||||
|
|
||||||
#include <vector>
|
#include <CGAL/assertions.h>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
|
|
@ -33,22 +32,31 @@ identifying every two paired sides in a way that respects the orientation of P w
|
||||||
orientable hyperbolic surface.
|
orientable hyperbolic surface.
|
||||||
*/
|
*/
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
class Hyperbolic_fundamental_domain_2 {
|
class Hyperbolic_fundamental_domain_2
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
typedef typename Traits::Hyperbolic_point_2 Point;
|
typedef typename Traits::Hyperbolic_point_2 Point;
|
||||||
|
|
||||||
Hyperbolic_fundamental_domain_2(){};
|
Hyperbolic_fundamental_domain_2() {};
|
||||||
|
|
||||||
template<class PointRange, class PairingRange>
|
template<class PointRange, class PairingRange>
|
||||||
Hyperbolic_fundamental_domain_2(PointRange & vertices, PairingRange & pairings){
|
Hyperbolic_fundamental_domain_2(PointRange & vertices, PairingRange & pairings)
|
||||||
|
{
|
||||||
_vertices = std::vector<Point>(vertices.begin(), vertices.end());
|
_vertices = std::vector<Point>(vertices.begin(), vertices.end());
|
||||||
_pairings = std::vector<int>(pairings.begin(), pairings.end());
|
_pairings = std::vector<int>(pairings.begin(), pairings.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t size() const; // Returns the number of vertices (equivalently, the number of sides)
|
// returns the number of vertices (equivalently, the number of sides)
|
||||||
const Point& vertex(std::size_t index) const; // Returns the index-th vertex
|
std::size_t size() const;
|
||||||
std::size_t paired_side(std::size_t index) const; // Returns the index of the side paired to side A, where A is the index-th side
|
|
||||||
Hyperbolic_isometry_2<Traits> side_pairing(std::size_t index) const;// Returns the isometry that maps side A to side B, where B is the index-th side, and A is the side paired to B
|
// returns the index-th vertex
|
||||||
|
const Point& vertex(std::size_t index) const;
|
||||||
|
|
||||||
|
// returns the index of the side paired to side A, where A is the index-th side
|
||||||
|
std::size_t paired_side(std::size_t index) const;
|
||||||
|
|
||||||
|
// returns the isometry that maps side A to side B, where B is the index-th side, and A is the side paired to B
|
||||||
|
Hyperbolic_isometry_2<Traits> side_pairing(std::size_t index) const;
|
||||||
|
|
||||||
std::istream& from_stream(std::istream& s);
|
std::istream& from_stream(std::istream& s);
|
||||||
std::ostream& to_stream(std::ostream& s) const;
|
std::ostream& to_stream(std::ostream& s) const;
|
||||||
|
|
@ -63,32 +71,43 @@ private:
|
||||||
//template<class Traits> std::ostream& operator<<(std::ostream& s, const Hyperbolic_fundamental_domain_2<Traits>& domain);
|
//template<class Traits> std::ostream& operator<<(std::ostream& s, const Hyperbolic_fundamental_domain_2<Traits>& domain);
|
||||||
//template<class Traits> std::istream& operator>>(std::istream& s, Hyperbolic_fundamental_domain_2<Traits>& domain);
|
//template<class Traits> std::istream& operator>>(std::istream& s, Hyperbolic_fundamental_domain_2<Traits>& domain);
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
std::size_t Hyperbolic_fundamental_domain_2<Traits>::size() const{
|
std::size_t
|
||||||
|
Hyperbolic_fundamental_domain_2<Traits>::
|
||||||
|
size() const
|
||||||
|
{
|
||||||
CGAL_precondition(is_valid());
|
CGAL_precondition(is_valid());
|
||||||
return _vertices.size();
|
return _vertices.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
const typename Hyperbolic_fundamental_domain_2<Traits>::Point& Hyperbolic_fundamental_domain_2<Traits>::vertex(std::size_t index) const{
|
const typename Hyperbolic_fundamental_domain_2<Traits>::Point&
|
||||||
|
Hyperbolic_fundamental_domain_2<Traits>::
|
||||||
|
vertex(std::size_t index) const
|
||||||
|
{
|
||||||
CGAL_precondition(is_valid());
|
CGAL_precondition(is_valid());
|
||||||
return _vertices[index];
|
return _vertices[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
std::size_t Hyperbolic_fundamental_domain_2<Traits>::paired_side(std::size_t index) const{
|
std::size_t
|
||||||
|
Hyperbolic_fundamental_domain_2<Traits>::
|
||||||
|
paired_side(std::size_t index) const
|
||||||
|
{
|
||||||
CGAL_precondition(is_valid());
|
CGAL_precondition(is_valid());
|
||||||
return _pairings[index];
|
return _pairings[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
Hyperbolic_isometry_2<Traits> Hyperbolic_fundamental_domain_2<Traits>::side_pairing(std::size_t index) const{
|
Hyperbolic_isometry_2<Traits>
|
||||||
|
Hyperbolic_fundamental_domain_2<Traits>::
|
||||||
|
side_pairing(std::size_t index) const
|
||||||
|
{
|
||||||
CGAL_precondition(is_valid());
|
CGAL_precondition(is_valid());
|
||||||
std::size_t n = size();
|
std::size_t n = size();
|
||||||
std::size_t paired_index = paired_side(index);
|
std::size_t paired_index = paired_side(index);
|
||||||
|
|
@ -106,23 +125,29 @@ Hyperbolic_isometry_2<Traits> Hyperbolic_fundamental_domain_2<Traits>::side_pair
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
std::ostream& Hyperbolic_fundamental_domain_2<Traits>::to_stream(std::ostream& s) const{
|
std::ostream&
|
||||||
|
Hyperbolic_fundamental_domain_2<Traits>::
|
||||||
|
to_stream(std::ostream& s) const
|
||||||
|
{
|
||||||
std::size_t n = size();
|
std::size_t n = size();
|
||||||
|
|
||||||
s << std::to_string(n) << std::endl;
|
s << std::to_string(n) << std::endl;
|
||||||
|
|
||||||
for (std::size_t k=0; k<n; ++k){
|
for (std::size_t k=0; k<n; ++k) {
|
||||||
s << paired_side(k) << std::endl;
|
s << paired_side(k) << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::size_t k=0; k<n; ++k){
|
for (std::size_t k=0; k<n; ++k) {
|
||||||
s << vertex(k) << std::endl;
|
s << vertex(k) << std::endl;
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
std::istream& Hyperbolic_fundamental_domain_2<Traits>::from_stream(std::istream& s){
|
std::istream&
|
||||||
|
Hyperbolic_fundamental_domain_2<Traits>::
|
||||||
|
from_stream(std::istream& s)
|
||||||
|
{
|
||||||
_vertices.clear();
|
_vertices.clear();
|
||||||
_pairings.clear();
|
_pairings.clear();
|
||||||
|
|
||||||
|
|
@ -132,12 +157,12 @@ std::istream& Hyperbolic_fundamental_domain_2<Traits>::from_stream(std::istream&
|
||||||
_vertices.reserve(size);
|
_vertices.reserve(size);
|
||||||
_pairings.reserve(size);
|
_pairings.reserve(size);
|
||||||
|
|
||||||
for (std::size_t k=0; k<size; ++k){
|
for (std::size_t k=0; k<size; ++k) {
|
||||||
s >> line;
|
s >> line;
|
||||||
_pairings.push_back(std::stoi(line));
|
_pairings.push_back(std::stoi(line));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::size_t k=0; k<size; ++k){
|
for (std::size_t k=0; k<size; ++k) {
|
||||||
Point p;
|
Point p;
|
||||||
s >> p;
|
s >> p;
|
||||||
_vertices.push_back(p);
|
_vertices.push_back(p);
|
||||||
|
|
@ -145,43 +170,45 @@ std::istream& Hyperbolic_fundamental_domain_2<Traits>::from_stream(std::istream&
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
bool Hyperbolic_fundamental_domain_2<Traits>::is_valid()const{
|
bool
|
||||||
|
Hyperbolic_fundamental_domain_2<Traits>::
|
||||||
|
is_valid()const
|
||||||
|
{
|
||||||
// Get the number of vertices
|
// Get the number of vertices
|
||||||
std::size_t n = _vertices.size();
|
std::size_t n = _vertices.size();
|
||||||
|
|
||||||
// Check that the number of vertices is even
|
// Check that the number of vertices is even
|
||||||
if (n%2){
|
if (n%2) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that there are as many side pairings as vertices
|
// Check that there are as many side pairings as vertices
|
||||||
if (_pairings.size() != n){
|
if (_pairings.size() != n) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that the _pairings vector encodes a perfect matching of the set {0,1,\dots,n-1}
|
// Check that the _pairings vector encodes a perfect matching of the set {0,1,\dots,n-1}
|
||||||
std::vector<bool> already_paired(n);
|
std::vector<bool> already_paired(n);
|
||||||
for (std::size_t k=0; k<n; ++k){
|
for (std::size_t k=0; k<n; ++k) {
|
||||||
already_paired[k] = false;
|
already_paired[k] = false;
|
||||||
}
|
}
|
||||||
for (std::size_t k=0; k<n; ++k){
|
for (std::size_t k=0; k<n; ++k) {
|
||||||
std::size_t paired_side = _pairings[k];
|
std::size_t paired_side = _pairings[k];
|
||||||
if ((paired_side<0) || (paired_side>=n)){
|
if ((paired_side<0) || (paired_side>=n)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (already_paired[paired_side]){
|
if (already_paired[paired_side]) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
already_paired[paired_side] = true;
|
already_paired[paired_side] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that the vertices all lie within the open unit disk
|
// Check that the vertices all lie within the open unit disk
|
||||||
for (std::size_t k=0; k<n; ++k){
|
for (std::size_t k=0; k<n; ++k) {
|
||||||
if (norm(Complex_number(_vertices[k].x(),_vertices[k].y())) >= typename Traits::FT(1)){
|
if (norm(Complex_number(_vertices[k].x(), _vertices[k].y())) >= typename Traits::FT(1)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,6 @@
|
||||||
//
|
//
|
||||||
// Author(s) : Vincent Despré, Loïc Dubois, Marc Pouget, Monique Teillaud
|
// Author(s) : Vincent Despré, Loïc Dubois, Marc Pouget, Monique Teillaud
|
||||||
|
|
||||||
// This file contains the declaration and the implementation of the class Hyperbolic_fundamental_domain_factory_2
|
|
||||||
|
|
||||||
#ifndef CGAL_HYPERBOLIC_FUNDAMENTAL_DOMAIN_FACTORY_2_H
|
#ifndef CGAL_HYPERBOLIC_FUNDAMENTAL_DOMAIN_FACTORY_2_H
|
||||||
#define CGAL_HYPERBOLIC_FUNDAMENTAL_DOMAIN_FACTORY_2_H
|
#define CGAL_HYPERBOLIC_FUNDAMENTAL_DOMAIN_FACTORY_2_H
|
||||||
|
|
||||||
|
|
@ -21,6 +19,7 @@
|
||||||
#include <CGAL/Random.h>
|
#include <CGAL/Random.h>
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
|
|
@ -31,7 +30,8 @@ closed orientable hyperbolic surfaces. The function
|
||||||
genus 2.
|
genus 2.
|
||||||
*/
|
*/
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
class Hyperbolic_fundamental_domain_factory_2{
|
class Hyperbolic_fundamental_domain_factory_2
|
||||||
|
{
|
||||||
private:
|
private:
|
||||||
typedef typename Traits::FT _FT;
|
typedef typename Traits::FT _FT;
|
||||||
typedef typename Traits::Complex _Cmplx;
|
typedef typename Traits::Complex _Cmplx;
|
||||||
|
|
@ -64,24 +64,26 @@ private:
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
Hyperbolic_fundamental_domain_factory_2<Traits>::Hyperbolic_fundamental_domain_factory_2(){}
|
Hyperbolic_fundamental_domain_factory_2<Traits>::Hyperbolic_fundamental_domain_factory_2() {}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
Hyperbolic_fundamental_domain_2<Traits> Hyperbolic_fundamental_domain_factory_2<Traits>::make_hyperbolic_fundamental_domain_g2(unsigned int seed){
|
Hyperbolic_fundamental_domain_2<Traits>
|
||||||
|
Hyperbolic_fundamental_domain_factory_2<Traits>::
|
||||||
|
make_hyperbolic_fundamental_domain_g2(unsigned int seed)
|
||||||
|
{
|
||||||
_random = Random(seed);
|
_random = Random(seed);
|
||||||
bool is_domain_generated = false;
|
bool is_domain_generated = false;
|
||||||
_Cmplx exact_z0, exact_z1, exact_z2, exact_z3;
|
_Cmplx exact_z0, exact_z1, exact_z2, exact_z3;
|
||||||
|
|
||||||
while (!is_domain_generated){
|
while (!is_domain_generated) {
|
||||||
// 1. Generate inexact z0,z1,z2,z3
|
// 1. Generate inexact z0,z1,z2,z3
|
||||||
Complex_number<float> z0, z1, z2, z3;
|
Complex_number<float> z0, z1, z2, z3;
|
||||||
z1 = random_complex_float();
|
z1 = random_complex_float();
|
||||||
z2 = random_complex_float();
|
z2 = random_complex_float();
|
||||||
z3 = random_complex_float();
|
z3 = random_complex_float();
|
||||||
while (! try_to_compute_inexact_z0_from_z1_z2_z3(z0,z1,z2,z3)){
|
while (! try_to_compute_inexact_z0_from_z1_z2_z3(z0,z1,z2,z3)) {
|
||||||
z1 = random_complex_float();
|
z1 = random_complex_float();
|
||||||
z2 = random_complex_float();
|
z2 = random_complex_float();
|
||||||
z3 = random_complex_float();
|
z3 = random_complex_float();
|
||||||
|
|
@ -95,7 +97,7 @@ Hyperbolic_fundamental_domain_2<Traits> Hyperbolic_fundamental_domain_factory_2<
|
||||||
|
|
||||||
// 3. Modify z3 to fix the area...
|
// 3. Modify z3 to fix the area...
|
||||||
is_domain_generated = try_to_compute_exact_z3_from_z0_z1_z2(exact_z0, exact_z1, exact_z2, exact_z3);
|
is_domain_generated = try_to_compute_exact_z3_from_z0_z1_z2(exact_z0, exact_z1, exact_z2, exact_z3);
|
||||||
if (is_domain_generated){
|
if (is_domain_generated) {
|
||||||
// ... and perform a sanity check
|
// ... and perform a sanity check
|
||||||
is_domain_generated = sanity_check(exact_z0, exact_z1, exact_z2, exact_z3);
|
is_domain_generated = sanity_check(exact_z0, exact_z1, exact_z2, exact_z3);
|
||||||
}
|
}
|
||||||
|
|
@ -113,7 +115,7 @@ Hyperbolic_fundamental_domain_2<Traits> Hyperbolic_fundamental_domain_factory_2<
|
||||||
vertices.push_back(_Point(-exact_z3.real(), -exact_z3.imag()));
|
vertices.push_back(_Point(-exact_z3.real(), -exact_z3.imag()));
|
||||||
|
|
||||||
std::vector<int> pairings;
|
std::vector<int> pairings;
|
||||||
for (int k=0; k<8; ++k){
|
for (int k=0; k<8; ++k) {
|
||||||
pairings.push_back((k+4)%8);
|
pairings.push_back((k+4)%8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -124,19 +126,22 @@ Hyperbolic_fundamental_domain_2<Traits> Hyperbolic_fundamental_domain_factory_2<
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
float Hyperbolic_fundamental_domain_factory_2<Traits>::random_positive_float(){
|
float Hyperbolic_fundamental_domain_factory_2<Traits>::random_positive_float() {
|
||||||
return _random.uniform_01<float>();
|
return _random.uniform_01<float>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
float Hyperbolic_fundamental_domain_factory_2<Traits>::random_float(){
|
float Hyperbolic_fundamental_domain_factory_2<Traits>::random_float() {
|
||||||
return _random.uniform_01<float>() * 2 - 1;
|
return _random.uniform_01<float>() * 2 - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
Complex_number<float> Hyperbolic_fundamental_domain_factory_2<Traits>::random_complex_float(){
|
Complex_number<float>
|
||||||
|
Hyperbolic_fundamental_domain_factory_2<Traits>::
|
||||||
|
random_complex_float()
|
||||||
|
{
|
||||||
Complex_number<float> result (random_float(), random_positive_float());
|
Complex_number<float> result (random_float(), random_positive_float());
|
||||||
while (norm(result) >= 1){
|
while (norm(result) >= 1) {
|
||||||
result.real(random_float());
|
result.real(random_float());
|
||||||
result.imag(random_positive_float());
|
result.imag(random_positive_float());
|
||||||
}
|
}
|
||||||
|
|
@ -147,23 +152,34 @@ Complex_number<float> Hyperbolic_fundamental_domain_factory_2<Traits>::random_co
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
typename Traits::FT Hyperbolic_fundamental_domain_factory_2<Traits>::exact_number_from_float(float x){
|
typename Traits::FT
|
||||||
if (x< 0){
|
Hyperbolic_fundamental_domain_factory_2<Traits>::
|
||||||
|
exact_number_from_float(float x)
|
||||||
|
{
|
||||||
|
if (x < 0) {
|
||||||
return _FT(0)-exact_number_from_float(-x);
|
return _FT(0)-exact_number_from_float(-x);
|
||||||
}
|
}
|
||||||
return _FT(int(x*CGAL_DENOMINATOR_FOR_GENERATION)%CGAL_DENOMINATOR_FOR_GENERATION)/_FT(CGAL_DENOMINATOR_FOR_GENERATION);
|
return _FT(int(x*CGAL_DENOMINATOR_FOR_GENERATION)%CGAL_DENOMINATOR_FOR_GENERATION)/_FT(CGAL_DENOMINATOR_FOR_GENERATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
typename Traits::Complex Hyperbolic_fundamental_domain_factory_2<Traits>::exact_complex_from_float_complex(const Complex_number<float>& z){
|
typename Traits::Complex
|
||||||
|
Hyperbolic_fundamental_domain_factory_2<Traits>::
|
||||||
|
exact_complex_from_float_complex(const Complex_number<float>& z)
|
||||||
|
{
|
||||||
return _Cmplx(exact_number_from_float(z.real()), exact_number_from_float(z.imag()));
|
return _Cmplx(exact_number_from_float(z.real()), exact_number_from_float(z.imag()));
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
bool Hyperbolic_fundamental_domain_factory_2<Traits>::try_to_compute_inexact_z0_from_z1_z2_z3(Complex_number<float>& z0, Complex_number<float>& z1, Complex_number<float>& z2, Complex_number<float>& z3){
|
bool Hyperbolic_fundamental_domain_factory_2<Traits>::
|
||||||
if ( ((z2/z1).imag()<=0) || ((z3/z2).imag()<=0) ){
|
try_to_compute_inexact_z0_from_z1_z2_z3(Complex_number<float>& z0,
|
||||||
|
Complex_number<float>& z1,
|
||||||
|
Complex_number<float>& z2,
|
||||||
|
Complex_number<float>& z3)
|
||||||
|
{
|
||||||
|
if (((z2/z1).imag()<=0) || ((z3/z2).imag()<=0)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -174,28 +190,31 @@ bool Hyperbolic_fundamental_domain_factory_2<Traits>::try_to_compute_inexact_z0_
|
||||||
float c = u.imag();
|
float c = u.imag();
|
||||||
|
|
||||||
const float COMPUTATION_TRESHOLD = 0.00001f;
|
const float COMPUTATION_TRESHOLD = 0.00001f;
|
||||||
if (a+b+c> 0 - COMPUTATION_TRESHOLD){
|
if (a+b+c> 0 - COMPUTATION_TRESHOLD) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
z0.real( 2*c/(std::sqrt(b*b-4*a*c)-b) );
|
z0.real(2*c/(std::sqrt(b*b-4*a*c)-b));
|
||||||
z0.imag(0);
|
z0.imag(0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
bool Hyperbolic_fundamental_domain_factory_2<Traits>::try_to_compute_exact_z3_from_z0_z1_z2(_Cmplx& z0, _Cmplx& z1, _Cmplx& z2, _Cmplx& z3){
|
bool
|
||||||
|
Hyperbolic_fundamental_domain_factory_2<Traits>::
|
||||||
|
try_to_compute_exact_z3_from_z0_z1_z2(_Cmplx& z0, _Cmplx& z1, _Cmplx& z2, _Cmplx& z3)
|
||||||
|
{
|
||||||
_FT zero_number (0);
|
_FT zero_number (0);
|
||||||
_FT one_number (1);
|
_FT one_number (1);
|
||||||
if ( (z0.real()<=zero_number) || (z1.imag()<=zero_number) || (z2.imag()<=zero_number) || (z3.imag()<=zero_number) ){
|
if ((z0.real()<=zero_number) || (z1.imag()<=zero_number) || (z2.imag()<=zero_number) || (z3.imag()<=zero_number)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (norm(z0)>=one_number) || (norm(z1)>=one_number) || (norm(z2)>=one_number) || (norm(z3)>=one_number) ){
|
if ((norm(z0)>=one_number) || (norm(z1)>=one_number) || (norm(z2)>=one_number) || (norm(z3)>=one_number)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ((z1/z0).imag()<=zero_number) || ((z2/z1).imag()<=zero_number) || ((z3/z2).imag()<=zero_number) ){
|
if (((z1/z0).imag()<=zero_number) || ((z2/z1).imag()<=zero_number) || ((z3/z2).imag()<=zero_number)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -211,14 +230,14 @@ bool Hyperbolic_fundamental_domain_factory_2<Traits>::try_to_compute_exact_z3_fr
|
||||||
_FT P_of_zero = intermediate.imag();
|
_FT P_of_zero = intermediate.imag();
|
||||||
_FT P_of_one = (intermediate * (one_cmplx-f_of_z2*conj(f_of_z3))).imag();
|
_FT P_of_one = (intermediate * (one_cmplx-f_of_z2*conj(f_of_z3))).imag();
|
||||||
|
|
||||||
if (P_of_one == P_of_zero){
|
if (P_of_one == P_of_zero) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_FT lbda = P_of_zero / (P_of_zero - P_of_one);
|
_FT lbda = P_of_zero / (P_of_zero - P_of_one);
|
||||||
_Cmplx V (lbda*(f_of_z3.real()), lbda*(f_of_z3.imag()));
|
_Cmplx V (lbda*(f_of_z3.real()), lbda*(f_of_z3.imag()));
|
||||||
|
|
||||||
if ( (V.imag()<=zero_number) || (norm(V)>=one_number) || ((V/f_of_z2).imag()<=zero_number) ){
|
if ((V.imag()<=zero_number) || (norm(V)>=one_number) || ((V/f_of_z2).imag()<=zero_number)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -230,27 +249,30 @@ bool Hyperbolic_fundamental_domain_factory_2<Traits>::try_to_compute_exact_z3_fr
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
bool Hyperbolic_fundamental_domain_factory_2<Traits>::sanity_check(_Cmplx& z0, _Cmplx& z1, _Cmplx& z2, _Cmplx& z3){
|
bool
|
||||||
|
Hyperbolic_fundamental_domain_factory_2<Traits>::
|
||||||
|
sanity_check(_Cmplx& z0, _Cmplx& z1, _Cmplx& z2, _Cmplx& z3)
|
||||||
|
{
|
||||||
_FT zero_number(0);
|
_FT zero_number(0);
|
||||||
_FT one_number(1);
|
_FT one_number(1);
|
||||||
|
|
||||||
// 1. Check the positions
|
// 1. Check the positions
|
||||||
if ( (z0.imag()!=zero_number) || (z0.real()<=zero_number) || (z1.imag()<=zero_number) || (z2.imag()<=zero_number) || (z3.imag()<=zero_number) ){
|
if ((z0.imag()!=zero_number) || (z0.real()<=zero_number) || (z1.imag()<=zero_number) || (z2.imag()<=zero_number) || (z3.imag()<=zero_number)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (norm(z0)>=one_number) || (norm(z1)>=one_number) || (norm(z2)>=one_number) || (norm(z3)>=one_number) ){
|
if ((norm(z0)>=one_number) || (norm(z1)>=one_number) || (norm(z2)>=one_number) || (norm(z3)>=one_number)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ((z2/z1).imag()<=zero_number) || ((z3/z2).imag()<=zero_number) ){
|
if (((z2/z1).imag()<=zero_number) || ((z3/z2).imag()<=zero_number)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Check the area
|
// 2. Check the area
|
||||||
_Cmplx one_cmplx (one_number, zero_number);
|
_Cmplx one_cmplx (one_number, zero_number);
|
||||||
_Cmplx Z = (one_cmplx-z0*conj(z1)) * (one_cmplx-z1*conj(z2)) *(one_cmplx-z2*conj(z3)) *(one_cmplx+z3*conj(z0));
|
_Cmplx Z = (one_cmplx-z0*conj(z1)) * (one_cmplx-z1*conj(z2)) *(one_cmplx-z2*conj(z3)) *(one_cmplx+z3*conj(z0));
|
||||||
if (Z.imag()!=zero_number){
|
if (Z.imag()!=zero_number) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,6 @@
|
||||||
//
|
//
|
||||||
// Author(s) : Vincent Despré, Loïc Dubois, Marc Pouget, Monique Teillaud
|
// Author(s) : Vincent Despré, Loïc Dubois, Marc Pouget, Monique Teillaud
|
||||||
|
|
||||||
// This file contains the declaration and the implementation of the class Hyperbolic_isometry_2
|
|
||||||
|
|
||||||
#ifndef CGAL_HYPERBOLIC_ISOMETRY_2_H
|
#ifndef CGAL_HYPERBOLIC_ISOMETRY_2_H
|
||||||
#define CGAL_HYPERBOLIC_ISOMETRY_2_H
|
#define CGAL_HYPERBOLIC_ISOMETRY_2_H
|
||||||
|
|
||||||
|
|
@ -22,11 +20,13 @@
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Represents a hyperbolic isometry in the Poincare disk model the hyperbolic plane. The isometry f is stored as list (c0, c1, c2, c3) of 4 complex numbers,
|
Represents a hyperbolic isometry in the Poincare disk model the hyperbolic plane.
|
||||||
|
The isometry f is stored as list (c0, c1, c2, c3) of 4 complex numbers,
|
||||||
so that f(z) = (c0 z + c1) / (c2 z + c3) holds on every complex z in the open unit disk.
|
so that f(z) = (c0 z + c1) / (c2 z + c3) holds on every complex z in the open unit disk.
|
||||||
*/
|
*/
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
class Hyperbolic_isometry_2{
|
class Hyperbolic_isometry_2
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
typedef Hyperbolic_isometry_2<Traits> Self;
|
typedef Hyperbolic_isometry_2<Traits> Self;
|
||||||
typedef typename Traits::FT FT;
|
typedef typename Traits::FT FT;
|
||||||
|
|
@ -38,14 +38,14 @@ public:
|
||||||
|
|
||||||
void set_to_identity();
|
void set_to_identity();
|
||||||
|
|
||||||
// Can be used to set the coefficients manually. Warning : the implementation does not check that the resulting moebius transform fixes the unit circle.
|
// Can be used to set the coefficients manually. Warning: the implementation does not check that the resulting moebius transform fixes the unit circle.
|
||||||
void set_coefficients(const Complex_number& c0, const Complex_number& c1, const Complex_number& c2, const Complex_number& c3);
|
void set_coefficients(const Complex_number& c0, const Complex_number& c1, const Complex_number& c2, const Complex_number& c3);
|
||||||
void set_coefficient(int index, const Complex_number& coefficient);
|
void set_coefficient(int index, const Complex_number& coefficient);
|
||||||
|
|
||||||
// Returns the index-th coefficient
|
// returns the index-th coefficient
|
||||||
const Complex_number& get_coefficient(int index) const;
|
const Complex_number& get_coefficient(int index) const;
|
||||||
|
|
||||||
// Evaluates the isometry at point
|
// evaluates the isometry at point
|
||||||
Point evaluate(const Point& point) const;
|
Point evaluate(const Point& point) const;
|
||||||
Point operator()(const Point& point) const;
|
Point operator()(const Point& point) const;
|
||||||
|
|
||||||
|
|
@ -59,35 +59,53 @@ template<class Traits>
|
||||||
|
|
||||||
// template<class Traits> std::ostream& operator<<(std::ostream& s, const Hyperbolic_isometry_2<Traits>& isometry);
|
// template<class Traits> std::ostream& operator<<(std::ostream& s, const Hyperbolic_isometry_2<Traits>& isometry);
|
||||||
|
|
||||||
// When inverse=false, returns the hyperbolic translation that maps -p to zero, and zero to p. Otherwise, returns the hyperbolic translation that maps p to zero, and zero to -p.
|
// When inverse is 'false', returns the hyperbolic translation that maps -p to zero, and zero to p.
|
||||||
|
// Otherwise, returns the hyperbolic translation that maps p to zero, and zero to -p.
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
Hyperbolic_isometry_2<Traits> hyperbolic_translation(const typename Traits::Hyperbolic_point_2& p, bool inverse=false);
|
Hyperbolic_isometry_2<Traits> hyperbolic_translation(const typename Traits::Hyperbolic_point_2& p,
|
||||||
|
bool inverse = false);
|
||||||
|
|
||||||
// When inverse=false, returns the hyperbolic rotation around zero that maps p to q. Otherwise, returns the hyperbolic rotation around zero that maps q to p.
|
// When inverse is 'false', returns the hyperbolic rotation around zero that maps p to q.
|
||||||
|
// Otherwise, returns the hyperbolic rotation around zero that maps q to p.
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
Hyperbolic_isometry_2<Traits> hyperbolic_rotation(const typename Traits::Hyperbolic_point_2& p, const typename Traits::Hyperbolic_point_2& q, bool inverse=false);
|
Hyperbolic_isometry_2<Traits> hyperbolic_rotation(const typename Traits::Hyperbolic_point_2& p,
|
||||||
|
const typename Traits::Hyperbolic_point_2& q,
|
||||||
|
bool inverse = false);
|
||||||
|
|
||||||
// Returns the hyperbolic isometry that maps p1 to q1 and p2 to q2
|
// returns the hyperbolic isometry that maps p1 to q1 and p2 to q2
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
Hyperbolic_isometry_2<Traits> isometry_pairing_the_sides(const typename Traits::Hyperbolic_point_2& p1, const typename Traits::Hyperbolic_point_2& p2, const typename Traits::Hyperbolic_point_2& q1, const typename Traits::Hyperbolic_point_2& q2);
|
Hyperbolic_isometry_2<Traits> isometry_pairing_the_sides(const typename Traits::Hyperbolic_point_2& p1,
|
||||||
|
const typename Traits::Hyperbolic_point_2& p2,
|
||||||
|
const typename Traits::Hyperbolic_point_2& q1,
|
||||||
|
const typename Traits::Hyperbolic_point_2& q2);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
Hyperbolic_isometry_2<Traits>::Hyperbolic_isometry_2(){
|
Hyperbolic_isometry_2<Traits>::
|
||||||
|
Hyperbolic_isometry_2()
|
||||||
|
{
|
||||||
set_to_identity();
|
set_to_identity();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
Hyperbolic_isometry_2<Traits>::Hyperbolic_isometry_2(const Complex_number& c0, const Complex_number& c1, const Complex_number& c2, const Complex_number& c3){
|
Hyperbolic_isometry_2<Traits>::
|
||||||
|
Hyperbolic_isometry_2(const Complex_number& c0,
|
||||||
|
const Complex_number& c1,
|
||||||
|
const Complex_number& c2,
|
||||||
|
const Complex_number& c3)
|
||||||
|
{
|
||||||
set_coefficients(c0,c1,c2,c3);
|
set_coefficients(c0,c1,c2,c3);
|
||||||
}
|
}
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
void Hyperbolic_isometry_2<Traits>::set_to_identity(){
|
void
|
||||||
|
Hyperbolic_isometry_2<Traits>::
|
||||||
|
set_to_identity()
|
||||||
|
{
|
||||||
set_coefficients(Complex_number(FT(1)),
|
set_coefficients(Complex_number(FT(1)),
|
||||||
Complex_number(FT(0)),
|
Complex_number(FT(0)),
|
||||||
Complex_number(FT(0)),
|
Complex_number(FT(0)),
|
||||||
|
|
@ -95,7 +113,13 @@ void Hyperbolic_isometry_2<Traits>::set_to_identity(){
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
void Hyperbolic_isometry_2<Traits>::set_coefficients(const Complex_number& c0, const Complex_number& c1, const Complex_number& c2, const Complex_number& c3){
|
void
|
||||||
|
Hyperbolic_isometry_2<Traits>::
|
||||||
|
set_coefficients(const Complex_number& c0,
|
||||||
|
const Complex_number& c1,
|
||||||
|
const Complex_number& c2,
|
||||||
|
const Complex_number& c3)
|
||||||
|
{
|
||||||
set_coefficient(0, c0);
|
set_coefficient(0, c0);
|
||||||
set_coefficient(1, c1);
|
set_coefficient(1, c1);
|
||||||
set_coefficient(2, c2);
|
set_coefficient(2, c2);
|
||||||
|
|
@ -103,39 +127,54 @@ void Hyperbolic_isometry_2<Traits>::set_coefficients(const Complex_number& c0, c
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
void Hyperbolic_isometry_2<Traits>::set_coefficient(int index, const Complex_number& coefficient){
|
void
|
||||||
|
Hyperbolic_isometry_2<Traits>::
|
||||||
|
set_coefficient(int index, const Complex_number& coefficient)
|
||||||
|
{
|
||||||
_coefficients[index] = coefficient;
|
_coefficients[index] = coefficient;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
const typename Traits::Complex& Hyperbolic_isometry_2<Traits>::get_coefficient(int index) const{
|
const typename Traits::Complex&
|
||||||
|
Hyperbolic_isometry_2<Traits>::
|
||||||
|
get_coefficient(int index) const
|
||||||
|
{
|
||||||
return _coefficients[index];
|
return _coefficients[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
typename Traits::Hyperbolic_point_2 Hyperbolic_isometry_2<Traits>::evaluate(const Point& point) const{
|
typename Traits::Hyperbolic_point_2
|
||||||
Complex_number z (point.x(), point.y());
|
Hyperbolic_isometry_2<Traits>::
|
||||||
|
evaluate(const Point& point) const
|
||||||
|
{
|
||||||
|
Complex_number z(point.x(), point.y());
|
||||||
Complex_number numerator_of_the_result = _coefficients[0] * z + _coefficients[1];
|
Complex_number numerator_of_the_result = _coefficients[0] * z + _coefficients[1];
|
||||||
Complex_number denominator_of_the_result = _coefficients[2] * z + _coefficients[3];
|
Complex_number denominator_of_the_result = _coefficients[2] * z + _coefficients[3];
|
||||||
Complex_number result = numerator_of_the_result / denominator_of_the_result;
|
Complex_number result = numerator_of_the_result / denominator_of_the_result;
|
||||||
return Point(result.real(), result.imag());
|
return Point(result.real(), result.imag());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
typename Traits::Hyperbolic_point_2 Hyperbolic_isometry_2<Traits>::operator()(const Point& point) const{
|
typename Traits::Hyperbolic_point_2
|
||||||
|
Hyperbolic_isometry_2<Traits>::
|
||||||
|
operator()(const Point& point) const
|
||||||
|
{
|
||||||
return evaluate(point);
|
return evaluate(point);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
Hyperbolic_isometry_2<Traits> operator*(const Hyperbolic_isometry_2<Traits>& iso1, const Hyperbolic_isometry_2<Traits>& iso2) {
|
Hyperbolic_isometry_2<Traits> operator*(const Hyperbolic_isometry_2<Traits>& iso1,
|
||||||
|
const Hyperbolic_isometry_2<Traits>& iso2)
|
||||||
|
{
|
||||||
Hyperbolic_isometry_2<Traits> result;
|
Hyperbolic_isometry_2<Traits> result;
|
||||||
for (int i=0; i<2; i++){
|
for (int i=0; i<2; i++) {
|
||||||
for (int j=0; j<2; j++){
|
for (int j=0; j<2; j++) {
|
||||||
result.set_coefficient(2*i+j,
|
result.set_coefficient(2*i+j,
|
||||||
iso1.get_coefficient(2*i) * iso2.get_coefficient(j) + iso1.get_coefficient(2*i+1) * iso2.get_coefficient(2+j));
|
iso1.get_coefficient(2*i) * iso2.get_coefficient(j) + iso1.get_coefficient(2*i+1) * iso2.get_coefficient(2+j));
|
||||||
}
|
}
|
||||||
|
|
@ -146,10 +185,12 @@ template<class Traits>
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
Hyperbolic_isometry_2<Traits> hyperbolic_translation(const typename Traits::Hyperbolic_point_2& p, bool inverse){
|
Hyperbolic_isometry_2<Traits> hyperbolic_translation(const typename Traits::Hyperbolic_point_2& p,
|
||||||
|
bool inverse)
|
||||||
|
{
|
||||||
typename Traits::Complex one (typename Traits::FT(1));
|
typename Traits::Complex one (typename Traits::FT(1));
|
||||||
typename Traits::Complex z;
|
typename Traits::Complex z;
|
||||||
if (inverse){
|
if (inverse) {
|
||||||
z = typename Traits::Complex(p.x(), p.y());
|
z = typename Traits::Complex(p.x(), p.y());
|
||||||
} else {
|
} else {
|
||||||
z = - typename Traits::Complex(p.x(), p.y());
|
z = - typename Traits::Complex(p.x(), p.y());
|
||||||
|
|
@ -160,10 +201,14 @@ Hyperbolic_isometry_2<Traits> hyperbolic_translation(const typename Traits::Hype
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
Hyperbolic_isometry_2<Traits> hyperbolic_rotation(const typename Traits::Hyperbolic_point_2& p, const typename Traits::Hyperbolic_point_2& q, bool inverse){
|
Hyperbolic_isometry_2<Traits> hyperbolic_rotation(const typename Traits::Hyperbolic_point_2& p,
|
||||||
|
const typename Traits::Hyperbolic_point_2& q,
|
||||||
|
bool inverse)
|
||||||
|
{
|
||||||
typename Traits::Complex zero (typename Traits::FT(0));
|
typename Traits::Complex zero (typename Traits::FT(0));
|
||||||
|
|
||||||
Hyperbolic_isometry_2<Traits> result;
|
Hyperbolic_isometry_2<Traits> result;
|
||||||
if (inverse){
|
if (inverse) {
|
||||||
result.set_coefficients(typename Traits::Complex(p.x(), p.y()), zero, zero, typename Traits::Complex(q.x(), q.y()));
|
result.set_coefficients(typename Traits::Complex(p.x(), p.y()), zero, zero, typename Traits::Complex(q.x(), q.y()));
|
||||||
} else {
|
} else {
|
||||||
result.set_coefficients(typename Traits::Complex(q.x(), q.y()), zero, zero, typename Traits::Complex(p.x(), p.y()));
|
result.set_coefficients(typename Traits::Complex(q.x(), q.y()), zero, zero, typename Traits::Complex(p.x(), p.y()));
|
||||||
|
|
@ -172,11 +217,15 @@ Hyperbolic_isometry_2<Traits> hyperbolic_rotation(const typename Traits::Hyperbo
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
Hyperbolic_isometry_2<Traits> isometry_pairing_the_sides(const typename Traits::Hyperbolic_point_2& p1, const typename Traits::Hyperbolic_point_2& p2, const typename Traits::Hyperbolic_point_2& q1, const typename Traits::Hyperbolic_point_2& q2){
|
Hyperbolic_isometry_2<Traits> isometry_pairing_the_sides(const typename Traits::Hyperbolic_point_2& p1,
|
||||||
|
const typename Traits::Hyperbolic_point_2& p2,
|
||||||
|
const typename Traits::Hyperbolic_point_2& q1,
|
||||||
|
const typename Traits::Hyperbolic_point_2& q2)
|
||||||
|
{
|
||||||
Hyperbolic_isometry_2<Traits> A,B,Binv,C;
|
Hyperbolic_isometry_2<Traits> A,B,Binv,C;
|
||||||
A = hyperbolic_translation<Traits>(p1);
|
A = hyperbolic_translation<Traits>(p1);
|
||||||
B = hyperbolic_translation<Traits>(q1);
|
B = hyperbolic_translation<Traits>(q1);
|
||||||
Binv = hyperbolic_translation<Traits>(q1,true);
|
Binv = hyperbolic_translation<Traits>(q1, true);
|
||||||
C = hyperbolic_rotation<Traits>(A.evaluate(p2), B.evaluate(q2));
|
C = hyperbolic_rotation<Traits>(A.evaluate(p2), B.evaluate(q2));
|
||||||
return (Binv*C)*A;
|
return (Binv*C)*A;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,6 @@
|
||||||
//
|
//
|
||||||
// Author(s) : Vincent Despré, Loïc Dubois, Marc Pouget, Monique Teillaud
|
// Author(s) : Vincent Despré, Loïc Dubois, Marc Pouget, Monique Teillaud
|
||||||
|
|
||||||
// This file contains the declaration and the implementation of the class Hyperbolic_surface_traits_2
|
|
||||||
|
|
||||||
#ifndef CGAL_HYPERBOLIC_SURFACE_TRAITS_2
|
#ifndef CGAL_HYPERBOLIC_SURFACE_TRAITS_2
|
||||||
#define CGAL_HYPERBOLIC_SURFACE_TRAITS_2
|
#define CGAL_HYPERBOLIC_SURFACE_TRAITS_2
|
||||||
|
|
||||||
|
|
@ -19,12 +17,12 @@
|
||||||
|
|
||||||
#include <CGAL/Complex_number.h>
|
#include <CGAL/Complex_number.h>
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
template<class HyperbolicTraitsClass>
|
template<class HyperbolicTraitsClass>
|
||||||
class Hyperbolic_surface_traits_2 : public HyperbolicTraitsClass {
|
class Hyperbolic_surface_traits_2
|
||||||
|
: public HyperbolicTraitsClass
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
typedef typename HyperbolicTraitsClass::FT FT;
|
typedef typename HyperbolicTraitsClass::FT FT;
|
||||||
typedef typename HyperbolicTraitsClass::Hyperbolic_point_2 Hyperbolic_point_2;
|
typedef typename HyperbolicTraitsClass::Hyperbolic_point_2 Hyperbolic_point_2;
|
||||||
|
|
|
||||||
|
|
@ -10,20 +10,24 @@
|
||||||
//
|
//
|
||||||
// Author(s) : Vincent Despré, Loïc Dubois, Marc Pouget, Monique Teillaud
|
// Author(s) : Vincent Despré, Loïc Dubois, Marc Pouget, Monique Teillaud
|
||||||
|
|
||||||
// This file contains the declaration and the implementation of the class Triangulation_on_hyperbolic_surface_2
|
|
||||||
|
|
||||||
#ifndef CGAL_TRIANGULATION_ON_HYPERBOLIC_SURFACE_2_H
|
#ifndef CGAL_TRIANGULATION_ON_HYPERBOLIC_SURFACE_2_H
|
||||||
#define CGAL_TRIANGULATION_ON_HYPERBOLIC_SURFACE_2_H
|
#define CGAL_TRIANGULATION_ON_HYPERBOLIC_SURFACE_2_H
|
||||||
|
|
||||||
#include <CGAL/license/Triangulation_on_hyperbolic_surface_2.h>
|
#include <CGAL/license/Triangulation_on_hyperbolic_surface_2.h>
|
||||||
|
|
||||||
#include <CGAL/Hyperbolic_fundamental_domain_2.h>
|
|
||||||
#include <CGAL/basic.h>
|
|
||||||
#include <CGAL/Combinatorial_map.h>
|
#include <CGAL/Combinatorial_map.h>
|
||||||
|
#include <CGAL/Hyperbolic_fundamental_domain_2.h>
|
||||||
|
|
||||||
|
#include <CGAL/assertions.h>
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
#include <vector>
|
||||||
|
#include <tuple>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
|
|
@ -34,31 +38,32 @@ It is also possible to specify an anchor for the triangulation. An anchor consis
|
||||||
2) three points A,B,C in the hyperbolic plane. The points A,B,C are the three vertices in counter-clockwise order of a triangle. This triangle is a lift
|
2) three points A,B,C in the hyperbolic plane. The points A,B,C are the three vertices in counter-clockwise order of a triangle. This triangle is a lift
|
||||||
of T, and A is a lift of V.
|
of T, and A is a lift of V.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
struct Combinatorial_map_with_cross_ratios_item{
|
struct Combinatorial_map_with_cross_ratios_item
|
||||||
|
{
|
||||||
template <class CMap>
|
template <class CMap>
|
||||||
struct Dart_wrapper{
|
struct Dart_wrapper
|
||||||
typedef Cell_attribute<CMap, Complex_number<typename Traits::FT>> Edge_attrib;
|
{
|
||||||
typedef std::tuple<void,Edge_attrib,void> Attributes;
|
typedef Cell_attribute<CMap, Complex_number<typename Traits::FT> > Edge_attrib;
|
||||||
};
|
typedef std::tuple<void, Edge_attrib, void> Attributes;
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
|
||||||
template<class Traits, class Attributes = Combinatorial_map_with_cross_ratios_item<Traits>>
|
template<class Traits, class Attributes = Combinatorial_map_with_cross_ratios_item<Traits> >
|
||||||
class Triangulation_on_hyperbolic_surface_2
|
class Triangulation_on_hyperbolic_surface_2
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
typedef Combinatorial_map<2, Attributes> Combinatorial_map_with_cross_ratios;
|
||||||
|
|
||||||
typedef Combinatorial_map<2,Attributes> Combinatorial_map_with_cross_ratios;
|
struct Anchor
|
||||||
|
{
|
||||||
struct Anchor{
|
|
||||||
typename Combinatorial_map_with_cross_ratios::Dart_descriptor dart;
|
typename Combinatorial_map_with_cross_ratios::Dart_descriptor dart;
|
||||||
typename Traits::Hyperbolic_point_2 vertices[3];
|
typename Traits::Hyperbolic_point_2 vertices[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef typename Combinatorial_map_with_cross_ratios::Dart_descriptor Dart_descriptor;
|
typedef typename Combinatorial_map_with_cross_ratios::Dart_descriptor Dart_descriptor;
|
||||||
//typedef typename Combinatorial_map_with_cross_ratios::Dart_range Dart_range;
|
// typedef typename Combinatorial_map_with_cross_ratios::Dart_range Dart_range;
|
||||||
// typedef typename Combinatorial_map_with_cross_ratios::Dart_range::iterator Dart_iterator;
|
// typedef typename Combinatorial_map_with_cross_ratios::Dart_range::iterator Dart_iterator;
|
||||||
typedef typename Combinatorial_map_with_cross_ratios::template One_dart_per_cell_range<0> Vertex_range;
|
typedef typename Combinatorial_map_with_cross_ratios::template One_dart_per_cell_range<0> Vertex_range;
|
||||||
typedef typename Combinatorial_map_with_cross_ratios::template One_dart_per_cell_range<1> Edge_range;
|
typedef typename Combinatorial_map_with_cross_ratios::template One_dart_per_cell_range<1> Edge_range;
|
||||||
typedef typename Combinatorial_map_with_cross_ratios::template One_dart_per_cell_range<2> Face_range;
|
typedef typename Combinatorial_map_with_cross_ratios::template One_dart_per_cell_range<2> Face_range;
|
||||||
|
|
@ -80,7 +85,6 @@ public:
|
||||||
// Triangulation_on_hyperbolic_surface_2(Combinatorial_map_with_cross_ratios& cmap);
|
// Triangulation_on_hyperbolic_surface_2(Combinatorial_map_with_cross_ratios& cmap);
|
||||||
Triangulation_on_hyperbolic_surface_2(Combinatorial_map_with_cross_ratios& cmap, Anchor& anchor);
|
Triangulation_on_hyperbolic_surface_2(Combinatorial_map_with_cross_ratios& cmap, Anchor& anchor);
|
||||||
|
|
||||||
|
|
||||||
Combinatorial_map_with_cross_ratios& combinatorial_map();
|
Combinatorial_map_with_cross_ratios& combinatorial_map();
|
||||||
bool has_anchor() const;
|
bool has_anchor() const;
|
||||||
Anchor& anchor();
|
Anchor& anchor();
|
||||||
|
|
@ -93,12 +97,11 @@ public:
|
||||||
void flip(Dart_descriptor dart);
|
void flip(Dart_descriptor dart);
|
||||||
bool is_Delaunay() const;
|
bool is_Delaunay() const;
|
||||||
int make_Delaunay();
|
int make_Delaunay();
|
||||||
std::vector<std::tuple<Dart_const_descriptor,Point,Point,Point>> lift(bool center=true) const;
|
std::vector<std::tuple<Dart_const_descriptor, Point, Point, Point> > lift(bool center=true) const;
|
||||||
|
|
||||||
bool is_valid() const;
|
bool is_valid() const;
|
||||||
|
|
||||||
//The following methods are not documented but they are non private for internal future use.
|
// The following methods are not documented but they are non private for internal future use.
|
||||||
|
|
||||||
Dart_descriptor ccw(Dart_descriptor dart);
|
Dart_descriptor ccw(Dart_descriptor dart);
|
||||||
Dart_descriptor cw(Dart_descriptor dart);
|
Dart_descriptor cw(Dart_descriptor dart);
|
||||||
Dart_descriptor opposite(Dart_descriptor dart);
|
Dart_descriptor opposite(Dart_descriptor dart);
|
||||||
|
|
@ -108,19 +111,19 @@ public:
|
||||||
|
|
||||||
Complex_number get_cross_ratio(Dart_const_descriptor dart) const;
|
Complex_number get_cross_ratio(Dart_const_descriptor dart) const;
|
||||||
|
|
||||||
// Returns the cross ratio of the points a,b,c,d
|
// returns the cross ratio of the points a,b,c,d
|
||||||
Complex_number cross_ratio(const Point& a, const Point& b, const Point& c, const Point& d) const;
|
Complex_number cross_ratio(const Point& a, const Point& b, const Point& c, const Point& d) const;
|
||||||
// Returns the point d such that the cross ratio of a,b,c,d is cratio
|
// returns the point d such that the cross ratio of a,b,c,d is cratio
|
||||||
Point fourth_point_from_cross_ratio(const Point& a, const Point& b, const Point& c, const Complex_number& cratio) const;
|
Point fourth_point_from_cross_ratio(const Point& a, const Point& b, const Point& c, const Complex_number& cratio) const;
|
||||||
|
|
||||||
// Wrapper around the Cmap for iterating over vertices, edges or faces.
|
// Wrapper around the Cmap for iterating over vertices, edges or faces.
|
||||||
Vertex_range vertices_range(){
|
Vertex_range vertices_range() {
|
||||||
return _combinatorial_map.template one_dart_per_cell<0>();
|
return _combinatorial_map.template one_dart_per_cell<0>();
|
||||||
}
|
}
|
||||||
Edge_range edges_range(){
|
Edge_range edges_range() {
|
||||||
return _combinatorial_map.template one_dart_per_cell<1>();
|
return _combinatorial_map.template one_dart_per_cell<1>();
|
||||||
}
|
}
|
||||||
Face_range faces_range(){
|
Face_range faces_range() {
|
||||||
return _combinatorial_map.template one_dart_per_cell<2>();
|
return _combinatorial_map.template one_dart_per_cell<2>();
|
||||||
}
|
}
|
||||||
Vertex_const_range vertices_const_range() const {
|
Vertex_const_range vertices_const_range() const {
|
||||||
|
|
@ -153,22 +156,24 @@ protected:
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template<class Traits, class Attributes>
|
template<class Traits, class Attributes>
|
||||||
Triangulation_on_hyperbolic_surface_2<Traits,Attributes>::Triangulation_on_hyperbolic_surface_2(const Domain& domain){
|
Triangulation_on_hyperbolic_surface_2<Traits,Attributes>::
|
||||||
|
Triangulation_on_hyperbolic_surface_2(const Domain& domain)
|
||||||
|
{
|
||||||
// (Triangulates by adding an internal edge between domain.vertex(size-1) and the other vertices)
|
// (Triangulates by adding an internal edge between domain.vertex(size-1) and the other vertices)
|
||||||
_combinatorial_map.clear();
|
_combinatorial_map.clear();
|
||||||
int size = domain.size();
|
int size = domain.size();
|
||||||
|
|
||||||
// Make the triangles
|
// Make the triangles
|
||||||
std::vector<Dart_descriptor> dart_of_triangle(size-2);
|
std::vector<Dart_descriptor> dart_of_triangle(size-2);
|
||||||
for (int k=0; k<size-2; ++k){
|
for (int k=0; k<size-2; ++k) {
|
||||||
dart_of_triangle[k] = _combinatorial_map.make_combinatorial_polygon(3);
|
dart_of_triangle[k] = _combinatorial_map.make_combinatorial_polygon(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sew the internal edges and set their cross ratios
|
// Sew the internal edges and set their cross ratios
|
||||||
Dart_descriptor dart_1, dart_2;
|
Dart_descriptor dart_1, dart_2;
|
||||||
Point p0,p1,p2,p3;
|
Point p0, p1, p2, p3;
|
||||||
|
|
||||||
for (int k=1; k<size-2; ++k){
|
for (int k=1; k<size-2; ++k) {
|
||||||
dart_1 = dart_of_triangle[k];
|
dart_1 = dart_of_triangle[k];
|
||||||
dart_2 = cw(dart_of_triangle[k-1]);
|
dart_2 = cw(dart_of_triangle[k-1]);
|
||||||
|
|
||||||
|
|
@ -182,13 +187,13 @@ Triangulation_on_hyperbolic_surface_2<Traits,Attributes>::Triangulation_on_hyper
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sew the boundary edges and set their cross ratios
|
// Sew the boundary edges and set their cross ratios
|
||||||
for (int k1=0; k1<size; k1++){
|
for (int k1=0; k1<size; k1++) {
|
||||||
int k2 = domain.paired_side(k1);
|
int k2 = domain.paired_side(k1);
|
||||||
|
|
||||||
p0 = domain.vertex((k1+1)%size);
|
p0 = domain.vertex((k1+1)%size);
|
||||||
p2 = domain.vertex(k1);
|
p2 = domain.vertex(k1);
|
||||||
|
|
||||||
if (k1 == size-1){
|
if (k1 == size-1) {
|
||||||
dart_1 = dart_of_triangle[0];
|
dart_1 = dart_of_triangle[0];
|
||||||
p1 = domain.vertex(1);
|
p1 = domain.vertex(1);
|
||||||
} else if (k1 == size-2) {
|
} else if (k1 == size-2) {
|
||||||
|
|
@ -199,7 +204,7 @@ Triangulation_on_hyperbolic_surface_2<Traits,Attributes>::Triangulation_on_hyper
|
||||||
p1 = domain.vertex(size-1);
|
p1 = domain.vertex(size-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (k2 == size-1){
|
if (k2 == size-1) {
|
||||||
dart_2 = dart_of_triangle[0];
|
dart_2 = dart_of_triangle[0];
|
||||||
p3 = domain.vertex(1);
|
p3 = domain.vertex(1);
|
||||||
} else if (k2 == size-2) {
|
} else if (k2 == size-2) {
|
||||||
|
|
@ -212,7 +217,7 @@ Triangulation_on_hyperbolic_surface_2<Traits,Attributes>::Triangulation_on_hyper
|
||||||
|
|
||||||
p3 = domain.side_pairing(k1).evaluate(p3);
|
p3 = domain.side_pairing(k1).evaluate(p3);
|
||||||
|
|
||||||
if (_combinatorial_map.template is_sewable<2>(dart_1, dart_2)){
|
if (_combinatorial_map.template is_sewable<2>(dart_1, dart_2)) {
|
||||||
_combinatorial_map.template sew<2>(dart_1, dart_2);
|
_combinatorial_map.template sew<2>(dart_1, dart_2);
|
||||||
_combinatorial_map.template set_attribute<1>(dart_1, _combinatorial_map.template create_attribute<1>(cross_ratio(p0,p1,p2,p3)));
|
_combinatorial_map.template set_attribute<1>(dart_1, _combinatorial_map.template create_attribute<1>(cross_ratio(p0,p1,p2,p3)));
|
||||||
}
|
}
|
||||||
|
|
@ -227,38 +232,51 @@ Triangulation_on_hyperbolic_surface_2<Traits,Attributes>::Triangulation_on_hyper
|
||||||
}
|
}
|
||||||
|
|
||||||
/* template<class Traits, class Attributes> */
|
/* template<class Traits, class Attributes> */
|
||||||
/* Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::Triangulation_on_hyperbolic_surface_2(Combinatorial_map_with_cross_ratios& cmap){ */
|
/* Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::Triangulation_on_hyperbolic_surface_2(Combinatorial_map_with_cross_ratios& cmap) { */
|
||||||
/* copy_from(cmap); */
|
/* copy_from(cmap); */
|
||||||
/* } */
|
/* } */
|
||||||
|
|
||||||
template<class Traits, class Attributes>
|
template<class Traits, class Attributes>
|
||||||
Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::Triangulation_on_hyperbolic_surface_2(Combinatorial_map_with_cross_ratios& cmap, Anchor& anchor){
|
Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::
|
||||||
|
Triangulation_on_hyperbolic_surface_2(Combinatorial_map_with_cross_ratios& cmap,
|
||||||
|
Anchor& anchor)
|
||||||
|
{
|
||||||
copy_from(cmap, anchor);
|
copy_from(cmap, anchor);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template<class Traits, class Attributes>
|
template<class Traits, class Attributes>
|
||||||
typename Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::Combinatorial_map_with_cross_ratios& Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::combinatorial_map(){
|
typename Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::Combinatorial_map_with_cross_ratios&
|
||||||
|
Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::
|
||||||
|
combinatorial_map()
|
||||||
|
{
|
||||||
return _combinatorial_map;
|
return _combinatorial_map;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Traits, class Attributes>
|
template<class Traits, class Attributes>
|
||||||
bool Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::has_anchor() const {
|
bool
|
||||||
|
Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::
|
||||||
|
has_anchor() const
|
||||||
|
{
|
||||||
CGAL_precondition(is_valid());
|
CGAL_precondition(is_valid());
|
||||||
return _has_anchor;
|
return _has_anchor;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Traits, class Attributes>
|
template<class Traits, class Attributes>
|
||||||
typename Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::Anchor&
|
typename Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::Anchor&
|
||||||
Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::anchor() {
|
Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::
|
||||||
|
anchor()
|
||||||
|
{
|
||||||
CGAL_precondition(is_valid() && has_anchor());
|
CGAL_precondition(is_valid() && has_anchor());
|
||||||
return _anchor;
|
return _anchor;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Traits, class Attributes>
|
template<class Traits, class Attributes>
|
||||||
const typename Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::Anchor&
|
const typename Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::Anchor&
|
||||||
Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::anchor() const {
|
Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::
|
||||||
|
anchor() const
|
||||||
|
{
|
||||||
CGAL_precondition(is_valid() && has_anchor());
|
CGAL_precondition(is_valid() && has_anchor());
|
||||||
return _anchor;
|
return _anchor;
|
||||||
}
|
}
|
||||||
|
|
@ -266,14 +284,21 @@ Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::anchor() const {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template<class Traits, class Attributes>
|
template<class Traits, class Attributes>
|
||||||
bool Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::is_Delaunay_flippable(Dart_const_descriptor dart) const{
|
bool
|
||||||
|
Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::
|
||||||
|
is_Delaunay_flippable(Dart_const_descriptor dart) const
|
||||||
|
{
|
||||||
CGAL_precondition(is_valid());
|
CGAL_precondition(is_valid());
|
||||||
return ( get_cross_ratio(dart).imag()>Number(0) );
|
return (get_cross_ratio(dart).imag() > Number(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Traits, class Attributes>
|
template<class Traits, class Attributes>
|
||||||
void Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::flip(Dart_descriptor dart){
|
void
|
||||||
|
Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::
|
||||||
|
flip(Dart_descriptor dart)
|
||||||
|
{
|
||||||
CGAL_precondition(is_valid());
|
CGAL_precondition(is_valid());
|
||||||
|
|
||||||
// First gather all the information needed
|
// First gather all the information needed
|
||||||
|
|
||||||
Dart_descriptor a = opposite(dart); // Get a fresh descriptor
|
Dart_descriptor a = opposite(dart); // Get a fresh descriptor
|
||||||
|
|
@ -292,30 +317,30 @@ void Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::flip(Dart_descri
|
||||||
|
|
||||||
// Modify the anchor
|
// Modify the anchor
|
||||||
|
|
||||||
if (_anchor.dart == a){
|
if (_anchor.dart == a) {
|
||||||
_anchor.dart = e;
|
_anchor.dart = e;
|
||||||
_anchor.vertices[1] = Point(fourth_point_from_cross_ratio(_anchor.vertices[1], _anchor.vertices[2], _anchor.vertices[0], cross_ratio_AC));
|
_anchor.vertices[1] = Point(fourth_point_from_cross_ratio(_anchor.vertices[1], _anchor.vertices[2], _anchor.vertices[0], cross_ratio_AC));
|
||||||
} else if (_anchor.dart == b){
|
} else if (_anchor.dart == b) {
|
||||||
_anchor.vertices[2] = Point(fourth_point_from_cross_ratio(_anchor.vertices[0], _anchor.vertices[1], _anchor.vertices[2], cross_ratio_AC));
|
_anchor.vertices[2] = Point(fourth_point_from_cross_ratio(_anchor.vertices[0], _anchor.vertices[1], _anchor.vertices[2], cross_ratio_AC));
|
||||||
} else if (_anchor.dart == c){
|
} else if (_anchor.dart == c) {
|
||||||
_anchor.vertices[2] = Point(fourth_point_from_cross_ratio(_anchor.vertices[2], _anchor.vertices[0], _anchor.vertices[1], cross_ratio_AC));
|
_anchor.vertices[2] = Point(fourth_point_from_cross_ratio(_anchor.vertices[2], _anchor.vertices[0], _anchor.vertices[1], cross_ratio_AC));
|
||||||
} else if (_anchor.dart == d){
|
} else if (_anchor.dart == d) {
|
||||||
_anchor.dart = b;
|
_anchor.dart = b;
|
||||||
_anchor.vertices[1] = Point(fourth_point_from_cross_ratio(_anchor.vertices[1], _anchor.vertices[2], _anchor.vertices[0], cross_ratio_AC));
|
_anchor.vertices[1] = Point(fourth_point_from_cross_ratio(_anchor.vertices[1], _anchor.vertices[2], _anchor.vertices[0], cross_ratio_AC));
|
||||||
} else if (_anchor.dart == e){
|
} else if (_anchor.dart == e) {
|
||||||
_anchor.vertices[2] = Point(fourth_point_from_cross_ratio(_anchor.vertices[0], _anchor.vertices[1], _anchor.vertices[2], cross_ratio_AC));
|
_anchor.vertices[2] = Point(fourth_point_from_cross_ratio(_anchor.vertices[0], _anchor.vertices[1], _anchor.vertices[2], cross_ratio_AC));
|
||||||
} else if (_anchor.dart == f){
|
} else if (_anchor.dart == f) {
|
||||||
_anchor.vertices[2] = Point(fourth_point_from_cross_ratio(_anchor.vertices[2], _anchor.vertices[0], _anchor.vertices[1], cross_ratio_AC));
|
_anchor.vertices[2] = Point(fourth_point_from_cross_ratio(_anchor.vertices[2], _anchor.vertices[0], _anchor.vertices[1], cross_ratio_AC));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute the new cross ratios
|
// Compute the new cross ratios
|
||||||
|
|
||||||
Complex_number one (Number(1), Number(0));
|
Complex_number one (Number(1), Number(0));
|
||||||
Complex_number cross_ratio_BD = (cross_ratio_AC) / ((cross_ratio_AC) - one) ;
|
Complex_number cross_ratio_BD = (cross_ratio_AC) / ((cross_ratio_AC) - one);
|
||||||
Complex_number cross_ratio_AB_2 = one - (one - (cross_ratio_AB)) * (cross_ratio_AC) ;
|
Complex_number cross_ratio_AB_2 = one - (one - (cross_ratio_AB)) * (cross_ratio_AC);
|
||||||
Complex_number cross_ratio_BC_2 = one - (one - (cross_ratio_BC)) / (cross_ratio_BD) ;
|
Complex_number cross_ratio_BC_2 = one - (one - (cross_ratio_BC)) / (cross_ratio_BD);
|
||||||
Complex_number cross_ratio_CD_2 = one - (one - (cross_ratio_CD)) * (cross_ratio_AC) ;
|
Complex_number cross_ratio_CD_2 = one - (one - (cross_ratio_CD)) * (cross_ratio_AC);
|
||||||
Complex_number cross_ratio_DA_2 = one - (one - (cross_ratio_DA)) / (cross_ratio_BD) ;
|
Complex_number cross_ratio_DA_2 = one - (one - (cross_ratio_DA)) / (cross_ratio_BD);
|
||||||
|
|
||||||
// Make the topological flip
|
// Make the topological flip
|
||||||
|
|
||||||
|
|
@ -346,30 +371,36 @@ void Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::flip(Dart_descri
|
||||||
|
|
||||||
// Take care of the particular cases where we need to "flip again"
|
// Take care of the particular cases where we need to "flip again"
|
||||||
|
|
||||||
if (opposite(e) == b){
|
if (opposite(e) == b) {
|
||||||
_combinatorial_map.template info<1>(e) = one - (one - cross_ratio_AB_2) * (cross_ratio_AC) ;
|
_combinatorial_map.template info<1>(e) = one - (one - cross_ratio_AB_2) * (cross_ratio_AC);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opposite(f) == c){
|
if (opposite(f) == c) {
|
||||||
_combinatorial_map.template info<1>(f) = one - (one - cross_ratio_BC_2) / (cross_ratio_BD) ;
|
_combinatorial_map.template info<1>(f) = one - (one - cross_ratio_BC_2) / (cross_ratio_BD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Traits, class Attributes>
|
template<class Traits, class Attributes>
|
||||||
bool Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::is_Delaunay() const{
|
bool
|
||||||
if (! is_valid()){
|
Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::
|
||||||
|
is_Delaunay() const
|
||||||
|
{
|
||||||
|
if (! is_valid()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return (pick_edge_to_flip() == nullptr);
|
return (pick_edge_to_flip() == nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Traits, class Attributes>
|
template<class Traits, class Attributes>
|
||||||
int Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::make_Delaunay(){
|
int
|
||||||
|
Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::
|
||||||
|
make_Delaunay()
|
||||||
|
{
|
||||||
CGAL_precondition(is_valid());
|
CGAL_precondition(is_valid());
|
||||||
int number_of_flips_done = 0;
|
int number_of_flips_done = 0;
|
||||||
|
|
||||||
Dart_descriptor edge_to_flip = pick_edge_to_flip();
|
Dart_descriptor edge_to_flip = pick_edge_to_flip();
|
||||||
while (edge_to_flip != nullptr){
|
while (edge_to_flip != nullptr) {
|
||||||
flip(edge_to_flip);
|
flip(edge_to_flip);
|
||||||
edge_to_flip = pick_edge_to_flip();
|
edge_to_flip = pick_edge_to_flip();
|
||||||
number_of_flips_done++;
|
number_of_flips_done++;
|
||||||
|
|
@ -380,19 +411,31 @@ int Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::make_Delaunay(){
|
||||||
|
|
||||||
|
|
||||||
template<class Traits, class Attributes>
|
template<class Traits, class Attributes>
|
||||||
std::vector<std::tuple<typename Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::Dart_const_descriptor, typename Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::Point, typename Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::Point, typename Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::Point>> Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::lift(bool center) const{
|
std::vector<std::tuple<typename Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::Dart_const_descriptor,
|
||||||
|
typename Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::Point,
|
||||||
|
typename Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::Point,
|
||||||
|
typename Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::Point> >
|
||||||
|
Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::
|
||||||
|
lift(bool center) const
|
||||||
|
{
|
||||||
CGAL_precondition(is_valid() && has_anchor());
|
CGAL_precondition(is_valid() && has_anchor());
|
||||||
std::vector<std::tuple<Dart_const_descriptor,Point,Point,Point>> realizations;
|
|
||||||
|
std::vector<std::tuple<Dart_const_descriptor, Point, Point, Point> > realizations;
|
||||||
|
|
||||||
size_t visited_darts_mark = _combinatorial_map.get_new_mark();
|
size_t visited_darts_mark = _combinatorial_map.get_new_mark();
|
||||||
_combinatorial_map.unmark_all(visited_darts_mark);
|
_combinatorial_map.unmark_all(visited_darts_mark);
|
||||||
|
|
||||||
struct Compare {
|
struct Compare
|
||||||
bool operator()(std::pair<Dart_const_descriptor,double> const & x, std::pair<Dart_const_descriptor,double> const & y) {
|
{
|
||||||
|
bool operator()(const std::pair<Dart_const_descriptor,double>& x,
|
||||||
|
const std::pair<Dart_const_descriptor,double>& y)
|
||||||
|
{
|
||||||
return x.second > y.second;
|
return x.second > y.second;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
std::priority_queue<std::pair<Dart_const_descriptor,double>, std::vector<std::pair<Dart_const_descriptor,double>>, Compare> queue;
|
|
||||||
|
std::priority_queue<std::pair<Dart_const_descriptor, double>,
|
||||||
|
std::vector<std::pair<Dart_const_descriptor, double> >, Compare> queue;
|
||||||
|
|
||||||
std::unordered_map<Dart_const_descriptor, Point> positions;
|
std::unordered_map<Dart_const_descriptor, Point> positions;
|
||||||
|
|
||||||
|
|
@ -402,7 +445,7 @@ std::vector<std::tuple<typename Triangulation_on_hyperbolic_surface_2<Traits, At
|
||||||
_combinatorial_map.mark(const_ccw(_anchor.dart), visited_darts_mark);
|
_combinatorial_map.mark(const_ccw(_anchor.dart), visited_darts_mark);
|
||||||
_combinatorial_map.mark(const_cw(_anchor.dart), visited_darts_mark);
|
_combinatorial_map.mark(const_cw(_anchor.dart), visited_darts_mark);
|
||||||
|
|
||||||
if (center){
|
if (center) {
|
||||||
Isometry center_the_drawing = hyperbolic_translation<Traits>(_anchor.vertices[0]);
|
Isometry center_the_drawing = hyperbolic_translation<Traits>(_anchor.vertices[0]);
|
||||||
positions[_anchor.dart] = center_the_drawing.evaluate(_anchor.vertices[0]);
|
positions[_anchor.dart] = center_the_drawing.evaluate(_anchor.vertices[0]);
|
||||||
positions[const_ccw(_anchor.dart)] = center_the_drawing.evaluate(_anchor.vertices[1]);
|
positions[const_ccw(_anchor.dart)] = center_the_drawing.evaluate(_anchor.vertices[1]);
|
||||||
|
|
@ -413,12 +456,16 @@ std::vector<std::tuple<typename Triangulation_on_hyperbolic_surface_2<Traits, At
|
||||||
positions[const_cw(_anchor.dart)] = _anchor.vertices[2];
|
positions[const_cw(_anchor.dart)] = _anchor.vertices[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<Dart_const_descriptor,Point,Point,Point> value = std::make_tuple(_anchor.dart, positions[_anchor.dart], positions[const_ccw(_anchor.dart)], positions[const_cw(_anchor.dart)]);
|
std::tuple<Dart_const_descriptor, Point, Point, Point> value =
|
||||||
|
std::make_tuple(_anchor.dart,
|
||||||
|
positions[_anchor.dart],
|
||||||
|
positions[const_ccw(_anchor.dart)],
|
||||||
|
positions[const_cw(_anchor.dart)]);
|
||||||
realizations.push_back(value);
|
realizations.push_back(value);
|
||||||
|
|
||||||
Complex_number anchor_z0 (_anchor.vertices[0].x(), _anchor.vertices[0].y());
|
Complex_number anchor_z0(_anchor.vertices[0].x(), _anchor.vertices[0].y());
|
||||||
Complex_number anchor_z1 (_anchor.vertices[1].x(), _anchor.vertices[1].y());
|
Complex_number anchor_z1(_anchor.vertices[1].x(), _anchor.vertices[1].y());
|
||||||
Complex_number anchor_z2 (_anchor.vertices[2].x(), _anchor.vertices[2].y());
|
Complex_number anchor_z2(_anchor.vertices[2].x(), _anchor.vertices[2].y());
|
||||||
|
|
||||||
double weight_of_anchor_dart = CGAL::to_double(norm(anchor_z0) + norm(anchor_z1));
|
double weight_of_anchor_dart = CGAL::to_double(norm(anchor_z0) + norm(anchor_z1));
|
||||||
double weight_of_ccw_anchor_dart = CGAL::to_double(norm(anchor_z1) + norm(anchor_z2));
|
double weight_of_ccw_anchor_dart = CGAL::to_double(norm(anchor_z1) + norm(anchor_z2));
|
||||||
|
|
@ -428,22 +475,20 @@ std::vector<std::tuple<typename Triangulation_on_hyperbolic_surface_2<Traits, At
|
||||||
queue.push(std::make_pair(const_ccw(_anchor.dart), weight_of_ccw_anchor_dart));
|
queue.push(std::make_pair(const_ccw(_anchor.dart), weight_of_ccw_anchor_dart));
|
||||||
queue.push(std::make_pair(const_cw(_anchor.dart), weight_of_cw_anchor_dart));
|
queue.push(std::make_pair(const_cw(_anchor.dart), weight_of_cw_anchor_dart));
|
||||||
|
|
||||||
|
while (! queue.empty()) {
|
||||||
|
|
||||||
while( ! queue.empty() ){
|
|
||||||
Dart_const_descriptor invader = queue.top().first;
|
Dart_const_descriptor invader = queue.top().first;
|
||||||
queue.pop();
|
queue.pop();
|
||||||
|
|
||||||
Dart_const_descriptor invaded = const_opposite(invader);
|
Dart_const_descriptor invaded = const_opposite(invader);
|
||||||
|
|
||||||
if (!_combinatorial_map.is_marked(invaded, visited_darts_mark)){
|
if (!_combinatorial_map.is_marked(invaded, visited_darts_mark)) {
|
||||||
_combinatorial_map.mark(invaded, visited_darts_mark);
|
_combinatorial_map.mark(invaded, visited_darts_mark);
|
||||||
_combinatorial_map.mark(const_ccw(invaded), visited_darts_mark);
|
_combinatorial_map.mark(const_ccw(invaded), visited_darts_mark);
|
||||||
_combinatorial_map.mark(const_cw(invaded), visited_darts_mark);
|
_combinatorial_map.mark(const_cw(invaded), visited_darts_mark);
|
||||||
|
|
||||||
const Point &a = positions[const_ccw(invader)];
|
const Point& a = positions[const_ccw(invader)];
|
||||||
const Point &b = positions[const_cw(invader)];
|
const Point& b = positions[const_cw(invader)];
|
||||||
const Point &c = positions[invader];
|
const Point& c = positions[invader];
|
||||||
Complex_number cross_ratio = get_cross_ratio(invader);
|
Complex_number cross_ratio = get_cross_ratio(invader);
|
||||||
|
|
||||||
positions[invaded] = a;
|
positions[invaded] = a;
|
||||||
|
|
@ -451,18 +496,18 @@ std::vector<std::tuple<typename Triangulation_on_hyperbolic_surface_2<Traits, At
|
||||||
Point d = fourth_point_from_cross_ratio(a, b, c, cross_ratio);
|
Point d = fourth_point_from_cross_ratio(a, b, c, cross_ratio);
|
||||||
positions[const_cw(invaded)] = d;
|
positions[const_cw(invaded)] = d;
|
||||||
|
|
||||||
Complex_number za (a.x(), a.y());
|
Complex_number za(a.x(), a.y());
|
||||||
Complex_number zc (c.x(), c.y());
|
Complex_number zc(c.x(), c.y());
|
||||||
double invaded_distance_to_zero = CGAL::to_double(norm(za));
|
double invaded_distance_to_zero = CGAL::to_double(norm(za));
|
||||||
double invaded_ccw_distance_to_zero = CGAL::to_double(norm(zc));
|
double invaded_ccw_distance_to_zero = CGAL::to_double(norm(zc));
|
||||||
Complex_number znew (positions[const_cw(invaded)].x(), positions[const_cw(invaded)].y());
|
Complex_number znew(positions[const_cw(invaded)].x(), positions[const_cw(invaded)].y());
|
||||||
double invaded_cw_distance_to_zero = CGAL::to_double(norm(znew));
|
double invaded_cw_distance_to_zero = CGAL::to_double(norm(znew));
|
||||||
|
|
||||||
double invaded_ccw_weight = invaded_ccw_distance_to_zero + invaded_cw_distance_to_zero;
|
double invaded_ccw_weight = invaded_ccw_distance_to_zero + invaded_cw_distance_to_zero;
|
||||||
double invaded_cw_weight = invaded_cw_distance_to_zero + invaded_distance_to_zero;
|
double invaded_cw_weight = invaded_cw_distance_to_zero + invaded_distance_to_zero;
|
||||||
|
|
||||||
queue.push( std::make_pair(const_ccw(invaded), invaded_ccw_weight) );
|
queue.push(std::make_pair(const_ccw(invaded), invaded_ccw_weight));
|
||||||
queue.push( std::make_pair(const_cw(invaded), invaded_cw_weight) );
|
queue.push(std::make_pair(const_cw(invaded), invaded_cw_weight));
|
||||||
|
|
||||||
value = std::make_tuple(invaded, Point(a), Point(c), Point(d));
|
value = std::make_tuple(invaded, Point(a), Point(c), Point(d));
|
||||||
realizations.push_back(value);
|
realizations.push_back(value);
|
||||||
|
|
@ -477,33 +522,36 @@ std::vector<std::tuple<typename Triangulation_on_hyperbolic_surface_2<Traits, At
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template<class Traits, class Attributes>
|
template<class Traits, class Attributes>
|
||||||
bool Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::is_valid() const{
|
bool
|
||||||
|
Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::
|
||||||
|
is_valid() const
|
||||||
|
{
|
||||||
// 1. Check the combinatorial map
|
// 1. Check the combinatorial map
|
||||||
|
|
||||||
// Check that the combinatorial map is valid
|
// Check that the combinatorial map is valid
|
||||||
if ( !_combinatorial_map.is_valid() ){
|
if (!_combinatorial_map.is_valid()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that the combinatorial map has no 1,2-boundary
|
// Check that the combinatorial map has no 1,2-boundary
|
||||||
for (int k=1; k<3; ++k){
|
for (int k=1; k<3; ++k) {
|
||||||
if ( !_combinatorial_map.is_without_boundary(k) ){
|
if (!_combinatorial_map.is_without_boundary(k)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Check the anchor, if any
|
// 2. Check the anchor, if any
|
||||||
|
|
||||||
if (_has_anchor){
|
if (_has_anchor) {
|
||||||
// Check that the dart descriptor of the anchor points to a dart of the combinatorial map
|
// Check that the dart descriptor of the anchor points to a dart of the combinatorial map
|
||||||
if ( !_combinatorial_map.is_dart_used(_anchor.dart) ){
|
if (!_combinatorial_map.is_dart_used(_anchor.dart)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that the three vertices of the anchor lie within the open unit disk
|
// Check that the three vertices of the anchor lie within the open unit disk
|
||||||
for (int k=0; k<3; ++k){
|
for (int k=0; k<3; ++k) {
|
||||||
// if (_anchor.vertices[k].get_z() >= Number(1)){
|
// if (_anchor.vertices[k].get_z() >= Number(1)) {
|
||||||
if ( norm(Complex_number(_anchor.vertices[k].x(),_anchor.vertices[k].y())) >= Number(1)){
|
if (norm(Complex_number(_anchor.vertices[k].x(),_anchor.vertices[k].y())) >= Number(1)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -515,12 +563,16 @@ bool Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::is_valid() const
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template<class Traits, class Attributes>
|
template<class Traits, class Attributes>
|
||||||
void Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::to_stream(std::ostream& s) const{
|
void
|
||||||
|
Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::
|
||||||
|
to_stream(std::ostream& s) const
|
||||||
|
{
|
||||||
CGAL_precondition(is_valid() && has_anchor());
|
CGAL_precondition(is_valid() && has_anchor());
|
||||||
|
|
||||||
// Give indices to the darts
|
// Give indices to the darts
|
||||||
std::map<Dart_const_descriptor, int> darts_indices;
|
std::map<Dart_const_descriptor, int> darts_indices;
|
||||||
int current_dart_index = 0;
|
int current_dart_index = 0;
|
||||||
for (typename Dart_const_range::const_iterator it=_combinatorial_map.darts().begin(); it!=_combinatorial_map.darts().end(); ++it){
|
for (typename Dart_const_range::const_iterator it=_combinatorial_map.darts().begin(); it!=_combinatorial_map.darts().end(); ++it) {
|
||||||
darts_indices[it] = current_dart_index;
|
darts_indices[it] = current_dart_index;
|
||||||
current_dart_index++;
|
current_dart_index++;
|
||||||
}
|
}
|
||||||
|
|
@ -529,7 +581,7 @@ void Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::to_stream(std::o
|
||||||
s << current_dart_index << std::endl;
|
s << current_dart_index << std::endl;
|
||||||
|
|
||||||
// Store the anchor, if any
|
// Store the anchor, if any
|
||||||
if (_has_anchor){
|
if (_has_anchor) {
|
||||||
s << "yes" << std::endl;
|
s << "yes" << std::endl;
|
||||||
s << darts_indices[_anchor.dart] << std::endl;
|
s << darts_indices[_anchor.dart] << std::endl;
|
||||||
s << _anchor.vertices[0] << std::endl;
|
s << _anchor.vertices[0] << std::endl;
|
||||||
|
|
@ -540,14 +592,14 @@ void Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::to_stream(std::o
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store the triangles
|
// Store the triangles
|
||||||
for (typename Face_const_range::const_iterator it = faces_const_range().begin(); it != faces_const_range().end(); ++it){
|
for (typename Face_const_range::const_iterator it = faces_const_range().begin(); it != faces_const_range().end(); ++it) {
|
||||||
s << darts_indices[it] << std::endl;
|
s << darts_indices[it] << std::endl;
|
||||||
s << darts_indices[const_cw(it)] << std::endl;
|
s << darts_indices[const_cw(it)] << std::endl;
|
||||||
s << darts_indices[const_ccw(it)] << std::endl;
|
s << darts_indices[const_ccw(it)] << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store the edges
|
// Store the edges
|
||||||
for (typename Edge_const_range::const_iterator it = edges_const_range().begin(); it != edges_const_range().end(); ++it){
|
for (typename Edge_const_range::const_iterator it = edges_const_range().begin(); it != edges_const_range().end(); ++it) {
|
||||||
s << darts_indices[it] << std::endl;
|
s << darts_indices[it] << std::endl;
|
||||||
s << darts_indices[const_opposite(it)] << std::endl;
|
s << darts_indices[const_opposite(it)] << std::endl;
|
||||||
s << get_cross_ratio(it);
|
s << get_cross_ratio(it);
|
||||||
|
|
@ -555,7 +607,10 @@ void Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::to_stream(std::o
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Traits, class Attributes>
|
template<class Traits, class Attributes>
|
||||||
void Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::from_stream(std::istream& s){
|
void
|
||||||
|
Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::
|
||||||
|
from_stream(std::istream& s)
|
||||||
|
{
|
||||||
_combinatorial_map.clear();
|
_combinatorial_map.clear();
|
||||||
|
|
||||||
// Load the number of darts
|
// Load the number of darts
|
||||||
|
|
@ -566,7 +621,7 @@ void Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::from_stream(std:
|
||||||
// Load the anchor
|
// Load the anchor
|
||||||
int anchor_dart_id;
|
int anchor_dart_id;
|
||||||
s >> line;
|
s >> line;
|
||||||
if (!line.compare("yes")){
|
if (!line.compare("yes")) {
|
||||||
_has_anchor = true;
|
_has_anchor = true;
|
||||||
|
|
||||||
s >> line;
|
s >> line;
|
||||||
|
|
@ -582,7 +637,7 @@ void Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::from_stream(std:
|
||||||
// Load the triangles
|
// Load the triangles
|
||||||
std::vector<Dart_descriptor> darts_by_id (nb_darts);
|
std::vector<Dart_descriptor> darts_by_id (nb_darts);
|
||||||
int index1, index2, index3;
|
int index1, index2, index3;
|
||||||
for (int k=0; k<nb_darts/3; ++k){
|
for (int k=0; k<nb_darts/3; ++k) {
|
||||||
Dart_descriptor triangle_dart = _combinatorial_map.make_combinatorial_polygon(3);
|
Dart_descriptor triangle_dart = _combinatorial_map.make_combinatorial_polygon(3);
|
||||||
|
|
||||||
s >> line;
|
s >> line;
|
||||||
|
|
@ -600,7 +655,7 @@ void Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::from_stream(std:
|
||||||
// Load the edges
|
// Load the edges
|
||||||
Dart_descriptor dart_1, dart_2;
|
Dart_descriptor dart_1, dart_2;
|
||||||
Complex_number cross_ratio;
|
Complex_number cross_ratio;
|
||||||
for (int k=0; k<nb_darts/2; ++k){
|
for (int k=0; k<nb_darts/2; ++k) {
|
||||||
s >> line;
|
s >> line;
|
||||||
index1 = std::stoi(line);
|
index1 = std::stoi(line);
|
||||||
s >> line;
|
s >> line;
|
||||||
|
|
@ -613,7 +668,7 @@ void Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::from_stream(std:
|
||||||
}
|
}
|
||||||
|
|
||||||
// (*) here
|
// (*) here
|
||||||
if (_has_anchor){
|
if (_has_anchor) {
|
||||||
_anchor.dart = darts_by_id[anchor_dart_id];
|
_anchor.dart = darts_by_id[anchor_dart_id];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -621,48 +676,50 @@ void Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::from_stream(std:
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template<class Traits, class Attributes>
|
template<class Traits, class Attributes>
|
||||||
typename Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::Dart_descriptor Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::ccw(Dart_descriptor dart){
|
typename Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::Dart_descriptor Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::ccw(Dart_descriptor dart) {
|
||||||
return _combinatorial_map.beta(dart, 1);
|
return _combinatorial_map.beta(dart, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Traits, class Attributes>
|
template<class Traits, class Attributes>
|
||||||
typename Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::Dart_descriptor Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::cw(Dart_descriptor dart){
|
typename Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::Dart_descriptor Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::cw(Dart_descriptor dart) {
|
||||||
return _combinatorial_map.beta(dart, 0);
|
return _combinatorial_map.beta(dart, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Traits, class Attributes>
|
template<class Traits, class Attributes>
|
||||||
typename Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::Dart_descriptor Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::opposite(Dart_descriptor dart){
|
typename Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::Dart_descriptor Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::opposite(Dart_descriptor dart) {
|
||||||
return _combinatorial_map.opposite(dart);
|
return _combinatorial_map.opposite(dart);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Traits, class Attributes>
|
template<class Traits, class Attributes>
|
||||||
typename Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::Dart_const_descriptor Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::const_ccw(Dart_const_descriptor dart) const{
|
typename Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::Dart_const_descriptor Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::const_ccw(Dart_const_descriptor dart) const {
|
||||||
return _combinatorial_map.beta(dart, 1);
|
return _combinatorial_map.beta(dart, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Traits, class Attributes>
|
template<class Traits, class Attributes>
|
||||||
typename Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::Dart_const_descriptor Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::const_cw(Dart_const_descriptor dart) const{
|
typename Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::Dart_const_descriptor Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::const_cw(Dart_const_descriptor dart) const {
|
||||||
return _combinatorial_map.beta(dart, 0);
|
return _combinatorial_map.beta(dart, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Traits, class Attributes>
|
template<class Traits, class Attributes>
|
||||||
typename Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::Dart_const_descriptor Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::const_opposite(Dart_const_descriptor dart) const{
|
typename Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::Dart_const_descriptor Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::const_opposite(Dart_const_descriptor dart) const {
|
||||||
return _combinatorial_map.opposite(dart);
|
return _combinatorial_map.opposite(dart);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template<class Traits, class Attributes>
|
template<class Traits, class Attributes>
|
||||||
typename Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::Complex_number Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::get_cross_ratio(Dart_const_descriptor dart) const{
|
typename Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::Complex_number Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::get_cross_ratio(Dart_const_descriptor dart) const {
|
||||||
return _combinatorial_map.template info_of_attribute<1>(_combinatorial_map.template attribute<1>(dart));
|
return _combinatorial_map.template info_of_attribute<1>(_combinatorial_map.template attribute<1>(dart));
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
template<class Traits, class Attributes>
|
template<class Traits, class Attributes>
|
||||||
typename Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::Dart_descriptor Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::pick_edge_to_flip(){
|
typename Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::Dart_descriptor Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::
|
||||||
auto &cm=_combinatorial_map.darts();
|
pick_edge_to_flip()
|
||||||
for (auto it = cm.begin(); it != cm.end(); ++it){
|
{
|
||||||
if ( is_Delaunay_flippable(it) ){
|
auto& cm = _combinatorial_map.darts();
|
||||||
|
for (auto it=cm.begin(); it!=cm.end(); ++it) {
|
||||||
|
if (is_Delaunay_flippable(it)) {
|
||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -672,10 +729,13 @@ template<class Traits, class Attributes>
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template<class Traits, class Attributes>
|
template<class Traits, class Attributes>
|
||||||
typename Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::Dart_const_descriptor Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::pick_edge_to_flip() const{
|
typename Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::Dart_const_descriptor
|
||||||
const auto &cm=_combinatorial_map.darts();
|
Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::
|
||||||
for (auto it = cm.begin(); it != cm.end(); ++it){
|
pick_edge_to_flip() const
|
||||||
if ( is_Delaunay_flippable(it) ){
|
{
|
||||||
|
const auto& cm = _combinatorial_map.darts();
|
||||||
|
for (auto it=cm.begin(); it!=cm.end(); ++it) {
|
||||||
|
if (is_Delaunay_flippable(it) ) {
|
||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -685,20 +745,27 @@ template<class Traits, class Attributes>
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template<class Traits, class Attributes>
|
template<class Traits, class Attributes>
|
||||||
void Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::copy_from(Combinatorial_map_with_cross_ratios& cmap){
|
void
|
||||||
|
Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::
|
||||||
|
copy_from(Combinatorial_map_with_cross_ratios& cmap)
|
||||||
|
{
|
||||||
//_combinatorial_map.copy_from_const(cmap);
|
//_combinatorial_map.copy_from_const(cmap);
|
||||||
_combinatorial_map.copy(cmap);
|
_combinatorial_map.copy(cmap);
|
||||||
_has_anchor = false;
|
_has_anchor = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Traits, class Attributes>
|
template<class Traits, class Attributes>
|
||||||
void Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::copy_from(Combinatorial_map_with_cross_ratios& cmap, const Anchor& anchor){
|
void
|
||||||
|
Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::
|
||||||
|
copy_from(Combinatorial_map_with_cross_ratios& cmap,
|
||||||
|
const Anchor& anchor)
|
||||||
|
{
|
||||||
// Because of the anchor, we must operate the copy ourself
|
// Because of the anchor, we must operate the copy ourself
|
||||||
_combinatorial_map.clear();
|
_combinatorial_map.clear();
|
||||||
|
|
||||||
// Copy the triangles and fill the darts conversion table
|
// Copy the triangles and fill the darts conversion table
|
||||||
std::map<Dart_const_descriptor, Dart_descriptor> darts_table;
|
std::map<Dart_const_descriptor, Dart_descriptor> darts_table;
|
||||||
for (typename Face_const_range::const_iterator it=cmap.template one_dart_per_cell<2>().begin(); it!=cmap.template one_dart_per_cell<2>().end(); ++it){
|
for (typename Face_const_range::const_iterator it=cmap.template one_dart_per_cell<2>().begin(); it!=cmap.template one_dart_per_cell<2>().end(); ++it) {
|
||||||
Dart_descriptor new_dart = _combinatorial_map.make_combinatorial_polygon(3);
|
Dart_descriptor new_dart = _combinatorial_map.make_combinatorial_polygon(3);
|
||||||
darts_table[it] = new_dart;
|
darts_table[it] = new_dart;
|
||||||
darts_table[cmap.beta(it,0)] = _combinatorial_map.beta(new_dart,0);
|
darts_table[cmap.beta(it,0)] = _combinatorial_map.beta(new_dart,0);
|
||||||
|
|
@ -706,7 +773,7 @@ void Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::copy_from(Combin
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sew the edges and set their cross-ratios
|
// Sew the edges and set their cross-ratios
|
||||||
for (typename Edge_const_range::const_iterator it=cmap.template one_dart_per_cell<1>().begin(); it!=cmap.template one_dart_per_cell<1>().end(); ++it){
|
for (typename Edge_const_range::const_iterator it=cmap.template one_dart_per_cell<1>().begin(); it!=cmap.template one_dart_per_cell<1>().end(); ++it) {
|
||||||
Dart_descriptor dart_1 = darts_table[it];
|
Dart_descriptor dart_1 = darts_table[it];
|
||||||
Dart_descriptor dart_2 = darts_table[cmap.opposite(it)];
|
Dart_descriptor dart_2 = darts_table[cmap.opposite(it)];
|
||||||
Complex_number cratio = cmap.template info_of_attribute<1>(cmap.template attribute<1>(it));
|
Complex_number cratio = cmap.template info_of_attribute<1>(cmap.template attribute<1>(it));
|
||||||
|
|
@ -719,7 +786,7 @@ void Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::copy_from(Combin
|
||||||
|
|
||||||
// Set the anchor
|
// Set the anchor
|
||||||
_anchor.dart = darts_table[anchor.dart];
|
_anchor.dart = darts_table[anchor.dart];
|
||||||
for (int k=0; k<3; ++k){
|
for (int k=0; k<3; ++k) {
|
||||||
_anchor.vertices[k] = anchor.vertices[k];
|
_anchor.vertices[k] = anchor.vertices[k];
|
||||||
}
|
}
|
||||||
_has_anchor = true;
|
_has_anchor = true;
|
||||||
|
|
@ -728,7 +795,10 @@ void Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::copy_from(Combin
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template<class Traits, class Attributes>
|
template<class Traits, class Attributes>
|
||||||
typename Traits::Complex Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::cross_ratio(const Point& a, const Point& b, const Point& c, const Point& d) const{
|
typename Traits::Complex
|
||||||
|
Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::
|
||||||
|
cross_ratio(const Point& a, const Point& b, const Point& c, const Point& d) const
|
||||||
|
{
|
||||||
Complex_number za (a.x(), a.y());
|
Complex_number za (a.x(), a.y());
|
||||||
Complex_number zb (b.x(), b.y());
|
Complex_number zb (b.x(), b.y());
|
||||||
Complex_number zc (c.x(), c.y());
|
Complex_number zc (c.x(), c.y());
|
||||||
|
|
@ -737,11 +807,15 @@ typename Traits::Complex Triangulation_on_hyperbolic_surface_2<Traits, Attribute
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Traits, class Attributes>
|
template<class Traits, class Attributes>
|
||||||
typename Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::Point Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::fourth_point_from_cross_ratio(const Point& a, const Point& b, const Point& c, const Complex_number& cratio) const{
|
typename Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::Point
|
||||||
|
Triangulation_on_hyperbolic_surface_2<Traits, Attributes>::
|
||||||
|
fourth_point_from_cross_ratio(const Point& a, const Point& b, const Point& c,
|
||||||
|
const Complex_number& cratio) const
|
||||||
|
{
|
||||||
Complex_number za (a.x(), a.y());
|
Complex_number za (a.x(), a.y());
|
||||||
Complex_number zb (b.x(), b.y());
|
Complex_number zb (b.x(), b.y());
|
||||||
Complex_number zc (c.x(), c.y());
|
Complex_number zc (c.x(), c.y());
|
||||||
Complex_number result = ( cratio*za*(zc-zb) + zb*(za-zc) ) / ( cratio*(zc-zb) + (za-zc) );
|
Complex_number result = ( cratio*za*(zc-zb) + zb*(za-zc) ) / ( cratio*(zc-zb) + (za-zc));
|
||||||
return Point(result.real(), result.imag());
|
return Point(result.real(), result.imag());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,35 +10,38 @@
|
||||||
//
|
//
|
||||||
// Author(s) : Vincent Despré, Loïc Dubois, Marc Pouget, Monique Teillaud
|
// Author(s) : Vincent Despré, Loïc Dubois, Marc Pouget, Monique Teillaud
|
||||||
|
|
||||||
// This file contains the declaration and the implementation of the input/output
|
|
||||||
// functions for the package Triangulation_on_hyperbolic_surface_2
|
|
||||||
|
|
||||||
#ifndef CGAL_TRIANGULATION_ON_HYPERBOLIC_SURFACE_2_IO_H
|
#ifndef CGAL_TRIANGULATION_ON_HYPERBOLIC_SURFACE_2_IO_H
|
||||||
#define CGAL_TRIANGULATION_ON_HYPERBOLIC_SURFACE_2_IO_H
|
#define CGAL_TRIANGULATION_ON_HYPERBOLIC_SURFACE_2_IO_H
|
||||||
|
|
||||||
#include <CGAL/license/Triangulation_on_hyperbolic_surface_2.h>
|
#include <CGAL/license/Triangulation_on_hyperbolic_surface_2.h>
|
||||||
|
|
||||||
#include <CGAL/Triangulation_on_hyperbolic_surface_2.h>
|
#include <CGAL/Triangulation_on_hyperbolic_surface_2.h>
|
||||||
#include <CGAL/basic.h>
|
|
||||||
|
#include <CGAL/assertions.h>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
std::ostream& operator<<(std::ostream& s, const Hyperbolic_fundamental_domain_2<Traits>& domain){
|
std::ostream& operator<<(std::ostream& s, const Hyperbolic_fundamental_domain_2<Traits>& domain)
|
||||||
|
{
|
||||||
CGAL_precondition(domain.is_valid());
|
CGAL_precondition(domain.is_valid());
|
||||||
return domain.to_stream(s);
|
return domain.to_stream(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
std::istream& operator>>(std::istream& s, Hyperbolic_fundamental_domain_2<Traits>& domain){
|
std::istream& operator>>(std::istream& s, Hyperbolic_fundamental_domain_2<Traits>& domain)
|
||||||
|
{
|
||||||
return domain.from_stream(s);
|
return domain.from_stream(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
template<class Traits>
|
template<class Traits>
|
||||||
std::ostream& operator<<(std::ostream& s, const Hyperbolic_isometry_2<Traits>& isometry){
|
std::ostream& operator<<(std::ostream& s, const Hyperbolic_isometry_2<Traits>& isometry)
|
||||||
for (int k=0; k<4; ++k){
|
{
|
||||||
|
for (int k=0; k<4; ++k) {
|
||||||
s << isometry.get_coefficient(k);
|
s << isometry.get_coefficient(k);
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
|
|
@ -46,13 +49,15 @@ std::ostream& operator<<(std::ostream& s, const Hyperbolic_isometry_2<Traits>& i
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
template<class Traits, class Attributes>
|
template<class Traits, class Attributes>
|
||||||
std::ostream& operator<<(std::ostream& s, const Triangulation_on_hyperbolic_surface_2<Traits, Attributes>& triangulation){
|
std::ostream& operator<<(std::ostream& s, const Triangulation_on_hyperbolic_surface_2<Traits, Attributes>& triangulation)
|
||||||
|
{
|
||||||
triangulation.to_stream(s);
|
triangulation.to_stream(s);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Traits, class Attributes>
|
template<class Traits, class Attributes>
|
||||||
void operator>>(std::istream& s, Triangulation_on_hyperbolic_surface_2<Traits, Attributes>& triangulation){
|
void operator>>(std::istream& s, Triangulation_on_hyperbolic_surface_2<Traits, Attributes>& triangulation)
|
||||||
|
{
|
||||||
triangulation.from_stream(s);
|
triangulation.from_stream(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,11 @@
|
||||||
# Created by the script cgal_create_cmake_script
|
# Created by the script cgal_create_cmake_script
|
||||||
# This is the CMake script for compiling a CGAL application.
|
# This is the CMake script for compiling a CGAL application.
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.12...3.29)
|
cmake_minimum_required(VERSION 3.12...3.31)
|
||||||
project(Triangulation_on_hyperbolic_surface_2_Tests)
|
project(Triangulation_on_hyperbolic_surface_2_Tests)
|
||||||
|
|
||||||
find_package(CGAL REQUIRED)
|
find_package(CGAL REQUIRED)
|
||||||
|
|
||||||
set(CMAKE_BUILD_TYPE "Debug")
|
|
||||||
|
|
||||||
include_directories(../../include/)
|
|
||||||
|
|
||||||
# create a target per cppfile
|
# create a target per cppfile
|
||||||
file(
|
file(
|
||||||
GLOB cppfiles
|
GLOB cppfiles
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
typedef CGAL::Circular_kernel_2<CGAL::Cartesian<CGAL::Exact_rational>,CGAL::Algebraic_kernel_for_circles_2_2<CGAL::Exact_rational>> Kernel;
|
typedef CGAL::Circular_kernel_2<CGAL::Cartesian<CGAL::Exact_rational>,CGAL::Algebraic_kernel_for_circles_2_2<CGAL::Exact_rational>> Kernel;
|
||||||
typedef CGAL::Hyperbolic_Delaunay_triangulation_CK_traits_2<Kernel> ParentTraits;
|
typedef CGAL::Hyperbolic_Delaunay_triangulation_CK_traits_2<Kernel> ParentTraits;
|
||||||
|
|
@ -22,15 +23,16 @@ typedef CGAL::Triangulation_on_hyperbolic_surface_2<Traits> Tria
|
||||||
|
|
||||||
typedef typename Traits::Hyperbolic_point_2 Point;
|
typedef typename Traits::Hyperbolic_point_2 Point;
|
||||||
|
|
||||||
int main() {
|
int main()
|
||||||
|
{
|
||||||
Factory factory;
|
Factory factory;
|
||||||
Domain domain = factory.make_hyperbolic_fundamental_domain_g2(3459);
|
Domain domain = factory.make_hyperbolic_fundamental_domain_g2(3459);
|
||||||
Triangulation triangulation0 = Triangulation(domain);
|
Triangulation triangulation0 = Triangulation(domain);
|
||||||
|
|
||||||
assert( triangulation0.is_valid() );
|
assert(triangulation0.is_valid());
|
||||||
|
|
||||||
Triangulation triangulation (triangulation0);
|
Triangulation triangulation (triangulation0);
|
||||||
assert( triangulation.has_anchor() );
|
assert(triangulation.has_anchor());
|
||||||
|
|
||||||
std::stringstream buffer;
|
std::stringstream buffer;
|
||||||
buffer << triangulation;
|
buffer << triangulation;
|
||||||
|
|
@ -44,7 +46,7 @@ int main() {
|
||||||
|
|
||||||
triangulation.make_Delaunay();
|
triangulation.make_Delaunay();
|
||||||
|
|
||||||
assert( triangulation.is_Delaunay() );
|
assert(triangulation.is_Delaunay());
|
||||||
|
|
||||||
std::vector<std::tuple<typename Triangulation::Combinatorial_map_with_cross_ratios::Dart_const_handle,Point,Point,Point>> output_not_centered;
|
std::vector<std::tuple<typename Triangulation::Combinatorial_map_with_cross_ratios::Dart_const_handle,Point,Point,Point>> output_not_centered;
|
||||||
std::vector<std::tuple<typename Triangulation::Combinatorial_map_with_cross_ratios::Dart_const_handle,Point,Point,Point>> output_centered;
|
std::vector<std::tuple<typename Triangulation::Combinatorial_map_with_cross_ratios::Dart_const_handle,Point,Point,Point>> output_centered;
|
||||||
|
|
@ -55,9 +57,9 @@ int main() {
|
||||||
|
|
||||||
Triangulation::Combinatorial_map_with_cross_ratios& cmap = triangulation.combinatorial_map();
|
Triangulation::Combinatorial_map_with_cross_ratios& cmap = triangulation.combinatorial_map();
|
||||||
Triangulation::Anchor& anchor = triangulation.anchor();
|
Triangulation::Anchor& anchor = triangulation.anchor();
|
||||||
assert( cmap.is_dart_used(anchor.dart) );
|
assert(cmap.is_dart_used(anchor.dart));
|
||||||
|
|
||||||
std::cout << "printing triangulation for test purposes : " << std::endl << triangulation;
|
std::cout << "printing triangulation for test purposes: " << std::endl << triangulation;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,13 +10,14 @@ typedef CGAL::Interval_nt<> Interval;
|
||||||
typedef CGAL::Complex_number<Exact_rational> Complex_rational;
|
typedef CGAL::Complex_number<Exact_rational> Complex_rational;
|
||||||
typedef CGAL::Complex_number<Interval> Complex_interval;
|
typedef CGAL::Complex_number<Interval> Complex_interval;
|
||||||
|
|
||||||
int main() {
|
int main()
|
||||||
|
{
|
||||||
// Complex_rational tests :
|
// Complex_rational tests :
|
||||||
Complex_rational zero_rational = Complex_rational ();
|
Complex_rational zero_rational = Complex_rational ();
|
||||||
assert( zero_rational == Complex_rational(Exact_rational(0), Exact_rational(0)) );
|
assert(zero_rational == Complex_rational(Exact_rational(0), Exact_rational(0)));
|
||||||
|
|
||||||
Complex_rational one_rational (Exact_rational(1));
|
Complex_rational one_rational (Exact_rational(1));
|
||||||
assert( one_rational == Complex_rational(Exact_rational(1), Exact_rational(0)) );
|
assert(one_rational == Complex_rational(Exact_rational(1), Exact_rational(0)));
|
||||||
|
|
||||||
Complex_rational z1_rational (Exact_rational(1,2), Exact_rational(-3));
|
Complex_rational z1_rational (Exact_rational(1,2), Exact_rational(-3));
|
||||||
z1_rational = - z1_rational;
|
z1_rational = - z1_rational;
|
||||||
|
|
@ -26,13 +27,13 @@ int main() {
|
||||||
z2_rational.imag(Exact_rational(11,13));
|
z2_rational.imag(Exact_rational(11,13));
|
||||||
z2_rational = conj(z2_rational) + z1_rational - one_rational;
|
z2_rational = conj(z2_rational) + z1_rational - one_rational;
|
||||||
|
|
||||||
assert( - z1_rational * z1_rational / z2_rational == -Complex_rational(Exact_rational(855491,632146), Exact_rational(844298,316073)) );
|
assert(- z1_rational * z1_rational / z2_rational == -Complex_rational(Exact_rational(855491,632146), Exact_rational(844298,316073)));
|
||||||
assert( z1_rational.real() == Exact_rational(-1,2) );
|
assert(z1_rational.real() == Exact_rational(-1,2));
|
||||||
assert( z1_rational.imag() == Exact_rational(3) );
|
assert(z1_rational.imag() == Exact_rational(3));
|
||||||
assert( norm(z1_rational) == Exact_rational(37,4) );
|
assert(norm(z1_rational) == Exact_rational(37,4));
|
||||||
assert( z1_rational != z2_rational);
|
assert(z1_rational != z2_rational);
|
||||||
assert( z2_rational == z2_rational );
|
assert(z2_rational == z2_rational);
|
||||||
assert( z2_rational == Complex_rational(Exact_rational(-31,14), Exact_rational(28,13)) );
|
assert(z2_rational == Complex_rational(Exact_rational(-31,14), Exact_rational(28,13)));
|
||||||
|
|
||||||
std::cout << "printing a complex for test purposes : " << std::endl << z2_rational << std::endl;
|
std::cout << "printing a complex for test purposes : " << std::endl << z2_rational << std::endl;
|
||||||
|
|
||||||
|
|
@ -40,11 +41,11 @@ int main() {
|
||||||
std::stringstream buffer;
|
std::stringstream buffer;
|
||||||
buffer << z2_rational;
|
buffer << z2_rational;
|
||||||
buffer >> z3_rational;
|
buffer >> z3_rational;
|
||||||
assert( z3_rational == z2_rational );
|
assert(z3_rational == z2_rational);
|
||||||
|
|
||||||
// Complex_interval test :
|
// Complex_interval test :
|
||||||
Complex_interval z_interval (Interval(1, 2), Interval(1, 2));
|
Complex_interval z_interval (Interval(1, 2), Interval(1, 2));
|
||||||
assert( norm(z_interval * z_interval / Complex_interval(Interval(5, 6))) < Interval(10,20) );
|
assert(norm(z_interval * z_interval / Complex_interval(Interval(5, 6))) < Interval(10,20));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
#include <CGAL/Hyperbolic_Delaunay_triangulation_traits_2.h>
|
#include <CGAL/Hyperbolic_Delaunay_triangulation_traits_2.h>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
typedef CGAL::Cartesian<CGAL::Exact_rational> Kernel;
|
typedef CGAL::Cartesian<CGAL::Exact_rational> Kernel;
|
||||||
typedef CGAL::Hyperbolic_Delaunay_triangulation_traits_2<Kernel> ParentTraits;
|
typedef CGAL::Hyperbolic_Delaunay_triangulation_traits_2<Kernel> ParentTraits;
|
||||||
|
|
@ -18,7 +19,8 @@ typedef typename Traits::Hyperbolic_point_2 Point;
|
||||||
typedef typename Traits::Complex Complex;
|
typedef typename Traits::Complex Complex;
|
||||||
|
|
||||||
|
|
||||||
int main() {
|
int main()
|
||||||
|
{
|
||||||
std::vector<Point> vertices;
|
std::vector<Point> vertices;
|
||||||
Point z0 = Point(FT("4881/5000"),FT("0"));
|
Point z0 = Point(FT("4881/5000"),FT("0"));
|
||||||
Point z1 = Point(FT("9211/10000"),FT("2733/10000"));
|
Point z1 = Point(FT("9211/10000"),FT("2733/10000"));
|
||||||
|
|
@ -38,39 +40,39 @@ int main() {
|
||||||
vertices.push_back(z7);
|
vertices.push_back(z7);
|
||||||
|
|
||||||
std::vector<int> pairings;
|
std::vector<int> pairings;
|
||||||
for (std::size_t k=0; k<8; ++k){
|
for (std::size_t k=0; k<8; ++k) {
|
||||||
pairings.push_back((k+4)%8);
|
pairings.push_back((k+4)%8);
|
||||||
}
|
}
|
||||||
|
|
||||||
Domain domain = Domain(vertices, pairings);
|
Domain domain = Domain(vertices, pairings);
|
||||||
assert( domain.size()==8 );
|
assert(domain.size()==8);
|
||||||
for (std::size_t k=0; k<8; ++k){
|
for (std::size_t k=0; k<8; ++k) {
|
||||||
assert( domain.vertex(k)==vertices[k] );
|
assert(domain.vertex(k)==vertices[k]);
|
||||||
assert( domain.paired_side(k)==(k+4)%8 );
|
assert(domain.paired_side(k)==(k+4)%8);
|
||||||
assert( domain.side_pairing(k).evaluate(domain.vertex((k+4)%8))==domain.vertex((k+1)%8) );
|
assert(domain.side_pairing(k).evaluate(domain.vertex((k+4)%8))==domain.vertex((k+1)%8));
|
||||||
assert( domain.side_pairing(k).evaluate(domain.vertex((k+5)%8))==domain.vertex(k) );
|
assert(domain.side_pairing(k).evaluate(domain.vertex((k+5)%8))==domain.vertex(k));
|
||||||
}
|
}
|
||||||
|
|
||||||
assert( domain.is_valid() );
|
assert(domain.is_valid());
|
||||||
|
|
||||||
Domain domain_prime = Domain(vertices, pairings);
|
Domain domain_prime = Domain(vertices, pairings);
|
||||||
assert( domain_prime.size()==8 );
|
assert(domain_prime.size()==8);
|
||||||
for (std::size_t k=0; k<8; ++k){
|
for (std::size_t k=0; k<8; ++k) {
|
||||||
assert( domain_prime.vertex(k)==vertices[k]);
|
assert(domain_prime.vertex(k)==vertices[k]);
|
||||||
assert( domain_prime.paired_side(k)==(k+4)%8 );
|
assert(domain_prime.paired_side(k)==(k+4)%8);
|
||||||
|
|
||||||
assert( domain_prime.side_pairing(k).evaluate(domain_prime.vertex((k+4)%8))==domain_prime.vertex((k+1)%8) );
|
assert(domain_prime.side_pairing(k).evaluate(domain_prime.vertex((k+4)%8))==domain_prime.vertex((k+1)%8));
|
||||||
assert( domain_prime.side_pairing(k).evaluate(domain_prime.vertex((k+5)%8))==domain_prime.vertex(k) );
|
assert(domain_prime.side_pairing(k).evaluate(domain_prime.vertex((k+5)%8))==domain_prime.vertex(k));
|
||||||
}
|
}
|
||||||
|
|
||||||
Domain domain_ter = Domain();
|
Domain domain_ter = Domain();
|
||||||
std::stringstream buffer;
|
std::stringstream buffer;
|
||||||
buffer << domain;
|
buffer << domain;
|
||||||
buffer >> domain_ter;
|
buffer >> domain_ter;
|
||||||
assert( domain_ter.size()==8 );
|
assert(domain_ter.size()==8);
|
||||||
for (std::size_t k=0; k<8; ++k){
|
for (std::size_t k=0; k<8; ++k) {
|
||||||
assert( domain_ter.vertex(k)==vertices[k]);
|
assert(domain_ter.vertex(k)==vertices[k]);
|
||||||
assert( domain_ter.paired_side(k)==(k+4)%8 );
|
assert(domain_ter.paired_side(k)==(k+4)%8);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "printing a domain for test purposes : " << std::endl << domain << std::endl;
|
std::cout << "printing a domain for test purposes : " << std::endl << domain << std::endl;
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
#include <CGAL/Hyperbolic_Delaunay_triangulation_traits_2.h>
|
#include <CGAL/Hyperbolic_Delaunay_triangulation_traits_2.h>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
typedef CGAL::Cartesian<CGAL::Exact_rational> Kernel;
|
typedef CGAL::Cartesian<CGAL::Exact_rational> Kernel;
|
||||||
typedef CGAL::Hyperbolic_Delaunay_triangulation_traits_2<Kernel> ParentTraits;
|
typedef CGAL::Hyperbolic_Delaunay_triangulation_traits_2<Kernel> ParentTraits;
|
||||||
|
|
@ -17,8 +18,8 @@ typedef typename Traits::FT FT;
|
||||||
typedef typename Traits::Hyperbolic_point_2 Point;
|
typedef typename Traits::Hyperbolic_point_2 Point;
|
||||||
typedef typename Traits::Complex Complex;
|
typedef typename Traits::Complex Complex;
|
||||||
|
|
||||||
|
int main()
|
||||||
int main() {
|
{
|
||||||
Factory factory;
|
Factory factory;
|
||||||
Domain domain = factory.make_hyperbolic_fundamental_domain_g2(3459);
|
Domain domain = factory.make_hyperbolic_fundamental_domain_g2(3459);
|
||||||
|
|
||||||
|
|
@ -40,10 +41,10 @@ int main() {
|
||||||
vertices.push_back(z6);
|
vertices.push_back(z6);
|
||||||
vertices.push_back(z7);
|
vertices.push_back(z7);
|
||||||
|
|
||||||
assert( domain.size()==8 );
|
assert(domain.size()==8);
|
||||||
for (std::size_t k=0; k<8; ++k){
|
for (std::size_t k=0; k<8; ++k) {
|
||||||
assert( domain.vertex(k)==vertices[k]);
|
assert(domain.vertex(k)==vertices[k]);
|
||||||
assert( domain.paired_side(k)==(k+4)%8 );
|
assert(domain.paired_side(k)==(k+4)%8);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -17,69 +17,69 @@ typedef typename Traits::FT FT;
|
||||||
typedef typename Traits::Hyperbolic_point_2 Point;
|
typedef typename Traits::Hyperbolic_point_2 Point;
|
||||||
typedef typename Traits::Complex Complex;
|
typedef typename Traits::Complex Complex;
|
||||||
|
|
||||||
|
int main()
|
||||||
int main() {
|
{
|
||||||
Isometry identity_1 = Isometry ();
|
Isometry identity_1 = Isometry ();
|
||||||
assert( identity_1.get_coefficient(0)==Complex(FT(1)) );
|
assert(identity_1.get_coefficient(0)==Complex(FT(1)));
|
||||||
assert( identity_1.get_coefficient(1)==Complex(FT(0)) );
|
assert(identity_1.get_coefficient(1)==Complex(FT(0)));
|
||||||
assert( identity_1.get_coefficient(2)==Complex(FT(0)) );
|
assert(identity_1.get_coefficient(2)==Complex(FT(0)));
|
||||||
assert( identity_1.get_coefficient(3)==Complex(FT(1)) );
|
assert(identity_1.get_coefficient(3)==Complex(FT(1)));
|
||||||
|
|
||||||
Isometry identity_2;
|
Isometry identity_2;
|
||||||
identity_2.set_to_identity();
|
identity_2.set_to_identity();
|
||||||
assert( identity_2.get_coefficient(0)==Complex(FT(1)) );
|
assert(identity_2.get_coefficient(0)==Complex(FT(1)));
|
||||||
assert( identity_2.get_coefficient(1)==Complex(FT(0)) );
|
assert(identity_2.get_coefficient(1)==Complex(FT(0)));
|
||||||
assert( identity_2.get_coefficient(2)==Complex(FT(0)) );
|
assert(identity_2.get_coefficient(2)==Complex(FT(0)));
|
||||||
assert( identity_2.get_coefficient(3)==Complex(FT(1)) );
|
assert(identity_2.get_coefficient(3)==Complex(FT(1)));
|
||||||
|
|
||||||
Isometry f;
|
Isometry f;
|
||||||
f.set_coefficient(0, Complex(FT(-12,17), FT(1,3)));
|
f.set_coefficient(0, Complex(FT(-12,17), FT(1,3)));
|
||||||
f.set_coefficient(1, Complex(FT(56,7), FT(21,5)));
|
f.set_coefficient(1, Complex(FT(56,7), FT(21,5)));
|
||||||
f.set_coefficient(2, Complex(FT(56,7), FT(-21,5)));
|
f.set_coefficient(2, Complex(FT(56,7), FT(-21,5)));
|
||||||
f.set_coefficient(3, Complex(FT(-12,17), FT(-1,3)));
|
f.set_coefficient(3, Complex(FT(-12,17), FT(-1,3)));
|
||||||
assert( f.get_coefficient(0)==Complex(FT(-12,17), FT(1,3)) );
|
assert(f.get_coefficient(0)==Complex(FT(-12,17), FT(1,3)));
|
||||||
assert( f.get_coefficient(1)==Complex(FT(56,7), FT(21,5)) );
|
assert(f.get_coefficient(1)==Complex(FT(56,7), FT(21,5)));
|
||||||
assert( f.get_coefficient(2)==Complex(FT(56,7), FT(-21,5)) );
|
assert(f.get_coefficient(2)==Complex(FT(56,7), FT(-21,5)));
|
||||||
assert( f.get_coefficient(3)==Complex(FT(-12,17), FT(-1,3)) );
|
assert(f.get_coefficient(3)==Complex(FT(-12,17), FT(-1,3)));
|
||||||
|
|
||||||
Isometry g;
|
Isometry g;
|
||||||
g.set_coefficients(Complex(FT(-12,17), FT(1,3)), Complex(FT(56,7), FT(21,5)), Complex(FT(56,7), FT(-21,5)), Complex(FT(-12,17), FT(-1,3)));
|
g.set_coefficients(Complex(FT(-12,17), FT(1,3)), Complex(FT(56,7), FT(21,5)), Complex(FT(56,7), FT(-21,5)), Complex(FT(-12,17), FT(-1,3)));
|
||||||
assert( g.get_coefficient(0)==Complex(FT(-12,17), FT(1,3)) );
|
assert(g.get_coefficient(0)==Complex(FT(-12,17), FT(1,3)));
|
||||||
assert( g.get_coefficient(1)==Complex(FT(56,7), FT(21,5)) );
|
assert(g.get_coefficient(1)==Complex(FT(56,7), FT(21,5)));
|
||||||
assert( g.get_coefficient(2)==Complex(FT(56,7), FT(-21,5)) );
|
assert(g.get_coefficient(2)==Complex(FT(56,7), FT(-21,5)));
|
||||||
assert( g.get_coefficient(3)==Complex(FT(-12,17), FT(-1,3)) );
|
assert(g.get_coefficient(3)==Complex(FT(-12,17), FT(-1,3)));
|
||||||
|
|
||||||
Isometry h = f*g;
|
Isometry h = f*g;
|
||||||
assert( h.get_coefficient(0) == Complex(FT(5333816,65025),FT(-8,17)) );
|
assert(h.get_coefficient(0) == Complex(FT(5333816,65025),FT(-8,17)));
|
||||||
assert( h.get_coefficient(1) == Complex(FT(-192,17),FT(-504,85)) );
|
assert(h.get_coefficient(1) == Complex(FT(-192,17),FT(-504,85)));
|
||||||
assert( h.get_coefficient(2) == Complex(FT(-192,17),FT(504,85)) );
|
assert(h.get_coefficient(2) == Complex(FT(-192,17),FT(504,85)));
|
||||||
assert( h.get_coefficient(3) == Complex(FT(5333816,65025),FT(8,17)) );
|
assert(h.get_coefficient(3) == Complex(FT(5333816,65025),FT(8,17)));
|
||||||
|
|
||||||
Point point (FT(3,11),FT(-1,73));
|
Point point (FT(3,11),FT(-1,73));
|
||||||
Point image_point = h.evaluate(point);
|
Point image_point = h.evaluate(point);
|
||||||
assert( image_point==Point(FT(9146011623056232,66567955527962869), FT(-12617302915955411,133135911055925738)) );
|
assert(image_point==Point(FT(9146011623056232,66567955527962869), FT(-12617302915955411,133135911055925738)));
|
||||||
|
|
||||||
std::cout << "printing an isometry for test purposes : " << std::endl << h;
|
std::cout << "printing an isometry for test purposes : " << std::endl << h;
|
||||||
|
|
||||||
Isometry tau_1 = CGAL::hyperbolic_translation<Traits>(point);
|
Isometry tau_1 = CGAL::hyperbolic_translation<Traits>(point);
|
||||||
Isometry tau_1_prime = CGAL::hyperbolic_translation<Traits>(Point (FT(-3,11),FT(1,73)), true);
|
Isometry tau_1_prime = CGAL::hyperbolic_translation<Traits>(Point (FT(-3,11),FT(1,73)), true);
|
||||||
Isometry tau_1_inv = CGAL::hyperbolic_translation<Traits>(point, true);
|
Isometry tau_1_inv = CGAL::hyperbolic_translation<Traits>(point, true);
|
||||||
assert( tau_1.evaluate(image_point) == tau_1_prime.evaluate(image_point) );
|
assert(tau_1.evaluate(image_point) == tau_1_prime.evaluate(image_point));
|
||||||
assert( (tau_1*tau_1_inv).evaluate(image_point) == image_point );
|
assert((tau_1*tau_1_inv).evaluate(image_point) == image_point);
|
||||||
|
|
||||||
Point p (FT(2,15),FT(0));
|
Point p (FT(2,15),FT(0));
|
||||||
Point q (FT(0),FT(17,93));
|
Point q (FT(0),FT(17,93));
|
||||||
Isometry rotation = CGAL::hyperbolic_rotation<Traits>(p, q);
|
Isometry rotation = CGAL::hyperbolic_rotation<Traits>(p, q);
|
||||||
Isometry rotation_prime = CGAL::hyperbolic_rotation<Traits>(q, p, true);
|
Isometry rotation_prime = CGAL::hyperbolic_rotation<Traits>(q, p, true);
|
||||||
Isometry rotation_inv = CGAL::hyperbolic_rotation<Traits>(p, q, true);
|
Isometry rotation_inv = CGAL::hyperbolic_rotation<Traits>(p, q, true);
|
||||||
assert( rotation.evaluate(image_point) == rotation_prime.evaluate(image_point) );
|
assert(rotation.evaluate(image_point) == rotation_prime.evaluate(image_point));
|
||||||
assert( (rotation*rotation_inv).evaluate(image_point) == image_point );
|
assert((rotation*rotation_inv).evaluate(image_point) == image_point);
|
||||||
|
|
||||||
Point p_imag = rotation.evaluate(p);
|
Point p_imag = rotation.evaluate(p);
|
||||||
Point q_imag = rotation.evaluate(q);
|
Point q_imag = rotation.evaluate(q);
|
||||||
Isometry pairing = CGAL::isometry_pairing_the_sides<Traits>(p, q, p_imag, q_imag);
|
Isometry pairing = CGAL::isometry_pairing_the_sides<Traits>(p, q, p_imag, q_imag);
|
||||||
assert( pairing.evaluate(p) == p_imag );
|
assert(pairing.evaluate(p) == p_imag);
|
||||||
assert( pairing.evaluate(q) == q_imag );
|
assert(pairing.evaluate(q) == q_imag);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,16 @@
|
||||||
#include <CGAL/Hyperbolic_fundamental_domain_factory_2.h>
|
#include <CGAL/Hyperbolic_fundamental_domain_factory_2.h>
|
||||||
#include <CGAL/Triangulation_on_hyperbolic_surface_2.h>
|
#include <CGAL/Triangulation_on_hyperbolic_surface_2.h>
|
||||||
#include <CGAL/Triangulation_on_hyperbolic_surface_2_IO.h>
|
#include <CGAL/Triangulation_on_hyperbolic_surface_2_IO.h>
|
||||||
|
#include <CGAL/Hyperbolic_Delaunay_triangulation_traits_2.h>
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <CGAL/Exact_rational.h>
|
#include <CGAL/Exact_rational.h>
|
||||||
#include <CGAL/Lazy_exact_nt.h>
|
#include <CGAL/Lazy_exact_nt.h>
|
||||||
#include <CGAL/Cartesian.h>
|
#include <CGAL/Cartesian.h>
|
||||||
#include <CGAL/Hyperbolic_Delaunay_triangulation_traits_2.h>
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <tuple>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
typedef CGAL::Cartesian<CGAL::Lazy_exact_nt<CGAL::Exact_rational>> Kernel;
|
typedef CGAL::Cartesian<CGAL::Lazy_exact_nt<CGAL::Exact_rational>> Kernel;
|
||||||
typedef CGAL::Hyperbolic_Delaunay_triangulation_traits_2<Kernel> ParentTraits;
|
typedef CGAL::Hyperbolic_Delaunay_triangulation_traits_2<Kernel> ParentTraits;
|
||||||
|
|
@ -19,15 +22,16 @@ typedef CGAL::Triangulation_on_hyperbolic_surface_2<Traits> Tr
|
||||||
|
|
||||||
typedef typename Traits::Hyperbolic_point_2 Point;
|
typedef typename Traits::Hyperbolic_point_2 Point;
|
||||||
|
|
||||||
int main() {
|
int main()
|
||||||
|
{
|
||||||
Factory factory;
|
Factory factory;
|
||||||
Domain domain = factory.make_hyperbolic_fundamental_domain_g2(3459);
|
Domain domain = factory.make_hyperbolic_fundamental_domain_g2(3459);
|
||||||
Triangulation triangulation0 = Triangulation(domain);
|
Triangulation triangulation0 = Triangulation(domain);
|
||||||
|
|
||||||
assert( triangulation0.is_valid() );
|
assert(triangulation0.is_valid());
|
||||||
|
|
||||||
Triangulation triangulation (triangulation0);
|
Triangulation triangulation (triangulation0);
|
||||||
assert( triangulation.has_anchor() );
|
assert(triangulation.has_anchor());
|
||||||
|
|
||||||
std::stringstream buffer;
|
std::stringstream buffer;
|
||||||
buffer << triangulation;
|
buffer << triangulation;
|
||||||
|
|
@ -41,7 +45,7 @@ int main() {
|
||||||
|
|
||||||
triangulation.make_Delaunay();
|
triangulation.make_Delaunay();
|
||||||
|
|
||||||
assert( triangulation.is_Delaunay() );
|
assert(triangulation.is_Delaunay());
|
||||||
|
|
||||||
std::vector<std::tuple<typename Triangulation::Combinatorial_map_with_cross_ratios::Dart_const_handle,Point,Point,Point>> output_not_centered;
|
std::vector<std::tuple<typename Triangulation::Combinatorial_map_with_cross_ratios::Dart_const_handle,Point,Point,Point>> output_not_centered;
|
||||||
std::vector<std::tuple<typename Triangulation::Combinatorial_map_with_cross_ratios::Dart_const_handle,Point,Point,Point>> output_centered;
|
std::vector<std::tuple<typename Triangulation::Combinatorial_map_with_cross_ratios::Dart_const_handle,Point,Point,Point>> output_centered;
|
||||||
|
|
@ -49,12 +53,11 @@ int main() {
|
||||||
output_not_centered = triangulation.lift(false);
|
output_not_centered = triangulation.lift(false);
|
||||||
output_centered = triangulation.lift();
|
output_centered = triangulation.lift();
|
||||||
|
|
||||||
|
|
||||||
Triangulation::Combinatorial_map_with_cross_ratios& cmap = triangulation.combinatorial_map();
|
Triangulation::Combinatorial_map_with_cross_ratios& cmap = triangulation.combinatorial_map();
|
||||||
Triangulation::Anchor& anchor = triangulation.anchor();
|
Triangulation::Anchor& anchor = triangulation.anchor();
|
||||||
assert( cmap.is_dart_used(anchor.dart) );
|
assert(cmap.is_dart_used(anchor.dart));
|
||||||
|
|
||||||
std::cout << "printing triangulation for test purposes : " << std::endl << triangulation;
|
std::cout << "printing triangulation for test purposes: " << std::endl << triangulation;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,14 @@
|
||||||
#include <CGAL/Hyperbolic_surface_traits_2.h>
|
#include <CGAL/Hyperbolic_surface_traits_2.h>
|
||||||
#include <CGAL/Triangulation_on_hyperbolic_surface_2.h>
|
#include <CGAL/Triangulation_on_hyperbolic_surface_2.h>
|
||||||
#include <CGAL/Triangulation_on_hyperbolic_surface_2_IO.h>
|
#include <CGAL/Triangulation_on_hyperbolic_surface_2_IO.h>
|
||||||
|
#include <CGAL/Hyperbolic_Delaunay_triangulation_traits_2.h>
|
||||||
|
|
||||||
#include <CGAL/Exact_rational.h>
|
#include <CGAL/Exact_rational.h>
|
||||||
#include <CGAL/Cartesian.h>
|
#include <CGAL/Cartesian.h>
|
||||||
#include <CGAL/Hyperbolic_Delaunay_triangulation_traits_2.h>
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
typedef CGAL::Cartesian<CGAL::Exact_rational> Kernel;
|
typedef CGAL::Cartesian<CGAL::Exact_rational> Kernel;
|
||||||
typedef CGAL::Hyperbolic_Delaunay_triangulation_traits_2<Kernel> ParentTraits;
|
typedef CGAL::Hyperbolic_Delaunay_triangulation_traits_2<Kernel> ParentTraits;
|
||||||
|
|
@ -19,33 +20,35 @@ typedef typename Traits::FT FT;
|
||||||
typedef typename Traits::Hyperbolic_point_2 Point;
|
typedef typename Traits::Hyperbolic_point_2 Point;
|
||||||
typedef typename Traits::Complex Complex;
|
typedef typename Traits::Complex Complex;
|
||||||
|
|
||||||
Domain build_domain(){
|
Domain build_domain()
|
||||||
|
{
|
||||||
std::vector<Point> vertices;
|
std::vector<Point> vertices;
|
||||||
vertices.push_back( Point(FT(809,10000),FT(0)) );
|
vertices.push_back( Point(FT(809,10000),FT(0)));
|
||||||
vertices.push_back( Point(FT(7359,10000),FT(1877,10000)) );
|
vertices.push_back( Point(FT(7359,10000),FT(1877,10000)));
|
||||||
vertices.push_back( Point(FT(-999,2500),FT(881,1000)) );
|
vertices.push_back( Point(FT(-999,2500),FT(881,1000)));
|
||||||
vertices.push_back( Point(FT("-22088524601252853411192791001942853611410938513/24711029456888649611435724068315791591836010000"),FT("9482675065452890527617859332378101016513362487/24711029456888649611435724068315791591836010000")) );
|
vertices.push_back( Point(FT("-22088524601252853411192791001942853611410938513/24711029456888649611435724068315791591836010000"),FT("9482675065452890527617859332378101016513362487/24711029456888649611435724068315791591836010000")));
|
||||||
vertices.push_back( Point(FT(-809,10000),FT(0)) );
|
vertices.push_back( Point(FT(-809,10000),FT(0)));
|
||||||
vertices.push_back( Point(FT(-7359,10000),FT(-1877,10000)) );
|
vertices.push_back( Point(FT(-7359,10000),FT(-1877,10000)));
|
||||||
vertices.push_back( Point(FT(999,2500),FT(-881,1000)) );
|
vertices.push_back( Point(FT(999,2500),FT(-881,1000)));
|
||||||
vertices.push_back( Point(FT("22088524601252853411192791001942853611410938513/24711029456888649611435724068315791591836010000"),FT("-9482675065452890527617859332378101016513362487/24711029456888649611435724068315791591836010000")) );
|
vertices.push_back( Point(FT("22088524601252853411192791001942853611410938513/24711029456888649611435724068315791591836010000"),FT("-9482675065452890527617859332378101016513362487/24711029456888649611435724068315791591836010000")));
|
||||||
|
|
||||||
std::vector<int> pairings;
|
std::vector<int> pairings;
|
||||||
for (int k=0; k<8; ++k){
|
for (int k=0; k<8; ++k) {
|
||||||
pairings.push_back((k+4)%8);
|
pairings.push_back((k+4)%8);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Domain(vertices, pairings);
|
return Domain(vertices, pairings);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main()
|
||||||
|
{
|
||||||
Domain domain = build_domain();
|
Domain domain = build_domain();
|
||||||
Triangulation triangulation0 = Triangulation(domain);
|
Triangulation triangulation0 = Triangulation(domain);
|
||||||
|
|
||||||
assert( triangulation0.is_valid() );
|
assert(triangulation0.is_valid());
|
||||||
|
|
||||||
Triangulation triangulation (triangulation0);
|
Triangulation triangulation (triangulation0);
|
||||||
assert( triangulation.has_anchor() );
|
assert(triangulation.has_anchor());
|
||||||
|
|
||||||
std::stringstream buffer;
|
std::stringstream buffer;
|
||||||
buffer << triangulation;
|
buffer << triangulation;
|
||||||
|
|
@ -59,7 +62,7 @@ int main() {
|
||||||
|
|
||||||
triangulation.make_Delaunay();
|
triangulation.make_Delaunay();
|
||||||
|
|
||||||
assert( triangulation.is_Delaunay() );
|
assert(triangulation.is_Delaunay());
|
||||||
|
|
||||||
std::vector<std::tuple<typename Triangulation::Combinatorial_map_with_cross_ratios::Dart_const_handle,Point,Point,Point>> output_not_centered;
|
std::vector<std::tuple<typename Triangulation::Combinatorial_map_with_cross_ratios::Dart_const_handle,Point,Point,Point>> output_not_centered;
|
||||||
std::vector<std::tuple<typename Triangulation::Combinatorial_map_with_cross_ratios::Dart_const_handle,Point,Point,Point>> output_centered;
|
std::vector<std::tuple<typename Triangulation::Combinatorial_map_with_cross_ratios::Dart_const_handle,Point,Point,Point>> output_centered;
|
||||||
|
|
@ -69,9 +72,9 @@ int main() {
|
||||||
|
|
||||||
Triangulation::Combinatorial_map_with_cross_ratios& cmap = triangulation.combinatorial_map();
|
Triangulation::Combinatorial_map_with_cross_ratios& cmap = triangulation.combinatorial_map();
|
||||||
Triangulation::Anchor& anchor = triangulation.anchor();
|
Triangulation::Anchor& anchor = triangulation.anchor();
|
||||||
assert( cmap.is_dart_used(anchor.dart) );
|
assert(cmap.is_dart_used(anchor.dart));
|
||||||
|
|
||||||
std::cout << "printing triangulation for test purposes : " << std::endl << triangulation;
|
std::cout << "printing triangulation for test purposes: " << std::endl << triangulation;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue