Merge pull request #3283 from imiordanov/Periodic_4_hyperbolic_triangulation_2-IIordanov

New packages: Hyperbolic_triangulation_2 / Periodic_4_hyperbolic_triangulation_2
This commit is contained in:
Laurent Rineau 2019-02-22 16:39:12 +01:00
commit 5199eb70ee
278 changed files with 19427 additions and 863 deletions

View File

@ -20,37 +20,38 @@ env:
- PACKAGE='Envelope_3 Filtered_kernel Generalized_map '
- PACKAGE='Generator Geomview GraphicsView '
- PACKAGE='HalfedgeDS Hash_map Heat_method_3 '
- PACKAGE='Homogeneous_kernel Inscribed_areas Installation '
- PACKAGE='Interpolation Intersections_2 Intersections_3 '
- PACKAGE='Interval_skip_list Interval_support Inventor '
- PACKAGE='Jet_fitting_3 Kernel_23 Kernel_d '
- PACKAGE='LEDA Linear_cell_complex MacOSX '
- PACKAGE='Maintenance Matrix_search Mesh_2 '
- PACKAGE='Mesh_3 Mesher_level Minkowski_sum_2 '
- PACKAGE='Minkowski_sum_3 Modifier Modular_arithmetic '
- PACKAGE='Nef_2 Nef_3 Nef_S2 '
- PACKAGE='NewKernel_d Number_types OpenNL '
- PACKAGE='Optimal_transportation_reconstruction_2 Optimisation_basic Partition_2 '
- PACKAGE='Periodic_2_triangulation_2 Periodic_3_mesh_3 Periodic_3_triangulation_3 '
- PACKAGE='Point_set_2 Point_set_3 Point_set_processing_3 '
- PACKAGE='Point_set_shape_detection_3 Poisson_surface_reconstruction_3 Polygon '
- PACKAGE='Polygon_mesh_processing Polyhedron Polyhedron_IO '
- PACKAGE='Polyline_simplification_2 Polynomial Polytope_distance_d '
- PACKAGE='Principal_component_analysis Principal_component_analysis_LGPL Profiling_tools '
- PACKAGE='Property_map QP_solver Random_numbers '
- PACKAGE='Ridges_3 Scale_space_reconstruction_3 Scripts '
- PACKAGE='SearchStructures Segment_Delaunay_graph_2 Segment_Delaunay_graph_Linf_2 '
- PACKAGE='Set_movable_separability_2 Skin_surface_3 Snap_rounding_2 '
- PACKAGE='Solver_interface Spatial_searching Spatial_sorting '
- PACKAGE='STL_Extension Straight_skeleton_2 Stream_lines_2 '
- PACKAGE='Stream_support Subdivision_method_3 Surface_mesh '
- PACKAGE='Surface_mesh_approximation Surface_mesh_deformation Surface_mesher '
- PACKAGE='Surface_mesh_parameterization Surface_mesh_segmentation Surface_mesh_shortest_path '
- PACKAGE='Surface_mesh_simplification Surface_mesh_skeletonization Surface_sweep_2 '
- PACKAGE='TDS_2 TDS_3 Testsuite '
- PACKAGE='Three Triangulation Triangulation_2 '
- PACKAGE='Triangulation_3 Union_find Visibility_2 '
- PACKAGE='Voronoi_diagram_2 wininst '
- PACKAGE='Homogeneous_kernel Hyperbolic_triangulation_2 Inscribed_areas '
- PACKAGE='Installation Interpolation Intersections_2 '
- PACKAGE='Intersections_3 Interval_skip_list Interval_support '
- PACKAGE='Inventor Jet_fitting_3 Kernel_23 '
- PACKAGE='Kernel_d LEDA Linear_cell_complex '
- PACKAGE='MacOSX Maintenance Matrix_search '
- PACKAGE='Mesh_2 Mesh_3 Mesher_level '
- PACKAGE='Minkowski_sum_2 Minkowski_sum_3 Modifier '
- PACKAGE='Modular_arithmetic Nef_2 Nef_3 '
- PACKAGE='Nef_S2 NewKernel_d Number_types '
- PACKAGE='OpenNL Optimal_transportation_reconstruction_2 Optimisation_basic '
- PACKAGE='Partition_2 Periodic_2_triangulation_2 Periodic_3_mesh_3 '
- PACKAGE='Periodic_3_triangulation_3 Periodic_4_hyperbolic_triangulation_2 Point_set_2 '
- PACKAGE='Point_set_3 Point_set_processing_3 Point_set_shape_detection_3 '
- PACKAGE='Poisson_surface_reconstruction_3 Polygon Polygon_mesh_processing '
- PACKAGE='Polyhedron Polyhedron_IO Polyline_simplification_2 '
- PACKAGE='Polynomial Polytope_distance_d Principal_component_analysis '
- PACKAGE='Principal_component_analysis_LGPL Profiling_tools Property_map '
- PACKAGE='QP_solver Random_numbers Ridges_3 '
- PACKAGE='Scale_space_reconstruction_3 Scripts SearchStructures '
- PACKAGE='Segment_Delaunay_graph_2 Segment_Delaunay_graph_Linf_2 Set_movable_separability_2 '
- PACKAGE='Skin_surface_3 Snap_rounding_2 Solver_interface '
- PACKAGE='Spatial_searching Spatial_sorting STL_Extension '
- PACKAGE='Straight_skeleton_2 Stream_lines_2 Stream_support '
- PACKAGE='Subdivision_method_3 Surface_mesh Surface_mesh_approximation '
- PACKAGE='Surface_mesh_deformation Surface_mesher Surface_mesh_parameterization '
- PACKAGE='Surface_mesh_segmentation Surface_mesh_shortest_path Surface_mesh_simplification '
- PACKAGE='Surface_mesh_skeletonization Surface_sweep_2 TDS_2 '
- PACKAGE='TDS_3 Testsuite Three '
- PACKAGE='Triangulation Triangulation_2 Triangulation_3 '
- PACKAGE='Union_find Visibility_2 Voronoi_diagram_2 '
- PACKAGE='wininst '
compiler: clang
install:
- echo "$PWD"

View File

@ -41,6 +41,7 @@ HalfedgeDS
Hash_map
Heat_method_3
Homogeneous_kernel
Hyperbolic_triangulation_2
Inscribed_areas
Installation
Interpolation
@ -76,6 +77,7 @@ Partition_2
Periodic_2_triangulation_2
Periodic_3_mesh_3
Periodic_3_triangulation_3
Periodic_4_hyperbolic_triangulation_2
Point_set_2
Point_set_3
Point_set_processing_3

View File

@ -216,8 +216,8 @@ namespace CGAL {
const FT cz = (p.a()*p.c())/sqbc;
const Root_of_2 x = make_root_of_2(s.a(),FT(i?-1:1),delta);
const Root_of_2 y = make_root_of_2(s.b(),FT(i?(cy):(-cy)),delta);
const Root_of_2 z = make_root_of_2(s.c(),FT(i?(cz):(-cz)),delta);
const Root_of_2 y = make_root_of_2(s.b(),FT(i?(cy):FT(-cy)),delta);
const Root_of_2 z = make_root_of_2(s.c(),FT(i?(cz):FT(-cz)),delta);
return Root_for_spheres_2_3(x,y,z);
}
@ -290,14 +290,14 @@ namespace CGAL {
const FT cz = (p.c()*p.b())/sqac;
if(!is_positive(cx)) {
const Root_of_2 x = make_root_of_2(s.a(),FT(i?(cx):(-cx)),delta);
const Root_of_2 x = make_root_of_2(s.a(),FT(i?(cx):FT(-cx)),delta);
const Root_of_2 y = make_root_of_2(s.b(),FT(i?-1:1),delta);
const Root_of_2 z = make_root_of_2(s.c(),FT(i?(cz):(-cz)),delta);
const Root_of_2 z = make_root_of_2(s.c(),FT(i?(cz):FT(-cz)),delta);
return Root_for_spheres_2_3(x,y,z);
} else {
const Root_of_2 x = make_root_of_2(s.a(),FT(i?(-cx):(cx)),delta);
const Root_of_2 x = make_root_of_2(s.a(),FT(i?FT(-cx):(cx)),delta);
const Root_of_2 y = make_root_of_2(s.b(),FT(i?1:-1),delta);
const Root_of_2 z = make_root_of_2(s.c(),FT(i?(-cz):(cz)),delta);
const Root_of_2 z = make_root_of_2(s.c(),FT(i?FT(-cz):(cz)),delta);
return Root_for_spheres_2_3(x,y,z);
}
}
@ -375,25 +375,25 @@ namespace CGAL {
const FT cy = (p.c()*p.b())/sqab;
if(is_negative(cx)) {
const Root_of_2 x = make_root_of_2(s.a(),FT(i?(cx):(-cx)),delta);
const Root_of_2 y = make_root_of_2(s.b(),FT(i?(cy):(-cy)),delta);
const Root_of_2 x = make_root_of_2(s.a(),FT(i?(cx):FT(-cx)),delta);
const Root_of_2 y = make_root_of_2(s.b(),FT(i?(cy):FT(-cy)),delta);
const Root_of_2 z = make_root_of_2(s.c(),FT(i?-1:1),delta);
return Root_for_spheres_2_3(x,y,z);
} else if(is_zero(cx)) {
if(!is_positive(cy)) {
const Root_of_2 x = s.a();
const Root_of_2 y = make_root_of_2(s.b(),FT(i?(cy):(-cy)),delta);
const Root_of_2 y = make_root_of_2(s.b(),FT(i?(cy):FT(-cy)),delta);
const Root_of_2 z = make_root_of_2(s.c(),FT(i?-1:1),delta);
return Root_for_spheres_2_3(x,y,z);
} else {
const Root_of_2 x = s.a();
const Root_of_2 y = make_root_of_2(s.b(),FT(i?(-cy):(cy)),delta);
const Root_of_2 y = make_root_of_2(s.b(),FT(i?FT(-cy):(cy)),delta);
const Root_of_2 z = make_root_of_2(s.c(),FT(i?1:-1),delta);
return Root_for_spheres_2_3(x,y,z);
}
} else {
const Root_of_2 x = make_root_of_2(s.a(),FT(i?(-cx):(cx)),delta);
const Root_of_2 y = make_root_of_2(s.b(),FT(i?(-cy):(cy)),delta);
const Root_of_2 x = make_root_of_2(s.a(),FT(i?FT(-cx):(cx)),delta);
const Root_of_2 y = make_root_of_2(s.b(),FT(i?FT(-cy):(cy)),delta);
const Root_of_2 z = make_root_of_2(s.c(),FT(i?1:-1),delta);
return Root_for_spheres_2_3(x,y,z);
}

View File

@ -98,4 +98,6 @@ Surface_mesh_shortest_path
Polygon_mesh_processing
Set_movable_separability_2
Classification
Hyperbolic_triangulation_2
Periodic_4_hyperbolic_triangulation_2
Surface_mesh_approximation

View File

@ -77,6 +77,8 @@ h1 {
\package_listing{Triangulation_2}
\package_listing{TDS_2}
\package_listing{Periodic_2_triangulation_2}
\package_listing{Hyperbolic_triangulation_2}
\package_listing{Periodic_4_hyperbolic_triangulation_2}
\package_listing{Triangulation_3}
\package_listing{TDS_3}
\package_listing{Periodic_3_triangulation_3}

View File

@ -142,6 +142,19 @@ Pion and Monique Teillaud and Mariette Yvinec"
, succeeds = "bdty-tcgal-00"
}
@ARTICLE{cgal:bdt-hdcvd-14,
AUTHOR = {Mikhail Bogdanov and Olivier Devillers and Monique Teillaud},
JOURNAL = {Journal of Computational Geometry},
NOTE = {http://hal.inria.fr/hal-00961390},
PAGES = {56--85},
TITLE = {Hyperbolic {Delaunay} complexes and {Voronoi} diagrams made practical},
VOLUME = {5},
YEAR = {2014},
DOI = {10.20382/jocg.v5i1a4},
}
@inproceedings{ cgal:behhms-cbcab-02
,author = {Berberich, Eric and Eigenwillig, Arno and Hemmer, Michael
and Hert, Susan and Mehlhorn, Kurt and Sch{\"o}mer, Elmar}
@ -288,6 +301,18 @@ Boissonnat}
,update = "13.04 lrineau"
}
@INPROCEEDINGS{ cgal:btv-dtosl-16,
AUTHOR = {Mikhail Bogdanov and Monique Teillaud and Gert Vegter},
BOOKTITLE = {Proceedings of the Thirty-second International Symposium on Computational Geometry},
PAGES = {20:1--20:17},
TITLE = {Delaunay triangulations on orientable surfaces of low genus},
YEAR = {2016},
DOI = {10.4230/LIPIcs.SoCG.2016.20},
URL = {https://hal.inria.fr/hal-01276386}
}
@incollection{ cgal:bv-sbc-96
,author = "G. Booch and M. Vilot"
,title = "Simplifying the Booch Components"
@ -1100,6 +1125,18 @@ Teillaud"
,pages = {71--86}
}
@INPROCEEDINGS{cgal:it-idtbs-17,
AUTHOR = {Iordan Iordanov and Monique Teillaud},
BOOKTITLE = {Proceedings of the Thirty-third International Symposium on Computational Geometry},
PAGES = {44:1--44:15},
TITLE = {{Implementing Delaunay triangulations of the Bolza surface}},
YEAR = {2017},
DOI = {10.4230/LIPIcs.SoCG.2017.44},
URL = {https://hal.inria.fr/hal-01568002},
}
@book{ cgal:j-csl-99
,author = "Nicolai M. Josuttis"
,title = "The {C}++ Standard Library, A Tutorial and Reference"

View File

@ -0,0 +1,50 @@
==== new ====
add operator == for triangulations (?)
** traits bisectors
class Construct_hyperbolic_bisector_2
Hyperbolic_segment_2 operator()(Point_2 p, Point_2 q, Point_2 r)
at the end
the following lines are giving the wrong arc (wrong orientation), aren't they?
CGAL_triangulation_assertion(assign(pair,inters[1]));
if ( Orientation_2()(approx_c,approx_a,approx_pinf) == POSITIVE )
return Circular_arc_2( *c_pq, pair.first, a);
return Circular_arc_2( *c_pq, a, pair.first);
but this is what works on the demo...
understand why
remove variant for supporting circle or line of bisector
call it only when we know that it is a circle
it will simplyfy the code of Construct_hyperbolic_bisector_2 at least in some cases
test bisectors dual functions in special cases of euclidean line segments
** Hyperbolic_random_points_in_disc
see with Olivier: small feature to add new object generator?
========== demo
--- fix bugs:
- conflict regions (when inserting or in mode 'show conflict zone)
show Euclidean triangles instead of hyperbolic triangles
- However, we could think to add a specific mode allowing to show
triangles that are not hyperbolic. Not sure whether this is interesting.
--- PainterOstream
Is it clean for CGAL to have a local file?
I have to ask Laurent to make some members of PainterOstream protected.
It allows me to have a local file with partial specialization of
the class PainterOstream.
I have to discuss with Laurent.
========== future
--- make Constrained_delaunay_... work with Hyperbolic_triangulation_2
--- make Mesh_2 work with Hyperbolic_triangulation_2
O.Faugeras and his student are waiting for it.

View File

@ -0,0 +1,24 @@
# Created by the script cgal_create_cmake_script
# This is the CMake script for compiling a CGAL application.
project( Hyperbolic_triangulation_2_benchmark )
cmake_minimum_required(VERSION 2.8.10)
find_package(CGAL QUIET COMPONENTS Core )
if ( CGAL_FOUND )
include( ${CGAL_USE_FILE} )
include( CGAL_CreateSingleSourceCGALProgram )
create_single_source_cgal_program( "bench_insertion_with_different_kernels.cpp" )
else()
message(STATUS "This program requires the CGAL library, and will not be compiled.")
endif()

View File

@ -0,0 +1,180 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Hyperbolic_Delaunay_triangulation_2.h>
#include <CGAL/Hyperbolic_Delaunay_triangulation_CK_traits_2.h>
#include <CGAL/Hyperbolic_Delaunay_triangulation_traits_2.h>
#include <CGAL/Cartesian.h>
#include <CGAL/point_generators_2.h>
#include <CGAL/Timer.h>
#include <iostream>
template<typename Point_type>
std::pair<double, double> insert_Euclidean(const std::vector<Point_type>& dpts)
{
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Delaunay_triangulation_2< K > Dt;
typedef Dt::Point_2 Point_2;
CGAL::Timer timer;
std::vector<Point_2> pts;
for(std::size_t i=0; i<dpts.size(); ++i)
pts.push_back(Point_2(dpts[i].x(), dpts[i].y()));
Dt dt_end;
timer.start();
dt_end.insert(pts.begin(),pts.end());
timer.stop();
double t1 = timer.time();
std::cout << "Euclidean insertion, iterator input: " << t1 << std::endl;
Dt dt_during;
timer.reset();
timer.start();
for(std::size_t i=0; i<pts.size(); ++i)
dt_during.insert(pts[i]);
timer.stop();
double t2 = timer.time();
std::cout << "Euclidean insertion, one-by-one: " << t2 << std::endl;
return std::pair<double, double>(t1, t2);
}
template<typename NT_point>
std::pair<double,double> insert_CK_points(const std::vector<NT_point>& dpts)
{
typedef CGAL::Hyperbolic_Delaunay_triangulation_CK_traits_2<> Gt;
typedef Gt::Point_2 Point_2;
typedef CGAL::Hyperbolic_Delaunay_triangulation_2<Gt> Dt;
CGAL::Timer timer;
std::vector<Point_2> pts;
std::vector<Point_2>::iterator ip;
for(std::size_t i=0; i<dpts.size(); ++i)
pts.push_back(Point_2(dpts[i].x(), dpts[i].y()));
Dt dt_end;
timer.start();
dt_end.insert(pts.begin(),pts.end());
timer.stop();
double t1 = timer.time();
std::cout << "CK traits insertion, iterator input: " << t1 << std::endl;
Dt dt_during;
timer.reset();
timer.start();
for(ip = pts.begin(); ip != pts.end(); ++ip)
dt_during.insert(*ip);
timer.stop();
double t2 = timer.time();
std::cout << "CK traits insertion, one-by-one: " << t2 << std::endl;
return std::pair<double, double>(t1,t2);
}
template<typename NT_point>
std::pair<double,double> insert_CORE_points(const std::vector<NT_point>& dpts)
{
typedef CGAL::Hyperbolic_Delaunay_triangulation_traits_2<> Gt;
typedef Gt::Point_2 Point_2;
typedef CGAL::Hyperbolic_Delaunay_triangulation_2<Gt> Dt;
CGAL::Timer timer;
std::vector<Point_2> pts;
std::vector<Point_2>::iterator ip;
for(std::size_t i=0; i<dpts.size(); ++i)
pts.push_back(Point_2(dpts[i].x(), dpts[i].y()));
Dt dt_end;
timer.start();
dt_end.insert(pts.begin(),pts.end());
timer.stop();
double t1 = timer.time();
std::cout << "CORE traits insertion, iterator input: " << t1 << std::endl;
Dt dt_during;
timer.reset();
timer.start();
for(ip = pts.begin(); ip != pts.end(); ++ip)
dt_during.insert(*ip);
timer.stop();
double t2 = timer.time();
std::cout << "CORE traits insertion, on-by-one: " << t2 << std::endl;
return std::pair<double,double>(t1, t2);
}
int main(int argc, char** argv)
{
typedef double NT;
typedef CGAL::Cartesian<NT> NT_kernel;
typedef NT_kernel::Point_2 NT_point;
typedef CGAL::Creator_uniform_2<NT, NT_point> Creator;
if(argc < 2) {
std::cout << "usage: " << argv[0] << " [number_of_points]" << std::endl;
return -1;
}
int N = atoi(argv[1]);
int iters = 1;
if(argc >= 3)
iters = atoi(argv[2]);
CGAL::Random_points_in_disc_2<NT_point, Creator> in_disc(0.998);
double timeCK1 = 0;
double timeCK2 = 0;
double timeCORE1 = 0;
double timeCORE2 = 0;
double timeEUCL1 = 0;
double timeEUCL2 = 0;
for(int j=0; j<iters; ++j)
{
std::vector<NT_point> pts;
for(int i=0; i<N; ++i)
pts.push_back(*(in_disc++));
std::cout << "----------- iteration " << j << " -----------" << std::endl;
std::pair<double, double> resEUCL = insert_Euclidean(pts);
timeEUCL1 += resEUCL.first;
timeEUCL2 += resEUCL.second;
std::pair<double, double> resCK = insert_CK_points(pts);
timeCK1 += resCK.first;
timeCK2 += resCK.second;
std::pair<double, double> resCORE = insert_CORE_points(pts);
timeCORE1 += resCORE.first;
timeCORE2 += resCORE.second;
std::cout << std::endl;
}
double diters(iters);
timeEUCL1 /= diters;
timeCORE1 /= diters;
timeCK1 /= diters;
timeEUCL2 /= diters;
timeCORE2 /= diters;
timeCK2 /= diters;
std::cout << "----------------------------------------------------" << std::endl;
std::cout << "Average time for EUCL (one-at-a-time): " << timeEUCL2 << std::endl;
std::cout << "Average time for CK (one-at-a-time): " << timeCK2 << std::endl;
std::cout << "Average time for CORE (one-at-a-time): " << timeCORE2 << std::endl;
std::cout << "----------------------------------------------------" << std::endl;
std::cout << "Average time for EUCL (iterator): " << timeEUCL1 << std::endl;
std::cout << "Average time for CK (iterator): " << timeCK1 << std::endl;
std::cout << "Average time for CORE (iterator): " << timeCORE1 << std::endl;
std::cout << std::endl;
return 0;
}

View File

@ -0,0 +1,147 @@
iordanov@zababa:~/Documents/Code/builds/bench-misha$ ./test_insertion_with_different_kernels 1000000 10
--> generating random points... DONE!
--> copying random points... DONE!
--> inserting into Euclidean triangulation with CK... DONE! Triangulation vertices: 1000000
--> inserting into hyperbolic triangulation with CK... DONE! Triangulation vertices: 1000000
--> inserting into Euclidean triangulation with CORE::Expr... DONE! Triangulation vertices: 1000000
--> inserting into hyperbolic triangulation with CORE::Expr... DONE! Triangulation vertices: 1000000
Time for Euclidean CK: 170.627
Time for hyperbolic CK: 169.556
Time for Euclidean CORE: 24.9678
Time for hyperbolic CORE: 26.3069
===========================================================
--> generating random points... DONE!
--> copying random points... DONE!
--> inserting into Euclidean triangulation with CK... DONE! Triangulation vertices: 1000000
--> inserting into hyperbolic triangulation with CK... DONE! Triangulation vertices: 1000000
--> inserting into Euclidean triangulation with CORE::Expr... DONE! Triangulation vertices: 1000000
--> inserting into hyperbolic triangulation with CORE::Expr... DONE! Triangulation vertices: 1000000
Time for Euclidean CK: 169.512
Time for hyperbolic CK: 169.033
Time for Euclidean CORE: 25.6256
Time for hyperbolic CORE: 26.9626
===========================================================
--> generating random points... DONE!
--> copying random points... DONE!
--> inserting into Euclidean triangulation with CK... DONE! Triangulation vertices: 1000000
--> inserting into hyperbolic triangulation with CK... DONE! Triangulation vertices: 1000000
--> inserting into Euclidean triangulation with CORE::Expr... DONE! Triangulation vertices: 1000000
--> inserting into hyperbolic triangulation with CORE::Expr... DONE! Triangulation vertices: 1000000
Time for Euclidean CK: 169.301
Time for hyperbolic CK: 168.705
Time for Euclidean CORE: 25.3268
Time for hyperbolic CORE: 26.6332
===========================================================
--> generating random points... DONE!
--> copying random points... DONE!
--> inserting into Euclidean triangulation with CK... DONE! Triangulation vertices: 1000000
--> inserting into hyperbolic triangulation with CK... DONE! Triangulation vertices: 1000000
--> inserting into Euclidean triangulation with CORE::Expr... DONE! Triangulation vertices: 1000000
--> inserting into hyperbolic triangulation with CORE::Expr... DONE! Triangulation vertices: 1000000
Time for Euclidean CK: 168.208
Time for hyperbolic CK: 169.394
Time for Euclidean CORE: 27.5368
Time for hyperbolic CORE: 27.9433
===========================================================
--> generating random points... DONE!
--> copying random points... DONE!
--> inserting into Euclidean triangulation with CK... DONE! Triangulation vertices: 1000000
--> inserting into hyperbolic triangulation with CK... DONE! Triangulation vertices: 1000000
--> inserting into Euclidean triangulation with CORE::Expr... DONE! Triangulation vertices: 1000000
--> inserting into hyperbolic triangulation with CORE::Expr... DONE! Triangulation vertices: 1000000
Time for Euclidean CK: 176.372
Time for hyperbolic CK: 173.679
Time for Euclidean CORE: 27.3384
Time for hyperbolic CORE: 28.2083
===========================================================
--> generating random points... DONE!
--> copying random points... DONE!
--> inserting into Euclidean triangulation with CK... DONE! Triangulation vertices: 1000000
--> inserting into hyperbolic triangulation with CK... DONE! Triangulation vertices: 1000000
--> inserting into Euclidean triangulation with CORE::Expr... DONE! Triangulation vertices: 1000000
--> inserting into hyperbolic triangulation with CORE::Expr... DONE! Triangulation vertices: 1000000
Time for Euclidean CK: 172.435
Time for hyperbolic CK: 173.389
Time for Euclidean CORE: 27.3188
Time for hyperbolic CORE: 27.9508
===========================================================
--> generating random points... DONE!
--> copying random points... DONE!
--> inserting into Euclidean triangulation with CK... DONE! Triangulation vertices: 1000000
--> inserting into hyperbolic triangulation with CK... DONE! Triangulation vertices: 1000000
--> inserting into Euclidean triangulation with CORE::Expr... DONE! Triangulation vertices: 1000000
--> inserting into hyperbolic triangulation with CORE::Expr... DONE! Triangulation vertices: 1000000
Time for Euclidean CK: 172.617
Time for hyperbolic CK: 178.942
Time for Euclidean CORE: 28.1969
Time for hyperbolic CORE: 29.7344
===========================================================
--> generating random points... DONE!
--> copying random points... DONE!
--> inserting into Euclidean triangulation with CK... DONE! Triangulation vertices: 1000000
--> inserting into hyperbolic triangulation with CK... DONE! Triangulation vertices: 1000000
--> inserting into Euclidean triangulation with CORE::Expr... DONE! Triangulation vertices: 1000000
--> inserting into hyperbolic triangulation with CORE::Expr... DONE! Triangulation vertices: 1000000
Time for Euclidean CK: 176.287
Time for hyperbolic CK: 175.15
Time for Euclidean CORE: 27.5943
Time for hyperbolic CORE: 28.5847
===========================================================
--> generating random points... DONE!
--> copying random points... DONE!
--> inserting into Euclidean triangulation with CK... DONE! Triangulation vertices: 1000000
--> inserting into hyperbolic triangulation with CK... DONE! Triangulation vertices: 1000000
--> inserting into Euclidean triangulation with CORE::Expr... DONE! Triangulation vertices: 1000000
--> inserting into hyperbolic triangulation with CORE::Expr... DONE! Triangulation vertices: 1000000
Time for Euclidean CK: 173.73
Time for hyperbolic CK: 178.054
Time for Euclidean CORE: 27.1537
Time for hyperbolic CORE: 29.1486
===========================================================
--> generating random points... DONE!
--> copying random points... DONE!
--> inserting into Euclidean triangulation with CK... DONE! Triangulation vertices: 1000000
--> inserting into hyperbolic triangulation with CK... DONE! Triangulation vertices: 1000000
--> inserting into Euclidean triangulation with CORE::Expr... DONE! Triangulation vertices: 1000000
--> inserting into hyperbolic triangulation with CORE::Expr... DONE! Triangulation vertices: 1000000
Time for Euclidean CK: 178.159
Time for hyperbolic CK: 176.271
Time for Euclidean CORE: 27.98
Time for hyperbolic CORE: 29.0716
===========================================================
######################################################################
Average time for Euclidean with CK: 172.725
Average time for hyperbolic with CK: 173.217
Average time for Euclidean with CORE: 26.9039
Average time for hyperbolic with CORE: 28.0544

View File

@ -0,0 +1,29 @@
project (Hyperbolic_triangulation_2_Demo)
# Find includes in corresponding build directories
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# Instruct CMake to run moc automatically when needed.
set(CMAKE_AUTOMOC ON)
cmake_minimum_required(VERSION 3.1...3.13)
find_package(CGAL QUIET COMPONENTS Core Qt5)
find_package(Qt5 QUIET COMPONENTS Widgets)
include_directories (BEFORE include)
if(CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND AND CGAL_Core_FOUND)
# ui files, created with Qt Designer
qt5_wrap_ui( UIS HDT2.ui )
# qrc files (resources files, that contain icons, at least)
qt5_add_resources ( RESOURCE_FILES resources/File.qrc resources/Input.qrc resources/Delaunay_triangulation_2.qrc )
# cpp files
add_executable ( HDT2_demo HDT2.cpp ${RESOURCE_FILES} ${UIS})
target_link_libraries ( HDT2_demo CGAL::CGAL CGAL::CGAL_Qt5 CGAL::CGAL_Core Qt5::Widgets)
else()
message(STATUS "NOTICE: This demo requires CGAL, Boost and Qt5 and will not be compiled.")
endif()

View File

@ -0,0 +1,432 @@
#include <fstream>
// CGAL headers
#define USE_CORE_EXPR_KERNEL
#ifndef USE_CORE_EXPR_KERNEL
#include <CGAL/Exact_circular_kernel_2.h>
#include <CGAL/Hyperbolic_Delaunay_triangulation_CK_traits_2.h>
#include <internal/Qt/HyperbolicPainterOstreamCK.h>
#else
#include <CGAL/Cartesian.h>
#include <CGAL/CORE_Expr.h>
#include <CGAL/Hyperbolic_Delaunay_triangulation_traits_2.h>
#include <internal/Qt/HyperbolicPainterOstream.h>
#endif
#include <CGAL/Hyperbolic_Delaunay_triangulation_2.h>
#include <CGAL/point_generators_2.h>
// Qt headers
#include <QtGui>
#include <QString>
#include <QActionGroup>
#include <QFileDialog>
#include <QInputDialog>
#include <QGraphicsEllipseItem>
// GraphicsView items and event filters (input classes)
#include <internal/Qt/TriangulationCircumcircle.h>
#include <internal/Qt/TriangulationConflictZone.h>
#include <internal/Qt/TriangulationPointInputAndConflictZone.h>
#include <internal/Qt/TriangulationGraphicsItem.h>
#include <internal/Qt/HyperbolicVoronoiGraphicsItem.h>
// for viewportsBbox
#include <CGAL/Qt/utility.h>
// the two base classes
#include <CGAL/Qt/DemosMainWindow.h>
#include "ui_HDT2.h"
#ifndef USE_CORE_EXPR_KERNEL
typedef CGAL::Hyperbolic_Delaunay_triangulation_CK_traits_2<> K;
#else
typedef CGAL::Hyperbolic_Delaunay_triangulation_traits_2<> K;
#endif
typedef K::Point_2 Point_2;
typedef K::Iso_rectangle_2 Iso_rectangle_2;
typedef CGAL::Hyperbolic_Delaunay_triangulation_2<K> Delaunay;
class MainWindow :
public CGAL::Qt::DemosMainWindow,
public Ui::Delaunay_triangulation_2
{
Q_OBJECT
private:
Delaunay dt;
QGraphicsEllipseItem* disk;
QGraphicsScene scene;
CGAL::Qt::TriangulationGraphicsItem<Delaunay> * dgi;
CGAL::Qt::VoronoiGraphicsItem<Delaunay> * vgi;
//CGAL::Qt::TriangulationMovingPoint<Delaunay> * mp;
CGAL::Qt::TriangulationConflictZone<Delaunay> * cz;
//CGAL::Qt::TriangulationRemoveVertex<Delaunay> * trv;
CGAL::Qt::TriangulationPointInputAndConflictZone<Delaunay> * pi;
CGAL::Qt::TriangulationCircumcircle<Delaunay> *tcc;
public:
MainWindow();
public slots:
void processInput(CGAL::Object o);
void on_actionShowConflictZone_toggled(bool checked);
void on_actionCircumcenter_toggled(bool checked);
void on_actionShowDelaunay_toggled(bool checked);
void on_actionShowVoronoi_toggled(bool checked);
void on_actionInsertPoint_toggled(bool checked);
void on_actionInsertRandomPoints_triggered();
void on_actionLoadPoints_triggered();
void on_actionSavePoints_triggered();
void on_actionClear_triggered();
void on_actionRecenter_triggered();
virtual void open(QString fileName);
signals:
void changed();
};
MainWindow::MainWindow()
: DemosMainWindow()
{
setupUi(this);
this->graphicsView->setAcceptDrops(false);
// Add Poincaré disk
qreal origin_x = 0, origin_y = 0, radius = 1, diameter = 2*radius;
qreal left_top_corner_x = origin_x - radius;
qreal left_top_corner_y = origin_y - radius;
qreal width = diameter, height = diameter;
disk = new QGraphicsEllipseItem(left_top_corner_x, left_top_corner_y, width, height);
QPen pen; // creates a default pen
pen.setWidthF(0.025);
pen.setBrush(Qt::black);
disk->setPen(pen);
scene.addItem(disk);
// Add a GraphicItem for the Delaunay triangulation
dgi = new CGAL::Qt::TriangulationGraphicsItem<Delaunay>(&dt);
QObject::connect(this, SIGNAL(changed()),
dgi, SLOT(modelChanged()));
QPen vpen;
vpen.setStyle(::Qt::SolidLine);
vpen.setWidth(15);
vpen.setBrush(::Qt::red);
vpen.setCapStyle(::Qt::RoundCap);
vpen.setJoinStyle(::Qt::RoundJoin);
dgi->setVerticesPen(vpen);
QPen epen;
epen.setWidthF(0.01);
epen.setBrush(::Qt::black);
dgi->setEdgesPen(epen);
scene.addItem(dgi);
// Add a GraphicItem for the Voronoi diagram
vgi = new CGAL::Qt::VoronoiGraphicsItem<Delaunay>(&dt);
QObject::connect(this, SIGNAL(changed()),
vgi, SLOT(modelChanged()));
vgi->setEdgesPen(QPen(Qt::blue, 0.01, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
scene.addItem(vgi);
vgi->hide();
// Setup input handlers. They get events before the scene gets them
// and the input they generate is passed to the triangulation with
// the signal/slot mechanism
pi = new CGAL::Qt::TriangulationPointInputAndConflictZone<Delaunay>(&scene, &dt, this);
QObject::connect(pi, SIGNAL(generate(CGAL::Object)),
this, SLOT(processInput(CGAL::Object)));
tcc = new CGAL::Qt::TriangulationCircumcircle<Delaunay>(&scene, &dt, this);
tcc->setPen(QPen(Qt::red, 0.005, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
cz = new CGAL::Qt::TriangulationConflictZone<Delaunay>(&scene, &dt, this);
//
// Manual handling of actions
//
QObject::connect(this->actionQuit, SIGNAL(triggered()),
this, SLOT(close()));
// We put mutually exclusive actions in an QActionGroup
QActionGroup* ag = new QActionGroup(this);
ag->addAction(this->actionInsertPoint);
//ag->addAction(this->actionMovingPoint);
ag->addAction(this->actionCircumcenter);
ag->addAction(this->actionShowConflictZone);
// Check two actions
this->actionInsertPoint->setChecked(true);
this->actionShowDelaunay->setChecked(true);
//
// Setup the scene and the view
//
scene.setItemIndexMethod(QGraphicsScene::NoIndex);
scene.setSceneRect(left_top_corner_x, left_top_corner_y, width, height);
this->graphicsView->setScene(&scene);
this->graphicsView->setMouseTracking(true);
// we want to adjust the coordinates of QGraphicsView to the coordinates of QGraphicsScene
// the following line must do this:
// this->graphicsView->fitInView( scene.sceneRect(), Qt::KeepAspectRatio);
// It does not do this sufficiently well.
// Current solution:
this->graphicsView->shear(230, 230);
// Turn the vertical axis upside down
this->graphicsView->matrix().scale(1, -1);
// The navigation adds zooming and translation functionality to the
// QGraphicsView
this->addNavigation(this->graphicsView);
this->setupStatusBar();
this->setupOptionsMenu();
this->addAboutDemo(":/cgal/help/about_Hyperbolic_Delaunay_triangulation_2.html");
this->addAboutCGAL();
this->addRecentFiles(this->menuFile, this->actionQuit);
connect(this, SIGNAL(openRecentFile(QString)),
this, SLOT(open(QString)));
}
void
MainWindow::processInput(CGAL::Object o)
{
Point_2 p;
if(CGAL::assign(p, o)){
QPointF qp(CGAL::to_double(p.x()), CGAL::to_double(p.y()));
// note that if the point is on the boundary then the disk contains the point
if(disk->contains(qp)){
dt.insert(p);
}
}
emit(changed());
}
/*
* Qt Automatic Connections
* http://doc.trolltech.com/4.4/designer-using-a-component.html#automatic-connections
*
* setupUi(this) generates connections to the slots named
* "on_<action_name>_<signal_name>"
*/
void
MainWindow::on_actionInsertPoint_toggled(bool checked)
{
if(checked){
scene.installEventFilter(pi);
} else {
scene.removeEventFilter(pi);
}
}
void
MainWindow::on_actionShowConflictZone_toggled(bool checked)
{
if(checked){
scene.installEventFilter(cz);
} else {
scene.removeEventFilter(cz);
}
}
void
MainWindow::on_actionCircumcenter_toggled(bool checked)
{
if(checked){
scene.installEventFilter(tcc);
tcc->show();
} else {
scene.removeEventFilter(tcc);
tcc->hide();
}
}
void
MainWindow::on_actionShowDelaunay_toggled(bool checked)
{
dgi->setVisibleEdges(checked);
}
void
MainWindow::on_actionShowVoronoi_toggled(bool checked)
{
vgi->setVisible(checked);
}
void
MainWindow::on_actionClear_triggered()
{
dt.clear();
emit(changed());
}
void
MainWindow::on_actionInsertRandomPoints_triggered()
{
QRectF rect = CGAL::Qt::viewportsBbox(&scene);
CGAL::Qt::Converter<K> convert;
Iso_rectangle_2 isor = convert(rect);
CGAL::Random_points_in_disc_2<Point_2> pg(1);
bool ok = false;
const int number_of_points =
QInputDialog::getInt(this,
tr("Number of random points"),
tr("Enter number of random points"),
100,
0,
std::numeric_limits<int>::max(),
1,
&ok);
if(!ok) {
return;
}
// wait cursor
QApplication::setOverrideCursor(Qt::WaitCursor);
std::vector<Point_2> points;
points.reserve(number_of_points);
for(int i = 0; i < number_of_points; ++i){
points.push_back(*pg++);
}
dt.insert(points.begin(), points.end());
// default cursor
QApplication::restoreOverrideCursor();
emit(changed());
}
void
MainWindow::on_actionLoadPoints_triggered()
{
QString fileName = QFileDialog::getOpenFileName(this,
tr("Open Points file"),
".");
if(! fileName.isEmpty()){
open(fileName);
}
}
void
MainWindow::open(QString fileName)
{
// wait cursor
QApplication::setOverrideCursor(Qt::WaitCursor);
std::ifstream ifs(qPrintable(fileName));
K::Point_2 p;
std::vector<K::Point_2> points;
while(ifs >> p) {
points.push_back(p);
}
dt.insert(points.begin(), points.end());
// default cursor
QApplication::restoreOverrideCursor();
this->addToRecentFiles(fileName);
actionRecenter->trigger();
emit(changed());
}
void
MainWindow::on_actionSavePoints_triggered()
{
QString fileName = QFileDialog::getSaveFileName(this,
tr("Save points"),
".");
if(! fileName.isEmpty()){
std::ofstream ofs(qPrintable(fileName));
for(Delaunay::All_vertices_iterator
vit = dt.all_vertices_begin(),
end = dt.all_vertices_end();
vit!= end; ++vit)
{
ofs << dt.point(vit) << std::endl;
}
}
}
void
MainWindow::on_actionRecenter_triggered()
{
this->graphicsView->setSceneRect(dgi->boundingRect());
this->graphicsView->fitInView(dgi->boundingRect(), Qt::KeepAspectRatio);
}
#include "HDT2.moc"
int main(int argc, char **argv)
{
QApplication app(argc, argv);
app.setOrganizationDomain("geometryfactory.com");
app.setOrganizationName("GeometryFactory");
app.setApplicationName("Delaunay_triangulation_2 demo");
// Import resources from libCGALQt4.
// See http://doc.trolltech.com/4.4/qdir.html#Q_INIT_RESOURCE
Q_INIT_RESOURCE(File);
Q_INIT_RESOURCE(Triangulation_2);
Q_INIT_RESOURCE(Input);
Q_INIT_RESOURCE(CGAL);
MainWindow mainWindow;
mainWindow.show();
QStringList args = app.arguments();
args.removeAt(0);
Q_FOREACH(QString filename, args) {
mainWindow.open(filename);
}
return app.exec();
}

View File

@ -0,0 +1,371 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<author>GeometryFactory</author>
<class>Delaunay_triangulation_2</class>
<widget class="QMainWindow" name="Hyperbolic_Delaunay_triangulation_2">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>CGAL Hyperbolic Delaunay Triangulation</string>
</property>
<property name="windowIcon">
<iconset resource="../../../GraphicsView/demo/resources/CGAL.qrc">
<normaloff>:/cgal/logos/cgal_icon</normaloff>:/cgal/logos/cgal_icon</iconset>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QGridLayout">
<item row="0" column="0">
<widget class="QGraphicsView" name="graphicsView">
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOn</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOn</enum>
</property>
<property name="transformationAnchor">
<enum>QGraphicsView::NoAnchor</enum>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<widget class="QToolBar" name="fileToolBar">
<property name="windowTitle">
<string>File Tools</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="actionClear"/>
<addaction name="actionLoadPoints"/>
<addaction name="actionSavePoints"/>
</widget>
<widget class="QToolBar" name="toolBar">
<property name="windowTitle">
<string>Visualization Tools</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="actionInsertPoint"/>
<addaction name="actionMovingPoint"/>
<addaction name="actionCircumcenter"/>
<addaction name="actionShowConflictZone"/>
<addaction name="separator"/>
<addaction name="actionShowDelaunay"/>
<addaction name="actionShowVoronoi"/>
<addaction name="separator"/>
<addaction name="actionRecenter"/>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>22</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
<property name="title">
<string>&amp;File</string>
</property>
<addaction name="separator"/>
<addaction name="actionClear"/>
<addaction name="actionLoadPoints"/>
<addaction name="actionSavePoints"/>
<addaction name="separator"/>
<addaction name="actionQuit"/>
</widget>
<widget class="QMenu" name="menuEdit">
<property name="title">
<string>&amp;Edit</string>
</property>
<addaction name="actionInsertRandomPoints"/>
</widget>
<widget class="QMenu" name="menuTools">
<property name="title">
<string>&amp;Tools</string>
</property>
<addaction name="actionInsertPoint"/>
<addaction name="actionG"/>
<addaction name="actionG2"/>
<addaction name="actionG4"/>
<addaction name="actionG8"/>
<addaction name="actionG16"/>
<addaction name="actionMovingPoint"/>
<addaction name="actionCircumcenter"/>
<addaction name="actionShowConflictZone"/>
<addaction name="separator"/>
<addaction name="actionShowDelaunay"/>
<addaction name="actionShowVoronoi"/>
<addaction name="separator"/>
<addaction name="actionRecenter"/>
</widget>
<addaction name="menuFile"/>
<addaction name="menuEdit"/>
<addaction name="menuTools"/>
</widget>
<action name="actionAbout">
<property name="text">
<string>&amp;About</string>
</property>
</action>
<action name="actionAboutCGAL">
<property name="text">
<string>About &amp;CGAL</string>
</property>
</action>
<action name="actionQuit">
<property name="text">
<string>&amp;Quit</string>
</property>
<property name="shortcut">
<string>Ctrl+Q</string>
</property>
</action>
<action name="actionInsertRandomPoints">
<property name="text">
<string>&amp;Insert random points</string>
</property>
<property name="shortcut">
<string>Ctrl+I</string>
</property>
</action>
<action name="actionMovingPoint">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="../../../GraphicsView/demo/Triangulation_2/Delaunay_triangulation_2.qrc">
<normaloff>:/cgal/Actions/icons/moving_point.png</normaloff>:/cgal/Actions/icons/moving_point.png</iconset>
</property>
<property name="text">
<string>&amp;Simulate insertion</string>
</property>
<property name="toolTip">
<string comment="The comment">Simulate Insertion</string>
</property>
<property name="statusTip">
<string comment="and its comment">Move mouse with left button pressed to see where point would be inserted</string>
</property>
<property name="whatsThis">
<string comment="what">whats this</string>
</property>
</action>
<action name="actionInsertPoint">
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<property name="icon">
<iconset resource="../../../GraphicsView/demo/icons/Input.qrc">
<normaloff>:/cgal/Input/inputPoint.png</normaloff>:/cgal/Input/inputPoint.png</iconset>
</property>
<property name="text">
<string>&amp;Insert Point</string>
</property>
<property name="toolTip">
<string>Insert Point</string>
</property>
<property name="statusTip">
<string>Left: Insert vtx</string>
</property>
</action>
<action name="actionClear">
<property name="icon">
<iconset resource="../../../GraphicsView/demo/icons/File.qrc">
<normaloff>:/cgal/fileToolbar/fileNew.png</normaloff>:/cgal/fileToolbar/fileNew.png</iconset>
</property>
<property name="text">
<string>&amp;Clear</string>
</property>
<property name="shortcut">
<string>Ctrl+C</string>
</property>
</action>
<action name="actionShowVoronoi">
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<property name="icon">
<iconset resource="../../../GraphicsView/demo/icons/Triangulation_2.qrc">
<normaloff>:/cgal/Triangulation_2/Voronoi_diagram_2.png</normaloff>:/cgal/Triangulation_2/Voronoi_diagram_2.png</iconset>
</property>
<property name="text">
<string>Show &amp;Voronoi Diagram</string>
</property>
<property name="shortcut">
<string>Ctrl+V</string>
</property>
</action>
<action name="actionShowDelaunay">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="../../../GraphicsView/demo/Triangulation_2/Delaunay_triangulation_2.qrc">
<normaloff>:/cgal/Actions/icons/triangulation.png</normaloff>:/cgal/Actions/icons/triangulation.png</iconset>
</property>
<property name="text">
<string>Show Hyperbolic &amp;Delaunay Triangulation</string>
</property>
<property name="shortcut">
<string>Ctrl+D</string>
</property>
</action>
<action name="actionLoadPoints">
<property name="icon">
<iconset resource="../../../GraphicsView/demo/icons/File.qrc">
<normaloff>:/cgal/fileToolbar/fileOpen.png</normaloff>:/cgal/fileToolbar/fileOpen.png</iconset>
</property>
<property name="text">
<string>&amp;Load Points...</string>
</property>
<property name="shortcut">
<string>Ctrl+L</string>
</property>
</action>
<action name="actionSavePoints">
<property name="icon">
<iconset resource="../../../GraphicsView/demo/icons/File.qrc">
<normaloff>:/cgal/fileToolbar/fileSave.png</normaloff>:/cgal/fileToolbar/fileSave.png</iconset>
</property>
<property name="text">
<string>&amp;Save Points...</string>
</property>
<property name="shortcut">
<string>Ctrl+S</string>
</property>
</action>
<action name="actionCircumcenter">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="../../../GraphicsView/demo/Triangulation_2/Delaunay_triangulation_2.qrc">
<normaloff>:/cgal/Actions/icons/circumcenter.png</normaloff>:/cgal/Actions/icons/circumcenter.png</iconset>
</property>
<property name="text">
<string>&amp;Circumcenter</string>
</property>
<property name="toolTip">
<string>Draw circumcenter</string>
</property>
</action>
<action name="actionRecenter">
<property name="icon">
<iconset resource="../../../GraphicsView/demo/icons/Input.qrc">
<normaloff>:/cgal/Input/zoom-best-fit</normaloff>:/cgal/Input/zoom-best-fit</iconset>
</property>
<property name="text">
<string>Re&amp;center the viewport</string>
</property>
<property name="shortcut">
<string>Ctrl+R</string>
</property>
</action>
<action name="actionShowConflictZone">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="../../../GraphicsView/demo/Triangulation_2/Delaunay_triangulation_2.qrc">
<normaloff>:/cgal/Actions/icons/conflict_zone.png</normaloff>:/cgal/Actions/icons/conflict_zone.png</iconset>
</property>
<property name="text">
<string>Show Conflict Zone</string>
</property>
</action>
<action name="actionG">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="Hyperbolic_translations_2.qrc">
<normaloff>:/cgal/Actions/icons/G.png</normaloff>:/cgal/Actions/icons/G.png</iconset>
</property>
<property name="text">
<string>G</string>
</property>
</action>
<action name="actionG2">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="Hyperbolic_translations_2.qrc">
<normaloff>:/cgal/Actions/icons/G2.png</normaloff>:/cgal/Actions/icons/G2.png</iconset>
</property>
<property name="text">
<string>G2</string>
</property>
</action>
<action name="actionG4">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="Hyperbolic_translations_2.qrc">
<normaloff>:/cgal/Actions/icons/G4.png</normaloff>:/cgal/Actions/icons/G4.png</iconset>
</property>
<property name="text">
<string>G4</string>
</property>
</action>
<action name="actionG8">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="Hyperbolic_translations_2.qrc">
<normaloff>:/cgal/Actions/icons/G8.png</normaloff>:/cgal/Actions/icons/G8.png</iconset>
</property>
<property name="text">
<string>G8</string>
</property>
</action>
<action name="actionG16">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="Hyperbolic_translations_2.qrc">
<normaloff>:/cgal/Actions/icons/G16.png</normaloff>:/cgal/Actions/icons/G16.png</iconset>
</property>
<property name="text">
<string>G16</string>
</property>
</action>
</widget>
<resources>
<include location="../../../GraphicsView/demo/Triangulation_2/Delaunay_triangulation_2.qrc"/>
<include location="../../../GraphicsView/demo/icons/File.qrc"/>
<include location="Hyperbolic_translations_2.qrc"/>
<include location="../../../GraphicsView/demo/resources/CGAL.qrc"/>
<include location="../../../GraphicsView/demo/icons/Triangulation_2.qrc"/>
<include location="../../../GraphicsView/demo/icons/Input.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -0,0 +1,122 @@
// Copyright (c) 2011-2018 INRIA Sophia Antipolis, INRIA Nancy (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0+
//
// Author(s) : Mikhail Bogdanov
#ifndef CGAL_HYPERBOLIC_PAINTER_OSTREAM_H
#define CGAL_HYPERBOLIC_PAINTER_OSTREAM_H
#include <CGAL/Qt/PainterOstream.h>
#include <CGAL/Hyperbolic_Delaunay_triangulation_traits_2.h>
namespace CGAL{
namespace Qt {
template <typename K>
class PainterOstream< Hyperbolic_Delaunay_triangulation_traits_2<K> >
: public PainterOstream<K>
{
typedef PainterOstream<K> Base;
typedef PainterOstream<Hyperbolic_Delaunay_triangulation_traits_2<K> > Self;
typedef Hyperbolic_Delaunay_triangulation_traits_2<K> Gt;
typedef typename Gt::Hyperbolic_segment_2 Hyperbolic_segment_2;
typedef typename Gt::Circular_arc_2 Circular_arc_2;
typedef typename Gt::Euclidean_segment_2 Euclidean_segment_2;
typedef typename Gt::Point_2 Point_2;
private:
PainterOstream& operator<<(const Circular_arc_2& arc)
{
const typename K::Circle_2 & circ = arc.supporting_circle();
const typename K::Point_2 & center = circ.center();
const typename K::Point_2 & source = arc.source();
const typename K::Point_2 & target = arc.target();
double asource = std::atan2( -to_double(source.y() - center.y()),
to_double(source.x() - center.x()));
double atarget = std::atan2( -to_double(target.y() - center.y()),
to_double(target.x() - center.x()));
std::swap(asource, atarget);
double aspan = atarget - asource;
if(aspan < 0.)
aspan += 2 * CGAL_PI;
const double coeff = 180*16/CGAL_PI;
qp->drawArc(convert(circ.bbox()), int(asource * coeff), int(aspan * coeff));
return *this;
}
PainterOstream& operator<<(const Euclidean_segment_2& seg)
{
const typename K::Point_2 & source = seg.source();
const typename K::Point_2 & target = seg.target();
QPointF src(to_double(source.x()), to_double(source.y()));
QPointF tgt(to_double(target.x()), to_double(target.y()));
qp->drawLine(src, tgt);
return *this;
}
public:
PainterOstream(QPainter* p, QRectF rect = QRectF())
: Base(p, rect), qp(p), convert(rect)
{}
using Base::operator <<;
PainterOstream& operator << (Hyperbolic_segment_2 s)
{
if(const Euclidean_segment_2* seg = boost::get<Euclidean_segment_2>(&s)) {
CGAL::Qt::PainterOstream<K>::operator << (*seg);
return *this;
}
Circular_arc_2* arc = boost::get<Circular_arc_2>(&s);
if(arc->squared_radius() > 100) {
Euclidean_segment_2 seg(arc->source(), arc->target());
CGAL::Qt::PainterOstream<K>::operator << (seg);
return *this;
}
operator << (*arc);
return *this;
}
private:
// ToDo: These objects must be deleted
// Copies of these objects are in the base class.
// We need access to the copies in the base class.
QPainter* qp;
Converter<K> convert;
};
} //namespace Qt
} //namespace CGAL
#endif // CGAL_HYPERBOLIC_PAINTER_OSTREAM_H

View File

@ -0,0 +1,92 @@
// Copyright (c) 2011-2016 INRIA Sophia Antipolis, INRIA Nancy (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL:
// $Id:
// SPDX-License-Identifier: GPL-3.0+
//
// Author(s) : Monique Teillaud <Monique.Teillaud@inria.fr>
// Mikhail Bogdanov
#ifndef CGAL_HYPERBOLIC_PAINTER_OSTREAM_H
#define CGAL_HYPERBOLIC_PAINTER_OSTREAM_H
#include <CGAL/Qt/PainterOstream.h>
namespace CGAL{
namespace Qt {
template <typename K>
class PainterOstream<Hyperbolic_Delaunay_triangulation_CK_traits_2<K> >
: public PainterOstream<K>
{
public:
typedef PainterOstream<K> Base;
typedef Hyperbolic_Delaunay_triangulation_CK_traits_2<K> Gt;
typedef PainterOstream<Gt> Self;
typedef typename Gt::Hyperbolic_segment_2 Hyperbolic_segment_2;
typedef typename Gt::Point_2 Point_2;
typedef Line_arc_2<K> Line_arc;
typedef Circular_arc_2<K> Circular_arc;
typedef Circular_arc_point_2<K> Circular_arc_point;
PainterOstream(QPainter* p, QRectF rect = QRectF())
: Base(p, rect), qp(p), convert(rect)
{}
using Base::operator <<;
PainterOstream& operator << (Hyperbolic_segment_2 s)
{
if(const Line_arc* seg = boost::get<Line_arc>(&s)) {
operator << (*seg);
return *this;
}
Circular_arc* arc = boost::get<Circular_arc>(&s);
if(arc->squared_radius() > 10)
// due to rounding, the arc drawn does not look like it
// passes through the endpoints
// so we replace the arc by a line segment
{
Point_2 source(to_double(arc->source().x()),to_double(arc->source().y()));
Point_2 target(to_double(arc->target().x()),to_double(arc->target().y()));
const Line_arc seg(source,target);
operator << (seg);
return *this;
}
operator << (*arc);
return *this;
}
private:
// ToDo: These objects must be deleted
// Copies of these objects are in the base class.
// We need access to the copies in the base class.
QPainter* qp;
Converter<K> convert;
};
} //namespace Qt
} //namespace CGAL
#endif // CGAL_HYPERBOLIC_PAINTER_OSTREAM_H

View File

@ -0,0 +1,132 @@
// Copyright (c) 2008 GeometryFactory Sarl (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0+
//
// Author(s) : Andreas Fabri <Andreas.Fabri@geometryfactory.com>
// Laurent Rineau <Laurent.Rineau@geometryfactory.com>
#ifndef CGAL_QT_VORONOI_GRAPHICS_ITEM_H
#define CGAL_QT_VORONOI_GRAPHICS_ITEM_H
#include <CGAL/Qt/GraphicsItem.h>
#include <CGAL/Qt/PainterOstream.h>
#include <CGAL/Qt/utility.h>
#include <QGraphicsScene>
#include <QGraphicsSceneMouseEvent>
#include <QPainter>
#include <QStyleOption>
#include <CGAL/intersection_2.h>
class QGraphicsSceneMouseEvent;
namespace CGAL {
namespace Qt {
template <typename DT>
class VoronoiGraphicsItem : public GraphicsItem
{
public:
VoronoiGraphicsItem(DT * dt_);
QRectF
boundingRect() const;
void
paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
void
modelChanged();
const QPen& edgesPen() const
{
return edges_pen;
}
void setEdgesPen(const QPen& pen)
{
edges_pen = pen;
}
private:
DT * dt;
QPen edges_pen;
};
template <typename DT>
VoronoiGraphicsItem<DT>::VoronoiGraphicsItem(DT * dt_)
: dt(dt_)
{
setZValue(3);
}
template <typename DT>
QRectF
VoronoiGraphicsItem<DT>::boundingRect() const
{
QRectF rect = CGAL::Qt::viewportsBbox(scene());
return rect;
}
template <typename DT>
void
VoronoiGraphicsItem<DT>::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget * /*w*/)
{
QRectF rect = option->exposedRect;
PainterOstream<typename DT::Geom_traits> pos(painter, rect);
painter->setPen(edgesPen());
// delete
QPen temp = painter->pen();
QPen old = temp;
temp.setWidthF(0.01);
painter->setPen(temp);
//
for(typename DT::All_edges_iterator eit = dt->all_edges_begin();
eit != dt->all_edges_end();
eit++)
{
typename DT::Hyperbolic_segment s = dt->dual(*eit);
pos << s;
}
// delete
painter->setPen(old);
}
template <typename T>
void
VoronoiGraphicsItem<T>::modelChanged()
{
update();
}
} // namespace Qt
} // namespace CGAL
#endif // CGAL_QT_VORONOI_GRAPHICS_ITEM_H

View File

@ -0,0 +1,151 @@
// Copyright (c) 2008 GeometryFactory Sarl (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0+
//
// Author(s) : Andreas Fabri <Andreas.Fabri@geometryfactory.com>
//
#ifndef CGAL_QT_TRIANGULATION_CIRCUMCIRCLE_H
#define CGAL_QT_TRIANGULATION_CIRCUMCIRCLE_H
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsScene>
#include <QGraphicsEllipseItem>
#include <QEvent>
#include <QPen>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Qt/GraphicsViewInput.h>
namespace CGAL {
namespace Qt {
template <typename DT>
class TriangulationCircumcircle : public GraphicsViewInput
{
public:
TriangulationCircumcircle(QGraphicsScene* s, DT * dt_, QObject* parent);
~TriangulationCircumcircle();
void setPen(const QPen& pen);
void show();
void hide();
protected:
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
bool eventFilter(QObject *obj, QEvent *event);
private:
DT * dt;
typename DT::Face_handle fh;
QGraphicsScene *scene_;
QGraphicsEllipseItem* circle;
};
template <typename T>
TriangulationCircumcircle<T>::TriangulationCircumcircle(QGraphicsScene* s,
T * dt_,
QObject* parent)
: GraphicsViewInput(parent), dt(dt_), scene_(s)
{
circle = new QGraphicsEllipseItem();
circle->hide();
scene_->addItem(circle);
}
template <typename T>
TriangulationCircumcircle<T>::~TriangulationCircumcircle()
{
}
template <typename T>
void
TriangulationCircumcircle<T>::setPen(const QPen& pen)
{
circle->setPen(pen);
}
template <typename T>
void
TriangulationCircumcircle<T>::show()
{
circle->show();
}
template <typename T>
void
TriangulationCircumcircle<T>::hide()
{
circle->hide();
}
template <typename T>
void
TriangulationCircumcircle<T>::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
if(dt->dimension() != 2){
circle->hide();
return;
}
typename T::Point p = typename T::Point(event->scenePos().x(), event->scenePos().y());
typedef typename T::Face_handle Face_handle;
fh = dt->locate(p);
if (fh != Face_handle()) {
if(dt->is_Delaunay_hyperbolic(fh)){
typename T::Geom_traits::Circle_2 c(dt->point(fh,0),
dt->point(fh,1),
dt->point(fh,2));
CGAL::Bbox_2 bb = c.bbox();
circle->setRect(bb.xmin(), bb.ymin(), bb.xmax()-bb.xmin(), bb.ymax()-bb.ymin());
circle->show();
} else {
circle->hide();
}
} else {
circle->hide();
}
}
template <typename T>
bool
TriangulationCircumcircle<T>::eventFilter(QObject *obj, QEvent *event)
{
if(event->type() == QEvent::GraphicsSceneMouseMove) {
QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
mouseMoveEvent(mouseEvent);
return false; // don't consume the event
} else{
// standard event processing
return QObject::eventFilter(obj, event);
}
}
} // namespace Qt
} // namespace CGAL
#endif // CGAL_QT_TRIANGULATION_CIRCUMCIRCLE_H

View File

@ -0,0 +1,170 @@
// Copyright (c) 2008 GeometryFactory Sarl (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0+
//
// Author(s) : Andreas Fabri <Andreas.Fabri@geometryfactory.com>
//
#ifndef CGAL_QT_TRIANGULATION_CONFLICT_ZONE
#define CGAL_QT_TRIANGULATION_CONFLICT_ZONE
#include <CGAL/Qt/GraphicsViewInput.h>
#include <CGAL/Qt/Converter.h>
#include <QGraphicsSceneMouseEvent>
#include <QEvent>
#include <list>
namespace CGAL {
namespace Qt {
template <typename DT>
class TriangulationConflictZone : public GraphicsViewInput
{
public:
typedef typename DT::Geom_traits K;
typedef typename DT::Face_handle Face_handle;
typedef typename DT::Point Point;
TriangulationConflictZone(QGraphicsScene* s, DT * dt_, QObject* parent);
protected:
void localize_and_insert_point(QPointF qt_point);
void mousePressEvent(QGraphicsSceneMouseEvent *event);
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
bool eventFilter(QObject *obj, QEvent *event);
std::list<Face_handle> faces;
std::list<QGraphicsPolygonItem*> qfaces;
DT * dt;
Converter<K> convert;
QGraphicsScene *scene_;
bool animate;
Face_handle hint;
};
template <typename T>
TriangulationConflictZone<T>::TriangulationConflictZone(QGraphicsScene* s,
T * dt_,
QObject* parent)
: GraphicsViewInput(parent), dt(dt_), scene_(s), animate(false)
{}
template <typename T>
void
TriangulationConflictZone<T>::localize_and_insert_point(QPointF qt_point)
{
Point p(convert(qt_point));
faces.clear();
for(std::list<QGraphicsPolygonItem*>::iterator it = qfaces.begin();
it != qfaces.end();
++it){
delete *it;
}
qfaces.clear();
hint = dt->locate(p, hint);
dt->find_conflicts(p, std::back_inserter(faces), hint);
for(typename std::list<Face_handle>::iterator it = faces.begin();
it != faces.end();
++it){
if(! dt->is_infinite(*it)){
QGraphicsPolygonItem *item = new QGraphicsPolygonItem(convert(dt->hyperbolic_triangle(*it)));
QColor color(::Qt::blue);
color.setAlpha(150);
item->setBrush(color);
scene_->addItem(item);
qfaces.push_back(item);
}
}
}
template <typename T>
void
TriangulationConflictZone<T>::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
if(dt->number_of_vertices() == 0 ||
event->modifiers() != 0 ||
event->button() != ::Qt::LeftButton) {
return;
}
hint = dt->locate(convert(event->scenePos()));
localize_and_insert_point(event->scenePos());
animate = true;
}
template <typename T>
void
TriangulationConflictZone<T>::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
if(animate){
localize_and_insert_point(event->scenePos());
}
}
template <typename T>
void
TriangulationConflictZone<T>::mouseReleaseEvent(QGraphicsSceneMouseEvent * /*event*/)
{
faces.clear();
for(std::list<QGraphicsPolygonItem*>::iterator it = qfaces.begin();
it != qfaces.end();
++it){
delete *it;
}
qfaces.clear();
animate = false;
}
template <typename T>
bool
TriangulationConflictZone<T>::eventFilter(QObject *obj, QEvent *event)
{
if(event->type() == QEvent::GraphicsSceneMousePress) {
QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
mousePressEvent(mouseEvent);
return true;
} else if(event->type() == QEvent::GraphicsSceneMouseMove) {
QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
mouseMoveEvent(mouseEvent);
return false; // do not eat move event!
} else if(event->type() == QEvent::GraphicsSceneMouseRelease) {
QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
mouseReleaseEvent(mouseEvent);
return true;
} else{
// standard event processing
return QObject::eventFilter(obj, event);
}
}
} // namespace Qt
} // namespace CGAL
#endif // CGAL_QT_TRIANGULATION_CONFLICT_ZONE

View File

@ -0,0 +1,248 @@
// Copyright (c) 2008 GeometryFactory Sarl (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/next/GraphicsView/include/CGAL/Qt/TriangulationGraphicsItem.h $
// $Id: TriangulationGraphicsItem.h 67117 2012-01-13 18:14:48Z lrineau $
//
//
// Author(s) : Andreas Fabri <Andreas.Fabri@geometryfactory.com>
// Laurent Rineau <Laurent.Rineau@geometryfactory.com>
#ifndef CGAL_QT_TRIANGULATION_GRAPHICS_ITEM_H
#define CGAL_QT_TRIANGULATION_GRAPHICS_ITEM_H
#include <CGAL/Bbox_2.h>
#include <CGAL/apply_to_range.h>
#include "HyperbolicPainterOstream.h"
#include <CGAL/Qt/GraphicsItem.h>
#include <CGAL/Qt/Converter.h>
#include <QGraphicsScene>
#include <QPainter>
#include <QStyleOption>
namespace CGAL {
namespace Qt {
template <typename T>
class TriangulationGraphicsItem : public GraphicsItem
{
typedef typename T::Geom_traits Geom_traits;
public:
TriangulationGraphicsItem(T* t_);
void modelChanged();
public:
QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
virtual void operator()(typename T::Face_handle fh);
void setVerticesPen(const QPen& pen)
{
vertices_pen = pen;
}
void setEdgesPen(const QPen& pen)
{
edges_pen = pen;
}
bool visibleVertices() const
{
return visible_vertices;
}
void setVisibleVertices(const bool b)
{
visible_vertices = b;
update();
}
bool visibleEdges() const
{
return visible_edges;
}
void setVisibleEdges(const bool b)
{
visible_edges = b;
update();
}
protected:
virtual void drawAll(QPainter *painter);
void paintVertices(QPainter *painter);
virtual void paintVertex(typename T::Vertex_handle vh);
void updateBoundingBox();
T * t;
QPainter* m_painter;
PainterOstream<Geom_traits> painterostream;
typename T::Vertex_handle vh;
typename T::Point p;
CGAL::Bbox_2 bb;
bool bb_initialized;
QRectF bounding_rect;
QPen vertices_pen;
QPen edges_pen;
bool visible_edges;
bool visible_vertices;
};
template <typename T>
TriangulationGraphicsItem<T>::TriangulationGraphicsItem(T * t_)
: t(t_), painterostream(0),
bb(0,0,0,0), bb_initialized(false),
visible_edges(true), visible_vertices(true)
{
if(t->number_of_vertices() == 0){
this->hide();
}
updateBoundingBox();
setZValue(3);
}
template <typename T>
QRectF
TriangulationGraphicsItem<T>::boundingRect() const
{
return bounding_rect;
}
template <typename T>
void
TriangulationGraphicsItem<T>::operator()(typename T::Face_handle fh)
{
if(visible_edges) {
for(int i=0; i<3; i++) {
if(fh < fh->neighbor(i) || !t->is_Delaunay_hyperbolic(fh->neighbor(i))){
painterostream << t->hyperbolic_segment(fh,i);
}
}
}
if(visible_vertices) {
for(int i=0; i<3; i++) {
paintVertex(fh->vertex(i));
}
}
}
template <typename T>
void
TriangulationGraphicsItem<T>::drawAll(QPainter *painter)
{
QPen pen;
pen.setWidthF(0.005);
pen.setBrush(::Qt::black);
painter->setPen(edges_pen);
painterostream = PainterOstream<Geom_traits>(painter);
if(visibleEdges()) {
for(typename T::All_edges_iterator eit = t->all_edges_begin();
eit != t->all_edges_end();
++eit){
painterostream << t->hyperbolic_segment(*eit);
}
}
paintVertices(painter);
}
template <typename T>
void
TriangulationGraphicsItem<T>::paintVertices(QPainter *painter)
{
if(visibleVertices()) {
Converter<Geom_traits> convert;
painter->setPen(vertices_pen);
QMatrix matrix = painter->matrix();
painter->resetMatrix();
for(typename T::All_vertices_iterator it = t->all_vertices_begin();
it != t->all_vertices_end();
it++){
QPointF point = matrix.map(convert(t->point(it)));
painter->drawPoint(point);
}
}
}
template <typename T>
void
TriangulationGraphicsItem<T>::paintVertex(typename T::Vertex_handle vh)
{
Converter<Geom_traits> convert;
m_painter->setPen(vertices_pen);
QMatrix matrix = m_painter->matrix();
m_painter->resetMatrix();
m_painter->drawPoint(matrix.map(convert(t->point(vh))));
m_painter->setMatrix(matrix);
}
template <typename T>
void
TriangulationGraphicsItem<T>::paint(QPainter *painter,
const QStyleOptionGraphicsItem *option,
QWidget * /*widget*/)
{
if(t->dimension()<2 || option->exposedRect.contains(boundingRect())) {
drawAll(painter);
} else {
m_painter = painter;
painterostream = PainterOstream<Geom_traits>(painter);
CGAL::apply_to_range (*t,
typename T::Point(option->exposedRect.left(),
option->exposedRect.bottom()),
typename T::Point(option->exposedRect.right(),
option->exposedRect.top()),
*this);
}
}
// We let the bounding box only grow, so that when vertices get removed
// the maximal bbox gets refreshed in the GraphicsView
template <typename T>
void
TriangulationGraphicsItem<T>::updateBoundingBox()
{
prepareGeometryChange();
bounding_rect = QRectF(-1,-1,2,2);
}
template <typename T>
void
TriangulationGraphicsItem<T>::modelChanged()
{
if((t->number_of_vertices() == 0)){
this->hide();
} else if((t->number_of_vertices() > 0) && (! this->isVisible())){
this->show();
}
updateBoundingBox();
update();
}
} // namespace Qt
} // namespace CGAL
#endif // CGAL_QT_TRIANGULATION_GRAPHICS_ITEM_H

View File

@ -0,0 +1,409 @@
// Copyright (c) 2008 GeometryFactory Sarl (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0+
//
//
// Author(s) : Andreas Fabri <Andreas.Fabri@geometryfactory.com>
// Laurent Rineau <Laurent.Rineau@geometryfactory.com>
#ifndef CGAL_QT_TRIANGULATION_GRAPHICS_ITEM_H
#define CGAL_QT_TRIANGULATION_GRAPHICS_ITEM_H
#include <CGAL/Bbox_2.h>
#include <CGAL/apply_to_range.h>
#include <CGAL/Qt/PainterOstream.h>
#include <CGAL/Qt/GraphicsItem.h>
#include <CGAL/Qt/Converter.h>
#include <QGraphicsScene>
#include <QPainter>
#include <QStyleOption>
namespace CGAL {
namespace Qt {
template <typename T>
class TriangulationGraphicsItem : public GraphicsItem
{
typedef typename T::Geom_traits Geom_traits;
public:
TriangulationGraphicsItem(T* t_);
void modelChanged();
public:
QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
virtual void operator()(typename T::Face_handle fh);
const QPen& verticesPen() const
{
return vertices_pen;
}
const QPen& edgesPen() const
{
return edges_pen;
}
void setVerticesPen(const QPen& pen)
{
vertices_pen = pen;
}
void setEdgesPen(const QPen& pen)
{
edges_pen = pen;
}
bool visibleVertices() const
{
return visible_vertices;
}
void setVisibleVertices(const bool b)
{
visible_vertices = b;
update();
}
bool visibleEdges() const
{
return visible_edges;
}
void setVisibleEdges(const bool b)
{
visible_edges = b;
update();
}
protected:
virtual void drawAll(QPainter *painter);
void paintVertices(QPainter *painter);
void paintOneVertex(const typename T::Point& point);
virtual void paintVertex(typename T::Vertex_handle vh);
void updateBoundingBox();
T * t;
QPainter* m_painter;
PainterOstream<Geom_traits> painterostream;
typename T::Vertex_handle vh;
typename T::Point p;
CGAL::Bbox_2 bb;
bool bb_initialized;
QRectF bounding_rect;
QPen vertices_pen;
QPen edges_pen;
bool visible_edges;
bool visible_vertices;
};
template <typename T>
TriangulationGraphicsItem<T>::TriangulationGraphicsItem(T * t_)
: t(t_), painterostream(0),
bb(0,0,0,0), bb_initialized(false),
visible_edges(true), visible_vertices(true)
{
setVerticesPen(QPen(::Qt::red, 3.));
if(t->number_of_vertices() == 0){
this->hide();
}
updateBoundingBox();
setZValue(3);
}
template <typename T>
QRectF
TriangulationGraphicsItem<T>::boundingRect() const
{
return bounding_rect;
}
template <typename T>
void
TriangulationGraphicsItem<T>::operator()(typename T::Face_handle fh)
{
if(visible_edges) {
for(int i=0; i<3; i++) {
if(fh < fh->neighbor(i) || t->is_infinite(fh->neighbor(i))){
m_painter->setPen(this->edgesPen());
painterostream << t->segment(fh,i);
}
}
}
if(visible_vertices) {
for(int i=0; i<3; i++) {
paintVertex(fh->vertex(i));
}
}
}
template <typename T>
void
TriangulationGraphicsItem<T>::drawAll(QPainter *painter)
{
//delete
QPen temp = painter->pen();
QPen old = temp;
temp.setWidthF(/*0.0035*/0.0045);
painter->setPen(temp);
//
painterostream = PainterOstream<Geom_traits>(painter);
if(visibleEdges()) {
for(typename T::Finite_edges_iterator eit = t->finite_edges_begin();
eit != t->finite_edges_end();
++eit){
painterostream << t->segment(*eit);
}
}
//delete
painter->setPen(old);
//
paintVertices(painter);
}
template <typename T>
void
TriangulationGraphicsItem<T>::paintVertices(QPainter *painter)
{
if(visibleVertices()) {
Converter<Geom_traits> convert;
painter->setPen(verticesPen());
QMatrix matrix = painter->matrix();
painter->resetMatrix();
for(typename T::Finite_vertices_iterator it = t->finite_vertices_begin();
it != t->finite_vertices_end();
it++){
// draw vertices with color storing in their info
if(it->info().getColor() == 0) {
painter->setPen(QPen(::Qt::red, 3.));
}
if(it->info().getColor() == 1) {
painter->setPen(QPen(::Qt::green, 3.));
}
if(it->info().getColor() == 2) {
painter->setPen(QPen(::Qt::cyan, 3.));
}
if(it->info().getColor() == 3) {
painter->setPen(QPen(::Qt::magenta, 3.));
}
if(it->info().getColor() == 6) {
painter->setPen(QPen(::Qt::yellow, 3.));
}
if(it->info().getColor() == 5) {
// brown
painter->setPen(QPen(QColor(139, 69, 19), 3.));
}
if(it->info().getColor() == 4) {
painter->setPen(QPen(::Qt::blue, 3.));
}
if(it->info().getColor() == 7) {
// orange
QColor orange = QColor(255, 165, 0);
painter->setPen(QPen(orange, 3.));
}
if(it->info().getColor() == 8) {
// dark green
QColor blue = QColor(0, 102, 51);
painter->setPen(QPen(blue, 3.));
}
if(it->info().getColor() == 9) {
// purple
QColor blue = QColor(102, 0, 102);
painter->setPen(QPen(blue, 3.));
}
if(it->info().getColor() == 10) {
// close to blue
QColor blue = QColor(131, 111, 255);
painter->setPen(QPen(blue, 3.));
}
//
// delete
QPen temp = painter->pen();
QPen old = temp;
temp.setWidth(9);
double px = to_double(t->point(it).x());
double py = to_double(t->point(it).y());
double dist = px*px + py*py;
if(dist > 0.25) {
temp.setWidth(8);//6
}
if(dist > 0.64) {
temp.setWidth(7);//5
}
if(dist > 0.81) {
temp.setWidth(5);//3
}
if(dist > 0.92) {
temp.setWidth(4);//3
}
if(dist > 0.98) {
temp.setWidth(3);//3
}
//painter->setPen(temp);
QPointF point = matrix.map(convert(t->point(it)));
painter->drawPoint(point);
painter->setPen(old);
/*
QBrush temp = painter->brush();
QBrush old = temp;
temp.setColor(painter->pen().color());
painter->setBrush(temp);
painter->drawEllipse(point, 10, 10);
painter->setBrush(old);
*/
}
}
}
template <typename T>
void
TriangulationGraphicsItem<T>::paintOneVertex(const typename T::Point& point)
{
Converter<Geom_traits> convert;
m_painter->setPen(this->verticesPen());
QMatrix matrix = m_painter->matrix();
m_painter->resetMatrix();
m_painter->drawPoint(matrix.map(convert(point)));
m_painter->setMatrix(matrix);
}
template <typename T>
void
TriangulationGraphicsItem<T>::paintVertex(typename T::Vertex_handle vh)
{
Converter<Geom_traits> convert;
m_painter->setPen(this->verticesPen());
QMatrix matrix = m_painter->matrix();
m_painter->resetMatrix();
m_painter->drawPoint(matrix.map(convert(t->point(vh))));
m_painter->setMatrix(matrix);
}
template <typename T>
void
TriangulationGraphicsItem<T>::paint(QPainter *painter,
const QStyleOptionGraphicsItem *option,
QWidget * /*widget*/)
{
painter->setPen(this->edgesPen());
// painter->drawRect(boundingRect());
if(t->dimension()<2 || option->exposedRect.contains(boundingRect())) {
drawAll(painter);
} else {
m_painter = painter;
painterostream = PainterOstream<Geom_traits>(painter);
CGAL::apply_to_range (*t,
typename T::Point(option->exposedRect.left(),
option->exposedRect.bottom()),
typename T::Point(option->exposedRect.right(),
option->exposedRect.top()),
*this);
}
}
// We let the bounding box only grow, so that when vertices get removed
// the maximal bbox gets refreshed in the GraphicsView
template <typename T>
void
TriangulationGraphicsItem<T>::updateBoundingBox()
{
prepareGeometryChange();
if(t->number_of_vertices() == 0){
bb = Bbox_2(0,0,0,0);
bb_initialized = false;
return;
} else if(! bb_initialized){
bb = t->point(t->finite_vertices_begin()).bbox();
bb_initialized = true;
}
if(t->dimension() <2){
for(typename T::Finite_vertices_iterator it = t->finite_vertices_begin();
it != t->finite_vertices_end();
++it){
bb = bb + t->point(it).bbox();
}
} else {
typename T::Vertex_handle inf = t->infinite_vertex();
typename T::Vertex_circulator vc = t->incident_vertices(inf), done(vc);
do {
bb = bb + t->point(vc).bbox();
++vc;
} while(vc != done);
}
bounding_rect = QRectF(bb.xmin(),
bb.ymin(),
bb.xmax()-bb.xmin(),
bb.ymax()-bb.ymin());
}
template <typename T>
void
TriangulationGraphicsItem<T>::modelChanged()
{
if((t->number_of_vertices() == 0)){
this->hide();
} else if((t->number_of_vertices() > 0) && (! this->isVisible())){
this->show();
}
updateBoundingBox();
update();
}
} // namespace Qt
} // namespace CGAL
#endif // CGAL_QT_TRIANGULATION_GRAPHICS_ITEM_H

View File

@ -0,0 +1,168 @@
// Copyright (c) 2008 GeometryFactory Sarl (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0+
//
// Author(s) : Andreas Fabri <Andreas.Fabri@geometryfactory.com>
// Laurent Rineau
//
#ifndef CGAL_QT_TRIANGULATION_MOVING_POINT
#define CGAL_QT_TRIANGULATION_MOVING_POINT
#include <CGAL/Qt/GraphicsViewInput.h>
#include <QGraphicsSceneMouseEvent>
#include <QEvent>
#include <list>
namespace CGAL {
namespace Qt {
template <typename DT>
class TriangulationMovingPoint : public GraphicsViewInput
{
public:
typedef typename DT::Face_handle Face_handle;
typedef typename DT::Vertex_handle Vertex_handle;
typedef typename DT::Point Point;
TriangulationMovingPoint(DT * dt_, QObject* parent);
protected:
void localize_and_insert_point(QPointF qt_point);
void mousePressEvent(QGraphicsSceneMouseEvent *event);
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
bool eventFilter(QObject *obj, QEvent *event);
DT * dt;
Vertex_handle vh;
bool movePointToInsert;
bool insertedPoint;
};
template <typename T>
TriangulationMovingPoint<T>::TriangulationMovingPoint(T * dt_,
QObject* parent)
: GraphicsViewInput(parent), dt(dt_), vh(), movePointToInsert(false), insertedPoint(false)
{}
template <typename T>
void
TriangulationMovingPoint<T>::localize_and_insert_point(QPointF qt_point)
{
Point p(qt_point.x(), qt_point.y());
typename T::Locate_type lt;
int li;
Face_handle fh = (vh == Vertex_handle()) ? Face_handle() : vh->face();
fh = dt->locate(p, lt, li, fh); // fh serves as a hint
if(lt != T::VERTEX){
vh = dt->insert(p, lt, fh, li);
insertedPoint = true;
emit(modelChanged());
} else {
vh = fh->vertex(0);
insertedPoint = false;
}
}
template <typename T>
void
TriangulationMovingPoint<T>::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
if(dt->number_of_vertices() == 0 ||
event->modifiers() != 0 ||
event->button() != ::Qt::LeftButton) {
return;
}
movePointToInsert = true;
localize_and_insert_point(event->scenePos());
}
template <typename T>
void
TriangulationMovingPoint<T>::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
if(! movePointToInsert) return;
// fh will be destroyed by the removal of vh.
// Let us take a neighbor that is not in the star of vh.
const Face_handle fh = vh->face();
Vertex_handle next_hint = fh->vertex((fh->index(vh)+1)&3);
if(insertedPoint){
dt->remove(vh);
}
vh = next_hint;
localize_and_insert_point(event->scenePos());
}
template <typename T>
void
TriangulationMovingPoint<T>::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
if(! movePointToInsert ||
event->button() != ::Qt::LeftButton) {
return;
}
if(insertedPoint){
dt->remove(vh);
}
vh = Vertex_handle();
emit(modelChanged());
movePointToInsert = false;
}
template <typename T>
bool
TriangulationMovingPoint<T>::eventFilter(QObject *obj, QEvent *event)
{
if(event->type() == QEvent::GraphicsSceneMousePress) {
QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
mousePressEvent(mouseEvent);
return true;
} else if(event->type() == QEvent::GraphicsSceneMouseMove) {
QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
mouseMoveEvent(mouseEvent);
return false; // do not eat move event!
} else if(event->type() == QEvent::GraphicsSceneMouseRelease) {
QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
mouseReleaseEvent(mouseEvent);
return true;
} else{
// standard event processing
return QObject::eventFilter(obj, event);
}
}
} // namespace Qt
} // namespace CGAL
#endif // CGAL_QT_TRIANGULATION_MOVING_POINT

View File

@ -0,0 +1,140 @@
// Copyright (c) 2008 GeometryFactory Sarl (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0+
//
// Author(s) : Andreas Fabri <Andreas.Fabri@geometryfactory.com>
//
#ifndef CGAL_QT_POINT_INPUT_AND_TRIANGULATION_CONFLICT_ZONE
#define CGAL_QT_POINT_INPUT_AND_TRIANGULATION_CONFLICT_ZONE
#include <CGAL/Qt/GraphicsViewInput.h>
#include <CGAL/Qt/Converter.h>
#include <QGraphicsSceneMouseEvent>
#include <QEvent>
#include <list>
namespace CGAL {
namespace Qt {
template <typename DT>
class TriangulationPointInputAndConflictZone : public GraphicsViewInput
{
public:
typedef typename DT::Geom_traits K;
typedef typename DT::Face_handle Face_handle;
typedef typename DT::Point Point;
TriangulationPointInputAndConflictZone(QGraphicsScene* s, DT * dt_, QObject* parent);
protected:
void localize_and_insert_point(QPointF qt_point);
void mousePressEvent(QGraphicsSceneMouseEvent *event);
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
bool eventFilter(QObject *obj, QEvent *event);
std::list<Face_handle> faces;
std::list<QGraphicsPolygonItem*> qfaces;
DT * dt;
Converter<K> convert;
QGraphicsScene *scene_;
Point p;
};
template <typename T>
TriangulationPointInputAndConflictZone<T>::TriangulationPointInputAndConflictZone(QGraphicsScene* s,
T * dt_,
QObject* parent)
: GraphicsViewInput(parent), dt(dt_), scene_(s)
{}
template <typename T>
void
TriangulationPointInputAndConflictZone<T>::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
p = convert(event->scenePos());
if(dt->dimension() < 2 ||
event->modifiers() != 0 ||
event->button() != ::Qt::LeftButton) {
return;
}
dt->find_conflicts(p, std::back_inserter(faces));
for(typename std::list<Face_handle>::iterator it = faces.begin();
it != faces.end();
++it){
if(dt->is_Delaunay_hyperbolic(*it)){
QGraphicsPolygonItem *item = new QGraphicsPolygonItem(convert(dt->hyperbolic_triangle(*it)));
QColor color(::Qt::blue);
color.setAlpha(150);
item->setBrush(color);
scene_->addItem(item);
qfaces.push_back(item);
}
}
}
template <typename T>
void
TriangulationPointInputAndConflictZone<T>::mouseReleaseEvent(QGraphicsSceneMouseEvent * /*event*/)
{
faces.clear();
for(std::list<QGraphicsPolygonItem*>::iterator it = qfaces.begin();
it != qfaces.end();
++it){
scene_->removeItem(*it);
delete *it;
}
qfaces.clear();
emit (generate(CGAL::make_object(p)));
}
template <typename T>
bool
TriangulationPointInputAndConflictZone<T>::eventFilter(QObject *obj, QEvent *event)
{
if(event->type() == QEvent::GraphicsSceneMousePress) {
QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
mousePressEvent(mouseEvent);
return true;
} else if(event->type() == QEvent::GraphicsSceneMouseRelease) {
QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
mouseReleaseEvent(mouseEvent);
return true;
} else{
// standard event processing
return QObject::eventFilter(obj, event);
}
}
} // namespace Qt
} // namespace CGAL
#endif // CGAL_QT_POINT_INPUT_AND_TRIANGULATION_CONFLICT_ZONE

View File

@ -0,0 +1,101 @@
// Copyright (c) 2008 GeometryFactory Sarl (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0+
//
// Author(s) : Andreas Fabri <Andreas.Fabri@geometryfactory.com>
//
#ifndef CGAL_QT_TRIANGULATION_REMOVE_VERTEX_H
#define CGAL_QT_TRIANGULATION_REMOVE_VERTEX_H
#include <CGAL/Qt/GraphicsViewInput.h>
#include <QGraphicsSceneMouseEvent>
#include <QEvent>
#include <list>
#include <CGAL/Qt/Converter.h>
namespace CGAL {
namespace Qt {
template <typename DT>
class TriangulationRemoveVertex : public GraphicsViewInput
{
public:
typedef typename DT::Face_handle Face_handle;
typedef typename DT::Vertex_handle Vertex_handle;
typedef typename DT::Point Point;
TriangulationRemoveVertex(DT * dt_, QObject* parent);
protected:
void mousePressEvent(QGraphicsSceneMouseEvent *event);
bool eventFilter(QObject *obj, QEvent *event);
DT * dt;
};
template <typename T>
TriangulationRemoveVertex<T>::TriangulationRemoveVertex(T * dt_,
QObject* parent)
: GraphicsViewInput(parent), dt(dt_)
{}
template <typename T>
void
TriangulationRemoveVertex<T>::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
if((event->modifiers() & ::Qt::ShiftModifier)
&& (! (event->modifiers() & ::Qt::ControlModifier))){
if(dt->number_of_vertices() == 0){
dt->clear();
}else {
Converter<typename T::Geom_traits> convert;
typename T::Vertex_handle selected_vertex = dt->nearest_vertex(convert(event->scenePos()));
dt->remove(selected_vertex);
}
emit (modelChanged());
}
}
template <typename T>
bool
TriangulationRemoveVertex<T>::eventFilter(QObject *obj, QEvent *event)
{
if(event->type() == QEvent::GraphicsSceneMousePress) {
QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
mousePressEvent(mouseEvent);
return false;
} else{
// standard event processing
return QObject::eventFilter(obj, event);
}
}
} // namespace Qt
} // namespace CGAL
#endif // CGAL_QT_TRIANGULATION_REMOVE_VERTEX_H

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@ -0,0 +1,12 @@
<RCC>
<qresource prefix="/cgal/Actions" >
<file>icons/conflict_zone.png</file>
<file>icons/moving_point.png</file>
<file>icons/triangulation.png</file>
<file>icons/circumcenter.png</file>
</qresource>
<qresource prefix="/cgal/help" >
<file alias="about_CGAL.html" >../resources/about_CGAL.html</file>
<file>about_Hyperbolic_Delaunay_triangulation_2.html</file>
</qresource>
</RCC>

View File

@ -0,0 +1,7 @@
<RCC>
<qresource prefix="/cgal/fileToolbar" >
<file>fileNew.png</file>
<file>fileOpen.png</file>
<file>fileSave.png</file>
</qresource>
</RCC>

View File

@ -0,0 +1,7 @@
<RCC>
<qresource prefix="/cgal/Input" >
<file>inputPoint.png</file>
<file alias="zoom-best-fit" >fit-page-32.png</file>
<file>inputPolyline.png</file>
</qresource>
</RCC>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -0,0 +1,8 @@
<html>
<body>
<p><img src=":/cgal/logos/CGAL.png"></p>
<h2>Computational Geometry Algorithms Library<!--CGAL_VERSION--></h2>
<p>CGAL provides efficient and reliable geometric algorithms in the form of a C++ library.</p>
<p>For more information visit <a href="http://www.cgal.org/">www.cgal.org</a></p>
</body>
</html>

View File

@ -0,0 +1,10 @@
<html>
<body>
<h2>Hyperbolic Delaunay Triangulation</h2>
<p>Copyright &copy; 2019 GeometryFactory</p>
<p>This application illustrates the 2D Hyperbolic Delaunay Triangulation
of <a href="https://www.cgal.org/">CGAL</a>, and the dual objects of its faces and edges.</p>
<p>See also <a href="https://www.cgal.org/Pkg/HyperbolicTriangulation2">the online
manual</a>.</p>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 768 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1,57 @@
%PDF-1.3
3 0 obj <<
/Length 385 /Filter /FlateDecode >>
stream
xÚ}S¹N1 íç+RSDNœcÒÒ ÑŸ° BPlÅïãøÈ$ZQ<5A>7~‡ídÁ½ºà¾Ž»_Üïúìâ™}kÍý OS¤ÿ<C2A4>põ‰ê„ÇùFÜàC<C3A0>S-LÎ<4C>m8Ôà.mšœÓp¶\«â¢ÅÅùÓ=?o×HÐ|¢è]HÚS¬Kè&„€«Q0TŠÀQ-v`æ*ÊMÚ2m>ggF<67>­¹Zm¶MÎû@¨A û@¦0qJݘÇ2¢XL²g­â¦˜¹†¢h†6,ꪑ+Õ²iËä¼Tø)¤ÐDZ³4DûÓØ¿f;QíMšJ]TŠ˜'g¶©°™Ÿ:O“¤¢]¨jô7µ~wï¶Àw1ž¸ïC‰ÿÐøqËs]iSáÛJã­„‡<E2809E>+ÅHÁý½¿P}M}lºCàk°/õô ¿L”Ú<<3C>QDÚä<>i¡úR/=~r»ô†5A~Zü%Gß
 ßg™ßÖ¡é·úU}ШÞ˜ð
endstream endobj
4 0 obj <<
/Type /Page
/Contents 3 0 R
/Resources <<
/ProcSet [ /PDF ]
>>
/MediaBox [ 0 0 595 842]
/CropBox [204.765 238.4 261.6 291.541]
/ArtBox [204.765 238.4 261.6 291.541]
/Parent 2 0 R
>> endobj
1 0 obj <<
/Type /Ipe
/Length 322 /Filter /FlateDecode >>
stream
xÚµ”Ínƒ0 Çï<…• &|ˆL¥§]ö)„6j Q ìãég@]é†vØZ倉ÿþÙŽ•lµS0(ßiÛ,Cä9ƒÒ+Ù[_°rf!ójÐêȹ ¶º­í¬QUÁžŸ8bŽŠHÄs<06>­t­×}û½}+Xé­#ƒmˆæäAÁÁëªÓª`Q6¦0ò]yheC;Ò¸£œ¤S “«»lƒ,{=ܨéO³êKÔõÞžH´7²<1pây©Ÿ4B<>à(ݘœ¬©ŠÖúFµ6æ¦èˆÎ¦÷²ý5Õ*ó1žáàq:ÓøðT8ú3øàíÙMcí<63>ßüº ]A,L°ÝŒ¸;P¯3ÿuÁ¹c­·Ôy÷ìþ'q³:.¯ª5VÈb!­Íc SL©ó4Ìé_-È㽿ôÀìOR P©
endstream endobj
2 0 obj <<
/Type /Pages
/Count 1
/Kids [ 4 0 R ]
>> endobj
5 0 obj <<
/Type /Catalog
/Pages 2 0 R
>> endobj
6 0 obj <<
/Creator (Ipe 6.0 preview 28)
/Producer (Ipe 6.0 preview 28)
/CreationDate (D:20080609193922)
/ModDate (D:20080609193922)
>> endobj
xref
0 7
0000000000 00000 f
0000000671 00000 n
0000001076 00000 n
0000000009 00000 n
0000000466 00000 n
0000001135 00000 n
0000001184 00000 n
trailer
<<
/Size 7
/Root 5 0 R
/Info 6 0 R
>>
startxref
1327
%%EOF

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -0,0 +1,348 @@
// Copyright (c) 2016-2017 INRIA Nancy - Grand Est (France).
// All rights reserved.
namespace CGAL {
/*!
\ingroup PkgHyperbolicTriangulation2MainClasses
The class `Hyperbolic_Delaunay_triangulation_2` is the main class of the 2D Hyperbolic Delaunay Triangulations package.
It is designed to represent Delaunay triangulations of sets of points in the hyperbolic plane.
The hyperbolic plane is represented in the Poincaré disk model.
\tparam Gt must be a model of `HyperbolicDelaunayTriangulationTraits_2`.
\tparam Tds must be a model of `TriangulationDataStructure_2`. By default, this parameter is instantiated with
`Triangulation_data_structure_2< Triangulation_vertex_base_2<Gt>, Hyperbolic_triangulation_face_base_2<Gt> >`
\sa HyperbolicDelaunayTriangulationTraits_2
\sa TriangulationDataStructure_2
\sa Delaunay_triangulation_2
*/
template < class Gt, class Tds >
class Hyperbolic_Delaunay_triangulation_2: private Delaunay_triangulation_2<Gt,Tds> {
public:
/// \name Types
/// @{
typedef Gt Geom_traits;
typedef Tds Triangulation_data_structure;
/// \name
/// \name
/// @{
/*!
Size type (integral unsigned).
*/
typedef typename Triangulation_data_structure::size_type size_type;
typedef typename Geom_traits::Hyperbolic_point_2 Point;
typedef typename Geom_traits::Hyperbolic_triangle_2 Hyperbolic_triangle;
/// @}
/// \name
/// The following types are defined to give access to the elements of the triangulation:
/// @{
typedef typename Triangulation_data_structure::Vertex_handle Vertex_handle;
typedef typename Triangulation_data_structure::Face_handle Face_handle;
typedef typename Triangulation_data_structure::Edge Edge;
/// @}
/// \name
/// The following types are defined for use in the construction of the Voronoi diagram:
/// @{
typedef typename Geom_traits::Hyperbolic_Voronoi_point_2 Hyperbolic_Voronoi_point;
typedef typename Geom_traits::Hyperbolic_segment_2 Hyperbolic_segment;
/// @}
/// \name
/// The following iterator and circulator types are defined to give access over hyperbolic faces and edges:
/// @{
typedef Triangulation_data_structure::Face_iterator All_faces_iterator;
typedef Triangulation_data_structure::Edge_iterator All_edges_iterator;
typedef Triangulation_data_structure::Vertex_iterator All_vertices_iterator;
typedef Triangulation_data_structure::Vertex_circulator Vertex_circulator;
/// @}
/// \name
/// The enumeration `Locate_type` is defined to specify which case occurs when locating a
/// point in the triangulation.
/// @{
enum Locate_type {
VERTEX = 0,
EDGE,
FACE,
OUTSIDE_CONVEX_HULL,
OUTSIDE_AFFINE_HULL
};
/// @}
/// \name Creation
/// @{
/*!
%Default constructor
*/
Hyperbolic_Delaunay_triangulation_2(const Geom_traits& gt = Geom_traits());
/*!
Copy constructor
*/
Hyperbolic_Delaunay_triangulation_2(const Hyperbolic_Delaunay_triangulation_2<Gt,Tds> &tr);
/*!
Equivalent to creating an empty triangulation and calling `insert(first, last)`.
*/
template<class InputIterator>
Hyperbolic_Delaunay_triangulation_2(InputIterator first, InputIterator last, const Geom_traits& gt = Geom_traits());
/// @}
/// \name Assignment
/// @{
/*!
The triangulation `tr` is duplicated, and modifying the copy after the duplication does not modify the original.
*/
Hyperbolic_Delaunay_triangulation_2& operator=(Hyperbolic_Delaunay_triangulation_2 tr);
/*!
The triangulation is swapped with `tr`.
*/
void swap(Hyperbolic_Delaunay_triangulation_2& tr);
/*!
Deletes all vertices and faces of the triangulation.
*/
void clear();
/*!
Equality operator.
\todo implement!
*/
bool operator==(const Hyperbolic_Delaunay_triangulation_2<Gt,Tds>& t1,
const Hyperbolic_Delaunay_triangulation_2<Gt,Tds>& t2);
/*!
Inequality operator.
\todo implement!
*/
bool operator!=(const Hyperbolic_Delaunay_triangulation_2<Gt,Tds>& t1,
const Hyperbolic_Delaunay_triangulation_2<Gt,Tds>& t2);
/// @}
/// \name Access functions
/// @{
/*!
Returns a const reference to the geometric traits object.
*/
const Geom_traits& geom_traits() const;
/*!
Returns a const reference to the triangulation data structure.
*/
const Triangulation_data_structure& tds() const;
/*!
Returns a reference to the triangulation data structure.
*/
Triangulation_data_structure& tds();
/*!
Checks the combinatorial validity of the triangulation, the validity of
its geometric embedding, and also that all edges and faces are Delaunay
hyperbolic.
*/
bool is_valid ();
/*!
Returns the dimension of the affine hull.
*/
int dimension() const;
/*!
Returns the number of vertices.
*/
size_type number_of_vertices() const;
/*!
Returns the number of hyperbolic edges.
*/
size_type number_of_hyperbolic_edges() const;
/*!
Returns the number of hyperbolic faces.
*/
size_type number_of_hyperbolic_faces() const;
/// @}
/// \name Geometric access functions
/// @{
/*
Returns the triangle formed by the three vertices of face `f`.
*/
Hyperbolic_triangle hyperbolic_triangle(const Face_handle f) const;
/*!
Returns the hyperbolic segment formed by the vertices of the edge `(f, i)`.
*/
Hyperbolic_segment hyperbolic_segment(const Face_handle f, const int i) const;
/*!
Returns the hyperbolic segment formed by the vertices of edge `e`.
*/
Hyperbolic_segment hyperbolic_segment (const Edge& e) const;
///@}
/// \name Insertion
/// @{
/*!
Inserts the point `p` in the triangulation.
If the point `p` coincides with a existing vertex, then the vertex is returned
and the triangulation is not modified. The optional parameter `start` is used
to initialize the location of `p`.
*/
Vertex_handle insert(const Point &p, Face_handle start = Face_handle());
/*!
Inserts the point p at the location given by `(lt,loc,li)`.
The handle to the new vertex is returned.
\sa locate()
*/
Vertex_handle insert(const Point& p, typename Locate_type lt, Face_handle loc, int li);
/*!
Inserts the points in the range [first,last) into the triangulation.
Returns the number of inserted points. Note that this function is not
guaranteed to insert the points following the order of `InputIterator`,
as `spatial_sort()` is used to improve efficiency.
\tparam InputIterator must be an input iterator with the value type
\link Hyperbolic_Delaunay_triangulation_2::Point `Point`\endlink.
*/
template < class InputIterator >
std::ptrdiff_t insert(InputIterator first, InputIterator last);
/// @}
/// \name Removal
/// @{
/*!
Removes the vertex `v` from the triangulation.
\pre `v` is a vertex of the triangulation.
*/
void remove(Vertex_handle v);
/*!
Removes the vertices in the iterator range `[firs, last)` from the triangulation.
\pre all vertices in `[first, last)` are vertices of the triangulation.
*/
template <class VertexRemoveIterator>
void remove(VertexRemoveIterator first, VertexRemoveIterator last);
/// @}
/// \name Point Location
/// @{
/*!
Locates the point `query` in the triangulation.
If the point `query` lies inside the hyperbolic convex hull of the points of the triangulation,
then the hyperbolic face that contains the query in its interior is returned.
If `query` lies on a vertex or on an edge, then one of the faces having `query` on its boundary is returned.
\todo verify case when `query` lies on dangling edge!
If `query` lies outside of the convex hull of the points of the triangulation, then a default-constructed
`Face_handle()` is returned.
The optional argument `hint` is used as a starting place for the search.
*/
Face_handle locate(const Point& query, const Face_handle hint = Face_handle()) const;
/*!
Same as above.
The variable `lt` contains information about the element in which `query` has been located. See
the enumeration \link Hyperbolic_Delaunay_triangulation_2::Locate_type `Locate_type`\endlink
for details.
If `lt` is \link Hyperbolic_Delaunay_triangulation_2::VERTEX `Locate_type::VERTEX`\endlink,
then the variable `li` contains the index of the vertex in the returned face. If `lt` is
\link Hyperbolic_Delaunay_triangulation_2::EDGE `Locate_type::EDGE`\endlink, then `li`
is the index of the edge in the returned face.
*/
Face_handle locate(const Point& query, Locate_type& lt, int &li, Face_handle hint = Face_handle()) const;
/// @}
/// \name Queries
/// @{
/*!
Computes the conflict zone induced by `p`.
If the optional parameter `start` is given, then it must be a face in conflict with `p`.
Returns an iterator on the faces of the triangulation in conflict with `p`.
*/
template<class OutputItFaces>
OutputItFaces find_conflicts(const Point& p,
OutputItFaces fit,
Face_handle start = Face_handle()) const;
///@}
/// \name Vertex, Face and Edge iterators and circulators
/// @{
All_vertices_iterator all_vertices_begin() const;
All_vertices_iterator all_vertices_end() const;
All_edges_iterator all_edges_begin() const;
All_edges_iterator all_edges_end() const;
All_faces_iterator all_faces_begin() const;
All_faces_iterator all_faces_end() const;
Vertex_circulator adjacent_vertices(Vertex_handle v) const;
/// @}
/// \name Voronoi Diagram
/// Users should use a kernel with exact constructions in order to guarantee
/// the computation of the Voronoi diagram (as opposed to computing the triangulation only,
/// which requires only exact predicates).
/// @{
/*!
Returns the hyperbolic center of the circumdisk of `f`.
\pre `f` is hyperbolic
*/
Hyperbolic_Voronoi_point dual(Face_handle f) const;
/*!
Returns the hyperbolic segment that is dual to `e`.
*/
Hyperbolic_segment dual(const Edge& e) const;
/*!
Returns the hyperbolic segment that is dual to the edge `(f,i)`.
\pre `f` is hyperbolic
*/
Hyperbolic_segment dual(Face_handle f, int i) const;
/// @}
};
} //namespace CGAL

View File

@ -0,0 +1,61 @@
// Copyright (c) 2016-2017 INRIA Nancy - Grand Est (France).
// All rights reserved.
namespace CGAL {
/*!
\ingroup PkgHyperbolicTriangulation2TraitsClasses
The class `Hyperbolic_Delaunay_triangulation_CK_traits_2` is designed as one of the
default models for the traits concept `HyperbolicDelaunayTriangulationTraits_2`
offered by %CGAL.
\tparam K must be a model of `CircularKernel`.
This class provides exact constructions and predicates. The default value for `K` is
`CGAL::Circular_kernel_2< CGAL::Exact_predicates_inexact_constructions_kernel, CGAL::Algebraic_kernel_for_circles_2_2< CGAL::Exact_predicates_inexact_constructions_kernel::RT > >`,
which guarantees exact constructions of Delaunay
triangulations and dual objects when the input points have rational coordinates.
\sa `Hyperbolic_Delaunay_triangulation_traits_2`
\cgalModels `HyperbolicDelaunayTriangulationTraits_2`
*/
template < class K >
class Hyperbolic_Delaunay_triangulation_CK_traits_2 : public K {
public:
/// \name Types
/// @{
typedef typename K::FT FT;
typedef typename K::Point_2 Hyperbolic_point_2;
typedef typename K::Circular_arc_point_2 Hyperbolic_Voronoi_point_2;
typedef typename K::Circular_arc_2 Circular_arc_2;
typedef typename K::Line_arc_2 Line_arc_2;
typedef boost::variant<Circular_arc_2,
Line_arc_2> Hyperbolic_segment_2;
typedef typename K::Triangle_2 Hyperbolic_triangle_2;
/// @}
/// \name Creation
/// @{
/*!
%Default constructor
*/
Hyperbolic_Delaunay_triangulation_CK_traits_2();
/*!
Copy constructor
*/
Hyperbolic_Delaunay_triangulation_CK_traits_2(const Hyperbolic_Delaunay_triangulation_CK_traits_2 & other);
/// @}
};
} //namespace CGAL

View File

@ -0,0 +1,61 @@
// Copyright (c) 2016-2017 INRIA Nancy - Grand Est (France).
// All rights reserved.
namespace CGAL {
/*!
\ingroup PkgHyperbolicTriangulation2TraitsClasses
The class `Hyperbolic_Delaunay_triangulation_traits_2` is designed as one of the
default models for the traits concept `HyperbolicDelaunayTriangulationTraits_2`
offered by %CGAL.
\tparam K must be a model of `Kernel`.
If `K` provides exact computations with square roots, then this class automatically
provides exact constructions and predicates. The default value for `K` is
`Exact_predicates_exact_constructions_kernel_with_sqrt`, which guarantees exact
constructions of Delaunay triangulations and dual objects for input points with
algebraic coordinates.
\sa Hyperbolic_Delaunay_triangulation_CK_traits_2
\cgalModels HyperbolicDelaunayTriangulationTraits_2
*/
template< class K >
class Hyperbolic_Delaunay_triangulation_traits_2 : public K {
public:
/// \name Types
/// @{
typedef typename K::FT FT;
typedef typename K::Point_2 Hyperbolic_point_2;
typedef Hyperbolic_point_2 Hyperbolic_Voronoi_point_2;
typedef unspecified_type Circular_arc_2;
typedef typename K::Segment_2 Euclidean_segment_2;
typedef boost::variant< Circular_arc_2,
Euclidean_segment_2 > Hyperbolic_segment_2;
typedef typename K::Triangle_2 Hyperbolic_triangle_2;
/// @}
/// \name Creation
/// @{
/*!
%Default constructor
*/
Hyperbolic_Delaunay_triangulation_traits_2();
/*!
Copy constructor
*/
Hyperbolic_Delaunay_triangulation_traits_2(const Hyperbolic_Delaunay_triangulation_traits_2 & other);
/// @}
};
} // namespace CGAL

View File

@ -0,0 +1,55 @@
// Copyright (c) 2016-2017 INRIA Nancy - Grand Est (France).
// All rights reserved.
namespace CGAL {
/*!
\ingroup PkgHyperbolicTriangulation2VertexFaceClasses
The class `Hyperbolic_triangulation_face_base_2` is designed as the
default model for the face concept `HyperbolicTriangulationFaceBase_2`
offered by %CGAL.
\tparam Gt must be a model of `HyperbolicDelaunayTriangulationTraits_2`.
\tparam Fb must be a model of `TriangulationFaceBase_2`. %Defaults to `Triangulation_face_base_2<Gt>`.
\cgalModels HyperbolicTriangulationFaceBase_2
*/
template < typename Gt, typename Fb >
class Hyperbolic_triangulation_face_base_2 : public Fb {
public:
/// \name Creation
/// @{
/*!
%Default constructor
*/
Hyperbolic_triangulation_face_base_2();
/*!
Creates a face to which the vertices `v0, v1, v2` are incident.
*/
Hyperbolic_triangulation_face_base_2(Vertex_handle v0,
Vertex_handle v1,
Vertex_handle v2);
/*!
Creates a face to which the vertices `v0, v1, v2` are incident, and the faces `n0, n1, n2` are neighbors.
*/
Hyperbolic_triangulation_face_base_2(Vertex_handle v0,
Vertex_handle v1,
Vertex_handle v2,
Face_handle n0,
Face_handle n1,
Face_handle n2);
/// @}
};
} //namespace CGAL

View File

@ -0,0 +1,181 @@
// Copyright (c) 2016-2017 INRIA Nancy - Grand Est (France).
// All rights reserved.
/*!
\ingroup PkgHyperbolicTriangulation2Concepts
\cgalConcept
\cgalRefines DelaunayTriangulationTraits_2
The concept `HyperbolicDelaunayTriangulationTraits_2` describes the set of requirements
to be fulfilled by any class used to instantiate the first template parameter of the class
`CGAL::Hyperbolic_Delaunay_triangulation_2<Traits, Tds>`. It defines the geometric objects
(points, segments...) forming the triangulation together with geometric predicates and
constructions on these objects.
This concept refines `DelaunayTriangulationTraits_2` because the class `CGAL::Hyperbolic_Delaunay_triangulation_2`
internally relies on the class `CGAL::Delaunay_triangulation_2`.
\cgalHasModel CGAL::Hyperbolic_Delaunay_triangulation_traits_2
\cgalHasModel CGAL::Hyperbolic_Delaunay_triangulation_CK_traits_2
*/
class HyperbolicDelaunayTriangulationTraits_2 {
public:
/// \name Types
/// @{
/*!
Field number type.
*/
typedef unspecified_type FT;
/*!
Represents a point in the Poincaré disk or on the (unit) circle at infinity.
*/
typedef unspecified_type Hyperbolic_point_2;
/*!
Represents the dual object of a triangle in the hyperbolic Delaunay triangulation.
The dual of a Delaunay triangle is the <i>hyperbolic</i> center of the circle circumscribing it.
*/
typedef unspecified_type Hyperbolic_Voronoi_point_2;
/*!
Represents a hyperbolic segment defined by two points.
In the Poincaré disk model, a hyperbolic segment is supported either by the Euclidean circle
that passes through the two points and is perpendicular to the circle at infinity, or by the
Euclidean line that passes through the two points and the origin. Abusively, we allow one or
both endpoints of the segment to lie on the circle at infinity, so a hyperbolic segment can
actually represent a hyperbolic ray or a hyperbolic line.
*/
typedef unspecified_type Hyperbolic_segment_2;
/*!
Represents a triangle in the hyperbolic plane defined by three hyperbolic points.
*/
typedef unspecified_type Hyperbolic_triangle_2;
/// @}
/// \name Predicate Types
/// @{
/*!
A predicate object. Must provide the function operator
`Oriented_side operator()(Hyperbolic_point_2 p, Hyperbolic_point_2 q, Hyperbolic_point_2 r, Hyperbolic_point_2 t),`
which returns the position of the point `t` relative to the oriented circle
defined by the points `p, q`, and `r`.
*/
typedef unspecified_type Side_of_oriented_circle_2;
/*!
A predicate object. Must provide the function operator
`Oriented_side operator()(Hyperbolic_point_2 p, Hyperbolic_point_2 q, Hyperbolic_point_2 query),`
which returns the position of the point `query` relative to the oriented hyperbolic
segment with vertices `p` and `q`.
*/
typedef unspecified_type Side_of_oriented_hyperbolic_segment_2;
/*!
A predicate object. Must provide the function operator
`bool operator()(Hyperbolic_point_2 p0, Hyperbolic_point_2 p1, Hyperbolic_point_2 p2),`
which returns a boolean indicating whether the triangle defined
by the points `p0, p1,` and `p2` is hyperbolic (i.e., if its
circumscribing disk is contained in the unit disk). It must also
provide the function operator
`bool operator() (Hyperbolic_point_2 p0, Hyperbolic_point_2 p1, Hyperbolic_point_2 p2, int& ind),`
which returns whether the triangle is hyperbolic, and if not stores in `ind` the index of the
non-hyperbolic edge of the triangle, as defined in \cgalCite{cgal:bdt-hdcvd-14}.
The edge of the triangle opposite to `pj` for `j = 0,1,2` is considered to have index `j`.
*/
typedef unspecified_type Is_Delaunay_hyperbolic;
/// @}
/// \name Construction Types
/// @{
/*!
A constructor object.
Must provide the function operator
`Hyperbolic_segment_2 operator()(Hyperbolic_point_2 p, Hyperbolic_point_2 q),`
which constructs a hyperbolic segment from two points `p` and `q`.
Note that `p` and `q` may also lie on the circle at infinity.
*/
typedef unspecified_type Construct_hyperbolic_segment_2;
/*!
A constructor object. Must provide the function operator
`Hyperbolic_Voronoi_point_2 operator()(Hyperbolic_point_2 p, Hyperbolic_point_2 q, Hyperbolic_point_2 r),`
which constructs the hyperbolic circumcenter of the triangle with
vertices `p, q`, and `r`.
*/
typedef unspecified_type Construct_hyperbolic_circumcenter_2;
/*!
A constructor object. Must provide the function operator
`Hyperbolic_segment_2 operator()(Hyperbolic_point_2 p, Hyperbolic_point_2 q),`
which constructs the hyperbolic bisector of two points `p` and `q` lying
in the Poincaré disk. The endpoints of the resulting hyperbolic segment
lie on the circle at infinity. It must also provide the function operator
`Hyperbolic_segment_2 operator()(Hyperbolic_point_2 p, Hyperbolic_point_2 q, Hyperbolic_point_2 r),`
where the points `p, q`, and `r` lie in the Poincaré disk. This overloaded
version constructs the hyperbolic bisector of the segment [p,q] limited by
the hyperbolic circumcenter of `p, q, r` on one side and the circle at
infinity on the other. Moreover, it must provide the function operator
`Hyperbolic_segment_2 operator()(Hyperbolic_point_2 p, Hyperbolic_point_2 q, Hyperbolic_point_2 r, Hyperbolic_point_2 s),`
where the points `p, q, r`, and `s` lie in the Poincaré disk. This overloaded
version constructs the hyperbolic bisector of the segment [p,q] limited by
the hyperbolic circumcenter of `p, q, r` on one side, and the hyperbolic
circumcenter of `p, s, q` on the other side.
*/
typedef unspecified_type Construct_hyperbolic_bisector_2;
/// @}
/// \name Operations
/// The following functions give access to the predicate objects.
/// @{
Orientation_2 orientation_2_object();
Side_of_oriented_circle_2 side_of_oriented_circle_2_object();
Side_of_oriented_hyperbolic_segment_2 side_of_oriented_hyperbolic_segment_2_object();
Is_Delaunay_hyperbolic is_Delaunay_hyperbolic_object();
/// @}
/// \name
/// The following functions must be provided only if the methods of `Hyperbolic_Delaunay_triangulation_2`
/// that return elements of the Voronoi diagram are instantiated:
/// @{
Construct_hyperbolic_segment_2 construct_hyperbolic_segment_2_object();
Construct_hyperbolic_circumcenter_2 construct_hyperbolic_circumcenter_2_object();
Construct_hyperbolic_bisector_2 construct_hyperbolic_bisector_2_object();
/// @}
};

View File

@ -0,0 +1,48 @@
// Copyright (c) 2016-2017 INRIA Nancy - Grand Est (France).
// All rights reserved.
/*!
\ingroup PkgHyperbolicTriangulation2Concepts
\cgalConcept
\cgalRefines TriangulationFaceBase_2
The concept HyperbolicTriangulationFaceBase_2 describes the requirements for the base
face class of a hyperbolic triangulation data structure.
This concept provides an interface for the functionality needed in faces to compute
Delaunay triangulations in the hyperbolic plane. The function `tds_data()` is used
internally by the triangulation class during the insertion of points in the triangulation.
\cgalHasModel CGAL::Hyperbolic_triangulation_face_base_2
\sa `TriangulationDataStructure_2`
*/
class HyperbolicTriangulationFaceBase_2 {
public:
/// \name Internal access functions
/// \cgalAdvancedBegin
/// These functions are used internally by the hyperbolic Delaunay triangulation.
/// The user is not encouraged to use them directly as they may change in the future.
/// \cgalAdvancedEnd
/// @{
/*!
This function gives non-`const` access to a variable of type `CGAL::Object`.
\cgalAdvancedFunction
*/
CGAL::Object& tds_data();
/*!
This function gives `const` access to a variable of type `CGAL::Object`.
\cgalAdvancedFunction
*/
const CGAL::Object& tds_data() const;
/// @}
};

View File

@ -0,0 +1,14 @@
@INCLUDE = ${CGAL_DOC_PACKAGE_DEFAULTS}
EXTRACT_PRIVATE = NO
EXAMPLE_PATH = ${CGAL_PACKAGE_DIR}/examples
PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - 2D Hyperbolic Delaunay Triangulations"
HTML_EXTRA_STYLESHEET = ${CGAL_PACKAGE_DOC_DIR}/css/customstyle.css
HTML_EXTRA_FILES = ${CGAL_PACKAGE_DOC_DIR}/fig/ht-empty-disks.svg \
${CGAL_PACKAGE_DOC_DIR}/fig/poincare-disk.svg \
${CGAL_PACKAGE_DOC_DIR}/fig/header.png \
${CGAL_PACKAGE_DOC_DIR}/fig/hyperbolic-vs-euclidean.svg

View File

@ -0,0 +1,188 @@
\page Chapter_2D_Hyperbolic_Triangulations 2D Hyperbolic Delaunay Triangulations
namespace CGAL {
/*!
\mainpage User Manual
\anchor Chapter_2D_Hyperbolic_Triangulations
\anchor ChapterHTriangulation2
\cgalAutoToc
\author Mikhail Bogdanov, Iordan Iordanov, and Monique Teillaud
<center>
<img src="header.png" style="max-width:50%; width=50%;"/>
</center>
This package enables the computation of Delaunay triangulations of
point sets in the Poincar&eacute; disk model of the hyperbolic plane.
\section HT2_Poincare_model The Poincar&eacute; Disk Model of the Hyperbolic Plane
The Poincar&eacute; disk model represents the hyperbolic plane
\f$\mathbb H^2\f$ in the unit disk centered at the origin in the Euclidean plane: points of
\f$\mathbb H^2\f$ lie in the interior of the disk, while its boundary,
the unit circle, represents the set \f$\mathcal
H_\infty\f$ of points at infinity.
In this model, a hyperbolic line is either an arc of circle
perpendicular to the unit circle or, if it passes through the origin,
a diameter of the unit disk. A hyperbolic circle is a Euclidean
circle contained in the unit disk; however, its hyperbolic center and radius
are not the same as its Euclidean center and radius.
\cgalFigureAnchor{Hyperbolic_triangulation_2Poincare_disk}
<center>
<img src="poincare-disk.svg" style="max-width:27%; width=27%;"/>
</center>
\cgalFigureCaptionBegin{Hyperbolic_triangulation_2Poincare_disk}
The Poincar&eacute; disk model for the hyperbolic plane. The figure shows
two hyperbolic lines and three concentric hyperbolic circles with different
radii.
\cgalFigureCaptionEnd
\section HT2_Euclidean_and_hyperbolic_Delaunay_triangulations Euclidean and Hyperbolic Delaunay Triangulations
As hyperbolic circles coincide with Euclidean circles contained in the
unit disk, the combinatorial structure of the hyperbolic Delaunay
triangulation of a set \f$\mathcal P\f$ of points in \f$\mathbb H^2\f$
is a subset of the Euclidean Delaunay triangulation of \f$\mathcal
P\f$ (see
\cgalFigureRef{Hyperbolic_triangulation_2Euclidean_vs_hyperbolic} - Left). More
precisely, the hyperbolic Delaunay triangulation of \f$\mathcal P\f$ only
contains the simplices of the Euclidean Delaunay triangulation that
are <i>hyperbolic</i>:
<ul>
<li> A Euclidean Delaunay face is hyperbolic if its
circumscribing circle is contained in \f$\mathbb H^2\f$.
<li> A Euclidean Delaunay edge is hyperbolic if one of the
empty disks (i.e., not containing any point of \f$\mathcal
P\f$) passing through its endpoints is contained in \f$\mathbb
H^2\f$.
</ul>
In the Euclidean Delaunay triangulation, there is a bijection between
non-hyperbolic faces and non-hyperbolic
edges&nbsp;\cgalCite{cgal:bdt-hdcvd-14}, illustrated by
\cgalFigureRef{Hyperbolic_triangulation_2Euclidean_vs_hyperbolic} - Right.
\cgalFigureAnchor{Hyperbolic_triangulation_2Euclidean_vs_hyperbolic}
<center>
<img src="hyperbolic-vs-euclidean.svg" style="max-width:27%; width=27%; display: inline-block; text-align:right;"/>
<img src="ht-empty-disks.svg" style="max-width:30%; width=30%; display: inline-block; text-align:left;"/>
</center>
\cgalFigureCaptionBegin{Hyperbolic_triangulation_2Euclidean_vs_hyperbolic}
<b>Left:</b> The Euclidean (red) and hyperbolic (black) Delaunay triangulations
of a given set of points in the unit disk. Only the colored faces
are faces of the hyperbolic Delaunay triangulation. The hyperbolic
and Euclidean geometric embeddings of a Delaunay face that exists
in both triangulations are different.
<b>Right:</b> The shaded face is non-hyperbolic. Its dashed edge is non-hyperbolic,
as no empty circle through its endpoints is contained in
\f$\mathbb H^2\f$. Its other two edges are hyperbolic.
\cgalFigureCaptionEnd
The hyperbolic Delaunay triangulation is a simplicial complex, i.e., a set of simplices such that
<ul>
<li>any face of a simplex is a simplex,
<li>two simplices either are disjoint or share a common face.
</ul>
Moreover, it is connected&nbsp;\cgalCite{cgal:bdt-hdcvd-14}.
\section HT2_Software_design Software Design
From what was said above, it is natural that the class
`Hyperbolic_Delaunay_triangulation_2` privately inherits from the class
`Delaunay_triangulation_2`. Consequently, users are encouraged to look at Chapter
\ref Chapter_2D_Triangulations "2D Triangulation" of the %CGAL manual to
know more in particular about the representation of triangulations in
CGAL and the flexibility of the design.
The class `Hyperbolic_Delaunay_triangulation_2` has two template
parameters:
<ul>
<li> A <b>geometric traits</b> class `Gt`, which provides geometric
primitives. The requirements on this first template parameter
are described by the concept
`HyperbolicDelaunayTriangulationTraits_2`, which refines
`DelaunayTriangulationTraits_2`.
<li> A <b>triangulation data structure</b> parameter, for which the
requirements are described by the concept
`TriangulationDataStructure_2`. The default for this second template parameter
is `Triangulation_data_structure_2< Triangulation_vertex_base_2<Gt>, Hyperbolic_triangulation_face_base_2<Gt> >`.
</ul>
Two models of the concept `HyperbolicDelaunayTriangulationTraits_2`
are proposed for the geometric traits
class. The first one, `CGAL::Hyperbolic_Delaunay_triangulation_CK_traits_2`, is based
upon `CGAL::Circular_kernel_2` and guarantees exact constructions of
Delaunay triangulations and dual objects when the input points have
rational coordinates. The second one,
`CGAL::Hyperbolic_Delaunay_triangulation_traits_2`, is more general,
as it guarantees exact constructions even for input points with
algebraic coordinates; however the first model is more efficient for
rational points.
\section Examples
The example below shows insertion of random points in a hyperbolic Delaunay triangulation.
The same set of points is inserted twice. The first time points are inserted one by one,
which causes Euclidean faces to be filtered at each insertion. The second time, all points
are inserted and the filtering is done once at the end.
\cgalExample{Hyperbolic_triangulation_2/ht2_example.cpp}
The example below shows how user-defined info can be added to the hyperbolic faces.
\cgalExample{Hyperbolic_triangulation_2/ht2_example_color.cpp}
\section HT2_Performance Performance
We have measured the insertion execution time of our implementation
with both traits classes `CGAL::Hyperbolic_Delaunay_triangulation_CK_traits_2`
and `CGAL::Hyperbolic_Delaunay_triangulation_traits_2` with their default template
parameters against the insertion time in a Euclidean \cgal triangulation.
We generate 1 million random points, uniformly distributed in the unit disk with respect
to the Euclidean metric. We insert the same set of points in three triangulations:
<ul>
<li> a hyperbolic Delaunay triangulation with `CGAL::Hyperbolic_Delaunay_triangulation_traits_2` (%CORE traits) as traits class;
<li> a hyperbolic Delaunay triangulation with `CGAL::Hyperbolic_Delaunay_triangulation_CK_traits_2` (CK traits) as traits class;
<li> a Euclidean Delaunay triangulation with `CGAL::Exact_predicates_inexact_constructions_kernel` (EPICK) as traits class.
</ul>
We create two instances of each type of triangulation. In one instance we insert the points one by one, which causes
non-hyperbolic faces to be filtered out at each insertion. In the other instance we insert the points via iterator
input, which causes non-hyperbolic faces to be filtered only once, after all points have been inserted. We report
results averaged over 10 executions of this experiment in \ref HT2_Table_1 "Table 1" below. The experiments have been
executed on two machines:
<ul>
<li> <b>Machine 1:</b> MacBook Pro (2015), CPU: Intel Core i5 @ 2.9 GHz, RAM: 16 GB @ 1867 MHz, OS: Mac OS X (10.10.5), Compiler: gcc version 7.3.0;
<li> <b>Machine 2:</b> Dell Vostro 5471 (2018), CPU: Intel Core i5 @ 1.6 GHZ (up to 3.4 GHz in TurboMode), RAM: 8GB @ 2400 MHz, OS: Ubuntu 18.04 (kernel 4.15.0), Compiler: gcc version 7.3.0.
</ul>
<center>
\anchor HT2_Table_1
<table>
<caption>Table 1: Comparison of insertion times of 1 million random points</caption>
<tr><th> %Triangulation type <th colspan="2"> Machine 1 <th colspan="2"> Machine 2
<tr><td> <td> Sequential insertion <td> %Iterator insertion <td> Sequential insertion <td> %Iterator insertion
<tr><td> Hyperbolic (%CORE traits) <td> 955 sec. <td> 23 sec. <td> 884 sec. <td> 20 sec.
<tr><td> Hyperbolic (CK traits) <td> 330 sec. <td> 1 sec. <td> 289 sec. <td> 1 sec.
<tr><td> Euclidean (EPICK) <td> 131 sec. <td> 0.71 sec. <td> 114 sec. <td> 0.68 sec.
</table>
</center>
\section HT2_Design Design and Implementation History
This package implements the algorithms for computing Delaunay complexes
in the hyperbolic plane, described by Mikhail Bogdanov, Olivier
Devillers, and Monique Teillaud \cgalCite{cgal:bdt-hdcvd-14}.
Mikhail Bogdanov wrote most of the code. Iordan Iordanov added the
traits class `CGAL::Hyperbolic_Delaunay_triangulation_traits_2` and
worked on the documentations. Both were PhD candidates advised by
Monique Teillaud.
Authors acknowledge partial support from <a href="https://members.loria.fr/Monique.Teillaud/collab/SoS/">ANR SoS</a>.
*/
} /* namespace CGAL */
\\\\\\\\\\\\

View File

@ -0,0 +1,64 @@
/// \defgroup PkgHyperbolicTriangulation2Ref 2D Hyperbolic Delaunay Triangulations Reference
/// \defgroup PkgHyperbolicTriangulation2Concepts Concepts
/// \ingroup PkgHyperbolicTriangulation2Ref
/// \defgroup PkgHyperbolicTriangulation2MainClasses Main Classes
/// \ingroup PkgHyperbolicTriangulation2Ref
/// \defgroup PkgHyperbolicTriangulation2TraitsClasses Traits Classes
/// \ingroup PkgHyperbolicTriangulation2Ref
/// \defgroup PkgHyperbolicTriangulation2VertexFaceClasses Face Classes
/// \ingroup PkgHyperbolicTriangulation2Ref
/*!
\addtogroup PkgHyperbolicTriangulation2Ref
\cgalPkgDescriptionBegin{2D Hyperbolic Delaunay Triangulations,PkgHyperbolicTriangulation2}
\cgalPkgPicture{Hyperbolic_triangulation_2/fig/ht-120px.png}
\cgalPkgSummaryBegin
\cgalPkgAuthor{Mikhail Bogdanov, Iordan Iordanov, and Monique Teillaud}
\cgalPkgDesc{This package enables building and handling Delaunay triangulations of point sets
in the Poincar&eacute; disk model of the hyperbolic plane. Triangulations are built incrementally and can be modified by insertion
and removal of vertices; point location facilities are also offered, as well as primitives to
build the dual Voronoi diagrams.}
\cgalPkgManuals{Chapter_2D_Hyperbolic_Triangulations,PkgHyperbolicTriangulation2Ref}
\cgalPkgSummaryEnd
\cgalPkgShortInfoBegin
\cgalPkgSince{4.14}
\cgalPkgDependsOn{\ref PkgTriangulation2}
\cgalPkgBib{cgal:bt-ht2-17}
\cgalPkgLicense{\ref licensesGPL "GPL"}
\cgalPkgDemo{Hyperbolic Delaunay Triangulation,Hyperbolic_Delaunay_triangulation_2.zip}
\cgalPkgShortInfoEnd
\cgalPkgDescriptionEnd
The Delaunay triangulation of a set of points \f$P\f$ in the hyperbolic plane \f$\mathbb H^2\f$ is a two-dimensional connected simplicial complex with vertex set defined by the points \f$P\f$.
\cgalClassifedRefPages
## Concepts ##
- `HyperbolicDelaunayTriangulationTraits_2` describes the requirements for an interface for geometric objects, constructions, and predicates in the hyperbolic plane.
- `HyperbolicTriangulationFaceBase_2` describes the requirements for faces of the hyperbolic Delaunay triangulation to be filtered from the faces of the Euclidean Delaunay triangulation.
## Classes ##
- `CGAL::Hyperbolic_Delaunay_triangulation_2` is the main class of the 2D Hyperbolic Triangulation package. It enables the constructions of Delaunay triangulations in the hyperbolic plane. It offers all the functionalities provided by `CGAL::Delaunay_triangulation_2`, such as point location, insertion, and removal. Construction of the dual Voronoi diagram is also provided.
- `CGAL::Hyperbolic_triangulation_face_base_2`
Two models for the concept `HyperbolicDelaunayTriangulationTraits_2` are provided:
- `CGAL::Hyperbolic_Delaunay_triangulation_traits_2` is by default based upon `CGAL::Exact_predicates_exact_constructions_kernel_with_sqrt` and guarantees exact constructions of Delaunay triangulations and dual objects for input points with algebraic coordinates.
- `CGAL::Hyperbolic_Delaunay_triangulation_CK_traits_2` is based upon `CGAL::Circular_kernel_2` and guarantees exact constructions of Delaunay triangulations and dual objects when the input points have rational coordinates.
The model `CGAL::Hyperbolic_Delaunay_triangulation_CK_traits_2` is faster than `CGAL::Hyperbolic_Delaunay_triangulation_traits_2` for points with rational coordinates.
*/

View File

@ -0,0 +1,4 @@
.image {
display: inline;
}

View File

@ -0,0 +1,13 @@
Kernel_23
Manual
STL_Extension
Algebraic_foundations
Circulator
Stream_support
TDS_2
Triangulation_2
Triangulation
Spatial_sorting
Circular_kernel_2
Number_types
Periodic_4_hyperbolic_triangulation_2

View File

@ -0,0 +1,4 @@
/*!
\example Hyperbolic_triangulation_2/ht2_example.cpp
\example Hyperbolic_triangulation_2/ht2_example_color.cpp
*/

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="364pt" height="325pt" viewBox="0 0 364 325" version="1.1">
<g id="surface1">
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(100%,84.3%,0%);fill-opacity:1;" d="M 120.945312 77.144531 C 166.851562 89.933594 215.964844 74.164062 245.84375 37.039062 C 203.269531 97.550781 146.648438 146.832031 80.839844 180.648438 L 80.839844 180.652344 C 104.625 151.144531 118.640625 114.96875 120.945312 77.140625 Z M 120.945312 77.144531 "/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 196.629344 357.685 C 193.352 368.286563 185.187938 376.673281 174.672313 380.227969 C 164.160594 383.782656 152.578563 382.075625 143.5395 375.634219 " transform="matrix(1,0,0,-1,-91.727,646.81)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 196.629344 357.685 C 205.902781 395.618594 197.012156 435.704531 172.566844 466.157656 " transform="matrix(1,0,0,-1,-91.727,646.81)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 143.5395 375.638125 C 165.977 400.118594 176.582469 433.192813 172.566844 466.157656 " transform="matrix(1,0,0,-1,-91.727,646.81)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 143.5395 375.638125 C 151.590281 386.337344 153.453563 400.474063 148.453563 412.899844 C 143.453563 425.325625 132.316844 434.227969 119.094188 436.364688 " transform="matrix(1,0,0,-1,-91.727,646.81)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 119.094188 436.364688 C 137.88325 444.454531 155.801219 454.435 172.566844 466.157656 " transform="matrix(1,0,0,-1,-91.727,646.81)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 119.094188 436.364688 C 129.816844 449.77875 129.332469 468.962344 117.949656 481.817813 " transform="matrix(1,0,0,-1,-91.727,646.81)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 172.566844 466.157656 C 155.277781 474.165469 136.852 479.446719 117.949656 481.817813 " transform="matrix(1,0,0,-1,-91.727,646.81)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 117.949656 481.817813 C 128.855906 490.048281 135.547313 502.696719 136.211375 516.345156 C 136.875438 529.993594 131.44575 543.231875 121.387156 552.477969 " transform="matrix(1,0,0,-1,-91.727,646.81)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 172.566844 466.157656 C 169.734813 501.286563 150.848094 533.142031 121.387156 552.477969 " transform="matrix(1,0,0,-1,-91.727,646.81)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 121.387156 552.477969 C 152.69575 541.423281 187.527781 547.981875 212.672313 569.665469 " transform="matrix(1,0,0,-1,-91.727,646.81)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 212.668406 569.665469 C 205.062938 588.431094 197.043406 607.024844 188.605906 625.431094 " transform="matrix(1,0,0,-1,-91.727,646.81)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 212.672313 569.665469 C 229.187938 583.642031 240.273875 602.974063 243.992625 624.286563 " transform="matrix(1,0,0,-1,-91.727,646.81)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 188.609813 625.431094 C 194.809031 616.356875 205.016063 610.833438 216.004344 610.606875 C 226.996531 610.380313 237.418406 615.474063 243.992625 624.286563 " transform="matrix(1,0,0,-1,-91.727,646.81)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 212.672313 569.665469 C 247.168406 571.005313 278.394969 590.46625 294.7895 620.849063 " transform="matrix(1,0,0,-1,-91.727,646.81)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 243.992625 624.286563 C 257.160594 609.493594 279.750437 607.962344 294.7895 620.849063 " transform="matrix(1,0,0,-1,-91.727,646.81)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 294.7895 620.849063 C 298.496531 613.188906 305.379344 607.544375 313.617625 605.411563 C 321.855906 603.27875 330.613719 604.8725 337.57075 609.770938 " transform="matrix(1,0,0,-1,-91.727,646.81)"/>
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(0%,0%,100%);fill-opacity:1;" d="M 107.902344 289.125 C 107.902344 285.125 101.902344 285.125 101.902344 289.125 C 101.902344 293.125 107.902344 293.125 107.902344 289.125 Z M 107.902344 289.125 "/>
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(0%,0%,100%);fill-opacity:1;" d="M 54.8125 271.171875 C 54.8125 267.171875 48.8125 267.171875 48.8125 271.171875 C 48.8125 275.171875 54.8125 275.171875 54.8125 271.171875 Z M 54.8125 271.171875 "/>
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(0%,0%,100%);fill-opacity:1;" d="M 30.367188 210.445312 C 30.367188 206.445312 24.367188 206.445312 24.367188 210.445312 C 24.367188 214.445312 30.367188 214.445312 30.367188 210.445312 Z M 30.367188 210.445312 "/>
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(0%,0%,100%);fill-opacity:1;" d="M 29.222656 164.992188 C 29.222656 160.992188 23.222656 160.992188 23.222656 164.992188 C 23.222656 168.992188 29.222656 168.992188 29.222656 164.992188 Z M 29.222656 164.992188 "/>
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(0%,0%,100%);fill-opacity:1;" d="M 32.660156 94.332031 C 32.660156 90.332031 26.660156 90.332031 26.660156 94.332031 C 26.660156 98.332031 32.660156 98.332031 32.660156 94.332031 Z M 32.660156 94.332031 "/>
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(0%,0%,100%);fill-opacity:1;" d="M 99.882812 21.378906 C 99.882812 17.378906 93.882812 17.378906 93.882812 21.378906 C 93.882812 25.378906 99.882812 25.378906 99.882812 21.378906 Z M 99.882812 21.378906 "/>
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(0%,0%,100%);fill-opacity:1;" d="M 155.265625 22.523438 C 155.265625 18.523438 149.265625 18.523438 149.265625 22.523438 C 149.265625 26.523438 155.265625 26.523438 155.265625 22.523438 Z M 155.265625 22.523438 "/>
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(0%,0%,100%);fill-opacity:1;" d="M 206.0625 25.960938 C 206.0625 21.960938 200.0625 21.960938 200.0625 25.960938 C 200.0625 29.960938 206.0625 29.960938 206.0625 25.960938 Z M 206.0625 25.960938 "/>
<path style="fill:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 253.793406 645.31 C 165.113719 645.31 93.227 573.423281 93.227 484.743594 C 93.227 396.063906 165.113719 324.177188 253.793406 324.177188 C 342.473094 324.177188 414.359812 396.063906 414.359812 484.743594 C 414.359812 573.423281 342.473094 645.31 253.793406 645.31 Z M 253.793406 645.31 " transform="matrix(1,0,0,-1,-91.727,646.81)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 212.672313 569.665469 C 258.578562 556.876406 307.691844 572.645938 337.57075 609.770938 " transform="matrix(1,0,0,-1,-91.727,646.81)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 172.566844 466.157656 C 196.352 495.665469 210.367625 531.84125 212.672313 569.669375 " transform="matrix(1,0,0,-1,-91.727,646.81)"/>
<path style="fill:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(100%,64.7%,0%);stroke-opacity:1;stroke-dasharray:4;stroke-miterlimit:10;" d="M 172.566844 466.161563 C 238.375438 499.977969 294.996531 549.259219 337.57075 609.770938 " transform="matrix(1,0,0,-1,-91.727,646.81)"/>
<path style="fill:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(100%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 313.137156 611.911563 C 235.492625 611.911563 172.551219 548.970156 172.551219 471.325625 C 172.551219 393.681094 235.492625 330.739688 313.137156 330.739688 C 390.781687 330.739688 453.723094 393.681094 453.723094 471.325625 C 453.723094 548.970156 390.781687 611.911563 313.137156 611.911563 Z M 313.137156 611.911563 " transform="matrix(1,0,0,-1,-91.727,646.81)"/>
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(0%,0%,100%);fill-opacity:1;" d="M 83.839844 180.652344 C 83.839844 176.652344 77.839844 176.652344 77.839844 180.652344 C 77.839844 184.652344 83.839844 184.652344 83.839844 180.652344 Z M 83.839844 180.652344 "/>
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(0%,0%,100%);fill-opacity:1;" d="M 123.945312 77.144531 C 123.945312 73.144531 117.945312 73.144531 117.945312 77.144531 C 117.945312 81.144531 123.945312 81.144531 123.945312 77.144531 Z M 123.945312 77.144531 "/>
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(0%,0%,100%);fill-opacity:1;" d="M 248.84375 37.039062 C 248.84375 33.039062 242.84375 33.039062 242.84375 37.039062 C 242.84375 41.039062 248.84375 41.039062 248.84375 37.039062 Z M 248.84375 37.039062 "/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.9 KiB

View File

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="325pt" height="325pt" viewBox="0 0 325 325" version="1.1">
<g id="surface1">
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(93.3%,51%,93.3%);fill-opacity:0.3;" d="M 120.945312 77.144531 C 113.34375 58.378906 105.320312 39.785156 96.882812 21.378906 C 103.085938 30.453125 113.289062 35.976562 124.28125 36.203125 C 135.269531 36.429688 145.695312 31.335938 152.265625 22.523438 C 165.433594 37.316406 188.023438 38.847656 203.066406 25.960938 C 206.773438 33.621094 213.65625 39.265625 221.890625 41.398438 C 230.128906 43.53125 238.886719 41.9375 245.84375 37.039062 C 215.964844 74.160156 166.851562 89.929688 120.945312 77.140625 Z M 120.945312 77.144531 "/>
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(93.3%,51%,93.3%);fill-opacity:0.3;" d="M 104.90625 289.125 C 101.628906 278.523438 93.460938 270.136719 82.945312 266.582031 C 72.433594 263.027344 60.851562 264.734375 51.8125 271.175781 L 51.8125 271.171875 C 59.863281 260.46875 61.730469 246.335938 56.726562 233.910156 C 51.726562 221.484375 40.589844 212.582031 27.367188 210.441406 L 27.367188 210.445312 C 38.089844 197.03125 37.605469 177.847656 26.222656 164.992188 C 37.132812 156.761719 43.820312 144.113281 44.488281 130.464844 C 45.152344 116.816406 39.71875 103.578125 29.660156 94.332031 L 29.660156 94.328125 C 60.96875 105.386719 95.800781 98.828125 120.945312 77.140625 L 120.945312 77.144531 C 118.640625 114.972656 104.625 151.144531 80.839844 180.652344 L 80.84375 180.652344 C 105.285156 211.105469 114.179688 251.191406 104.90625 289.125 Z M 104.90625 289.125 "/>
<path style="fill:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 205.792335 645.309805 C 117.112648 645.309805 45.225929 573.423086 45.225929 484.743399 C 45.225929 396.063711 117.112648 324.176992 205.792335 324.176992 C 294.472023 324.176992 366.358741 396.063711 366.358741 484.743399 C 366.358741 573.423086 294.472023 645.309805 205.792335 645.309805 Z M 205.792335 645.309805 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 148.628273 357.684805 C 145.354835 368.286367 137.186866 376.673086 126.671241 380.227774 C 116.159523 383.782461 104.577491 382.07543 95.538429 375.63793 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 148.632179 357.684805 C 157.905616 395.618399 149.011085 435.704336 124.565773 466.157461 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 95.538429 375.63793 C 117.975929 400.118399 128.581398 433.192617 124.565773 466.157461 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 95.538429 375.63793 C 103.58921 386.341055 105.456398 400.473867 100.452491 412.899649 C 95.452491 425.32543 84.315773 434.227774 71.093116 436.364492 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 71.093116 436.368399 C 89.886085 444.454336 107.800148 454.434805 124.565773 466.157461 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 71.093116 436.364492 C 81.815773 449.778555 81.331398 468.962149 69.948585 481.817617 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 124.565773 466.157461 C 107.27671 474.165274 88.854835 479.446524 69.948585 481.817617 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 69.948585 481.817617 C 80.858741 490.048086 87.546241 502.696524 88.210304 516.344961 C 88.874366 529.993399 83.444679 543.23168 73.386085 552.477774 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 124.565773 466.157461 C 121.733741 501.286367 102.847023 533.141836 73.386085 552.477774 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 124.565773 466.157461 C 148.350929 495.665274 162.366554 531.837149 164.671241 569.665274 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 73.386085 552.477774 C 104.694679 541.423086 139.52671 547.98168 164.671241 569.665274 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 164.667335 569.665274 C 157.065773 588.430899 149.042335 607.024649 140.604835 625.430899 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 164.671241 569.665274 C 181.186866 583.641836 192.272804 602.973867 195.991554 624.286367 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 140.608741 625.430899 C 146.811866 616.35668 157.014991 610.833242 168.007179 610.60668 C 178.99546 610.380117 189.421241 615.473867 195.991554 624.286367 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 164.671241 569.665274 C 199.171241 571.005117 230.393898 590.466055 246.792335 620.848867 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 195.991554 624.286367 C 209.159523 609.493399 231.749366 607.962149 246.792335 620.848867 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 164.671241 569.66918 C 210.577491 556.876211 259.690773 572.649649 289.569679 609.770742 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 246.792335 620.848867 C 250.49546 613.188711 257.382179 607.54418 265.616554 605.411367 C 273.854835 603.278555 282.612648 604.872305 289.569679 609.770742 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style="fill:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(100%,0%,0%);stroke-opacity:1;stroke-dasharray:4;stroke-miterlimit:10;" d="M 246.792335 620.848867 L 289.569679 609.770742 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style="fill:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(100%,0%,0%);stroke-opacity:1;stroke-dasharray:4;stroke-miterlimit:10;" d="M 195.991554 624.286367 L 164.671241 569.66918 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style="fill:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(100%,0%,0%);stroke-opacity:1;stroke-dasharray:4;stroke-miterlimit:10;" d="M 164.671241 569.66918 L 246.792335 620.848867 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style="fill:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(100%,0%,0%);stroke-opacity:1;stroke-dasharray:4;stroke-miterlimit:10;" d="M 195.991554 624.286367 L 246.792335 620.848867 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style="fill:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(100%,0%,0%);stroke-opacity:1;stroke-dasharray:4;stroke-miterlimit:10;" d="M 164.671241 569.66918 L 124.565773 466.157461 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style="fill:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(100%,0%,0%);stroke-opacity:1;stroke-dasharray:4;stroke-miterlimit:10;" d="M 289.569679 609.770742 L 164.671241 569.66918 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style="fill:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(100%,0%,0%);stroke-opacity:1;stroke-dasharray:4;stroke-miterlimit:10;" d="M 124.565773 466.157461 L 289.569679 609.770742 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style="fill:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(100%,0%,0%);stroke-opacity:1;stroke-dasharray:4;stroke-miterlimit:10;" d="M 140.608741 625.430899 L 195.991554 624.286367 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style="fill:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(100%,0%,0%);stroke-opacity:1;stroke-dasharray:4;stroke-miterlimit:10;" d="M 140.608741 625.430899 L 164.671241 569.66918 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style="fill:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(100%,0%,0%);stroke-opacity:1;stroke-dasharray:4;stroke-miterlimit:10;" d="M 73.386085 552.48168 L 140.608741 625.430899 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style="fill:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(100%,0%,0%);stroke-opacity:1;stroke-dasharray:4;stroke-miterlimit:10;" d="M 73.386085 552.48168 L 124.565773 466.157461 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style="fill:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(100%,0%,0%);stroke-opacity:1;stroke-dasharray:4;stroke-miterlimit:10;" d="M 164.671241 569.66918 L 73.386085 552.48168 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style="fill:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(100%,0%,0%);stroke-opacity:1;stroke-dasharray:4;stroke-miterlimit:10;" d="M 69.948585 481.817617 L 73.386085 552.48168 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style="fill:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(100%,0%,0%);stroke-opacity:1;stroke-dasharray:4;stroke-miterlimit:10;" d="M 124.565773 466.157461 L 69.948585 481.817617 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style="fill:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(100%,0%,0%);stroke-opacity:1;stroke-dasharray:4;stroke-miterlimit:10;" d="M 124.565773 466.157461 L 71.093116 436.368399 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style="fill:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(100%,0%,0%);stroke-opacity:1;stroke-dasharray:4;stroke-miterlimit:10;" d="M 289.569679 609.770742 L 148.628273 357.684805 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style="fill:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(100%,0%,0%);stroke-opacity:1;stroke-dasharray:4;stroke-miterlimit:10;" d="M 71.093116 436.368399 L 69.948585 481.817617 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style="fill:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(100%,0%,0%);stroke-opacity:1;stroke-dasharray:4;stroke-miterlimit:10;" d="M 148.628273 357.684805 L 124.565773 466.157461 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style="fill:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(100%,0%,0%);stroke-opacity:1;stroke-dasharray:4;stroke-miterlimit:10;" d="M 95.538429 375.63793 L 148.628273 357.684805 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style="fill:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(100%,0%,0%);stroke-opacity:1;stroke-dasharray:4;stroke-miterlimit:10;" d="M 124.565773 466.157461 L 95.538429 375.63793 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style="fill:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(100%,0%,0%);stroke-opacity:1;stroke-dasharray:4;stroke-miterlimit:10;" d="M 95.538429 375.63793 L 71.093116 436.368399 " transform="matrix(1,0,0,-1,-43.725929,646.809805)"/>
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(0%,0%,100%);fill-opacity:1;" d="M 107.902344 289.125 C 107.902344 285.125 101.902344 285.125 101.902344 289.125 C 101.902344 293.125 107.902344 293.125 107.902344 289.125 Z M 107.902344 289.125 "/>
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(0%,0%,100%);fill-opacity:1;" d="M 54.8125 271.171875 C 54.8125 267.171875 48.8125 267.171875 48.8125 271.171875 C 48.8125 275.171875 54.8125 275.171875 54.8125 271.171875 Z M 54.8125 271.171875 "/>
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(0%,0%,100%);fill-opacity:1;" d="M 83.839844 180.652344 C 83.839844 176.652344 77.839844 176.652344 77.839844 180.652344 C 77.839844 184.652344 83.839844 184.652344 83.839844 180.652344 Z M 83.839844 180.652344 "/>
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(0%,0%,100%);fill-opacity:1;" d="M 30.367188 210.445312 C 30.367188 206.445312 24.367188 206.445312 24.367188 210.445312 C 24.367188 214.445312 30.367188 214.445312 30.367188 210.445312 Z M 30.367188 210.445312 "/>
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(0%,0%,100%);fill-opacity:1;" d="M 29.222656 164.992188 C 29.222656 160.992188 23.222656 160.992188 23.222656 164.992188 C 23.222656 168.992188 29.222656 168.992188 29.222656 164.992188 Z M 29.222656 164.992188 "/>
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(0%,0%,100%);fill-opacity:1;" d="M 32.660156 94.332031 C 32.660156 90.332031 26.660156 90.332031 26.660156 94.332031 C 26.660156 98.332031 32.660156 98.332031 32.660156 94.332031 Z M 32.660156 94.332031 "/>
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(0%,0%,100%);fill-opacity:1;" d="M 123.945312 77.144531 C 123.945312 73.144531 117.945312 73.144531 117.945312 77.144531 C 117.945312 81.144531 123.945312 81.144531 123.945312 77.144531 Z M 123.945312 77.144531 "/>
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(0%,0%,100%);fill-opacity:1;" d="M 99.882812 21.378906 C 99.882812 17.378906 93.882812 17.378906 93.882812 21.378906 C 93.882812 25.378906 99.882812 25.378906 99.882812 21.378906 Z M 99.882812 21.378906 "/>
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(0%,0%,100%);fill-opacity:1;" d="M 155.265625 22.523438 C 155.265625 18.523438 149.265625 18.523438 149.265625 22.523438 C 149.265625 26.523438 155.265625 26.523438 155.265625 22.523438 Z M 155.265625 22.523438 "/>
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(0%,0%,100%);fill-opacity:1;" d="M 206.066406 25.960938 C 206.066406 21.960938 200.066406 21.960938 200.066406 25.960938 C 200.066406 29.960938 206.066406 29.960938 206.066406 25.960938 Z M 206.066406 25.960938 "/>
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(0%,0%,100%);fill-opacity:1;" d="M 248.84375 37.039062 C 248.84375 33.039062 242.84375 33.039062 242.84375 37.039062 C 242.84375 41.039062 248.84375 41.039062 248.84375 37.039062 Z M 248.84375 37.039062 "/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="260pt" height="260pt" viewBox="0 0 260 260" version="1.1">
<defs>
<g>
<symbol overflow="visible" id="glyph0-0">
<path style="stroke:none;" d=""/>
</symbol>
<symbol overflow="visible" id="glyph0-1">
<path style="stroke:none;" d="M 4.75 -4.8125 C 4.9375 -5.484375 5.125 -6.203125 5.265625 -6.90625 C 5.4375 -7.859375 5.53125 -8.828125 5.53125 -9 C 5.53125 -9.796875 4.75 -9.796875 4.578125 -9.796875 C 3.484375 -9.796875 2.515625 -9.390625 1.84375 -8.9375 C 0.671875 -8.140625 0.296875 -7.1875 0.296875 -7.109375 C 0.296875 -7.015625 0.40625 -7.015625 0.4375 -7.015625 C 0.5625 -7.015625 1.234375 -7.1875 1.53125 -7.734375 C 1.921875 -8.46875 2.34375 -9.015625 3.625 -9.015625 C 4.21875 -9.015625 4.3125 -8.609375 4.3125 -8.375 C 4.3125 -8.359375 4.28125 -7.6875 4.109375 -6.703125 C 4.03125 -6.296875 3.984375 -6.03125 3.6875 -4.8125 L 3.171875 -4.8125 C 2.765625 -4.796875 2.109375 -4.328125 2.109375 -4.109375 C 2.109375 -4.03125 2.125 -4.015625 2.4375 -4.015625 L 3.46875 -4.015625 C 3.171875 -3.015625 2.765625 -1.640625 2.109375 0.109375 C 1.984375 0.4375 1.984375 0.46875 1.984375 0.484375 C 1.984375 0.59375 2.09375 0.59375 2.125 0.59375 C 2.328125 0.59375 2.765625 0.40625 3.0625 0.109375 C 3.125 0.03125 3.15625 0 3.21875 -0.140625 C 3.71875 -1.40625 4.140625 -2.703125 4.515625 -4.015625 L 7.75 -4.015625 C 7.90625 -4.015625 8.171875 -4.015625 8.40625 -4.15625 C 8.25 -3.5625 7.65625 -1.21875 7.65625 -0.09375 C 7.65625 0.328125 7.90625 0.703125 8.515625 0.703125 C 10.421875 0.703125 11.484375 -0.484375 11.484375 -0.953125 C 11.484375 -1.03125 11.421875 -1.0625 11.34375 -1.0625 C 11.234375 -1.0625 10.46875 -0.859375 10.25 -0.296875 C 10.203125 -0.1875 10.1875 -0.171875 9.90625 -0.125 C 9.75 -0.09375 9.484375 -0.09375 9.46875 -0.09375 C 9.203125 -0.09375 8.875 -0.265625 8.875 -0.703125 C 8.875 -0.875 8.984375 -1.65625 9.015625 -1.984375 C 9.265625 -3.578125 9.96875 -6.265625 11.203125 -9.53125 C 11.25 -9.640625 11.25 -9.671875 11.25 -9.703125 C 11.25 -9.796875 11.15625 -9.796875 11.109375 -9.796875 C 10.890625 -9.796875 10.46875 -9.59375 10.203125 -9.359375 C 10.1875 -9.328125 10.09375 -9.25 10.046875 -9.125 C 9.46875 -7.71875 9.015625 -6.265625 8.59375 -4.8125 Z M 4.75 -4.8125 "/>
</symbol>
<symbol overflow="visible" id="glyph1-0">
<path style="stroke:none;" d=""/>
</symbol>
<symbol overflow="visible" id="glyph1-1">
<path style="stroke:none;" d="M 5.0625 -2.703125 C 4.53125 -3.375 4.40625 -3.53125 4.09375 -3.78125 C 3.53125 -4.234375 2.984375 -4.40625 2.46875 -4.40625 C 1.3125 -4.40625 0.546875 -3.3125 0.546875 -2.140625 C 0.546875 -1 1.28125 0.109375 2.4375 0.109375 C 3.578125 0.109375 4.40625 -0.796875 4.890625 -1.59375 C 5.4375 -0.921875 5.546875 -0.765625 5.859375 -0.515625 C 6.421875 -0.0625 6.984375 0.109375 7.484375 0.109375 C 8.65625 0.109375 9.40625 -0.984375 9.40625 -2.15625 C 9.40625 -3.296875 8.671875 -4.40625 7.53125 -4.40625 C 6.375 -4.40625 5.546875 -3.5 5.0625 -2.703125 Z M 5.328125 -2.359375 C 5.734375 -3.078125 6.46875 -4.09375 7.59375 -4.09375 C 8.65625 -4.09375 9.1875 -3.046875 9.1875 -2.15625 C 9.1875 -1.171875 8.515625 -0.375 7.640625 -0.375 C 7.0625 -0.375 6.625 -0.78125 6.40625 -1 C 6.15625 -1.265625 5.9375 -1.578125 5.328125 -2.359375 Z M 4.640625 -1.9375 C 4.234375 -1.21875 3.484375 -0.203125 2.359375 -0.203125 C 1.3125 -0.203125 0.765625 -1.25 0.765625 -2.140625 C 0.765625 -3.125 1.4375 -3.921875 2.3125 -3.921875 C 2.890625 -3.921875 3.34375 -3.515625 3.546875 -3.296875 C 3.796875 -3.03125 4.03125 -2.71875 4.640625 -1.9375 Z M 4.640625 -1.9375 "/>
</symbol>
<symbol overflow="visible" id="glyph2-0">
<path style="stroke:none;" d=""/>
</symbol>
<symbol overflow="visible" id="glyph2-1">
<path style="stroke:none;" d="M 10.40625 -6.28125 C 10.40625 -8.65625 8.859375 -10.09375 6.859375 -10.09375 C 3.78125 -10.09375 0.6875 -6.796875 0.6875 -3.484375 C 0.6875 -1.234375 2.1875 0.296875 4.265625 0.296875 C 7.265625 0.296875 10.40625 -2.84375 10.40625 -6.28125 Z M 4.34375 -0.03125 C 3.171875 -0.03125 1.921875 -0.890625 1.921875 -3.125 C 1.921875 -4.4375 2.390625 -6.5625 3.578125 -8 C 4.625 -9.265625 5.828125 -9.78125 6.78125 -9.78125 C 8.046875 -9.78125 9.265625 -8.859375 9.265625 -6.796875 C 9.265625 -5.515625 8.71875 -3.53125 7.765625 -2.171875 C 6.71875 -0.703125 5.40625 -0.03125 4.34375 -0.03125 Z M 4.34375 -0.03125 "/>
</symbol>
</g>
</defs>
<g id="surface1">
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,100%);stroke-opacity:1;stroke-miterlimit:10;" d="M 307.769531 336.398438 L 302.863281 334.285156 L 304.855469 329.652344 L 309.761719 331.765625 Z M 307.769531 336.398438 " transform="matrix(1,0,0,-1,-126.5,577.5)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,100%);stroke-opacity:1;stroke-miterlimit:10;" d="M 372.519531 500.988281 C 341.6875 486.964844 317.726562 461.226562 305.945312 429.472656 C 294.164062 397.71875 295.539062 362.574219 309.765625 331.839844 " transform="matrix(1,0,0,-1,-126.5,577.5)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,100%);stroke-opacity:1;stroke-miterlimit:10;" d="M 165.488281 357.488281 L 346.511719 538.511719 " transform="matrix(1,0,0,-1,-126.5,577.5)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,100%);stroke-opacity:1;stroke-miterlimit:10;" d="M 165.738281 364.929688 L 161.878906 361.234375 L 165.367188 357.589844 L 169.226562 361.285156 Z M 165.738281 364.929688 " transform="matrix(1,0,0,-1,-126.5,577.5)"/>
<path style="fill:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 384 448 C 384 518.691406 326.691406 576 256 576 C 185.308594 576 128 518.691406 128 448 C 128 377.308594 185.308594 320 256 320 C 326.691406 320 384 377.308594 384 448 Z M 384 448 " transform="matrix(1,0,0,-1,-126.5,577.5)"/>
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(18%,54.5%,34.1%);fill-opacity:1;" d="M 54.816406 40.414062 C 54.816406 36.414062 48.816406 36.414062 48.816406 40.414062 C 48.816406 44.414062 54.816406 44.414062 54.816406 40.414062 Z M 54.816406 40.414062 "/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(18%,54.5%,34.1%);stroke-opacity:1;stroke-miterlimit:10;" d="M 236.0625 514.859375 C 236.0625 536.046875 218.886719 553.222656 197.699219 553.222656 C 176.511719 553.222656 159.335938 536.046875 159.335938 514.859375 C 159.335938 493.671875 176.511719 476.496094 197.699219 476.496094 C 218.886719 476.496094 236.0625 493.671875 236.0625 514.859375 Z M 236.0625 514.859375 " transform="matrix(1,0,0,-1,-126.5,577.5)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(18%,54.5%,34.1%);stroke-opacity:1;stroke-miterlimit:10;" d="M 201.441406 529.914062 C 201.441406 539.234375 193.886719 546.789062 184.570312 546.789062 C 175.25 546.789062 167.695312 539.234375 167.695312 529.914062 C 167.695312 520.597656 175.25 513.042969 184.570312 513.042969 C 193.886719 513.042969 201.441406 520.597656 201.441406 529.914062 Z M 201.441406 529.914062 " transform="matrix(1,0,0,-1,-126.5,577.5)"/>
<path style="fill:none;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(18%,54.5%,34.1%);stroke-opacity:1;stroke-miterlimit:10;" d="M 187.914062 535.074219 C 187.914062 539.40625 184.402344 542.917969 180.070312 542.917969 C 175.738281 542.917969 172.226562 539.40625 172.226562 535.074219 C 172.226562 530.742188 175.738281 527.230469 180.070312 527.230469 C 184.402344 527.230469 187.914062 530.742188 187.914062 535.074219 Z M 187.914062 535.074219 " transform="matrix(1,0,0,-1,-126.5,577.5)"/>
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(0%,0%,100%);fill-opacity:1;" d="M 132.5 129.5 C 132.5 125.5 126.5 125.5 126.5 129.5 C 126.5 133.5 132.5 133.5 132.5 129.5 Z M 132.5 129.5 "/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-1" x="144.724" y="16.40017"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph1-1" x="156.84" y="18.55217"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph2-1" x="119.0963" y="124.692"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.2 KiB

View File

@ -0,0 +1,25 @@
# Created by the script cgal_create_cmake_script
# This is the CMake script for compiling a CGAL application.
project( Hyperbolic_triangulation_2_Examples )
cmake_minimum_required(VERSION 2.8.10)
find_package(CGAL QUIET COMPONENTS Core )
if ( CGAL_FOUND )
include( ${CGAL_USE_FILE} )
include( CGAL_CreateSingleSourceCGALProgram )
create_single_source_cgal_program( "ht2_example.cpp" )
create_single_source_cgal_program( "ht2_example_color.cpp" )
else()
message(STATUS "This program requires the CGAL library, and will not be compiled.")
endif()

View File

@ -0,0 +1,64 @@
#include <CGAL/Hyperbolic_Delaunay_triangulation_2.h>
#include <CGAL/Hyperbolic_Delaunay_triangulation_traits_2.h>
#include <CGAL/point_generators_2.h>
#include <CGAL/Timer.h>
#include <iostream>
#include <vector>
typedef CGAL::Hyperbolic_Delaunay_triangulation_traits_2<> Gt;
typedef Gt::Point_2 Point_2;
typedef Gt::Circle_2 Circle_2;
typedef Gt::FT FT;
typedef CGAL::Hyperbolic_Delaunay_triangulation_2<Gt> Dt;
typedef CGAL::Creator_uniform_2<FT, Point_2> Creator;
int main(int argc, char** argv)
{
int N;
if(argc < 2) {
std::cout << "usage: " << argv[0] << " [number_of_points]" << std::endl;
std::cout << "Defaulting to 100k points..." << std::endl;
N = 100000;
} else {
N = atoi(argv[1]);
}
CGAL::Timer timer;
CGAL::Random_points_in_disc_2<Point_2, Creator> in_disc;
std::vector<Point_2> pts;
std::vector<Point_2>::iterator ip;
for(int i=0; i<N; ++i)
pts.push_back(*(in_disc++));
Dt dt_during;
std::cout << "Insertion of points one by one (hyperbolic filtering at each step)" << std::endl;
std::cout << "===================================================================" << std::endl;
timer.start();
for(ip = pts.begin(); ip != pts.end(); ++ip)
dt_during.insert(*ip);
timer.stop();
std::cout << "Number of vertices: " << dt_during.number_of_vertices() << std::endl;
std::cout << "Number of hyperbolic faces: " << dt_during.number_of_hyperbolic_faces() << std::endl;
std::cout << "Number of hyperbolic edges: " << dt_during.number_of_hyperbolic_edges() << std::endl;
std::cout << "Time: " << timer.time() << std::endl << std::endl;
Dt dt_end;
std::cout << "Insertion of point set (hyperbolic filtering only once at the end)" << std::endl;
std::cout << "===================================================================" << std::endl;
timer.reset();
timer.start();
dt_end.insert(pts.begin(),pts.end());
timer.stop();
std::cout << "Number of vertices: " << dt_end.number_of_vertices() << std::endl;
std::cout << "Number of hyperbolic faces: " << dt_end.number_of_hyperbolic_faces() << std::endl;
std::cout << "Number of hyperbolic edges: " << dt_end.number_of_hyperbolic_edges() << std::endl;
std::cout << "Time: " << timer.time() << std::endl;
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,74 @@
#include <CGAL/Hyperbolic_triangulation_face_base_2.h>
#include <CGAL/Hyperbolic_Delaunay_triangulation_2.h>
#include <CGAL/Hyperbolic_Delaunay_triangulation_CK_traits_2.h>
#include <CGAL/Triangulation_face_base_with_info_2.h>
#include <CGAL/Triangulation_vertex_base_2.h>
#include <CGAL/point_generators_2.h>
#include <CGAL/IO/Color.h>
#include <iostream>
#include <vector>
typedef CGAL::Hyperbolic_Delaunay_triangulation_CK_traits_2<> Gt;
typedef CGAL::Hyperbolic_triangulation_face_base_2<Gt> Hyperbolic_face_base;
typedef CGAL::Triangulation_face_base_with_info_2<CGAL::Color, Gt,
Hyperbolic_face_base> Face_base_with_info;
typedef CGAL::Triangulation_vertex_base_2<Gt> Vertex_base;
typedef CGAL::Triangulation_data_structure_2<Vertex_base,
Face_base_with_info> TDS;
typedef CGAL::Hyperbolic_Delaunay_triangulation_2<Gt, TDS> Dt;
typedef Dt::Point Point_2;
typedef CGAL::Creator_uniform_2<Gt::FT, Point_2> Creator;
int main(int argc, char** argv)
{
int N;
if(argc < 2) {
std::cout << "usage: " << argv[0] << " [number_of_points]" << std::endl;
std::cout << "Defaulting to 100k points..." << std::endl;
N = 100000;
} else {
N = atoi(argv[1]);
}
std::cout << "Number of points: " << N << std::endl;
CGAL::Random_points_in_disc_2<Point_2, Creator> in_disc;
std::vector<Point_2> pts;
for(int i=0; i<N; ++i)
pts.push_back(*(in_disc++));
Dt dt;
dt.insert(pts.begin(), pts.end());
Dt::Vertex_handle vo = dt.insert(Point_2(0,0));
int origin_faces = 0;
Dt::Hyperbolic_faces_iterator fit;
for(fit = dt.hyperbolic_faces_begin(); fit != dt.hyperbolic_faces_end(); ++fit)
{
if(fit->has_vertex(vo))
{
fit->info() = CGAL::RED;
origin_faces++;
}
}
int red_faces = 0;
for(fit = dt.hyperbolic_faces_begin(); fit != dt.hyperbolic_faces_end(); ++fit)
{
if(fit->info() == CGAL::RED)
{
red_faces++;
}
}
assert(red_faces == origin_faces);
std::cout << "Number of points " << N << std::endl;
std::cout << "Number of vertices: " << dt.number_of_vertices() << std::endl;
std::cout << "Number of hyperbolic faces: " << dt.number_of_hyperbolic_faces() << std::endl;
std::cout << "Number of faces incident to the origin: " << origin_faces << std::endl;
return EXIT_SUCCESS;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,427 @@
// Copyright (c) 2010-2018 INRIA Sophia Antipolis, INRIA Nancy (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0+
//
// Author(s) : Mikhail Bogdanov
// Monique Teillaud <Monique.Teillaud@inria.fr>
#ifndef CGAL_HYPERBOLIC_DELAUNAY_TRIANGULATION_CK_TRAITS_2_H
#define CGAL_HYPERBOLIC_DELAUNAY_TRIANGULATION_CK_TRAITS_2_H
#include <CGAL/license/Hyperbolic_triangulation_2.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Algebraic_kernel_for_circles_2_2.h>
#include <CGAL/Circular_kernel_2/Intersection_traits.h>
#include <CGAL/Circular_kernel_2.h>
#include <CGAL/triangulation_assertions.h>
#include <CGAL/determinant.h>
#include <boost/tuple/tuple.hpp>
#include <boost/variant.hpp>
#include <CGAL/internal/Hyperbolic_Delaunay_triangulation_traits_2_functions.h>
namespace CGAL {
namespace internal {
template <typename Traits>
class Construct_hyperbolic_circumcenter_CK_2
{
typedef typename Traits::Hyperbolic_Voronoi_point_2 Hyperbolic_Voronoi_point_2;
typedef typename Traits::Hyperbolic_point_2 Hyperbolic_point_2;
typedef typename Traits::Euclidean_circle_or_line_2 Euclidean_circle_or_line_2;
typedef typename Traits::Euclidean_line_2 Euclidean_line_2;
typedef typename Traits::Circle_2 Circle_2;
typedef typename Traits::FT FT;
typedef typename Traits::Circular_arc_point_2 Circular_arc_point_2;
public:
Construct_hyperbolic_circumcenter_CK_2(const Traits gt = Traits()): _gt(gt) {}
Hyperbolic_Voronoi_point_2 operator()(const Hyperbolic_point_2& p,
const Hyperbolic_point_2& q,
const Hyperbolic_point_2& r) const
{
Construct_circle_or_line_supporting_bisector<Traits> cclsb(_gt);
Hyperbolic_point_2 po(CGAL::ORIGIN);
Circle_2 l_inf(po, FT(1));
if( _gt.compare_distance_2_object()(po, p, q) == EQUAL &&
_gt.compare_distance_2_object()(po, p, r) == EQUAL)
return po;
// now supporting objects cannot both be Euclidean lines
Euclidean_circle_or_line_2 bis_pq = cclsb(p, q);
Euclidean_circle_or_line_2 bis_qr = cclsb(q, r);
std::pair<Circular_arc_point_2, unsigned> pair;
Euclidean_line_2* l;
Circle_2* c;
if(Circle_2* c_pq = boost::get<Circle_2>(&bis_pq))
{
if(Circle_2* c_qr = boost::get<Circle_2>(&bis_qr))
{
typedef typename CK2_Intersection_traits<Traits, Circle_2, Circle_2>::type Intersection_result;
std::vector< Intersection_result > inters;
intersection(*c_pq, *c_qr, std::back_inserter(inters));
CGAL_triangulation_assertion(assign(pair, inters[0]));
if(pair.second == 1)
{
if(_gt.has_on_bounded_side_2_object()(l_inf, pair.first))
return pair.first;
CGAL_triangulation_assertion(assign(pair, inters[1]));
return pair.first;
}
return pair.first;
}
// here bis_qr is a line
l = boost::get<Euclidean_line_2>(&bis_qr);
c = c_pq;
}
else
{
// here bis_pq is a line, and bis_qr is necessarily a circle
l = boost::get<Euclidean_line_2>(&bis_pq);
c = boost::get<Circle_2>(&bis_qr);
}
typedef typename CK2_Intersection_traits<Traits, Euclidean_line_2, Circle_2>::type Intersection_result;
std::vector< Intersection_result > inters;
intersection(*l, *c, std::back_inserter(inters));
CGAL_triangulation_assertion(assign(pair,inters[0]));
if(pair.second == 1)
{
if(_gt.has_on_bounded_side_2_object()(l_inf, pair.first))
return pair.first;
CGAL_triangulation_assertion(assign(pair, inters[1]));
return pair.first;
}
return pair.first;
}
private:
const Traits& _gt;
}; // end Construct_hyperbolic_circumcenter_2
template <typename Traits>
class Construct_hyperbolic_bisector_CK_2
{
typedef typename Traits::Hyperbolic_segment_2 Hyperbolic_segment_2;
typedef typename Traits::Hyperbolic_point_2 Hyperbolic_point_2;
typedef typename Traits::Circle_2 Circle_2;
typedef typename Traits::Euclidean_line_2 Euclidean_line_2;
typedef typename Traits::Euclidean_circle_or_line_2 Euclidean_circle_or_line_2;
typedef typename Traits::Circular_arc_2 Circular_arc_2;
typedef typename Traits::Line_arc_2 Line_arc_2;
typedef typename Traits::Circular_arc_point_2 Circular_arc_point_2;
typedef typename Traits::FT FT;
public:
Construct_hyperbolic_bisector_CK_2(const Traits& gt = Traits()) : _gt(gt) {}
// constructs a hyperbolic line
Hyperbolic_segment_2 operator()(const Hyperbolic_point_2& p,
const Hyperbolic_point_2& q) const
{
Construct_circle_or_line_supporting_bisector<Traits> cclsb(_gt);
Hyperbolic_point_2 po(CGAL::ORIGIN);
Circle_2 l_inf = Circle_2(po, FT(1));
if(_gt.compare_distance_2_object()(po, p, q) == EQUAL)
{
Euclidean_line_2 l = _gt.construct_Euclidean_bisector_2_object()(p, q);
if(_gt.less_y_2_object()(p, q))
return Line_arc_2(l, l_inf, false, l_inf, true);
return Line_arc_2(l, l_inf, true, l_inf, false);
}
Euclidean_circle_or_line_2 bis_pq = cclsb(p, q);
Circle_2* c = boost::get<Circle_2>(&bis_pq);
if(_gt.less_y_2_object()(po, c->center()))
return Circular_arc_2(*c, l_inf, true, l_inf, false);
else if(_gt.less_y_2_object()(c->center(), po))
return Circular_arc_2(*c, l_inf, false, l_inf, true);
// the center of the circle is on the x-axis
if(_gt.less_x_2_object()(po, c->center())) { return Circular_arc_2(*c, l_inf, true, l_inf, false); }
return Circular_arc_2(*c, l_inf, false, l_inf, true);
}
// constructs the hyperbolic bisector of segment [p, q] limited by
// circumcenter(p, q, r) on one side
// and circumcenter(p, s, q) on the other side
Hyperbolic_segment_2 operator()(const Hyperbolic_point_2& p,
const Hyperbolic_point_2& q,
const Hyperbolic_point_2& r,
const Hyperbolic_point_2& s) const
{
CGAL_triangulation_precondition((_gt.orientation_2_object()(p, q, r) == ON_POSITIVE_SIDE) &&
(_gt.orientation_2_object()(p, s, q) == ON_POSITIVE_SIDE));
CGAL_triangulation_precondition((_gt.side_of_oriented_circle_2_object()(p, q, r,s) == ON_NEGATIVE_SIDE) &&
(_gt.side_of_oriented_circle_2_object()(p, s, q, r) == ON_NEGATIVE_SIDE));
Construct_circle_or_line_supporting_bisector<Traits> cclsb(_gt);
Construct_hyperbolic_circumcenter_CK_2<Traits> chc(_gt);
Hyperbolic_point_2 po(CGAL::ORIGIN);
// TODO MT this is non-optimal...
// the bisector is already computed here
// and it will be recomputed below
Circular_arc_point_2 a = chc(p, q, r);
Circular_arc_point_2 b = chc(p, s, q);
if(_gt.compare_distance_2_object()(po, p, q) == EQUAL)
{
Euclidean_line_2 l = _gt.construct_Euclidean_bisector_2_object()(p, q);
return Line_arc_2(l, a, b);
}
Euclidean_circle_or_line_2
bis_pq = cclsb(p, q);
Circle_2* c_pq = boost::get<Circle_2>(&bis_pq);
if(_gt.compare_distance_2_object()(po, p, q) == POSITIVE)
{
// then p is inside the supporting circle
return Circular_arc_2(*c_pq, b, a);
}
return Circular_arc_2(*c_pq, a, b);
}
// constructs the hyperbolic bisector of segment [p, q]
// limited by hyperbolic circumcenter(p, q, r) on one side
// and going to the infinite line on the other side
Hyperbolic_segment_2 operator()(const Hyperbolic_point_2& p,
const Hyperbolic_point_2& q,
const Hyperbolic_point_2& r) const
{
CGAL_triangulation_precondition(_gt.orientation_2_object()(p, q, r) == POSITIVE);
Construct_circle_or_line_supporting_bisector<Traits> cclsb(_gt);
Construct_hyperbolic_circumcenter_CK_2<Traits> chc(_gt);
Hyperbolic_point_2 po(CGAL::ORIGIN);
Circle_2 l_inf(po, FT(1));
// TODO MT this is non-optimal...
// the bisector is computed (at least) twice
Circular_arc_point_2 a = chc(p, q, r);
if(_gt.compare_distance_2_object()(po, p, q) == EQUAL)
{
Euclidean_line_2 bis_pq = _gt.construct_Euclidean_bisector_2_object()(p, q);
typedef typename
CK2_Intersection_traits<Traits, Euclidean_line_2, Circle_2>::type
Intersection_result;
std::vector< Intersection_result > inters;
intersection(bis_pq, l_inf, std::back_inserter(inters));
std::pair<Circular_arc_point_2, unsigned> pair;
CGAL_triangulation_assertion(assign(pair,inters[0]));
CGAL_triangulation_assertion(pair.second == 1);
if(_gt.less_y_2_object()(p, q))
return Line_arc_2(bis_pq,a,pair.first);
CGAL_triangulation_assertion(assign(pair,inters[1]));
CGAL_triangulation_assertion(pair.second == 1);
return Line_arc_2(bis_pq,a,pair.first);
}
Euclidean_circle_or_line_2 bis_pq = cclsb(p, q);
Circle_2* c_pq = boost::get<Circle_2>(&bis_pq);
Hyperbolic_point_2 approx_a(to_double(a.x()),to_double(a.y()));
typedef typename
CK2_Intersection_traits<Traits, Circle_2, Circle_2>::type Intersection_result;
std::vector< Intersection_result > inters;
intersection(*c_pq, l_inf, std::back_inserter(inters));
std::pair<Circular_arc_point_2, unsigned> pair;
CGAL_triangulation_assertion(assign(pair,inters[0]));
CGAL_triangulation_assertion(pair.second == 1);
Hyperbolic_point_2 approx_pinf(to_double(pair.first.x()), to_double(pair.first.y()));
Hyperbolic_point_2 approx_c(to_double(c_pq->center().x()),
to_double(c_pq->center().y()));
if(_gt.orientation_2_object()(p, q,approx_pinf) == NEGATIVE)
{
if(_gt.orientation_2_object()(approx_c,approx_a,approx_pinf) == POSITIVE)
return Circular_arc_2(*c_pq, a, pair.first);
return Circular_arc_2(*c_pq, pair.first, a);
}
CGAL_triangulation_assertion(assign(pair,inters[1]));
if(_gt.orientation_2_object()(approx_c,approx_a,approx_pinf) == POSITIVE)
return Circular_arc_2(*c_pq, pair.first, a);
return Circular_arc_2(*c_pq, a, pair.first);
}
private:
const Traits& _gt;
}; // end Construct_hyperbolic_bisector_2
} // end namespace internal
template<class R = CGAL::Circular_kernel_2<
CGAL::Exact_predicates_inexact_constructions_kernel,
CGAL::Algebraic_kernel_for_circles_2_2<
CGAL::Exact_predicates_inexact_constructions_kernel::RT >
>
>
class Hyperbolic_Delaunay_triangulation_CK_traits_2
: public R // R is supposed to be a model of CircularKernel2
{
typedef Hyperbolic_Delaunay_triangulation_CK_traits_2<R> Self;
typedef R Base;
public:
typedef typename R::FT FT;
typedef typename R::Point_2 Hyperbolic_point_2;
typedef typename R::Circle_2 Circle_2;
typedef typename R::Line_2 Euclidean_line_2;
typedef boost::variant<Circle_2, Euclidean_line_2> Euclidean_circle_or_line_2;
typedef typename R::Circular_arc_2 Circular_arc_2;
typedef typename R::Line_arc_2 Line_arc_2;
typedef typename R::Circular_arc_point_2 Circular_arc_point_2;
typedef Circular_arc_point_2 Hyperbolic_Voronoi_point_2;
typedef typename R::Segment_2 Euclidean_segment_2; // only used internally here
typedef boost::variant<Circular_arc_2, Line_arc_2> Hyperbolic_segment_2;
typedef typename R::Triangle_2 Hyperbolic_triangle_2;
typedef typename R::Compare_x_2 Compare_x_2;
typedef typename R::Compare_y_2 Compare_y_2;
typedef typename R::Compare_distance_2 Compare_distance_2;
typedef typename R::Orientation_2 Orientation_2;
typedef typename R::Side_of_oriented_circle_2 Side_of_oriented_circle_2;
// the following types are only used internally in this traits class,
// so they need not be documented, and they don't need _object()
typedef typename R::Collinear_2 Euclidean_collinear_2;
typedef typename R::Construct_bisector_2 Construct_Euclidean_bisector_2;
typedef typename R::Construct_midpoint_2 Construct_Euclidean_midpoint_2;
typedef typename R::Compute_squared_distance_2 Compute_squared_Euclidean_distance_2;
typedef typename R::Has_on_bounded_side_2 Has_on_bounded_side_2;
typedef typename R::Less_x_2 Less_x_2;
typedef typename R::Less_y_2 Less_y_2;
// only kept for demo to please T2graphicsitems
typedef Euclidean_segment_2 Line_segment_2;
typedef Hyperbolic_segment_2 Segment_2;
typedef internal::Construct_hyperbolic_circumcenter_CK_2<Self> Construct_hyperbolic_circumcenter_2;
typedef internal::Construct_hyperbolic_bisector_CK_2<Self> Construct_hyperbolic_bisector_2;
typedef internal::Is_Delaunay_hyperbolic<Self> Is_Delaunay_hyperbolic;
typedef internal::Side_of_oriented_hyperbolic_segment_2<Self> Side_of_oriented_hyperbolic_segment_2;
typedef typename internal::Construct_circle_or_line_supporting_bisector<Self> Construct_circle_or_line_supporting_bisector;
typedef internal::Construct_hyperbolic_segment_2<Self> Construct_hyperbolic_segment_2;
typedef typename Base::Construct_segment_2 Construct_segment_2;
public:
Hyperbolic_Delaunay_triangulation_CK_traits_2(const Base& kernel = Base()) : Base(kernel) {}
Construct_hyperbolic_segment_2
construct_hyperbolic_segment_2_object() const
{ return Construct_hyperbolic_segment_2(*this); }
Construct_segment_2
construct_segment_2_object() const
{ return this->Base::construct_segment_2_object(); }
Construct_hyperbolic_circumcenter_2
construct_hyperbolic_circumcenter_2_object() const
{ return Construct_hyperbolic_circumcenter_2(*this); }
Construct_hyperbolic_bisector_2
construct_hyperbolic_bisector_2_object() const
{ return Construct_hyperbolic_bisector_2(*this); }
Is_Delaunay_hyperbolic
is_Delaunay_hyperbolic_2_object() const
{ return Is_Delaunay_hyperbolic(*this); }
Side_of_oriented_hyperbolic_segment_2
side_of_oriented_hyperbolic_segment_2_object() const
{ return Side_of_oriented_hyperbolic_segment_2(*this); }
Construct_Euclidean_bisector_2
construct_Euclidean_bisector_2_object() const
{ return this->Base::construct_bisector_2_object(); }
Construct_circle_or_line_supporting_bisector
construct_circle_or_line_supporting_bisector_2_object() const
{ return Construct_circle_or_line_supporting_bisector(*this); }
Euclidean_collinear_2
euclidean_collinear_2_object() const
{ return this->Base::collinear_2_object(); }
Compute_squared_Euclidean_distance_2
compute_squared_Euclidean_distance_2_object() const
{ return this->Base::compute_squared_distance_2_object(); }
};
// Take out the code below to some separate file
#ifdef CGAL_EXACT_PREDICATES_EXACT_CONSTRUCTIONS_KERNEL_H
template <>
struct Triangulation_structural_filtering_traits< Hyperbolic_Delaunay_triangulation_CK_traits_2<Epeck> > {
typedef Tag_true Use_structural_filtering_tag;
};
#endif // CGAL_EXACT_PREDICATES_EXACT_CONSTRUCTIONS_KERNEL_H
#ifdef CGAL_EXACT_PREDICATES_INEXACT_CONSTRUCTIONS_KERNEL_H
template <>
struct Triangulation_structural_filtering_traits< Hyperbolic_Delaunay_triangulation_CK_traits_2<Epick> > {
typedef Tag_true Use_structural_filtering_tag;
};
#endif // CGAL_EXACT_PREDICATES_INEXACT_CONSTRUCTIONS_KERNEL_H
} //namespace CGAL
#endif // CGAL_HYPERBOLIC_DELAUNAY_TRIANGULATION_CK_TRAITS_2_H

View File

@ -0,0 +1,566 @@
// Copyright (c) 2010-2018 INRIA Sophia Antipolis, INRIA Nancy (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0+
//
// Author(s) : Iordan Iordanov
// Monique Teillaud
//
#ifndef CGAL_HYPERBOLIC_DELAUNAY_TRIANGULATION_TRAITS_2_H
#define CGAL_HYPERBOLIC_DELAUNAY_TRIANGULATION_TRAITS_2_H
#include <CGAL/license/Hyperbolic_triangulation_2.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel_with_sqrt.h>
#include <CGAL/basic.h>
#include <CGAL/basic_constructions_2.h>
#include <CGAL/Bbox_2.h>
#include <CGAL/determinant.h>
#include <CGAL/distance_predicates_2.h>
#include <CGAL/internal/Exact_complex.h>
#include <CGAL/Origin.h>
#include <CGAL/predicates_on_points_2.h>
#include <CGAL/triangulation_assertions.h>
#include <CGAL/utility.h>
#include <boost/tuple/tuple.hpp>
#include <boost/variant.hpp>
#include <utility>
#include <CGAL/internal/Hyperbolic_Delaunay_triangulation_traits_2_functions.h>
namespace CGAL {
namespace internal {
template <typename Traits>
class HDT_2_Circular_arc_2
{
typedef typename Traits::FT FT;
typedef Exact_complex<FT> Cplx;
typedef typename Traits::Point_2 Point;
typedef typename Traits::Circle_2 Circle;
typedef typename Traits::Orientation_2 Orientation_2;
private:
Circle _c;
Point _s, _t;
const Traits& _gt;
public:
HDT_2_Circular_arc_2(const Traits& gt = Traits())
: _c(Point(FT(0),FT(0)), FT(0)),
_s(FT(0),FT(0)),
_t(FT(0),FT(0)),
_gt(gt)
{}
HDT_2_Circular_arc_2(const Circle& c,
const Point& source, const Point& target,
const Traits& gt = Traits())
: _c(c), _s(source), _t(target), _gt(gt)
{}
HDT_2_Circular_arc_2(const Point& p1, const Point& p2,
const Traits& gt = Traits())
: _gt(gt)
{
Cplx p(p1), q(p2);
Cplx O(0,0);
Cplx inv;
if(p == O)
inv = q.invert_in_unit_circle();
else
inv = p.invert_in_unit_circle();
Point ip(inv.real(), inv.imag());
_c = Circle(p1, p2, ip);
if(_gt.orientation_2_object()(p1, p2, _c.center()) == LEFT_TURN)
{
_s = p1;
_t = p2;
}
else
{
_s = p2;
_t = p1;
}
}
Circle supporting_circle() const { return _c; }
Point source() const { return _s; }
Point target() const { return _t; }
FT squared_radius() const { return _c.squared_radius(); }
Point center() const { return _c.center(); }
Bbox_2 bbox(void) const { return _gt.construct_bbox_2_object()(*this); }
};
// only used internally
template <typename Traits>
class Construct_intersection_2
{
typedef typename Traits::FT FT;
typedef typename Traits::Hyperbolic_point_2 Hyperbolic_point_2;
typedef typename Traits::Hyperbolic_segment_2 Hyperbolic_segment_2;
typedef typename Traits::Euclidean_segment_2 Euclidean_segment_2;
typedef typename Traits::Euclidean_line_2 Euclidean_line_2;
typedef typename Traits::Circle_2 Circle_2;
typedef typename Traits::Circular_arc_2 Circular_arc_2;
public:
Construct_intersection_2(const Traits& gt = Traits()) : _gt(gt) { }
Hyperbolic_point_2 operator()(const Euclidean_line_2& /*ell1*/,
const Euclidean_line_2& /*ell2*/)
{
// The only point where two Euclidean lines can intersect in the Poincaré disk is the origin.
return Hyperbolic_point_2(0,0);
}
std::pair<Hyperbolic_point_2, Hyperbolic_point_2> operator()(const Euclidean_line_2& ell,
const Circle_2& c)
{
if(ell.b() == FT(0))
{
FT p = c.center().x();
FT q = c.center().y();
FT y1 = q + CGAL::sqrt(c.squared_radius() - p*p);
FT y2 = q - CGAL::sqrt(c.squared_radius() - p*p);
Hyperbolic_point_2 p1(FT(0), y1);
Hyperbolic_point_2 p2(FT(0), y2);
return std::make_pair(p1, p2);
}
FT lambda = -ell.a()/ell.b();
FT mu = -ell.c()/ell.b();
FT p = c.center().x();
FT q = c.center().y();
FT A = FT(1) + lambda*lambda;
FT B = FT(2)*(lambda * mu - lambda*q - p);
FT C = p*p + mu*mu + q*q - c.squared_radius() - FT(2)*q*mu;
FT Delta = B*B - FT(4)*A*C;
FT x1 = (-B + CGAL::sqrt(Delta))/(FT(2)*A);
FT x2 = (-B - CGAL::sqrt(Delta))/(FT(2)*A);
FT y1 = lambda*x1 + mu;
FT y2 = lambda*x2 + mu;
Hyperbolic_point_2 sol1(x1, y1);
Hyperbolic_point_2 sol2(x2, y2);
return std::make_pair(sol1, sol2);
}
std::pair<Hyperbolic_point_2, Hyperbolic_point_2> operator()(const Circle_2& c,
const Euclidean_line_2& ell)
{
return operator()(ell, c);
}
std::pair<Hyperbolic_point_2, Hyperbolic_point_2> operator()(const Circle_2& c1, const Circle_2& c2)
{
FT xa = c1.center().x(), ya = c1.center().y();
FT xb = c2.center().x(), yb = c2.center().y();
FT d2 = _gt.compute_squared_distance_2_object()(c1.center(), c2.center());
FT ra = CGAL::sqrt(c1.squared_radius());
FT rb = CGAL::sqrt(c2.squared_radius());
FT K = CGAL::sqrt(((ra+rb)*(ra+rb)-d2)*(d2-(ra-rb)*(ra-rb)))/FT(4);
FT xbase = (xb + xa)/FT(2) + (xb - xa)*(ra*ra - rb*rb)/d2/FT(2);
FT xdiff = FT(2)*(yb - ya)*K/d2;
FT x1 = xbase + xdiff;
FT x2 = xbase - xdiff;
FT ybase = (yb + ya)/FT(2) + (yb - ya)*(ra*ra - rb*rb)/d2/FT(2);
FT ydiff = FT(-2)*(xb - xa)*K/d2;
FT y1 = ybase + ydiff;
FT y2 = ybase - ydiff;
Hyperbolic_point_2 res1(x1, y1);
Hyperbolic_point_2 res2(x2, y2);
return std::make_pair(res1, res2);
}
Hyperbolic_point_2 operator()(Hyperbolic_segment_2 s1, Hyperbolic_segment_2 s2)
{
if(Circular_arc_2* c1 = boost::get<Circular_arc_2>(&s1))
{
if(Circular_arc_2* c2 = boost::get<Circular_arc_2>(&s2))
{
std::pair<Hyperbolic_point_2, Hyperbolic_point_2> res = operator()(c1->supporting_circle(), c2->supporting_circle());
Hyperbolic_point_2 p1 = res.first;
if(p1.x()*p1.x() + p1.y()*p1.y() < FT(1))
return p1;
Hyperbolic_point_2 p2 = res.second;
CGAL_assertion(p2.x()*p2.x() + p2.y()*p2.y() < FT(1));
return p2;
}
else
{
Euclidean_segment_2* ell2 = boost::get<Euclidean_segment_2>(&s2);
std::pair<Hyperbolic_point_2, Hyperbolic_point_2> res = operator()(c1->supporting_circle(),
ell2->supporting_line());
Hyperbolic_point_2 p1 = res.first;
if(p1.x()*p1.x() + p1.y()*p1.y() < FT(1))
return p1;
Hyperbolic_point_2 p2 = res.second;
CGAL_assertion(p2.x()*p2.x() + p2.y()*p2.y() < FT(1));
return p2;
}
}
else
{
Euclidean_segment_2* ell1 = boost::get<Euclidean_segment_2>(&s1);
if(Circular_arc_2* c2 = boost::get<Circular_arc_2>(&s2))
{
std::pair<Hyperbolic_point_2, Hyperbolic_point_2> res = operator()(ell1->supporting_line(),
c2->supporting_circle());
Hyperbolic_point_2 p1 = res.first;
if(p1.x()*p1.x() + p1.y()*p1.y() < FT(1))
return p1;
Hyperbolic_point_2 p2 = res.second;
CGAL_assertion(p2.x()*p2.x() + p2.y()*p2.y() < FT(1));
return p2;
}
else
{
Euclidean_segment_2* ell2 = boost::get<Euclidean_segment_2>(&s2);
Hyperbolic_point_2 p1 = operator()(ell1->supporting_line(), ell2->supporting_line());
CGAL_assertion(p1.x()*p1.x() + p1.y()*p1.y() < FT(1));
return p1;
}
}
}
private:
const Traits& _gt;
};
template <typename Traits>
class Construct_hyperbolic_circumcenter_2
{
typedef typename Traits::FT FT;
typedef typename Traits::Circle_2 Circle_2;
typedef typename Traits::Hyperbolic_point_2 Hyperbolic_point_2;
typedef typename Traits::Hyperbolic_Voronoi_point_2 Hyperbolic_Voronoi_point_2;
typedef typename Traits::Euclidean_line_2 Euclidean_line_2;
typedef typename Traits::Euclidean_circle_or_line_2 Euclidean_circle_or_line_2;
public:
typedef Hyperbolic_Voronoi_point_2 result_type;
Construct_hyperbolic_circumcenter_2(const Traits& gt = Traits()) : _gt(gt) {}
Hyperbolic_Voronoi_point_2 operator()(const Hyperbolic_point_2& p,
const Hyperbolic_point_2& q,
const Hyperbolic_point_2& r) const
{
Hyperbolic_point_2 po(CGAL::ORIGIN);
Circle_2 l_inf(po, FT(1));
Construct_circle_or_line_supporting_bisector<Traits> cclsb(_gt);
Construct_intersection_2<Traits> ci(_gt);
Euclidean_circle_or_line_2 bis_pq = cclsb(p, q);
Euclidean_circle_or_line_2 bis_qr = cclsb(q, r);
if(_gt.compare_distance_2_object()(po, p, q) == EQUAL &&
_gt.compare_distance_2_object()(po, p, r) == EQUAL)
return po;
// now supporting objects cannot both be Euclidean lines
Euclidean_line_2* l;
Circle_2* c;
if(Circle_2* c_pq = boost::get<Circle_2>(&bis_pq))
{
if(Circle_2* c_qr = boost::get<Circle_2>(&bis_qr))
{
std::pair<Hyperbolic_point_2, Hyperbolic_point_2> inters = ci(*c_pq, *c_qr);
if(_gt.has_on_bounded_side_2_object()(l_inf, inters.first))
return inters.first;
return inters.second;
}
l = boost::get<Euclidean_line_2>(&bis_qr);
c = c_pq;
}
else
{
// here bis_pq is a line
l = boost::get<Euclidean_line_2>(&bis_pq);
c = boost::get<Circle_2>(&bis_qr);
}
std::pair<Hyperbolic_point_2, Hyperbolic_point_2> inters = ci(*c, *l);
if(_gt.has_on_bounded_side_2_object()(l_inf, inters.first))
return inters.first;
return inters.second;
}
private:
const Traits& _gt;
}; // end Construct_hyperbolic_circumcenter_2
template <typename Traits>
class Construct_hyperbolic_bisector_2
{
typedef typename Traits::FT FT;
typedef typename Traits::Hyperbolic_point_2 Hyperbolic_point_2;
typedef typename Traits::Hyperbolic_segment_2 Hyperbolic_segment_2;
typedef typename Traits::Euclidean_segment_2 Euclidean_segment_2;
typedef typename Traits::Euclidean_line_2 Euclidean_line_2;
typedef typename Traits::Euclidean_circle_or_line_2 Euclidean_circle_or_line_2;
typedef typename Traits::Circle_2 Circle_2;
typedef typename Traits::Circular_arc_2 Circular_arc_2;
public:
Construct_hyperbolic_bisector_2(const Traits& gt = Traits())
: _gt(gt)
{}
// constructs a hyperbolic line
Hyperbolic_segment_2 operator()(const Hyperbolic_point_2& p,
const Hyperbolic_point_2& q) const
{
Construct_circle_or_line_supporting_bisector<Traits> cclsb(_gt);
Construct_intersection_2<Traits> ci(_gt);
Hyperbolic_point_2 po(CGAL::ORIGIN);
Circle_2 l_inf(po, FT(1));
if(_gt.compare_distance_2_object()(po, p, q) == EQUAL)
{
Euclidean_line_2 l = _gt.construct_bisector_2_object()(p, q);
std::pair<Hyperbolic_point_2, Hyperbolic_point_2> inters = ci(l, l_inf);
return Euclidean_segment_2(inters.first, inters.second);
}
Euclidean_circle_or_line_2 bis_pq = cclsb(p, q);
Circle_2* c = boost::get<Circle_2>(&bis_pq);
std::pair<Hyperbolic_point_2, Hyperbolic_point_2> inters = ci(*c, l_inf);
if(_gt.orientation_2_object()(c->center(), inters.first, inters.second) == POSITIVE)
return Circular_arc_2(*c, inters.first, inters.second);
else
return Circular_arc_2(*c, inters.second, inters.first);
}
// constructs the hyperbolic bisector of segment [p, q] limited by
// circumcenter(p, q, r) on one side
// and circumcenter(p, s, q) on the other side
Hyperbolic_segment_2 operator()(const Hyperbolic_point_2& p,
const Hyperbolic_point_2& q,
const Hyperbolic_point_2& r,
const Hyperbolic_point_2& s) const
{
CGAL_triangulation_precondition((_gt.orientation_2_object()(p, q, r) == ON_POSITIVE_SIDE) &&
(_gt.orientation_2_object()(p, s, q) == ON_POSITIVE_SIDE));
CGAL_triangulation_precondition((_gt.side_of_oriented_circle_2_object()(p, q, r,s) == ON_NEGATIVE_SIDE) &&
(_gt.side_of_oriented_circle_2_object()(p, s, q, r) == ON_NEGATIVE_SIDE));
Construct_hyperbolic_circumcenter_2<Traits> chc(_gt);
Construct_circle_or_line_supporting_bisector<Traits> cclsb(_gt);
Hyperbolic_point_2 po(CGAL::ORIGIN);
// TODO MT this is non-optimal...
// the bisector is already computed here
// and it will be recomputed below
Hyperbolic_point_2 a = chc(p, q, r);
Hyperbolic_point_2 b = chc(p, s, q);
if(_gt.compare_distance_2_object()(po, p, q) == EQUAL)
{
Euclidean_line_2 l = _gt.construct_bisector_2_object()(p, q);
return Euclidean_segment_2(a, b);
}
Euclidean_circle_or_line_2 bis_pq = cclsb(p, q);
Circle_2* c_pq = boost::get<Circle_2>(&bis_pq);
if(_gt.compare_distance_2_object()(po, p, q) == POSITIVE) {
// then p is inside the supporting circle
return Circular_arc_2(*c_pq, b, a);
}
return Circular_arc_2(*c_pq, a, b);
}
// constructs the hyperbolic bisector of segment [p, q]
// limited by hyperbolic circumcenter(p, q, r) on one side
// and going to the infinite line on the other side
Hyperbolic_segment_2 operator()(const Hyperbolic_point_2& p,
const Hyperbolic_point_2& q,
const Hyperbolic_point_2& r) const
{
CGAL_triangulation_precondition(_gt.orientation_2_object()(p, q, r) == POSITIVE);
Construct_circle_or_line_supporting_bisector<Traits> cclsb(_gt);
Construct_hyperbolic_circumcenter_2<Traits> chc(_gt);
Construct_intersection_2<Traits> ci(_gt);
Hyperbolic_point_2 po(CGAL::ORIGIN);
Circle_2 l_inf(po, FT(1));
// TODO MT this is non-optimal...
// the bisector is computed (at least) twice
Hyperbolic_point_2 a = chc(p, q, r);
if(_gt.compare_distance_2_object()(po, p, q) == EQUAL)
{
Euclidean_line_2 bis_pq = _gt.construct_bisector_2_object()(p, q);
std::pair<Hyperbolic_point_2,Hyperbolic_point_2> inters = ci(bis_pq, l_inf);
if(_gt.less_y_2_object()(p, q))
return Euclidean_segment_2(a,inters.first);
return Euclidean_segment_2(a,inters.second);
}
Euclidean_circle_or_line_2 bis_pq = cclsb(p, q);
Circle_2* c_pq = boost::get<Circle_2>(&bis_pq);
std::pair<Hyperbolic_point_2,Hyperbolic_point_2> inters = ci(*c_pq, l_inf);
Hyperbolic_point_2 approx_pinf = inters.first;
if(_gt.orientation_2_object()(p, q,inters.first) == NEGATIVE)
{
if(_gt.orientation_2_object()(c_pq->center(),a,inters.first) == POSITIVE)
return Circular_arc_2(*c_pq, a, inters.first);
return Circular_arc_2(*c_pq, inters.first, a);
}
if(_gt.orientation_2_object()(c_pq->center(),a,inters.first) == POSITIVE)
return Circular_arc_2(*c_pq, inters.second, a);
return Circular_arc_2(*c_pq, a, inters.second);
}
private:
const Traits& _gt;
}; // end Construct_hyperbolic_bisector_2
} // end namespace internal
//template<typename Kernel = CGAL::Cartesian<CORE::Expr> >
template<typename Kernel = Exact_predicates_exact_constructions_kernel_with_sqrt>
class Hyperbolic_Delaunay_triangulation_traits_2
: public Kernel
{
typedef Hyperbolic_Delaunay_triangulation_traits_2<Kernel> Self;
typedef Kernel Base;
public:
typedef typename Kernel::FT FT;
typedef typename Kernel::Point_2 Hyperbolic_point_2;
typedef Hyperbolic_point_2 Hyperbolic_Voronoi_point_2;
typedef typename Kernel::Circle_2 Circle_2;
typedef typename Kernel::Line_2 Euclidean_line_2;
typedef boost::variant<Circle_2,Euclidean_line_2> Euclidean_circle_or_line_2;
typedef internal::HDT_2_Circular_arc_2<Self> Circular_arc_2;
typedef typename Kernel::Segment_2 Euclidean_segment_2; // only used internally here
typedef boost::variant<Circular_arc_2, Euclidean_segment_2> Hyperbolic_segment_2;
typedef typename Kernel::Triangle_2 Hyperbolic_triangle_2;
// only kept for demo to please T2graphicsitems
typedef Euclidean_segment_2 Line_segment_2;
typedef Hyperbolic_segment_2 Segment_2;
// The objects Ray_2, Iso_rectangle_2 and Line_2 are needed by the CGAL::Qt::PainterOstream
typedef typename Kernel::Direction_2 Direction_2;
typedef typename Kernel::Ray_2 Ray_2;
typedef Euclidean_line_2 Line_2;
typedef typename Kernel::Iso_rectangle_2 Iso_rectangle_2;
typedef internal::Construct_hyperbolic_segment_2<Self> Construct_hyperbolic_segment_2;
typedef typename Base::Construct_segment_2 Construct_segment_2;
typedef internal::Construct_hyperbolic_circumcenter_2<Self> Construct_hyperbolic_circumcenter_2;
typedef internal::Construct_hyperbolic_bisector_2<Self> Construct_hyperbolic_bisector_2;
typedef internal::Is_Delaunay_hyperbolic<Self> Is_Delaunay_hyperbolic;
typedef internal::Side_of_oriented_hyperbolic_segment_2<Self> Side_of_oriented_hyperbolic_segment_2;
// Needed for P4HT2
typedef typename Kernel::Construct_bisector_2 Construct_Euclidean_bisector_2;
typedef typename internal::Construct_intersection_2<Self> Construct_intersection_2;
typedef typename internal::Construct_circle_or_line_supporting_bisector<Self> Construct_circle_or_line_supporting_bisector;
typedef typename Kernel::Collinear_2 Euclidean_collinear_2;
typedef typename Kernel::Compute_squared_distance_2 Compute_squared_Euclidean_distance_2;
public:
Hyperbolic_Delaunay_triangulation_traits_2(const Base& kernel = Base())
: Base(kernel)
{}
Construct_hyperbolic_segment_2
construct_hyperbolic_segment_2_object() const
{ return Construct_hyperbolic_segment_2(*this); }
Construct_segment_2
construct_segment_2_object() const
{ return this->Base::construct_segment_2_object(); }
Construct_hyperbolic_circumcenter_2
construct_hyperbolic_circumcenter_2_object() const
{ return Construct_hyperbolic_circumcenter_2(*this); }
Construct_hyperbolic_bisector_2
construct_hyperbolic_bisector_2_object() const
{ return Construct_hyperbolic_bisector_2(*this); }
Is_Delaunay_hyperbolic
is_Delaunay_hyperbolic_2_object() const
{ return Is_Delaunay_hyperbolic(*this); }
Side_of_oriented_hyperbolic_segment_2
side_of_oriented_hyperbolic_segment_2_object() const
{ return Side_of_oriented_hyperbolic_segment_2(*this); }
Construct_Euclidean_bisector_2
construct_Euclidean_bisector_2_object() const
{ return this->Base::construct_bisector_2_object(); }
Construct_intersection_2
construct_intersection_2_object() const
{ return Construct_intersection_2(*this); }
Construct_circle_or_line_supporting_bisector
construct_circle_or_line_supporting_bisector_2_object() const
{ return Construct_circle_or_line_supporting_bisector(*this); }
Euclidean_collinear_2
euclidean_collinear_2_object() const
{ return this->Base::collinear_2_object(); }
Compute_squared_Euclidean_distance_2
compute_squared_Euclidean_distance_2_object() const
{ return this->Base::compute_squared_distance_2_object(); }
}; // class Hyperbolic_Delaunay_triangulation_traits_2
} // namespace CGAL
#endif // CGAL_HYPERBOLIC_DELAUNAY_TRIANGULATION_TRAITS_2_H

View File

@ -0,0 +1,81 @@
// Copyright (c) 2016-2018 INRIA Nancy (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0+
//
// Author(s) : Monique Teillaud <Monique.Teillaud@inria.fr>
// Mikhail Bogdanov
#ifndef CGAL_HYPERBOLIC_TRIANGULATION_FACE_BASE_2_H
#define CGAL_HYPERBOLIC_TRIANGULATION_FACE_BASE_2_H
#include <CGAL/license/Hyperbolic_triangulation_2.h>
#include <CGAL/basic.h>
#include <CGAL/triangulation_assertions.h>
#include <CGAL/Triangulation_ds_face_base_2.h>
#include <CGAL/Object.h>
namespace CGAL {
template<typename Gt,
typename Fb = Triangulation_ds_face_base_2<> >
class Hyperbolic_triangulation_face_base_2
: public Fb
{
public:
typedef Gt Geom_traits;
typedef typename Fb::Vertex_handle Vertex_handle;
typedef typename Fb::Face_handle Face_handle;
template<typename TDS2>
struct Rebind_TDS
{
typedef typename Fb::template Rebind_TDS<TDS2>::Other Fb2;
typedef Hyperbolic_triangulation_face_base_2<Gt, Fb2> Other;
};
public:
Hyperbolic_triangulation_face_base_2() : Fb() {}
Hyperbolic_triangulation_face_base_2(Vertex_handle v0,
Vertex_handle v1,
Vertex_handle v2)
: Fb(v0, v1, v2)
{}
Hyperbolic_triangulation_face_base_2(Vertex_handle v0,
Vertex_handle v1,
Vertex_handle v2,
Face_handle n0,
Face_handle n1,
Face_handle n2)
: Fb(v0, v1, v2, n0, n1, n2)
{}
static int ccw(int i) {return Triangulation_cw_ccw_2::ccw(i);}
static int cw(int i) {return Triangulation_cw_ccw_2::cw(i);}
CGAL::Object& tds_data() { return this->_tds_data; }
const CGAL::Object& tds_data() const { return this->_tds_data; }
private:
CGAL::Object _tds_data;
};
} // namespace CGAL
#endif //CGAL_HYPERBOLIC_TRIANGULATION_FACE_BASE_2_H

View File

@ -0,0 +1,143 @@
// Copyright (c) 2016-2018 INRIA Sophia Antipolis, INRIA Nancy (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0+
//
// Author(s) : Iordan Iordanov
//
#ifndef CGAL_EXACT_COMPLEX_H
#define CGAL_EXACT_COMPLEX_H
#include <CGAL/license/Hyperbolic_triangulation_2.h>
#include <CGAL/assertions.h>
#include <CGAL/number_utils.h>
#include <iostream>
#include <fstream>
// Complex number in the form a + bi, where a and b are of type NT.
// NT must be an exact number type, model of:
// + FieldWithRootOf
// + RealEmbeddable
// + FromDoubleConstructible
//
namespace CGAL {
template <class NumberType>
class Exact_complex
{
typedef Exact_complex<NumberType> Self;
private:
NumberType _a, _b;
public:
typedef NumberType NT;
Exact_complex() : _a(0), _b(0) {}
Exact_complex(NT a, NT b) : _a(a), _b(b) {}
NT real() const { return _a; }
void set_real(NT val) { _a = val; }
NT imag() const { return _b; }
void set_imag(NT val) { _b = val; }
Self conj() const { return Self(_a, -_b); }
NT square_modulus() const { return (_a*_a + _b*_b); }
NT modulus() const { return CGAL::sqrt(this->square_modulus()); }
Self reciprocal()
{
NT denom = _a*_a + _b*_b;
if(denom == NT(0))
return Self(0,0);
else
return Self(_a/denom, -_b/denom);
}
Self invert_in_unit_circle() { return this->reciprocal().conj(); }
template <class Circle_2>
Self invert_in_circle(Circle_2 c)
{
NT r2 = c.squared_radius();
NT xc = c.center().x();
NT yc = c.center().y();
NT denom = (_a - xc)*(_a - xc) + (_b - yc)*(_b - yc);
return Self(xc + r2*(_a-xc)/denom, yc + r2*(_b-yc)/denom);
}
Self operator+(const Self& other) const
{
return Self(this->_a + other._a, this->_b + other._b);
}
Self operator-(const Self& other) const
{
return Self(this->_a - other._a, this->_b - other._b);
}
Self operator*(const Self& other) const
{
NT rp = _a*other._a - _b*other._b;
NT ip = _b*other._a + _a*other._b;
return Self(rp, ip);
}
Self operator/(const Self& other) const
{
NT denom = other._a*other._a + other._b*other._b;
CGAL_assertion(denom != 0);
NT rp = _a*other._a + _b*other._b;
NT ip = _b*other._a - _a*other._b;
return Self(rp/denom, ip/denom);
}
};
template <class NT>
std::ostream& operator<<(std::ostream& s, const Exact_complex<NT>& c)
{
s << c.real() << (c.imag() >= 0 ? " + " : " - ") << abs(c.imag()) << "i";
return s;
}
// just to give an ordering
template<class NT>
bool operator==(const Exact_complex<NT>& lh, const Exact_complex<NT>& rh)
{
return (lh.real() == rh.real() && lh.imag() == rh.imag());
}
template<class NT>
bool operator!=(const Exact_complex<NT>& lh, const Exact_complex<NT>& rh)
{
return !operator==(lh, rh);
}
// just to give an ordering
template<class NT>
bool operator<(const Exact_complex<NT>& lh, const Exact_complex<NT>& rh)
{
return lh.square_modulus() < rh.square_modulus();
}
} // namespace CGAL
#endif // CGAL_EXACT_COMPLEX_H

View File

@ -0,0 +1,307 @@
// Copyright (c) 2010-2018 INRIA Sophia Antipolis, INRIA Nancy (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0+
//
// Author(s) : Mikhail Bogdanov
// Monique Teillaud <Monique.Teillaud@inria.fr>
#ifndef CGAL_HYPERBOLIC_DELAUNAY_TRIANGULATION_TRAITS_2_FUNCTIONS
#define CGAL_HYPERBOLIC_DELAUNAY_TRIANGULATION_TRAITS_2_FUNCTIONS
#include <CGAL/Origin.h>
#include <CGAL/enum.h>
namespace CGAL {
namespace internal {
// only used internally to construct the Euclidean circle or line supporting the hyperbolic
// bisector of two points
template <typename Traits>
class Construct_circle_or_line_supporting_bisector
{
typedef typename Traits::FT FT;
typedef typename Traits::Hyperbolic_point_2 Hyperbolic_point_2;
typedef typename Traits::Euclidean_line_2 Euclidean_line_2;
typedef typename Traits::Euclidean_circle_or_line_2 Euclidean_circle_or_line_2;
typedef typename Traits::Circle_2 Circle_2;
typedef typename Traits::Point_3 Point_3;
public:
Construct_circle_or_line_supporting_bisector(const Traits& gt = Traits()) : _gt(gt) {}
Euclidean_circle_or_line_2 operator()(const Hyperbolic_point_2& p,
const Hyperbolic_point_2& q) const
{
Hyperbolic_point_2 po = CGAL::ORIGIN;
if(_gt.compare_distance_2_object()(po, p, q) == EQUAL)
return _gt.construct_bisector_2_object()(p, q);
FT dop2 = p.x()*p.x() + p.y()*p.y();
FT doq2 = q.x()*q.x() + q.y()*q.y();
Point_3 p3(p.x(), p.y(), dop2);
Point_3 q3(q.x(), q.y(), doq2);
// TODO MT improve
// The cirle belongs to the pencil with limit points p and q
// p, q are zero-circles
// (x, y, xˆ2 + yˆ2 - rˆ2) = alpha*(xp, yp, xpˆ2 + ypˆ2) + (1-alpha)*(xq, yq, xqˆ2 + yqˆ2)
// xˆ2 + yˆ2 - rˆ2 = 1 (= radius of the Poincare disc)
FT op = p.x()*p.x() + p.y()*p.y();
FT oq = q.x()*q.x() + q.y()*q.y();
FT alpha = (FT(1) - oq) / (op - oq);
FT x = alpha*p.x() + (1-alpha)*q.x();
FT y = alpha*p.y() + (1-alpha)*q.y();
FT sq_radius = x*x + y*y - FT(1);
// TODO MT improve
// ?? orientation should depend on
// Compare_distance(O,p, q)
// so that p always on positive side
// ???
// CK does not care about orientation, circular arcs are
// considered in CCW order in any case
Euclidean_line_2 l = _gt.construct_bisector_2_object()(p, q);
Hyperbolic_point_2 middle = _gt.construct_midpoint_2_object()(p, q);
Hyperbolic_point_2 temp = middle + l.to_vector();
if(_gt.orientation_2_object()(middle, temp, Hyperbolic_point_2(x, y)) == ON_POSITIVE_SIDE)
return Circle_2(Hyperbolic_point_2(x, y), sq_radius, CLOCKWISE);
return Circle_2(Hyperbolic_point_2(x, y), sq_radius, COUNTERCLOCKWISE);
}
private:
const Traits& _gt;
}; // end Construct_supporting_circle_of_bisector
template <typename Traits>
class Construct_hyperbolic_segment_2
{
typedef typename Traits::FT FT;
typedef typename Traits::Point_2 Bare_point;
typedef typename Traits::Weighted_point_2 Weighted_point_2;
typedef typename Traits::Euclidean_segment_2 Euclidean_segment_2;
typedef typename Traits::Hyperbolic_point_2 Hyperbolic_point_2;
typedef typename Traits::Hyperbolic_segment_2 Hyperbolic_segment_2;
typedef typename Traits::Circle_2 Circle_2;
typedef typename Traits::Circular_arc_2 Circular_arc_2;
typedef typename Traits::Construct_weighted_circumcenter_2 Construct_weighted_circumcenter_2;
public:
Construct_hyperbolic_segment_2(const Traits& gt = Traits()) : _gt(gt) {}
typedef Hyperbolic_segment_2 result_type;
Hyperbolic_segment_2 operator()(const Hyperbolic_point_2& p,
const Hyperbolic_point_2& q) const
{
Origin o;
if(_gt.collinear_2_object()(p, q, Hyperbolic_point_2(o)))
return Euclidean_segment_2(p, q);
Weighted_point_2 wp(p);
Weighted_point_2 wq(q);
Weighted_point_2 wo(Hyperbolic_point_2(o), FT(1)); // Poincaré circle
Bare_point center = _gt.construct_weighted_circumcenter_2_object()(wp, wo, wq);
FT sq_radius = _gt.compute_squared_distance_2_object()(p, center);
Circle_2 circle = _gt.construct_circle_2_object()(center, sq_radius);
// uncomment!!!
//assert(circle.has_on_boundary(p) && circle.has_on_boundary(q));
if(_gt.orientation_2_object()(p, q, center) == LEFT_TURN)
return Circular_arc_2(circle, p, q);
return Circular_arc_2(circle, q, p);
}
private:
const Traits& _gt;
}; // end Construct_hyperbolic_segment_2
// For details see the JoCG paper (5:56-85, 2014)
template <typename Traits>
class Is_Delaunay_hyperbolic
{
public:
typedef typename Traits::FT FT;
typedef typename Traits::Hyperbolic_point_2 Hyperbolic_point_2;
typedef typename Traits::Direction_2 Direction_2;
typedef typename Traits::Point_3 Point_3;
typedef typename Traits::Vector_3 Vector_3;
Is_Delaunay_hyperbolic(const Traits& gt = Traits())
: _gt(gt)
{}
bool operator()(const Hyperbolic_point_2& p0,
const Hyperbolic_point_2& p1,
const Hyperbolic_point_2& p2) const
{
// @todo use _gt
Vector_3 v0 = Vector_3(p0.x()*p0.x() + p0.y()*p0.y(),
p1.x()*p1.x() + p1.y()*p1.y(),
p2.x()*p2.x() + p2.y()*p2.y());
Vector_3 v1 = Vector_3(p0.x(), p1.x(), p2.x());
Vector_3 v2 = Vector_3(p0.y(), p1.y(), p2.y());
Vector_3 v3 = Vector_3(FT(1), FT(1), FT(1));
FT dt0 = determinant(v0, v1, v3);
FT dt1 = determinant(v0, v2, v3);
FT dt2 = determinant(v0 - v3, v1, v2);
return (dt0*dt0 + dt1*dt1 - dt2*dt2 < 0);
}
bool operator()(const Hyperbolic_point_2& p0,
const Hyperbolic_point_2& p1,
const Hyperbolic_point_2& p2,
int& ind) const
{
if(this->operator()(p0, p1, p2) == false)
{
ind = find_non_hyperbolic_edge(p0, p1, p2);
return false;
}
return true;
}
private:
// assume the face (p0, p1, p2) is non-hyperbolic
int find_non_hyperbolic_edge(const Hyperbolic_point_2& p0,
const Hyperbolic_point_2& p1,
const Hyperbolic_point_2& p2) const
{
Vector_3 v0 = Vector_3(p0.x()*p0.x() + p0.y()*p0.y(),
p1.x()*p1.x() + p1.y()*p1.y(),
p2.x()*p2.x() + p2.y()*p2.y());
Vector_3 v1 = Vector_3(p0.x(), p1.x(), p2.x());
Vector_3 v2 = Vector_3(p0.y(), p1.y(), p2.y());
Vector_3 v3 = Vector_3(FT(1), FT(1), FT(1));
FT dt0 = determinant(v0, 2*v2, -v3);
FT dt1 = determinant(2*v1, v0, -v3);
FT dt2 = determinant(2*v1, 2*v2, -v3);
Direction_2 d0(p0.x()*dt2 - dt0, p0.y()*dt2 - dt1);
Direction_2 d1(p1.x()*dt2 - dt0, p1.y()*dt2 - dt1);
Direction_2 d2(p2.x()*dt2 - dt0, p2.y()*dt2 - dt1);
Direction_2 d(dt0, dt1);
if(d.counterclockwise_in_between(d0, d1))
return 2;
if(d.counterclockwise_in_between(d1, d2))
return 0;
return 1;
}
private:
const Traits& _gt;
}; // end Is_Delaunay_hyperbolic
template <typename Traits>
class Side_of_oriented_hyperbolic_segment_2
{
typedef typename Traits::FT FT;
typedef typename Traits::Point_2 Bare_point;
typedef typename Traits::Weighted_point_2 Weighted_point_2;
typedef typename Traits::Hyperbolic_point_2 Hyperbolic_point_2;
typedef typename Traits::Circle_2 Circle_2;
typedef typename Traits::Euclidean_line_2 Euclidean_line_2;
typedef typename Traits::Construct_weighted_circumcenter_2 Construct_weighted_circumcenter_2;
public:
typedef Oriented_side result_type;
Side_of_oriented_hyperbolic_segment_2(const Traits& gt = Traits()) : _gt(gt) {}
result_type operator()(const Hyperbolic_point_2& p,
const Hyperbolic_point_2& q,
const Hyperbolic_point_2& query) const
{
// Check first if the points are collinear with the origin
Circle_2 poincare(Hyperbolic_point_2(FT(0),FT(0)), FT(1));
Hyperbolic_point_2 O(FT(0), FT(0));
Orientation ori = _gt.orientation_2_object()(p, q, O);
if(ori == COLLINEAR)
{
Euclidean_line_2 seg(p, q);
Orientation qori = _gt.orientation_2_object()(p, q, query);
if(qori == COLLINEAR)
{
return ON_ORIENTED_BOUNDARY;
}
else
{
// It is sufficient that these are consistent.
if(qori == LEFT_TURN)
return ON_POSITIVE_SIDE;
else
return ON_NEGATIVE_SIDE;
}
}
Weighted_point_2 wp(p);
Weighted_point_2 wq(q);
Weighted_point_2 wo(O, FT(1)); // Poincaré circle
Bare_point center = _gt.construct_weighted_circumcenter_2_object()(wp, wo, wq);
FT sq_radius = _gt.compute_squared_distance_2_object()(p, center);
Circle_2 circle = _gt.construct_circle_2_object()(center, sq_radius);
Bounded_side bs = _gt.bounded_side_2_object()(circle, query);
if(bs == ON_BOUNDARY)
{
return ON_ORIENTED_BOUNDARY;
}
else
{
if(bs == ON_BOUNDED_SIDE)
return ON_POSITIVE_SIDE;
else
return ON_NEGATIVE_SIDE;
}
}
private:
const Traits& _gt;
};
} // end namespace internal
} // end namespace CGAL
#endif // CGAL_HYPERBOLIC_DELAUNAY_TRIANGULATION_TRAITS_2_FUNCTIONS

View File

@ -0,0 +1,2 @@
INRIA Sophia Antipolis -- Méditerranée (France)
and INRIA Nancy -- Grand Est (France)

View File

@ -0,0 +1,29 @@
Algebraic_foundations
Algebraic_kernel_for_circles
Arithmetic_kernel
CGAL_Core
Cartesian_kernel
Circular_kernel_2
Circulator
Distance_2
Distance_3
Filtered_kernel
Hash_map
Homogeneous_kernel
Hyperbolic_triangulation_2
Installation
Intersections_2
Intersections_3
Interval_support
Kernel_23
Kernel_d
Modular_arithmetic
Number_types
Polygon
Profiling_tools
Property_map
STL_Extension
Spatial_sorting
Stream_support
TDS_2
Triangulation_2

View File

@ -0,0 +1,3 @@
Package 2D hyperbolic triangulation: provides Delaunay triangulations
in the Poincaré disk model of the hyperbolic plane, with demos,
examples, and tests.

View File

@ -0,0 +1 @@
GPL (v3 or later)

View File

@ -0,0 +1,12 @@
The package 2D Hyperbolic Triangulation provides Delaunay triangulations
in the Poincaré disk model of the hyperbolic plane, complete with demos,
examples, and tests. The hyperbolic Delaunay triangulation defined by a
set of points in the Poincaré disk model is a simplicial sub-complex of
the Euclidean Delaunay triangulation defined by the same set of points in
the unit disk centered at the origin of the Euclidean plane. More information
is available in:
Mikhail Bogdanov, Olivier Devillers, and Monique Teillaud. Hyperbolic
Delaunay complexes and Voronoi diagrams made practical. Journal of
Computational Geometry, 5(1):5685, 2014.
URL: https://hal.inria.fr/hal-00961390,
doi:10.20382/jocg.v5i1a4.

View File

@ -0,0 +1 @@
Monique Teillaud <Monique.Teillaud@inria.fr>

View File

@ -0,0 +1,30 @@
# Created by the script cgal_create_cmake_script
# This is the CMake script for compiling a CGAL application.
project( Hyperbolic_triangulation_2_Tests )
cmake_minimum_required(VERSION 2.8.10)
find_package(CGAL QUIET COMPONENTS Core )
if ( CGAL_FOUND )
include( ${CGAL_USE_FILE} )
include( CGAL_CreateSingleSourceCGALProgram )
create_single_source_cgal_program( "ht2_test_clear.cpp" )
create_single_source_cgal_program( "ht2_test_locate.cpp" )
create_single_source_cgal_program( "ht2_test_remove.cpp" )
create_single_source_cgal_program( "ht2_test_swap.cpp" )
create_single_source_cgal_program( "ht2_test_copy.cpp" )
create_single_source_cgal_program( "ht2_test_hyperbolic_circulator.cpp" )
create_single_source_cgal_program( "ht2_test_insert_degenerate.cpp" )
else()
message(STATUS "This program requires the CGAL library, and will not be compiled.")
endif()

View File

@ -0,0 +1,56 @@
#include <CGAL/Hyperbolic_Delaunay_triangulation_2.h>
#include <CGAL/Hyperbolic_Delaunay_triangulation_traits_2.h>
#include <CGAL/point_generators_2.h>
typedef CGAL::Hyperbolic_Delaunay_triangulation_traits_2<> Traits;
typedef CGAL::Hyperbolic_Delaunay_triangulation_2<Traits> HDTriangulation;
typedef HDTriangulation::Point Point;
typedef CGAL::Random_points_in_square_2<
Point,
CGAL::Creator_uniform_2< double, Point > > Point_generator;
int main()
{
Point_generator gen(1.);
std::vector<Point> pts;
for (int i = 0; i < 100; ++i)
pts.push_back(*(++gen));
HDTriangulation tri;
tri.insert(pts.begin(), pts.end());
std::size_t nv = tri.number_of_vertices();
std::size_t nf = tri.number_of_hyperbolic_faces();
std::cout << " -------- inserting --------" << std::endl;
std::cout << "Vertices in triangulation: " << nv << std::endl;
std::cout << "Faces in triangulation: " << nf << std::endl;
std::cout << "Dimension of triangulation: " << tri.dimension() << std::endl;
assert(tri.dimension() == 2);
tri.clear();
std::cout << " -------- clearing --------" << std::endl;
std::cout << "Vertices in triangulation: " << tri.number_of_vertices() << std::endl;
std::cout << "Faces in triangulation: " << tri.number_of_hyperbolic_faces() << std::endl;
std::cout << "Dimension of triangulation: " << tri.dimension() << std::endl;
assert(tri.number_of_vertices() == 0);
assert(tri.number_of_hyperbolic_faces() == 0);
assert(tri.dimension() < 2);
tri.insert(pts.begin(), pts.end());
std::cout << " -------- re-inserting --------" << std::endl;
std::cout << "Vertices in triangulation: " << tri.number_of_vertices() << std::endl;
std::cout << "Faces in triangulation: " << tri.number_of_hyperbolic_faces() << std::endl;
std::cout << "Dimension of triangulation: " << tri.dimension() << std::endl;
assert(tri.number_of_hyperbolic_faces() == nf);
assert(tri.number_of_vertices() == nv);
assert(tri.dimension() == 2);
assert(tri.is_valid());
std::cout << " -------- SUCCESS --------" << std::endl;
return 0;
}

View File

@ -0,0 +1,41 @@
#include <CGAL/Hyperbolic_Delaunay_triangulation_2.h>
#include <CGAL/Hyperbolic_Delaunay_triangulation_traits_2.h>
#include <CGAL/point_generators_2.h>
typedef CGAL::Hyperbolic_Delaunay_triangulation_traits_2<> Traits;
typedef CGAL::Hyperbolic_Delaunay_triangulation_2<Traits> HDTriangulation;
typedef HDTriangulation::Point Point;
typedef HDTriangulation::Vertex_handle Vertex_handle;
typedef CGAL::Random_points_in_disc_2<
Point,
CGAL::Creator_uniform_2< double, Point > > Point_generator;
int main()
{
Point_generator gen(0.95);
std::vector<Point> pts1;
for (int i = 0; i < 75; ++i)
pts1.push_back(*(++gen));
HDTriangulation tri1;
tri1.insert(pts1.begin(), pts1.end());
std::cout << "Vertices in tri1: " << tri1.number_of_vertices() << std::endl;
std::cout << "Faces in tri1: " << tri1.number_of_hyperbolic_faces() << std::endl;
HDTriangulation tri2;
tri2 = tri1;
std::cout << "Vertices in tri2: " << tri2.number_of_vertices() << std::endl;
std::cout << "Faces in tri2: " << tri2.number_of_hyperbolic_faces() << std::endl;
assert(tri1.is_valid());
assert(tri2.is_valid());
assert(tri1.number_of_vertices() == tri2.number_of_vertices());
assert(tri1.number_of_hyperbolic_faces() == tri2.number_of_hyperbolic_faces());
std::cout << " -------- SUCCESS --------" << std::endl;
return 0;
}

View File

@ -0,0 +1,64 @@
#include <CGAL/Hyperbolic_Delaunay_triangulation_2.h>
#include <CGAL/Hyperbolic_Delaunay_triangulation_traits_2.h>
#include <CGAL/point_generators_2.h>
typedef CGAL::Hyperbolic_Delaunay_triangulation_traits_2<> Traits;
typedef CGAL::Hyperbolic_Delaunay_triangulation_2<Traits> HDTriangulation;
typedef HDTriangulation::FT FT;
typedef HDTriangulation::Point Point;
typedef HDTriangulation::Vertex_handle Vertex_handle;
typedef HDTriangulation::Vertex_circulator Vertex_circulator;
int main()
{
HDTriangulation tri;
std::cout << "Constructing points..." << std::endl;
FT F100(100);
Point p1 = tri.geom_traits().construct_point_2_object()(-FT(62)/F100, -FT(49)/F100);
Point p2 = tri.geom_traits().construct_point_2_object()(-FT(57)/F100, FT(68)/F100);
Point p3 = tri.geom_traits().construct_point_2_object()( FT(60)/F100, FT(58)/F100);
Point p4 = tri.geom_traits().construct_point_2_object()( FT(48)/F100, -FT(64)/F100);
Point p5 = tri.geom_traits().construct_point_2_object()(-FT(07)/F100, -FT(04)/F100);
std::cout << "Inserting points..." << std::endl;
Vertex_handle v1 = tri.insert(p1);
Vertex_handle v2 = tri.insert(p2);
Vertex_handle v3 = tri.insert(p3);
Vertex_handle v4 = tri.insert(p4);
Vertex_handle v5 = tri.insert(p5);
std::cout << "Testing first circulator..." << std::endl;
Vertex_circulator vc1 = tri.adjacent_vertices(v5);
assert(vc1 == v1 || vc1 == v2 || vc1 == v3 || vc1 == v4);
++vc1;
assert(vc1 == v1 || vc1 == v2 || vc1 == v3 || vc1 == v4);
++vc1;
assert(vc1 == v1 || vc1 == v2 || vc1 == v3 || vc1 == v4);
++vc1;
assert(vc1 == v1 || vc1 == v2 || vc1 == v3 || vc1 == v4);
--vc1;
assert(vc1 == v1 || vc1 == v2 || vc1 == v3 || vc1 == v4);
--vc1;
assert(vc1 == v1 || vc1 == v2 || vc1 == v3 || vc1 == v4);
--vc1;
assert(vc1 == v1 || vc1 == v2 || vc1 == v3 || vc1 == v4);
--vc1;
assert(vc1 == v1 || vc1 == v2 || vc1 == v3 || vc1 == v4);
std::cout << " -------- SUCCESS --------" << std::endl;
std::cout << std::endl << "Testing second circulator..." << std::endl;
Vertex_circulator vc2 = tri.adjacent_vertices(v1);
assert(vc2 == v5);
++vc2;
assert(vc2 == v5);
--vc2;
assert(vc2 == v5);
std::cout << " -------- SUCCESS --------" << std::endl;
return 0;
}

View File

@ -0,0 +1,91 @@
#include <CGAL/Hyperbolic_Delaunay_triangulation_2.h>
#include <CGAL/Hyperbolic_Delaunay_triangulation_traits_2.h>
typedef CGAL::Hyperbolic_Delaunay_triangulation_traits_2<> Traits;
typedef CGAL::Hyperbolic_Delaunay_triangulation_2<Traits> HDTriangulation;
typedef HDTriangulation::Point Point;
typedef Traits::FT FT;
typedef Traits::Circle_2 Circle;
typedef Traits::Euclidean_line_2 ELine;
typedef Traits::Construct_hyperbolic_segment_2 CHSegment;
typedef Traits::Construct_intersection_2 CIntersection;
int main()
{
std::vector<Point> P(10), Pp(10);
std::vector<ELine> S(10), Sp(10);
P[0] = Point( FT(2)/FT(10), FT(8)/FT(10));
Pp[0] = Point( -FT(2)/FT(10), -FT(8)/FT(10));
P[1] = Point( FT(4)/FT(10), FT(8)/FT(10));
Pp[1] = Point( -FT(4)/FT(10), -FT(8)/FT(10));
P[2] = Point( FT(6)/FT(10), FT(6)/FT(10));
Pp[2] = Point( -FT(6)/FT(10), -FT(6)/FT(10));
P[3] = Point( FT(8)/FT(10), FT(4)/FT(10));
Pp[3] = Point( -FT(8)/FT(10), -FT(4)/FT(10));
P[4] = Point( FT(8)/FT(10), FT(2)/FT(10));
Pp[4] = Point( -FT(8)/FT(10), -FT(2)/FT(10));
P[5] = Point( FT(8)/FT(10), -FT(2)/FT(10));
Pp[5] = Point( -FT(8)/FT(10), FT(2)/FT(10));
P[6] = Point( FT(8)/FT(10), -FT(4)/FT(10));
Pp[6] = Point( -FT(8)/FT(10), FT(4)/FT(10));
P[7] = Point( FT(6)/FT(10), -FT(6)/FT(10));
Pp[7] = Point( -FT(6)/FT(10), FT(6)/FT(10));
P[8] = Point( FT(4)/FT(10), -FT(8)/FT(10));
Pp[9] = Point( -FT(4)/FT(10), FT(8)/FT(10));
P[9] = Point( FT(2)/FT(10), -FT(8)/FT(10));
Pp[9] = Point( -FT(2)/FT(10), FT(8)/FT(10));
Point O(FT(0), FT(0));
for (int i = 0; i < 10; i++) {
S[i] = ELine( P[i], Pp[i] );
}
HDTriangulation tri;
Circle c1( O, FT(1)/FT(3) );
for (int i = 0; i < 10; i++) {
std::cout << "--- c1, i = " << i << std::endl;
std::pair<Point, Point> res = CIntersection()(c1, S[i]);
tri.insert(res.first);
tri.insert(res.second);
}
Circle c2( O, FT(1)/FT(2) );
for (int i = 0; i < 10; i++) {
std::cout << "--- c2, i = " << i << std::endl;
std::pair<Point, Point> res = CIntersection()(c2, S[i]);
tri.insert(res.first);
tri.insert(res.second);
}
Circle c3( O, FT(2)/FT(3) );
for (int i = 0; i < 10; i++) {
std::cout << "--- c3, i = " << i << std::endl;
std::pair<Point, Point> res = CIntersection()(c3, S[i]);
tri.insert(res.first);
tri.insert(res.second);
}
std::cout << " -------- inserting --------" << std::endl;
std::cout << "Vertices in triangulation: " << tri.number_of_vertices() << std::endl;
std::cout << "Faces in triangulation: " << tri.number_of_hyperbolic_faces() << std::endl;
std::cout << "Dimension of triangulation: " << tri.dimension() << std::endl;
assert(tri.dimension() == 2);
assert(tri.is_valid());
std::cout << " -------- SUCCESS --------" << std::endl;
return 0;
}

View File

@ -0,0 +1,65 @@
#include <CGAL/Hyperbolic_Delaunay_triangulation_2.h>
#include <CGAL/Hyperbolic_Delaunay_triangulation_traits_2.h>
#include <CGAL/point_generators_2.h>
typedef CGAL::Hyperbolic_Delaunay_triangulation_traits_2<> Traits;
typedef CGAL::Hyperbolic_Delaunay_triangulation_2<Traits> HDTriangulation;
typedef HDTriangulation::FT FT;
typedef HDTriangulation::Point Point;
typedef HDTriangulation::Face_handle Face_handle;
typedef HDTriangulation::Locate_type Locate_type;
typedef HDTriangulation::Hyperbolic_segment Hyperbolic_segment;
int main()
{
FT F100(100);
Point p1(-FT(81)/F100, -FT(35)/F100 );
Point p2(-FT(78)/F100, FT(12)/F100 );
Point p3(-FT(64)/F100, FT(59)/F100 );
Point p4(-FT(31)/F100, -FT(25)/F100 );
Point p5( FT(66)/F100, FT(18)/F100 );
HDTriangulation tri;
tri.insert(p1);
tri.insert(p2);
tri.insert(p3);
tri.insert(p4);
tri.insert(p5);
std::size_t nv = tri.number_of_vertices();
std::size_t nf = tri.number_of_hyperbolic_faces();
std::cout << " -------- inserting --------" << std::endl;
std::cout << "Vertices in triangulation: " << nv << std::endl;
std::cout << "Faces in triangulation: " << nf << std::endl;
std::cout << "Dimension of triangulation: " << tri.dimension() << std::endl;
assert(tri.dimension() == 2);
int idx;
Face_handle fh;
// Test a vertex location
Locate_type lt1;
fh = tri.locate(p1, lt1, idx);
assert(lt1 == HDTriangulation::VERTEX);
// Test an edge location
Hyperbolic_segment s1 = tri.geom_traits().construct_hyperbolic_segment_2_object()(p1, p2);
Hyperbolic_segment b1 = tri.geom_traits().construct_hyperbolic_bisector_2_object()(p1, p2);
Point i1 = tri.geom_traits().construct_intersection_2_object()(s1, b1);
Locate_type lt2;
fh = tri.locate(i1, lt2, idx);
assert(lt2 == HDTriangulation::EDGE);
// Test a "dangling" edge location
Hyperbolic_segment s2 = tri.geom_traits().construct_hyperbolic_segment_2_object()(p4, p5);
Hyperbolic_segment b2 = tri.geom_traits().construct_hyperbolic_bisector_2_object()(p4, p5);
Point i2 = tri.geom_traits().construct_intersection_2_object()(s2, b2);
Locate_type lt3;
fh = tri.locate(i2, lt3, idx);
assert(lt3 == HDTriangulation::EDGE);
std::cout << " -------- SUCCESS --------" << std::endl;
return 0;
}

View File

@ -0,0 +1,72 @@
#include <CGAL/Hyperbolic_Delaunay_triangulation_2.h>
#include <CGAL/Hyperbolic_Delaunay_triangulation_traits_2.h>
#include <CGAL/point_generators_2.h>
typedef CGAL::Hyperbolic_Delaunay_triangulation_traits_2<> Traits;
typedef CGAL::Hyperbolic_Delaunay_triangulation_2<Traits> HDTriangulation;
typedef HDTriangulation::Point Point;
typedef HDTriangulation::Vertex_handle Vertex_handle;
typedef CGAL::Random_points_in_square_2<
Point,
CGAL::Creator_uniform_2< double, Point > > Point_generator;
int main()
{
Point_generator gen(1.);
std::vector<Point> pts;
for (int i = 0; i < 100; ++i)
pts.push_back(*(++gen));
HDTriangulation tri;
std::vector<Vertex_handle> verts;
for (unsigned int i = 0; i < pts.size(); ++i)
verts.push_back(tri.insert(pts[i]));
std::size_t nv = tri.number_of_vertices();
std::size_t nf = tri.number_of_hyperbolic_faces();
std::cout << " -------- inserting --------" << std::endl;
std::cout << "Vertices in triangulation: " << nv << std::endl;
std::cout << "Faces in triangulation: " << nf << std::endl;
std::cout << "Dimension of triangulation: " << tri.dimension() << std::endl;
assert(tri.dimension() == 2);
std::cout << " -------- removing --------" << std::endl;
for (unsigned int i = 0; i < verts.size(); ++i)
{
tri.remove(verts[i]);
}
std::cout << "Vertices in triangulation: " << tri.number_of_vertices() << std::endl;
std::cout << "Faces in triangulation: " << tri.number_of_hyperbolic_faces() << std::endl;
std::cout << "Dimension of triangulation: " << tri.dimension() << std::endl;
assert(tri.is_valid());
std::cout << " -------- SUCCESS --------" << std::endl;
HDTriangulation tri2;
verts.clear();
for (unsigned int i = 0; i < pts.size(); ++i)
verts.push_back(tri2.insert(pts[i]));
std::cout << " -------- inserting --------" << std::endl;
std::cout << "Vertices in triangulation: " << tri2.number_of_vertices() << std::endl;
std::cout << "Faces in triangulation: " << tri2.number_of_hyperbolic_faces() << std::endl;
std::cout << "Dimension of triangulation: " << tri2.dimension() << std::endl;
assert(tri2.dimension() == 2);
tri2.remove(verts.begin(), verts.end());
std::cout << "Vertices in triangulation: " << tri2.number_of_vertices() << std::endl;
std::cout << "Faces in triangulation: " << tri2.number_of_hyperbolic_faces() << std::endl;
std::cout << "Dimension of triangulation: " << tri2.dimension() << std::endl;
assert(tri2.is_valid());
std::cout << " -------- SUCCESS --------" << std::endl;
return 0;
}

View File

@ -0,0 +1,56 @@
#include <CGAL/Hyperbolic_Delaunay_triangulation_2.h>
#include <CGAL/Hyperbolic_Delaunay_triangulation_traits_2.h>
#include <CGAL/point_generators_2.h>
typedef CGAL::Hyperbolic_Delaunay_triangulation_traits_2<> Traits;
typedef CGAL::Hyperbolic_Delaunay_triangulation_2<Traits> HDTriangulation;
typedef HDTriangulation::Point Point;
typedef HDTriangulation::Vertex_handle Vertex_handle;
typedef CGAL::Random_points_in_disc_2<
Point,
CGAL::Creator_uniform_2< double, Point > > Point_generator;
int main()
{
Point_generator gen(0.95);
std::vector<Point> pts1;
for (int i = 0; i < 75; ++i)
pts1.push_back(*(++gen));
std::vector<Point> pts2;
for (int i = 0; i < 150; ++i)
pts2.push_back(*(++gen));
HDTriangulation tri1;
tri1.insert(pts1.begin(), pts1.end());
std::cout << "Vertices in tri1: " << tri1.number_of_vertices() << std::endl;
std::cout << "Faces in tri1: " << tri1.number_of_hyperbolic_faces() << std::endl;
HDTriangulation tri2;
tri2.insert(pts2.begin(), pts2.end());
std::cout << "Vertices in tri2: " << tri2.number_of_vertices() << std::endl;
std::cout << "Faces in tri2: " << tri2.number_of_hyperbolic_faces() << std::endl;
assert(tri1.is_valid());
assert(tri2.is_valid());
tri1.swap(tri2);
std::cout << " -------- AFTER SWAP --------" << std::endl;
std::cout << "Vertices in tri1: " << tri1.number_of_vertices() << std::endl;
std::cout << "Faces in tri1: " << tri1.number_of_hyperbolic_faces() << std::endl;
std::cout << "Vertices in tri2: " << tri2.number_of_vertices() << std::endl;
std::cout << "Faces in tri2: " << tri2.number_of_hyperbolic_faces() << std::endl;
assert(tri1.is_valid());
assert(tri2.is_valid());
std::cout << " -------- SUCCESS --------" << std::endl;
return 0;
}

View File

@ -6,6 +6,19 @@ Release 4.14
Release date: March 2019
### 2D Periodic Hyperbolic Triangulations (new package)
- This package allows the computation of Delaunay triangulations of the Bolza surface.
The Bolza surface is the most symmetric hyperbolic surface of genus 2. Its fundamental
domain is the regular hyperbolic octagon with angles π/4 centered at the origin of the
Poincaré disk. Triangulations of the Bolza surface can be seen as triangulations of the
hyperbolic plane that are periodic in the four directions defined by the sides of this
regular octagon.
### 2D Hyperbolic Triangulations (new package)
- This package allows the computation of Delaunay Triangulations of sets of points in the
Poincaré disk, which is one of the conformal models for the hyperbolic plane.
### The Heat Method (new package)
- This package provides an algorithm that solves the single- or multiple-source
shortest path problem by returning an approximation of the geodesic distance

View File

@ -136,6 +136,14 @@ macro(check_cgal_component COMPONENT)
else()
set( CGAL_Qt5_FOUND TRUE )
endif()
elseif("${CGAL_LIB}" STREQUAL "CGAL_Core")
include("${CGAL_MODULES_DIR}/CGAL_SetupCGAL_CoreDependencies.cmake")
if(CGAL_Core_MISSING_DEPS)
set( CGAL_Core_FOUND FALSE )
message(STATUS "libCGAL_Core is missing the dependencies: ${CGAL_Core_MISSING_DEPS} cannot be configured.")
else()
set( CGAL_Core_FOUND TRUE )
endif()
else("${CGAL_LIB}" STREQUAL "CGAL_Qt5")
# Librairies that have no dependencies
set( ${CGAL_LIB}_FOUND TRUE )

View File

@ -111,6 +111,14 @@ macro(check_cgal_component COMPONENT)
else()
set( CGAL_Qt5_FOUND TRUE )
endif()
elseif("${CGAL_LIB}" STREQUAL "CGAL_Core")
include("${CGAL_MODULES_DIR}/CGAL_SetupCGAL_CoreDependencies.cmake")
if(CGAL_Core_MISSING_DEPS)
set( CGAL_Core_FOUND FALSE )
message(STATUS "libCGAL_Core is missing the dependencies: ${CGAL_Core_MISSING_DEPS} cannot be configured.")
else()
set( CGAL_Core_FOUND TRUE )
endif()
else("${CGAL_LIB}" STREQUAL "CGAL_Qt5")
# Librairies that have no dependencies
set( ${CGAL_LIB}_FOUND TRUE )

View File

@ -17,17 +17,19 @@ if(CGAL_SetupGMP_included OR CGAL_DISABLE_GMP)
endif()
set(CGAL_SetupGMP_included TRUE)
# Locally setting of CMAKE_MODULE_PATH, not exported to parent scope.
# That is required to find the FindGMP and FindMPFR modules.
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CGAL_MODULES_DIR})
find_package(GMP REQUIRED)
find_package(MPFR REQUIRED)
if(NOT DEFINED WITH_GMPXX)
option(CGAL_WITH_GMPXX "Use CGAL with GMPXX: use C++ classes of GNU MP instead of CGAL wrappers" OFF)
endif()
set(CGAL_GMPXX_find_package_keyword QUIET)
if(WITH_GMPXX OR CGAL_WITH_GMPXX)
set(CGAL_GMPXX_find_package_keyword REQUIRED)
find_package(GMPXX REQUIRED)
endif()
find_package(GMPXX ${CGAL_GMPXX_find_package_keyword})
#.rst:
# Provided Functions

View File

@ -20,16 +20,12 @@
//
// Warning: this file is generated, see include/CGAL/licence/README.md
#ifndef CGAL_LICENSE_AABB_TREE_H
#define CGAL_LICENSE_AABB_TREE_H
#include <CGAL/config.h>
#include <CGAL/license.h>
#ifdef CGAL_AABB_TREE_COMMERCIAL_LICENSE
# if CGAL_AABB_TREE_COMMERCIAL_LICENSE < CGAL_RELEASE_DATE
@ -42,8 +38,8 @@
# ifdef CGAL_LICENSE_ERROR
# error "Your commercial license for CGAL does not cover this release \
of the 3D Fast Intersection and Distance Computation package. \
You get this error, as you defined CGAL_LICENSE_ERROR."
of the 3D Fast Intersection and Distance Computation package. \
You get this error, as you defined CGAL_LICENSE_ERROR."
# endif // CGAL_LICENSE_ERROR
# endif // CGAL_AABB_TREE_COMMERCIAL_LICENSE < CGAL_RELEASE_DATE
@ -58,10 +54,10 @@ You get this error, as you defined CGAL_LICENSE_ERROR."
# ifdef CGAL_LICENSE_ERROR
# error "The macro CGAL_AABB_TREE_COMMERCIAL_LICENSE is not defined.\
You use the CGAL 3D Fast Intersection and Distance Computation package under the terms of \
the GPLv3+. You get this error, as you defined CGAL_LICENSE_ERROR."
You use the CGAL 3D Fast Intersection and Distance Computation package under the terms of \
the GPLv3+. You get this error, as you defined CGAL_LICENSE_ERROR."
# endif // CGAL_LICENSE_ERROR
#endif // no CGAL_AABB_TREE_COMMERCIAL_LICENSE
#endif // CGAL_LICENSE_CHECK_AABB_TREE_H
#endif // CGAL_LICENSE_AABB_TREE_H

View File

@ -20,16 +20,12 @@
//
// Warning: this file is generated, see include/CGAL/licence/README.md
#ifndef CGAL_LICENSE_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_H
#define CGAL_LICENSE_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_H
#include <CGAL/config.h>
#include <CGAL/license.h>
#ifdef CGAL_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_COMMERCIAL_LICENSE
# if CGAL_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_COMMERCIAL_LICENSE < CGAL_RELEASE_DATE
@ -42,8 +38,8 @@
# ifdef CGAL_LICENSE_ERROR
# error "Your commercial license for CGAL does not cover this release \
of the Advancing Front Surface Reconstruction package. \
You get this error, as you defined CGAL_LICENSE_ERROR."
of the Advancing Front Surface Reconstruction package. \
You get this error, as you defined CGAL_LICENSE_ERROR."
# endif // CGAL_LICENSE_ERROR
# endif // CGAL_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_COMMERCIAL_LICENSE < CGAL_RELEASE_DATE
@ -58,10 +54,10 @@ You get this error, as you defined CGAL_LICENSE_ERROR."
# ifdef CGAL_LICENSE_ERROR
# error "The macro CGAL_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_COMMERCIAL_LICENSE is not defined.\
You use the CGAL Advancing Front Surface Reconstruction package under the terms of \
the GPLv3+. You get this error, as you defined CGAL_LICENSE_ERROR."
You use the CGAL Advancing Front Surface Reconstruction package under the terms of \
the GPLv3+. You get this error, as you defined CGAL_LICENSE_ERROR."
# endif // CGAL_LICENSE_ERROR
#endif // no CGAL_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_COMMERCIAL_LICENSE
#endif // CGAL_LICENSE_CHECK_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_H
#endif // CGAL_LICENSE_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_H

View File

@ -20,16 +20,12 @@
//
// Warning: this file is generated, see include/CGAL/licence/README.md
#ifndef CGAL_LICENSE_ALPHA_SHAPES_2_H
#define CGAL_LICENSE_ALPHA_SHAPES_2_H
#include <CGAL/config.h>
#include <CGAL/license.h>
#ifdef CGAL_ALPHA_SHAPES_2_COMMERCIAL_LICENSE
# if CGAL_ALPHA_SHAPES_2_COMMERCIAL_LICENSE < CGAL_RELEASE_DATE
@ -42,8 +38,8 @@
# ifdef CGAL_LICENSE_ERROR
# error "Your commercial license for CGAL does not cover this release \
of the 2D Alpha Shapes package. \
You get this error, as you defined CGAL_LICENSE_ERROR."
of the 2D Alpha Shapes package. \
You get this error, as you defined CGAL_LICENSE_ERROR."
# endif // CGAL_LICENSE_ERROR
# endif // CGAL_ALPHA_SHAPES_2_COMMERCIAL_LICENSE < CGAL_RELEASE_DATE
@ -58,10 +54,10 @@ You get this error, as you defined CGAL_LICENSE_ERROR."
# ifdef CGAL_LICENSE_ERROR
# error "The macro CGAL_ALPHA_SHAPES_2_COMMERCIAL_LICENSE is not defined.\
You use the CGAL 2D Alpha Shapes package under the terms of \
the GPLv3+. You get this error, as you defined CGAL_LICENSE_ERROR."
You use the CGAL 2D Alpha Shapes package under the terms of \
the GPLv3+. You get this error, as you defined CGAL_LICENSE_ERROR."
# endif // CGAL_LICENSE_ERROR
#endif // no CGAL_ALPHA_SHAPES_2_COMMERCIAL_LICENSE
#endif // CGAL_LICENSE_CHECK_ALPHA_SHAPES_2_H
#endif // CGAL_LICENSE_ALPHA_SHAPES_2_H

View File

@ -20,16 +20,12 @@
//
// Warning: this file is generated, see include/CGAL/licence/README.md
#ifndef CGAL_LICENSE_ALPHA_SHAPES_3_H
#define CGAL_LICENSE_ALPHA_SHAPES_3_H
#include <CGAL/config.h>
#include <CGAL/license.h>
#ifdef CGAL_ALPHA_SHAPES_3_COMMERCIAL_LICENSE
# if CGAL_ALPHA_SHAPES_3_COMMERCIAL_LICENSE < CGAL_RELEASE_DATE
@ -42,8 +38,8 @@
# ifdef CGAL_LICENSE_ERROR
# error "Your commercial license for CGAL does not cover this release \
of the 3D Alpha Shapes package. \
You get this error, as you defined CGAL_LICENSE_ERROR."
of the 3D Alpha Shapes package. \
You get this error, as you defined CGAL_LICENSE_ERROR."
# endif // CGAL_LICENSE_ERROR
# endif // CGAL_ALPHA_SHAPES_3_COMMERCIAL_LICENSE < CGAL_RELEASE_DATE
@ -58,10 +54,10 @@ You get this error, as you defined CGAL_LICENSE_ERROR."
# ifdef CGAL_LICENSE_ERROR
# error "The macro CGAL_ALPHA_SHAPES_3_COMMERCIAL_LICENSE is not defined.\
You use the CGAL 3D Alpha Shapes package under the terms of \
the GPLv3+. You get this error, as you defined CGAL_LICENSE_ERROR."
You use the CGAL 3D Alpha Shapes package under the terms of \
the GPLv3+. You get this error, as you defined CGAL_LICENSE_ERROR."
# endif // CGAL_LICENSE_ERROR
#endif // no CGAL_ALPHA_SHAPES_3_COMMERCIAL_LICENSE
#endif // CGAL_LICENSE_CHECK_ALPHA_SHAPES_3_H
#endif // CGAL_LICENSE_ALPHA_SHAPES_3_H

View File

@ -20,16 +20,12 @@
//
// Warning: this file is generated, see include/CGAL/licence/README.md
#ifndef CGAL_LICENSE_APOLLONIUS_GRAPH_2_H
#define CGAL_LICENSE_APOLLONIUS_GRAPH_2_H
#include <CGAL/config.h>
#include <CGAL/license.h>
#ifdef CGAL_APOLLONIUS_GRAPH_2_COMMERCIAL_LICENSE
# if CGAL_APOLLONIUS_GRAPH_2_COMMERCIAL_LICENSE < CGAL_RELEASE_DATE
@ -42,8 +38,8 @@
# ifdef CGAL_LICENSE_ERROR
# error "Your commercial license for CGAL does not cover this release \
of the 2D Apollonius Graphs (Delaunay Graphs of Disks) package. \
You get this error, as you defined CGAL_LICENSE_ERROR."
of the 2D Apollonius Graphs (Delaunay Graphs of Disks) package. \
You get this error, as you defined CGAL_LICENSE_ERROR."
# endif // CGAL_LICENSE_ERROR
# endif // CGAL_APOLLONIUS_GRAPH_2_COMMERCIAL_LICENSE < CGAL_RELEASE_DATE
@ -58,10 +54,10 @@ You get this error, as you defined CGAL_LICENSE_ERROR."
# ifdef CGAL_LICENSE_ERROR
# error "The macro CGAL_APOLLONIUS_GRAPH_2_COMMERCIAL_LICENSE is not defined.\
You use the CGAL 2D Apollonius Graphs (Delaunay Graphs of Disks) package under the terms of \
the GPLv3+. You get this error, as you defined CGAL_LICENSE_ERROR."
You use the CGAL 2D Apollonius Graphs (Delaunay Graphs of Disks) package under the terms of \
the GPLv3+. You get this error, as you defined CGAL_LICENSE_ERROR."
# endif // CGAL_LICENSE_ERROR
#endif // no CGAL_APOLLONIUS_GRAPH_2_COMMERCIAL_LICENSE
#endif // CGAL_LICENSE_CHECK_APOLLONIUS_GRAPH_2_H
#endif // CGAL_LICENSE_APOLLONIUS_GRAPH_2_H

Some files were not shown because too many files have changed in this diff Show More