Modifications to Dehn's algorithm and reorganization of classes hierarchy (inheriting from Misha's classes)

This commit is contained in:
Iordan Iordanov 2016-03-22 10:07:07 +01:00
parent 1b9351f8fb
commit 2a3e9bac34
14 changed files with 631 additions and 7191 deletions

View File

@ -19,7 +19,7 @@ include(${CGAL_USE_FILE})
find_package(Qt5 QUIET COMPONENTS Widgets)
include_directories (BEFORE ../../include include ../../../Hyperbolic_triangulation_2/include)
include_directories (BEFORE ../../../Hyperbolic_triangulation_2/include ../../include include)
# ui files, created with Qt Designer
qt5_wrap_ui( uis Periodic_4_hyperbolic_triangulation_2.ui )
@ -30,12 +30,6 @@ qt5_add_resources ( RESOURCE_FILES resources/Periodic_4_hyperbolic_triangulation
# cpp files
add_executable ( Periodic_4_hyperbolic_triangulation_2_demo Periodic_4_hyperbolic_triangulation_2_demo.cpp )
qt5_use_modules( Periodic_4_hyperbolic_triangulation_2_demo Widgets)
add_to_cached_list( CGAL_EXECUTABLE_TARGETS Periodic_4_hyperbolic_triangulation_2_demo )
target_link_libraries( Periodic_4_hyperbolic_triangulation_2_demo ${CGAL_LIBRARIES} ${QT_LIBRARIES} ${CGAL_QT_LIBRARIES} )
add_executable ( Periodic_4_hyperbolic_Delaunay_triangulation_2_demo Periodic_4_hyperbolic_Delaunay_triangulation_2_demo.cpp )
qt5_use_modules( Periodic_4_hyperbolic_Delaunay_triangulation_2_demo Widgets)
add_to_cached_list( CGAL_EXECUTABLE_TARGETS Periodic_4_hyperbolic_Delaunay_triangulation_2_demo )

View File

@ -4,15 +4,17 @@
#include <CGAL/Triangulation_vertex_base_with_info_2.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Delaunay_hyperbolic_triangulation_2.h>
#include <CGAL/Periodic_4_hyperbolic_Delaunay_triangulation_2.h>
#include <CGAL/Periodic_4_hyperbolic_Delaunay_triangulation_traits_2.h>
// to be deleted
#include <CGAL/Qt/HyperbolicPainterOstream.h>
//
#include <CGAL/point_generators_2.h>
// unique words
#include <CGAL/Square_root_2_field.h>
#include <CGAL/Hyperbolic_octagon_group.h>
#include <CGAL/Hyperbolic_random_points_in_disc_2.h>
// to be deleted (iiordano: why?)
#include <CGAL/Qt/HyperbolicPainterOstream.h>
// for viewportsBbox
#include <CGAL/Qt/utility.h>
// Qt headers
#include <QtGui>
@ -22,50 +24,42 @@
#include <QInputDialog>
#include <QGraphicsEllipseItem>
// for filtering
#include <set>
#include <string>
// GraphicsView items and event filters (input classes)
#include "CGAL/Qt/TriangulationCircumcircle.h"
#include "CGAL/Qt/TriangulationMovingPoint.h"
#include "CGAL/Qt/TriangulationConflictZone.h"
#include "CGAL/Qt/TriangulationRemoveVertex.h"
#include "CGAL/Qt/TriangulationPointInputAndConflictZone.h"
//#include <CGAL/Qt/TriangulationGraphicsItem.h>
#include <CGAL/Qt/VoronoiGraphicsItem.h>
// store color
#include <CGAL/TranslationInfo.h>
// visualise color
#include <CGAL/Qt/TriangulationGraphicsItemWithColorInfo.h>
// unique words
//#include <temp.h>
#include <CGAL/Square_root_2_field.h>
#include <CGAL/Hyperbolic_octagon_group.h>
#include <CGAL/Hyperbolic_random_points_in_disc_2.h>
// dummy points
//#include <CGAL/Periodic_2_hyperbolic_triangulation_dummy.h>
// for filtering
#include <set>
// for viewportsBbox
#include <CGAL/Qt/utility.h>
// the two base classes
#include "ui_Delaunay_triangulation_2.h"
#include <CGAL/Qt/TriangulationGraphicsItemWithColorInfo.h> // Visualise color
#include <CGAL/TranslationInfo.h> // Store color
#include <CGAL/Qt/DemosMainWindow.h>
#define OPTION_INSERT_DUMMY_POINTS 0
#define OPTION_INSERT_FIELD_DUMMY_POINTS 0
#define OPTION_INSERT_DUMMY_POINTS 0
// dummy points
#if OPTION_INSERT_DUMMY_POINTS == 1
#include <CGAL/Periodic_4_hyperbolic_Delaunay_triangulation_dummy.h>
#endif
// the two base classes
#include "ui_Periodic_4_hyperbolic_Delaunay_triangulation_2.h"
typedef CGAL::Exact_predicates_inexact_constructions_kernel InR;
typedef CGAL::Exact_predicates_exact_constructions_kernel R;
typedef CGAL::Triangulation_hyperbolic_traits_2<R> K;
typedef CGAL::Triangulation_hyperbolic_traits_2<R> THT2;
typedef CGAL::Periodic_4_hyperbolic_Delaunay_triangulation_traits_2<R>
K;
typedef K::Point_2 Point;
// keep color
typedef TranslationInfo<std::string> Vb_info;
@ -73,12 +67,9 @@ typedef CGAL::Triangulation_vertex_base_with_info_2< Vb_info, K >
Vb;
typedef CGAL::Triangulation_face_base_with_info_2 <CGAL::Hyperbolic_face_info_2, K >
Fb;
typedef CGAL::Delaunay_hyperbolic_triangulation_2< K, CGAL::Triangulation_data_structure_2<Vb, Fb> >
typedef CGAL::Periodic_4_hyperbolic_Delaunay_triangulation_2< K, CGAL::Triangulation_data_structure_2<Vb, Fb> >
Delaunay;
typedef Delaunay::Vertex_handle Vertex_handle;
struct PointsComparator {
@ -103,12 +94,12 @@ double PointsComparator::eps = 0.0001;
string glabels[] = { "a", "\\bar{b}", "c", "\\bar{d}", "\\bar{a}", "b", "\\bar{c}", "d" };
void recurr(vector<HyperbolicOctagonGroup>& v, vector<HyperbolicOctagonGroup> g, int depth = 1) {
void recurr(vector<Octagon_group>& v, vector<Octagon_group> g, int depth = 1) {
if (depth > 1) {
recurr(v, g, depth-1);
vector<HyperbolicOctagonGroup> tmp;
vector<Octagon_group> tmp;
vector<string> tmpw;
for (int i = 0; i < v.size(); i++) {
tmp.push_back(v[i]);
@ -127,24 +118,24 @@ void recurr(vector<HyperbolicOctagonGroup>& v, vector<HyperbolicOctagonGroup> g,
}
void my_unique_words(std::vector<Point>& p, Point input, int length) {
std::vector<HyperbolicOctagonGroup> g;
void my_unique_words(std::vector<Point>& p, Point input, int depth) {
std::vector<Octagon_group> g;
get_generators(g);
std::vector<HyperbolicOctagonGroup> v;
recurr(v, g, length);
std::set<HyperbolicOctagonGroup> s;
std::vector<Octagon_group> v;
recurr(v, g, depth);
std::set<Octagon_group> s;
for (int i = 0; i < v.size(); i++) {
s.insert( v[i] );
}
cout << "Original point and images: " << endl;
cout << input.x() << ", " << input.y() << endl;
for (set<HyperbolicOctagonGroup>::iterator it = s.begin(); it != s.end(); it++) {
HyperbolicOctagonGroup m = *it;
//cout << "Original point and images: " << endl;
//cout << input.x() << ", " << input.y() << endl;
for (set<Octagon_group>::iterator it = s.begin(); it != s.end(); it++) {
Octagon_group m = *it;
pair<double, double> res;
res = m.apply(to_double(input.x()), to_double(input.y()));
cout << res.first << ", " << res.second << endl;
//cout << res.first << ", " << res.second << endl;
p.push_back( Point(res.first, res.second) );
}
@ -157,7 +148,7 @@ void apply_unique_words(std::vector<Point>& points, Point input = Point(0, 0), d
cout << "apply_unique_words called with threshold = " << threshold << ", word_length = " << word_length << ", d = " << d << endl;
static vector<HyperbolicOctagonGroup> unique_words;
static vector<Octagon_group> unique_words;
static bool generated = false;
if(generated == false) {
generate_unique_words(unique_words, threshold, word_length);
@ -179,7 +170,7 @@ void apply_unique_words(std::vector<Point>& points, Point input = Point(0, 0), d
void apply_unique_words_G(std::vector<Point>& points, Point input = Point(0, 0), double threshold = 6/*13.5*/, int word_length = 6/*20*/)
{
static vector<HyperbolicOctagonGroup> unique_words;
static vector<Octagon_group> unique_words;
static bool generated = false;
if(generated == false) {
generate_unique_words(unique_words, threshold, word_length);
@ -221,12 +212,13 @@ void apply_unique_words_G(std::vector<Point>& points, Point input = Point(0, 0),
class MainWindow :
public CGAL::Qt::DemosMainWindow,
public Ui::Delaunay_triangulation_2
public Ui::Periodic_4_hyperbolic_Delaunay_triangulation_2
{
Q_OBJECT
private:
int recursion_depth;
int cidx;
std::vector<int> ccol;
@ -266,6 +258,8 @@ public slots:
void on_actionInsertRandomPoints_triggered();
void on_actionModifyDepth_triggered();
void on_actionLoadPoints_triggered();
void on_actionSavePoints_triggered();
@ -284,7 +278,7 @@ signals:
MainWindow::MainWindow()
: DemosMainWindow(), dt(K(1))
{
recursion_depth = 1;
cidx = 0;
for (int i = 0; i < 10; i++)
ccol.push_back(i);
@ -424,7 +418,6 @@ MainWindow::MainWindow()
// // The navigation adds zooming and translation functionality to the
// // QGraphicsView
this->addNavigation(this->graphicsView);
this->setupStatusBar();
this->setupOptionsMenu();
this->addAboutDemo(":/cgal/help/about_Delaunay_triangulation_2.html");
@ -448,15 +441,6 @@ MainWindow::MainWindow()
#endif
#if OPTION_INSERT_FIELD_DUMMY_POINTS == 1
Point mypt(1. - sqrt(2.), 1. - sqrt(2.));
processInput(make_object(mypt));
emit(changed());
#endif
}
@ -483,7 +467,7 @@ MainWindow::processInput(CGAL::Object o)
//delete
vector<Point> points;
//apply_unique_words(points, p, 4, 1, .998);
my_unique_words(points, p, 1);
my_unique_words(points, p, recursion_depth);
points.push_back(p);
Vertex_handle v;
@ -626,10 +610,6 @@ MainWindow::on_actionClear_triggered()
void
MainWindow::on_actionInsertRandomPoints_triggered()
{
QRectF rect = CGAL::Qt::viewportsBbox(&scene);
CGAL::Qt::Converter<K> convert;
//Circle_2 isor = convert(rect);
//CGAL::Random_points_in_disc_2<Point> pg(1.0);
bool ok = false;
const int number_of_points =
QInputDialog::getInt(this,
@ -647,8 +627,6 @@ MainWindow::on_actionInsertRandomPoints_triggered()
// wait cursor
QApplication::setOverrideCursor(Qt::WaitCursor);
//std::vector<Point> points;
//points.reserve(number_of_points);
typedef CGAL::Exact_predicates_inexact_constructions_kernel GT;
typedef GT::Point_2 Point_2;
@ -658,16 +636,35 @@ MainWindow::on_actionInsertRandomPoints_triggered()
Hyperbolic_random_points_in_disc_2<GT>(pts, number_of_points);
for(int i = 0; i < number_of_points; ++i){
processInput(make_object(pts[i]));
//points.push_back(*pg++);
processInput(make_object(pts[i]));
}
//dt.insert(points.begin(), points.end());
// default cursor
QApplication::restoreOverrideCursor();
emit(changed());
}
void
MainWindow::on_actionModifyDepth_triggered()
{
bool ok = false;
const int result =
QInputDialog::getInt(this,
tr("Modify recursion depth"),
tr("Enter new recursion depth"),
recursion_depth,
0,
10,
1,
&ok);
if(!ok) {
return;
}
recursion_depth = result;
}
void
MainWindow::on_actionLoadPoints_triggered()
{
@ -757,7 +754,7 @@ int main(int argc, char **argv)
app.setOrganizationDomain("geometryfactory.com");
app.setOrganizationName("GeometryFactory");
app.setApplicationName("Delaunay_triangulation_2 demo");
app.setApplicationName("Periodic_4_hyperbolic_Delaunay_triangulation_2 demo");
// Import resources from libCGALQt4.
// See http://doc.trolltech.com/4.4/qdir.html#Q_INIT_RESOURCE

View File

@ -1,767 +0,0 @@
#include <fstream>
// CGAL headers
#include <CGAL/Triangulation_vertex_base_with_info_2.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Delaunay_hyperbolic_triangulation_2.h>
#include <CGAL/Periodic_4_hyperbolic_triangulation_traits_2.h>
// to be deleted
#include <CGAL/Qt/HyperbolicPainterOstream.h>
//
#include <CGAL/point_generators_2.h>
// Qt headers
#include <QtGui>
#include <QString>
#include <QActionGroup>
#include <QFileDialog>
#include <QInputDialog>
#include <QGraphicsEllipseItem>
#include <string>
// GraphicsView items and event filters (input classes)
#include "CGAL/Qt/TriangulationCircumcircle.h"
#include "CGAL/Qt/TriangulationMovingPoint.h"
#include "CGAL/Qt/TriangulationConflictZone.h"
#include "CGAL/Qt/TriangulationRemoveVertex.h"
#include "CGAL/Qt/TriangulationPointInputAndConflictZone.h"
//#include <CGAL/Qt/TriangulationGraphicsItem.h>
#include <CGAL/Qt/VoronoiGraphicsItem.h>
// store color
#include <CGAL/TranslationInfo.h>
// visualise color
#include <CGAL/Qt/TriangulationGraphicsItemWithColorInfo.h>
// unique words
//#include <temp.h>
#include <CGAL/Square_root_2_field.h>
#include <CGAL/Hyperbolic_octagon_group.h>
#include <CGAL/Hyperbolic_random_points_in_disc_2.h>
// dummy points
//#include <CGAL/Periodic_2_hyperbolic_triangulation_dummy.h>
// for filtering
#include <set>
// for viewportsBbox
#include <CGAL/Qt/utility.h>
// the two base classes
#include "ui_Delaunay_triangulation_2.h"
#include <CGAL/Qt/DemosMainWindow.h>
#define OPTION_INSERT_DUMMY_POINTS 0
typedef CGAL::Exact_predicates_inexact_constructions_kernel InR;
typedef CGAL::Exact_predicates_exact_constructions_kernel R;
typedef CGAL::Triangulation_hyperbolic_traits_2<R> K;
typedef K::Point_2 Point;
// keep color
typedef TranslationInfo<std::string> Vb_info;
typedef CGAL::Triangulation_vertex_base_with_info_2< Vb_info, K >
Vb;
typedef CGAL::Triangulation_face_base_with_info_2 <CGAL::Hyperbolic_face_info_2, K >
Fb;
typedef CGAL::Delaunay_hyperbolic_triangulation_2< K, CGAL::Triangulation_data_structure_2<Vb, Fb> >
Delaunay;
typedef Delaunay::Vertex_handle Vertex_handle;
struct PointsComparator {
static double eps;
bool operator() (const Point& l, const Point& r) const
{
if(l.x() < r.x() - eps) {
return true;
}
if(l.x() < r.x() + eps) {
if(l.y() < r.y() - eps) {
return true;
}
}
return false;
}
};
double PointsComparator::eps = 0.0001;
string glabels[] = { "a", "\\bar{b}", "c", "\\bar{d}", "\\bar{a}", "b", "\\bar{c}", "d" };
void recurr(vector<HyperbolicOctagonGroup>& v, vector<HyperbolicOctagonGroup> g, int depth = 1) {
if (depth > 1) {
recurr(v, g, depth-1);
vector<HyperbolicOctagonGroup> tmp;
vector<string> tmpw;
for (int i = 0; i < v.size(); i++) {
tmp.push_back(v[i]);
}
for (int i = 0; i < tmp.size(); i++) {
for (int j = 0; j < g.size(); j++) {
v.push_back(tmp[i]*g[j]);
}
}
} else {
for (int i = 0; i < g.size(); i++) {
v.push_back(g[i]);
}
}
}
void my_unique_words(std::vector<Point>& p, Point input, int length) {
std::vector<HyperbolicOctagonGroup> g;
get_generators(g);
std::vector<HyperbolicOctagonGroup> v;
recurr(v, g, length);
std::set<HyperbolicOctagonGroup> s;
for (int i = 0; i < v.size(); i++) {
s.insert( v[i] );
}
cout << "Original point and images: " << endl;
cout << input.x() << ", " << input.y() << endl;
for (set<HyperbolicOctagonGroup>::iterator it = s.begin(); it != s.end(); it++) {
HyperbolicOctagonGroup m = *it;
pair<double, double> res;
res = m.apply(to_double(input.x()), to_double(input.y()));
cout << res.first << ", " << res.second << endl;
p.push_back( Point(res.first, res.second) );
}
}
void apply_unique_words(std::vector<Point>& points, Point input = Point(0, 0), double threshold = 10, int word_length = 6, double d = .998)
{
cout << "apply_unique_words called with threshold = " << threshold << ", word_length = " << word_length << ", d = " << d << endl;
static vector<HyperbolicOctagonGroup> unique_words;
static bool generated = false;
if(generated == false) {
generate_unique_words(unique_words, threshold, word_length);
generated = true;
}
//points.resize(unique_words.size());
pair<double, double> res;
for(size_t i = 0; i < unique_words.size(); i++) {
pair<double, double> res;
res = unique_words[i].apply(to_double(input.x()), to_double(input.y()));
double dist = res.first*res.first + res.second*res.second;
if(dist < d) {
points.push_back( Point(res.first, res.second) );
}
}
}
void apply_unique_words_G(std::vector<Point>& points, Point input = Point(0, 0), double threshold = 6/*13.5*/, int word_length = 6/*20*/)
{
static vector<HyperbolicOctagonGroup> unique_words;
static bool generated = false;
if(generated == false) {
generate_unique_words(unique_words, threshold, word_length);
generated = true;
// to generate all words
/*
ofstream fwords("m_w");
fwords << "local words;\nPrint(\"words!\\n\");\nwords := [\n";
for(size_t i = 0; i < unique_words.size() - 1; i++) {
fwords << unique_words[i].label << "," <<endl;
}
fwords << unique_words[unique_words.size() - 1].label << endl;
fwords << "];\nreturn words;";
fwords.close();
*/
//
}
ifstream findices("indicesG8_1");
long index;
vector<long> indices;
while(findices >> index) {
indices.push_back(index);
}
cout << "indices size " << indices.size() << endl;
pair<double, double> res;
for(size_t i = 0; i < indices.size(); i++) {
pair<double, double> res;
if(indices[i] < unique_words.size() /*&& unique_words[indices[i]].length() < 13.*/) {
res = unique_words[indices[i]].apply(to_double(input.x()), to_double(input.y()));
points.push_back(Point(res.first, res.second));
}
}
cout << "nb of points to insert " << points.size() << endl;
}
class MainWindow :
public CGAL::Qt::DemosMainWindow,
public Ui::Delaunay_triangulation_2
{
Q_OBJECT
private:
int cidx;
std::vector<int> ccol;
Delaunay dt;
QGraphicsEllipseItem * disk;
QGraphicsScene scene;
CGAL::Qt::TriangulationGraphicsItem<Delaunay> * dgi;
CGAL::Qt::VoronoiGraphicsItem<Delaunay> * vgi;
// for drawing Voronoi diagram of the orbit of the origin
CGAL::Qt::VoronoiGraphicsItem<Delaunay> * origin_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_actionMovingPoint_toggled(bool checked);
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(), dt(K(1))
{
cidx = 0;
for (int i = 0; i < 10; i++)
ccol.push_back(i);
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;
// set background
qreal eps = 0.01;
QGraphicsRectItem* rect = new QGraphicsRectItem(left_top_corner_x - eps, left_top_corner_y - eps, width + 2*eps, height + 2*eps);
rect->setPen(Qt::NoPen);
rect->setBrush(Qt::white);
scene.addItem(rect);
// set disk
disk = new QGraphicsEllipseItem(left_top_corner_x, left_top_corner_y, width, height);
QPen pen; // creates a default pen
pen.setWidth(0);
//pen.setBrush(Qt::black);
pen.setBrush(QColor(200, 200, 0));
disk->setPen(pen);
scene.addItem(disk);
// another input point, instead of the origin
double phi = CGAL_PI / 8.;
double psi = CGAL_PI / 3.;
double rho = std::sqrt(cos(psi)*cos(psi) - sin(phi)*sin(phi));
Point origin = Point(0, 0);
const Point a(cos(phi)*cos(phi + psi)/rho, sin(phi)*cos(phi + psi)/rho);
// dt to form the octagon tessellation
vector<Point> origin_orbit;
apply_unique_words(origin_orbit, origin, 10, 6);
origin_orbit.push_back(Point(0, 0));
// for(long i = 0; i < origin_orbit.size(); i++) {
// cout << origin_orbit[i] << endl;
// }
cout << "nb of points on the orbit of the origin: " << origin_orbit.size() << endl;
Delaunay* dtO = new Delaunay(K(1));
dtO->insert(origin_orbit.begin(), origin_orbit.end());
origin_vgi = new CGAL::Qt::VoronoiGraphicsItem<Delaunay>(dtO);
origin_vgi->setVisible(true);
QObject::connect(this, SIGNAL(changed()),
origin_vgi, SLOT(modelChanged()));
QColor br(149, 179, 179);
origin_vgi->setEdgesPen(QPen(br, 0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
scene.addItem(origin_vgi);
// Add a GraphicItem for the Delaunay triangulation
dgi = new CGAL::Qt::TriangulationGraphicsItem<Delaunay>(&dt);
QObject::connect(this, SIGNAL(changed()),
dgi, SLOT(modelChanged()));
dgi->setVerticesPen(QPen(Qt::red, 3, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
dgi->setEdgesPen(QPen(QColor(200, 200, 0), 0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
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()));
QColor brown(139, 69, 19);
vgi->setEdgesPen(QPen(brown, 0, 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)));
mp = new CGAL::Qt::TriangulationMovingPoint<Delaunay>(&dt, this);
// TriangulationMovingPoint<Delaunay> emits a modelChanged() signal each
// time the moving point moves.
// The following connection is for the purpose of emitting changed().
QObject::connect(mp, SIGNAL(modelChanged()),
this, SIGNAL(changed()));
trv = new CGAL::Qt::TriangulationRemoveVertex<Delaunay>(&dt, this);
QObject::connect(trv, SIGNAL(modelChanged()),
this, SIGNAL(changed()));
tcc = new CGAL::Qt::TriangulationCircumcircle<Delaunay>(&scene, &dt, this);
tcc->setPen(QPen(Qt::red, 0, 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);
this->graphicsView->shear(230, 230);
// // The navigation adds zooming and translation functionality to the
// // QGraphicsView
this->addNavigation(this->graphicsView);
this->setupStatusBar();
this->setupOptionsMenu();
this->addAboutDemo(":/cgal/help/about_Delaunay_triangulation_2.html");
this->addAboutCGAL();
this->addRecentFiles(this->menuFile, this->actionQuit);
connect(this, SIGNAL(openRecentFile(QString)),
this, SLOT(open(QString)));
#if OPTION_INSERT_DUMMY_POINTS == 1
std::vector<Point> pts;
cout << "Inserting dummy points now! " << endl;
dt.insert_dummy_points(pts);
for (int i = 0; i < pts.size(); i++) {
processInput(make_object(pts[i]));
}
cout << "Dummy points inserted! " << endl;
emit(changed());
#endif
}
void
MainWindow::processInput(CGAL::Object o)
{
typedef CGAL::Exact_predicates_inexact_constructions_kernel GT;
typedef GT::Point_2 Point_2;
Point_2 pp;
if (CGAL::assign(pp, o)) {
Point tmp(pp.x(), pp.y());
o = make_object(tmp);
}
Point 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);
//delete
vector<Point> points;
//apply_unique_words(points, p, 4, 1, .998);
my_unique_words(points, p, 1);
points.push_back(p);
Vertex_handle v;
for(size_t j = 0; j < points.size() ; j++) {
v = dt.insert(points[j]);
v->info().setColor(ccol[cidx]);
}
cidx = (cidx + 1) % ccol.size();
//
}
// delete
else {
static double phi = CGAL_PI / 8.;
static double psi = CGAL_PI / 3.;
static double rho = std::sqrt(cos(psi)*cos(psi) - sin(phi)*sin(phi));
static Point origin = Point(0, 0);
static Point a(cos(phi)*cos(phi + psi)/rho, sin(phi)*cos(phi + psi)/rho);
static Point b((cos(psi)-sin(phi))/rho, 0.);
static Point current_point_a = origin;
static Point current_point_b = origin;
static double dT = 0.05;
static double dx_a = dT * CGAL::to_double(a.x());
static double dy_a = dT * CGAL::to_double(a.y());
current_point_a = Point(current_point_a.x() + dx_a, current_point_a.y() + dy_a);
if(current_point_a.x() > a.x()) {
current_point_a = origin;
}
static double dx_b = dT * CGAL::to_double(b.x());
static double dy_b = dT * CGAL::to_double(b.y());
current_point_b = Point(current_point_b.x() + dx_b, current_point_b.y() + dy_b);
std::cout << current_point_b.x() << " : " << current_point_b.y() << std::endl;
if(current_point_b.x() > b.x()) {
current_point_b = origin;
}
vector<Point> points;
// current_point_b <-> current_point_b
Point current_point = current_point_a;
apply_unique_words(points, current_point);
points.push_back(current_point);
dt.clear();
dt.insert(points.begin(), points.end());
}
}
emit(changed());
cout << "v = " << dt.number_of_vertices() << ", f = " << dt.number_of_faces() << endl;
}
/*
* 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);
scene.installEventFilter(trv);
} else {
scene.removeEventFilter(pi);
scene.removeEventFilter(trv);
}
}
void
MainWindow::on_actionMovingPoint_toggled(bool checked)
{
if(checked){
scene.installEventFilter(mp);
} else {
scene.removeEventFilter(mp);
}
}
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;
//Circle_2 isor = convert(rect);
//CGAL::Random_points_in_disc_2<Point> pg(1.0);
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> points;
//points.reserve(number_of_points);
typedef CGAL::Exact_predicates_inexact_constructions_kernel GT;
typedef GT::Point_2 Point_2;
typedef GT::FT FT;
vector<Point_2> pts;
Hyperbolic_random_points_in_disc_2<GT>(pts, number_of_points);
for(int i = 0; i < number_of_points; ++i){
processInput(make_object(pts[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 p;
std::vector<K::Point> 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()
{
/* // dump points
QString fileName = QFileDialog::getSaveFileName(this,
tr("Save points"),
".");
if(! fileName.isEmpty()){
std::ofstream ofs(qPrintable(fileName));
for(Delaunay::Finite_vertices_iterator
vit = dt.finite_vertices_begin(),
end = dt.finite_vertices_end();
vit!= end; ++vit)
{
ofs << vit->point() << std::endl;
}
}
*/
// take a snapshot
std::cout << "snapshot...";
const QRect viewerRect = graphicsView->mapFromScene(scene.sceneRect()).boundingRect();
const QRect imageRect = QRect(QPoint(0, 0), viewerRect.size());
QImage snapshot(imageRect.size(), QImage::Format_ARGB32);//QImage::Format_ARGB32_Premultiplied
QPainter painter(&snapshot);
painter.setRenderHint(QPainter::Antialiasing);
//painter.setRenderHint(QPainter::SmoothPixmapTransform);
graphicsView->render(&painter, imageRect, viewerRect);
bool saved = snapshot.save("mysnap.png", "PNG", 100);
assert(saved == true);
std::cout << "done" << std::endl;
}
void
MainWindow::on_actionRecenter_triggered()
{
this->graphicsView->setSceneRect(dgi->boundingRect());
this->graphicsView->fitInView(dgi->boundingRect(), Qt::KeepAspectRatio);
}
#include "Periodic_4_hyperbolic_triangulation_2_demo.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

@ -1,625 +0,0 @@
// Copyright (c) 2010 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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/candidate-packages/Triangulation_2/include/CGAL/Delaunay_triangulation_2.h $
// $Id: Delaunay_triangulation_2.h 57509 2010-07-15 09:14:09Z sloriot $
//
//
// Author(s) : Mikhail Bogdanov
#ifndef CGAL_DELAUNAY_HYPERBOLIC_TRIANGULATION_2_H
#define CGAL_DELAUNAY_HYPERBOLIC_TRIANGULATION_2_H
#include <CGAL/Triangulation_face_base_with_info_2.h>
#include <CGAL/Delaunay_triangulation_2.h>
#include <stack>
#include <set>
namespace CGAL {
class Hyperbolic_face_info_2
{
public:
Hyperbolic_face_info_2() : _is_finite_invisible(false), _invisible_edge(UCHAR_MAX)
{
}
bool is_finite_invisible() const
{
return _is_finite_invisible;
}
void set_finite_invisible(bool is_finite_invisible)
{
_is_finite_invisible = is_finite_invisible;
}
// Supposed to be called before "get_invisible_edge"
bool has_invisible_edge() const
{
return _invisible_edge <= 2;
}
// Higly recommended to call "has_invisible_edge" before
unsigned char get_invisible_edge() const
{
assert(_is_finite_invisible);
assert(_invisible_edge <= 2);
return _invisible_edge;
}
void set_invisible_edge(unsigned char invisible_edge)
{
assert(_is_finite_invisible);
assert(invisible_edge <= 2);
_invisible_edge = invisible_edge;
}
private:
// a face is invisible if its circumscribing circle intersects the circle at infinity
bool _is_finite_invisible;
// defined only if the face is finite and invisible
unsigned char _invisible_edge;
};
template < class Gt,
class Tds = Triangulation_data_structure_2 <
Triangulation_vertex_base_2<Gt>,
Triangulation_face_base_with_info_2<Hyperbolic_face_info_2, Gt> > >
class Delaunay_hyperbolic_triangulation_2 : public Delaunay_triangulation_2<Gt,Tds>
{
public:
typedef Delaunay_hyperbolic_triangulation_2<Gt, Tds> Self;
typedef Delaunay_triangulation_2<Gt,Tds> Base;
typedef Triangulation_face_base_with_info_2<Hyperbolic_face_info_2, Gt> Face_base;
typedef typename Face_base::Info Face_info;
typedef typename Base::size_type size_type;
typedef typename Base::Vertex_handle Vertex_handle;
typedef typename Base::Face_handle Face_handle;
typedef typename Base::Edge Edge;
#ifndef CGAL_CFG_USING_BASE_MEMBER_BUG_2
using Base::cw;
using Base::ccw;
using Base::geom_traits;
#endif
typedef typename Base::Edge_circulator Edge_circulator;
typedef typename Base::Face_circulator Face_circulator;
typedef typename Base::Vertex_circulator Vertex_circulator;
typedef typename Base::All_vertices_iterator All_vertices_iterator;
typedef typename Base::All_edges_iterator All_edges_iterator;
typedef typename Base::All_faces_iterator All_faces_iterator;
typedef Gt Geom_traits;
typedef typename Geom_traits::FT FT;
typedef typename Geom_traits::Point_2 Point;
typedef typename Geom_traits::Segment_2 Segment;
/*
#ifndef CGAL_CFG_USING_BASE_MEMBER_BUG_2
using Triangulation::side_of_oriented_circle;
using Triangulation::circumcenter;
using Triangulation::collinear_between;
using Triangulation::test_dim_down;
using Triangulation::make_hole;
using Triangulation::fill_hole_delaunay;
using Triangulation::delete_vertex;
#endif
*/
Delaunay_hyperbolic_triangulation_2(const Gt& gt = Gt())
: Delaunay_triangulation_2<Gt,Tds>(gt) {}
Delaunay_hyperbolic_triangulation_2(
const Delaunay_hyperbolic_triangulation_2<Gt,Tds> &tr)
: Delaunay_triangulation_2<Gt,Tds>(tr)
{ CGAL_triangulation_postcondition( this->is_valid() );}
void mark_star(Vertex_handle v) const
{
if(!is_star_bounded(v)) {
mark_star_faces(v);
}
}
Vertex_handle insert(const Point &p,
Face_handle start = Face_handle() )
{
Vertex_handle v = Base::insert(p, start);
mark_star(v);
return v;
}
Vertex_handle insert(const Point& p,
typename Base::Locate_type lt,
Face_handle loc, int li )
{
Vertex_handle v = Base::insert(p, lt, loc, li);
mark_star(v);
return v;
}
#ifndef CGAL_TRIANGULATION_2_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO
template < class InputIterator >
std::ptrdiff_t
insert( InputIterator first, InputIterator last,
typename boost::enable_if<
boost::is_base_of<
Point,
typename std::iterator_traits<InputIterator>::value_type
>
>::type* = NULL
)
#else
template < class InputIterator >
std::ptrdiff_t
insert(InputIterator first, InputIterator last)
#endif //CGAL_TRIANGULATION_2_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO
{
size_type n = Base::insert(first, last);
mark_faces();
return n;
}
//test version of insert function
#ifndef CGAL_TRIANGULATION_2_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO
template < class InputIterator >
std::ptrdiff_t
insert2( InputIterator first, InputIterator last,
typename boost::enable_if<
boost::is_base_of<
Point,
typename std::iterator_traits<InputIterator>::value_type
>
>::type* = NULL
)
#else
template < class InputIterator >
std::ptrdiff_t
insert_2(InputIterator first, InputIterator last)
#endif //CGAL_TRIANGULATION_2_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO
{
size_type n = this->number_of_vertices();
spatial_sort(first, last, geom_traits());
Face_handle f;
while(first != last) {
f = insert (*first++, f)->face();
}
return this->number_of_vertices() - n;
}
bool is_infinite(Vertex_handle v) const
{
return Base::is_infinite(v);
}
bool is_infinite(Face_handle f) const
{
return has_infinite_vertex(f) || is_finite_invisible(f);
}
bool is_infinite(Face_handle f, int i) const
{
return has_infinite_vertex(f, i) || is_finite_invisible(f, i);
}
bool is_infinite(const Edge& e) const
{
return is_infinite(e.first, e.second);
}
bool is_infinite(const Edge_circulator& ec) const
{
return is_infinite(*ec);
}
bool is_infinite(const All_edges_iterator& ei) const
{
return is_infinite(*ei);
}
private:
bool has_infinite_vertex(Face_handle f) const
{
return Base::is_infinite(f);
}
bool has_infinite_vertex(Face_handle f, int i) const
{
return Base::is_infinite(f, i);
}
bool has_infinite_vertex(const Edge& e) const
{
return Base::is_infinite(e);
}
int get_finite_invisible_edge(Face_handle f) const
{
assert(is_finite_invisible(f));
return f->info().get_invisible_edge();
}
bool is_finite_invisible(Face_handle f) const
{
return f->info().is_finite_invisible();
}
bool is_finite_invisible(Face_handle f, int i) const
{
if(this->dimension() <= 1) {
return false;
}
if(is_finite_invisible(f) && get_finite_invisible_edge(f) == i) {
return true;
}
// another incident face and corresponding index
Face_handle f2 = f->neighbor(i);
int i2 = f2->index(f);
if(is_finite_invisible(f2) && get_finite_invisible_edge(f2) == i2) {
return true;
}
return false;
}
bool is_finite_invisible(const Edge& e) const
{
return is_finite_invisible(e.first, e.second);
}
// Depth-first search (dfs) and marking the finite invisible faces.
void mark_faces() const
{
if(this->dimension() <= 1) return;
std::set<Face_handle> visited_faces;
// maintain a stack to be able to backtrack
// to the most recent faces which neighbors are not visited
std::stack<Face_handle> backtrack;
// start from a face with infinite vertex
Face_handle current = Base::infinite_face();
// mark it as visited
visited_faces.insert(current);
// put the element whose neighbors we are going to explore.
backtrack.push(current);
// test whether a face is finite invisible or not
Mark_face test(*this);
Face_handle next;
Face_info face_info;
while(!backtrack.empty()) {
// take a face
current = backtrack.top();
// start visiting the neighbors
int i = 0;
for(; i < 3; i++) {
next = current->neighbor(i);
// if a neighbor is already visited, then stop going deeper
if(visited_faces.find(next) != visited_faces.end()) {
continue;
}
visited_faces.insert(next);
mark_face(next, test);
// go deeper if the neighbor is infinite
if(is_infinite(next)) {
backtrack.push(next);
break;
}
}
// if all the neighbors are already visited, then remove "current" face.
if(i == 3) {
backtrack.pop();
}
}
}
// check if a star is bounded by finite faces
// TODO: rename this function name
bool is_star_bounded(Vertex_handle v) const
{
if(this->dimension() <= 1) {
return true;
}
Face_handle f = v->face();
Face_handle next;
int i;
Face_handle start(f);
Face_handle opposite_face;
do {
i = f->index(v);
next = f->neighbor(ccw(i)); // turn ccw around v
opposite_face = f->neighbor(i);
if(this->is_infinite(opposite_face)) {
return false;
}
f = next;
} while(next != start);
return true;
}
//use the function: insert_and_give_new_faces?
void mark_star_faces(Vertex_handle v) const
{
// TODO: think of it
if(this->dimension() <= 1) return;
Mark_face test(*this);
Face_handle f = v->face();
Face_handle start(f), next;
int i;
do {
i = f->index(v);
next = f->neighbor(ccw(i)); // turn ccw around v
mark_face(f, test);
f = next;
} while(next != start);
return;
}
template<class Mark_face_test>
void mark_face(const Face_handle& f, const Mark_face_test& test) const
{
f->info() = test(f);
}
void mark_face(const Face_handle& f) const
{
Mark_face test(*this);
mark_face(f, test);
}
class Mark_face
{
public:
Mark_face(const Self& tr) :
_tr(tr)
{}
Face_info operator ()(const Face_handle& f) const
{
typedef typename Gt::Is_hyperbolic Is_hyperbolic;
Face_info info;
if(_tr.has_infinite_vertex(f)) {
return info;
}
Point p0 = f->vertex(0)->point();
Point p1 = f->vertex(1)->point();
Point p2 = f->vertex(2)->point();
int ind = 0;
Is_hyperbolic is_hyperbolic = _tr.geom_traits().Is_hyperbolic_object();
if(is_hyperbolic(p0, p1, p2, ind) == false) {
info.set_finite_invisible(true);
info.set_invisible_edge(ind);
return info;
}
return info;
}
private:
Mark_face(const Mark_face&);
Mark_face& operator= (const Mark_face&);
const Self& _tr;
};
public:
// This class is used to generate the Finite_*_iterators.
class Infinite_hyperbolic_tester
{
const Self *t;
public:
Infinite_hyperbolic_tester() {}
Infinite_hyperbolic_tester(const Self *tr) : t(tr) {}
bool operator()(const All_vertices_iterator & vit) const {
return t->is_infinite(vit);
}
bool operator()(const All_faces_iterator & fit) const {
return t->is_infinite(fit);
}
bool operator()(const All_edges_iterator & eit ) const {
return t->is_infinite(eit);
}
};
Infinite_hyperbolic_tester
infinite_hyperbolic_tester() const
{
return Infinite_hyperbolic_tester(this);
}
//Finite faces iterator
class Finite_faces_iterator
: public Filter_iterator<All_faces_iterator, Infinite_hyperbolic_tester>
{
typedef Filter_iterator<All_faces_iterator, Infinite_hyperbolic_tester> Base;
typedef Finite_faces_iterator Self;
public:
Finite_faces_iterator() : Base() {}
Finite_faces_iterator(const Base &b) : Base(b) {}
Self & operator++() { Base::operator++(); return *this; }
Self & operator--() { Base::operator--(); return *this; }
Self operator++(int) { Self tmp(*this); ++(*this); return tmp; }
Self operator--(int) { Self tmp(*this); --(*this); return tmp; }
operator const Face_handle() const { return Base::base(); }
};
Finite_faces_iterator
finite_faces_begin() const
{
if ( this->dimension() < 2 )
return finite_faces_end();
return CGAL::filter_iterator(this->all_faces_end(),
Infinite_hyperbolic_tester(this),
this->all_faces_begin() );
}
Finite_faces_iterator
finite_faces_end() const
{
return CGAL::filter_iterator(this->all_faces_end(),
Infinite_hyperbolic_tester(this) );
}
//Finite edges iterator
typedef Filter_iterator<All_edges_iterator,
Infinite_hyperbolic_tester>
Finite_edges_iterator;
Finite_edges_iterator
finite_edges_begin() const
{
if ( this->dimension() < 1 )
return finite_edges_end();
return CGAL::filter_iterator(this->all_edges_end(),
infinite_hyperbolic_tester(),
this->all_edges_begin());
}
Finite_edges_iterator
finite_edges_end() const
{
return CGAL::filter_iterator(this->all_edges_end(),
infinite_hyperbolic_tester() );
}
using Base::dual;
Object
dual(const Finite_edges_iterator& ei) const
{
return this->dual(*ei);
}
Object
dual(const Edge &e) const
{
CGAL_triangulation_precondition (!this->is_infinite(e));
if(this->dimension() == 1) {
const Point& p = (e.first)->vertex(cw(e.second))->point();
const Point& q = (e.first)->vertex(ccw(e.second))->point();
// hyperbolic line
Segment line = this->geom_traits().construct_hyperbolic_bisector_2_object()(p,q);
return make_object(line);
}
// incident faces
Face_handle f1 = e.first;
int i1 = e.second;
Face_handle f2 = f1->neighbor(i1);
int i2 = f2->index(f1);
// boths faces are infinite, but the incident edge is finite
if(is_infinite(f1) && is_infinite(f2)){
const Point& p = (f1)->vertex(cw(i1))->point();
const Point& q = (f1)->vertex(ccw(i1))->point();
// hyperbolic line
Segment line = this->geom_traits().construct_hyperbolic_bisector_2_object()(p,q);
return make_object(line);
}
// both faces are finite
if(!is_infinite(f1) && !is_infinite(f2)) {
Segment s = this->geom_traits().construct_segment_2_object()
(dual(f1),dual(f2));
return make_object(s);
}
// one of the incident faces is infinite
Face_handle finite_face = f1;
int i = i1;
if(is_infinite(f1)) {
finite_face = f2;
i = i2;
}
const Point& p = finite_face->vertex(cw(i))->point();
const Point& q = finite_face->vertex(ccw(i))->point();
// ToDo: Line or Segment?
// hyperbolic line and ray
Segment line = this->geom_traits().construct_hyperbolic_bisector_2_object()(p,q);
Segment ray = this->geom_traits().construct_ray_2_object()(dual(finite_face), line);
return make_object(ray);
}
public:
void insert_dummy_points(std::vector<typename Gt::Point_2>& );
};
} //namespace CGAL
#include <CGAL/Periodic_4_hyperbolic_triangulation_dummy.h>
#endif // CGAL_DELAUNAY_HYPERBOLIC_TRIANGULATION_2_H

View File

@ -1,81 +0,0 @@
// Copyright (c) 2010 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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/candidate-packages/Triangulation_2/include/CGAL/Delaunay_triangulation_2.h $
// $Id: Delaunay_triangulation_2.h 57509 2010-07-15 09:14:09Z sloriot $
//
//
// Author(s) : Mikhail Bogdanov
#ifndef CGAL_DELAUNAY_HYPERBOLIC_FACE_INFO_2_H
#define CGAL_DELAUNAY_HYPERBOLIC_FACE_INFO_2_H
#include <CGAL/Triangulation_face_base_with_info_2.h>
#include <CGAL/Delaunay_triangulation_2.h>
#include <stack>
#include <set>
namespace CGAL {
class Hyperbolic_face_info_2
{
public:
Hyperbolic_face_info_2() : _is_finite_invisible(false), _invisible_edge(UCHAR_MAX)
{
}
bool is_finite_invisible() const
{
return _is_finite_invisible;
}
void set_finite_invisible(bool is_finite_invisible)
{
_is_finite_invisible = is_finite_invisible;
}
// Supposed to be called before "get_invisible_edge"
bool has_invisible_edge() const
{
return _invisible_edge <= 2;
}
// Higly recommended to call "has_invisible_edge" before
unsigned char get_invisible_edge() const
{
assert(_is_finite_invisible);
assert(_invisible_edge <= 2);
return _invisible_edge;
}
void set_invisible_edge(unsigned char invisible_edge)
{
assert(_is_finite_invisible);
assert(invisible_edge <= 2);
_invisible_edge = invisible_edge;
}
private:
// a face is invisible if its circumscribing circle intersects the circle at infinity
bool _is_finite_invisible;
// defined only if the face is finite and invisible
unsigned char _invisible_edge;
};
} //namespace CGAL
#endif // CGAL_DELAUNAY_HYPERBOLIC_FACE_INFO_2_H

View File

@ -154,8 +154,9 @@ public:
};
template<class Square_root_2_field>
Square_root_2_field Hyperbolic_octagon_group<Square_root_2_field>::factor = Square_root_2_field(-1, 1);
Square_root_2_field Hyperbolic_octagon_group<Square_root_2_field>::factor = Square_root_2_field(-1, 1); /*Square_root_2_field(-1, 1);*/
// just to give an order(ing)
template<class Int>
@ -207,57 +208,349 @@ ostream& operator<<(ostream& os, const Hyperbolic_octagon_group<Square_root_2_fi
return os;
}
typedef long long ll;
typedef Square_root_2_field<ll> SqrtField;
typedef Hyperbolic_octagon_group<SqrtField> HyperbolicOctagonGroup;
typedef HyperbolicOctagonGroup::Matrix_element Element;
typedef long long ll;
typedef Square_root_2_field<ll> Sqrt_field;
typedef Hyperbolic_octagon_group<Sqrt_field> Octagon_group;
typedef pair<Octagon_group, int> Octagon_group_with_index;
typedef Octagon_group::Matrix_element Element;
enum Direction {
G_A = 0, // 0
G_InvB, // 1
G_C, // 2
G_InvD, // 3
G_InvA, // 4
G_B, // 5
G_InvC, // 6
G_D // 7
DIRECTION_A = 0, // 0
DIRECTION_B_BAR, // 1
DIRECTION_C, // 2
DIRECTION_D_BAR, // 3
DIRECTION_A_BAR, // 4
DIRECTION_B, // 5
DIRECTION_C_BAR, // 6
DIRECTION_D // 7
};
void get_generators(vector<HyperbolicOctagonGroup>& gens)
void get_generators(vector<Octagon_group>& gens)
{
// This is a in the matrix, equal to sqrt(2) + 1
Element A = Element(SqrtField(1, 1), SqrtField(0, 0));
Element A = Element(Sqrt_field(1, 1), Sqrt_field(0, 0));
// This vector holds all other elements, results of the exponentials for various k
vector<Element> B(8, Element(SqrtField(0, 0), SqrtField(0, 0)));
vector<Element> B(8, Element(Sqrt_field(0, 0), Sqrt_field(0, 0)));
// Corrected ordering (initial ordering is present in backup file)
B[G_A] = A * Element(SqrtField( 0, 0), SqrtField( 0, -1));
B[G_B] = A * Element(SqrtField( 1, 0), SqrtField(-1, 0));
B[G_C] = A * Element(SqrtField( 0, 1), SqrtField( 0, 0));
B[G_D] = A * Element(SqrtField( 1, 0), SqrtField( 1, 0));
B[G_InvA] = A * Element(SqrtField( 0, 0), SqrtField( 0, 1));
B[G_InvB] = A * Element(SqrtField(-1, 0), SqrtField( 1, 0));
B[G_InvC] = A * Element(SqrtField( 0, -1), SqrtField( 0, 0));
B[G_InvD] = A * Element(SqrtField(-1, 0), SqrtField(-1, 0));
/* This here produces the correct ordering, and identity is given by g[G_A]*g[G_B]*g[G_C]*g[G_D]*g[G_InvA]*g[G_InvB]*g[G_InvC]*g[G_InvD] */
B[DIRECTION_A] = A * Element(Sqrt_field( 0, 1), Sqrt_field( 0, 0));
B[DIRECTION_B] = A * Element(Sqrt_field(-1, 0), Sqrt_field(-1, 0));
B[DIRECTION_C] = A * Element(Sqrt_field( 0, 0), Sqrt_field( 0, 1));
B[DIRECTION_D] = A * Element(Sqrt_field( 1, 0), Sqrt_field(-1, 0));
B[DIRECTION_A_BAR] = A * Element(Sqrt_field( 0, -1), Sqrt_field( 0, 0));
B[DIRECTION_B_BAR] = A * Element(Sqrt_field( 1, 0), Sqrt_field( 1, 0));
B[DIRECTION_C_BAR] = A * Element(Sqrt_field( 0, 0), Sqrt_field( 0, -1));
B[DIRECTION_D_BAR] = A * Element(Sqrt_field(-1, 0), Sqrt_field( 1, 0));
string labels[8] = {string("a"), string("\\bar{b}"), string("c"), string("\\bar{d}"),
string("\\bar{a}"), string("b"), string("\\bar{c}"), string("d")};
for(int i = 0; i < 8; i++) {
gens.push_back(HyperbolicOctagonGroup(A, B[i], labels[i]));
gens.push_back(Octagon_group(A, B[i], labels[i]));
}
}
/***************************************************************/
// Check whether two elements of the group are inverse of each other
bool Are_inverse(Octagon_group_with_index x, Octagon_group_with_index y) {
int idx = x.second % 4;
int idy = y.second % 4;
bool r = ((idx == idy) && (x.second != y.second));
return r;
}
// Recursively eliminate neighboring inverse elements present in the word
void Simplify_word(vector<Octagon_group_with_index>& w) {
vector<Octagon_group_with_index> t;
bool reduced = false;
int N = w.size();
if (N > 0) {
for (int i = 0; i < N-1; i++) {
if (!Are_inverse(w[i], w[i+1])) {
t.push_back(w[i]);
} else {
reduced = true;
i++;
}
}
if (!Are_inverse(w[N-2], w[N-1])) {
t.push_back(w[N-1]);
} else {
reduced = true;
}
if (reduced) {
Simplify_word(t);
}
w = t;
}
}
// Checks whether y is the next element from x
bool Is_next(Octagon_group_with_index x, Octagon_group_with_index y) {
return (((y.second + 5) % 8) == x.second);
}
// Given a word, find the largest subsequence of consecutive elements it contains.
// The sequence itself is placed in 'seq', while the index at which it starts is
// the return argument of the function.
int Longest_sequence(vector<Octagon_group_with_index>& seq, vector<Octagon_group_with_index> const w) {
int start = 0;
int mstart = 0;
int end = 1;
int max = 1;
int len = 1;
vector<Octagon_group_with_index> tmp, mvec;
tmp.push_back(w[0]);
for (int i = 1; i < w.size(); i++) {
if ( Is_next( w[i], w[i-1] ) ) {
end++;
len++;
tmp.push_back(w[i]);
if (len > max) {
max = len;
mvec = tmp;
mstart = start;
}
} else {
tmp.clear();
tmp.push_back(w[i]);
start = i;
end = i;
len = 0;
}
}
seq = mvec;
return mstart;
}
Octagon_group_with_index Invert(Octagon_group_with_index x) {
Octagon_group y = x.first.inverse();
int idx = (x.second + 4) % 8;
return Octagon_group_with_index(y, idx);
}
// Given a word, construct its inverse
void Invert(vector<Octagon_group_with_index>& w, vector<Octagon_group_with_index> const original) {
w.clear();
for (int i = original.size() - 1; i >= 0; i--) {
w.push_back( Invert(original[i]) );
}
}
// Computes and returns the next index in the identity element chain
int Next_index(int idx) {
return ( (idx + 5) % 8 );
}
// Given a sequence of consecutive indices, return the complementary set of consecutive indices in mod 8.
// For instance, if start = 5 and end = 1, the output is the sequence 2, 3, 4
void Get_complement_indices(vector<int>& v, int begin, int end) {
vector<int> tmp;
for (int i = Next_index(end); i != begin; i = Next_index(i)) {
tmp.push_back(i);
}
for (int i = tmp.size() - 1; i >= 0; i--) {
v.push_back(tmp[i]);
}
}
int Inverse(int idx) {
return ((idx + 4) % 8);
}
// Given the start and end indices of a sequence of consecutive elements, construct the complementary sequence of elements
void Get_complement_word(vector<Octagon_group_with_index>& c, int start, int end) {
vector<int> idx;
vector<Octagon_group> gens;
get_generators(gens);
Get_complement_indices(idx, start, end);
for (int i = idx.size()-1; i >= 0; i--) {
int ii = idx[i];
c.push_back(Octagon_group_with_index(gens[ii], ii));
}
}
// Given a word consisting of consecutive elements, construct its complementary word
void Get_complement_word(vector<Octagon_group_with_index>& c, vector<Octagon_group_with_index> w) {
if (w.size() > 0) {
Get_complement_word(c, w[0].second, w[w.size()-1].second);
} else {
c = w;
}
}
// Given a word, identifies the longest subword consisting of consecutive elements and substitutes
// it with its equivalent shorter word. The search is executed in both the original word and its
// inverse, and the substitution is made considering the longest subword from both cases.
bool Replace_subword(vector<Octagon_group_with_index>& w, vector<Octagon_group_with_index> original) {
bool replaced = false;
// Handle empty string case
if (original.size() == 0) {
return replaced; // false
}
// Look for longest subword forward
vector<Octagon_group_with_index> lfwd;
int idxf = Longest_sequence(lfwd, original);
int Nf = lfwd.size();
// Get inverse of the original word
vector<Octagon_group_with_index> inv;
Invert(inv, original);
// Look for longest subword backwards
vector<Octagon_group_with_index> lbwd;
int idxb = Longest_sequence(lbwd, inv);
int Nb = lbwd.size();
// Assign parameters based on results to homogenise the logic
vector<Octagon_group_with_index> word, sub;
bool is_inverse;
int N, idx;
//cout << "Nb = " << Nb << ", Nf = " << Nf << endl;
if (Nb > Nf) {
word = inv;
sub = lbwd;
idx = idxb;
is_inverse = true;
N = Nb;
} else {
word = original;
sub = lfwd;
idx = idxf;
is_inverse = false;
N = Nf;
}
// Take care of sequences with length greater or equal to 8 -- each chain of length 8
// is by default equal to the identity element and can be directly eliminated.
while (N >= 8) {
replaced = true;
vector<Octagon_group_with_index> ttt = word;
word.clear();
for (int i = 0; i < idx; i++) {
word.push_back(ttt[i]);
}
for (int i = idx + 8; i < ttt.size(); i++) {
word.push_back(ttt[i]);
}
w = word;
ttt = sub;
sub.clear();
for (int i = 8; i < ttt.size(); i++) {
sub.push_back(ttt[i]);
}
N -= 8;
}
// Dehn's algorithm substitutes only chains longer that half-circle.
// Considering equality may lead to infinite loop -- the equivalent
// of a chain with length 4 is also a chain of length 4, so the
// substitution becomes cyclic.
if (N > 4) {
replaced = true;
vector<Octagon_group_with_index> cmpl;
Get_complement_word(cmpl, sub);
vector<Octagon_group_with_index> tmp;
Invert(tmp, cmpl);
cmpl = tmp;
for (int i = 0; i < idx; i++) {
w.push_back(word[i]);
}
for (int i = 0; i < cmpl.size(); i++) {
w.push_back(cmpl[i]);
}
for (int i = N + idx; i < word.size(); i++) {
w.push_back(word[i]);
}
}
// If we have been working with the inverse of the original, the result has to be inverted.
if (is_inverse) {
vector<Octagon_group_with_index> tmp;
Invert(tmp, w);
w = tmp;
}
return replaced;
}
// Applies Dehn's algorithm to a given word. The result is the equivalent ireducible word
// of the original. The boolean return argument of the function indicates whether the
// resulting equivalent irreducible word is the identity element or not.
bool Apply_Dehn(vector<Octagon_group_with_index>& w, vector<Octagon_group_with_index> const original) {
bool is_identity = false;
vector<Octagon_group_with_index> tmp;
tmp = original;
while (tmp.size() > 0) {
Simplify_word(tmp);
vector<Octagon_group_with_index> sub;
bool replaced = Replace_subword(sub, tmp);
if (!replaced) {
w = tmp;
return false;
}
tmp = sub;
}
w = tmp;
return true;
}
/**************************************************************/
// a, \bar{b}, c, \bar{d}, \bar{a}, b, \bar{c}, d
vector<HyperbolicOctagonGroup> gens;
vector<Octagon_group> gens;
bool IsCanonical(const HyperbolicOctagonGroup& m);
bool IsCanonical(const Octagon_group& m);
void generate_words( set<HyperbolicOctagonGroup>& words, vector<HyperbolicOctagonGroup>& prev, int depth, double threshold )
void generate_words( set<Octagon_group>& words, vector<Octagon_group>& prev, int depth, double threshold )
{
if (depth == 1) {
for(int i = 0; i < 8; i++) {
@ -267,10 +560,10 @@ void generate_words( set<HyperbolicOctagonGroup>& words, vector<HyperbolicOctago
return;
}
vector<HyperbolicOctagonGroup> els;
vector<Octagon_group> els;
generate_words( words, els, depth - 1, threshold);
HyperbolicOctagonGroup temp = HyperbolicOctagonGroup(Element(), Element());
Octagon_group temp = Octagon_group(Element(), Element());
ll size = els.size();
bool is_new = false;
for(ll k = 0; k < size; k++) {
@ -290,13 +583,13 @@ void generate_words( set<HyperbolicOctagonGroup>& words, vector<HyperbolicOctago
}
// does the axis of a given matrix go through the fundamental octagon
bool IsCanonical(const HyperbolicOctagonGroup& m)
bool IsCanonical(const Octagon_group& m)
{
HyperbolicOctagonGroup temp = m;
Octagon_group temp = m;
// rotate while |B1| < |B2|
SqrtField B1, B2;
SqrtField C = SqrtField(-1, -1);
Sqrt_field B1, B2;
Sqrt_field C = Sqrt_field(-1, -1);
for(int i = 0; i < 8 && C != C.abs(); i++) {
B1 = real(temp.B).abs();
B2 = imag(temp.B).abs();
@ -307,22 +600,22 @@ bool IsCanonical(const HyperbolicOctagonGroup& m)
assert(C == C.abs());
// (2 - sqrt(2))(|B1| + (sqrt(2) - 1)|B2|)
SqrtField right = SqrtField(2, -1)*(B1 + SqrtField(-1, 1)*B2);
Sqrt_field right = Sqrt_field(2, -1)*(B1 + Sqrt_field(-1, 1)*B2);
// |A2|
SqrtField left = imag(temp.A).abs();
Sqrt_field left = imag(temp.A).abs();
// left <= right -> true
C = right - left;
return C == C.abs();
}
void dfs(const HyperbolicOctagonGroup& m, set<HyperbolicOctagonGroup>& visited)
void dfs(const Octagon_group& m, set<Octagon_group>& visited)
{
assert(IsCanonical(m));
visited.insert(m);
HyperbolicOctagonGroup candidate = m;
Octagon_group candidate = m;
for(int i = 0; i < 8; i++) {
candidate = gens[i]*m*gens[(i + 4) % 8];
if(IsCanonical(candidate) == true && visited.find(candidate) == visited.end()) {
@ -331,33 +624,33 @@ void dfs(const HyperbolicOctagonGroup& m, set<HyperbolicOctagonGroup>& visited)
}
}
// map<HyperbolicOctagonGroup m, HyperbolicOctagonGroup Aux>, m = Aux * origin * Aux^{-1}
void dfs_with_info(const pair<HyperbolicOctagonGroup, HyperbolicOctagonGroup>& new_pair,
map <HyperbolicOctagonGroup, HyperbolicOctagonGroup>& visited)
// map<Octagon_group m, Octagon_group Aux>, m = Aux * origin * Aux^{-1}
void dfs_with_info(const pair<Octagon_group, Octagon_group>& new_pair,
map <Octagon_group, Octagon_group>& visited)
{
assert(IsCanonical(new_pair.first));
visited.insert(new_pair);
const HyperbolicOctagonGroup& current = new_pair.first;
const HyperbolicOctagonGroup& current_factor = new_pair.second;
HyperbolicOctagonGroup candidate = current, candidate_factor = current_factor;
const Octagon_group& current = new_pair.first;
const Octagon_group& current_factor = new_pair.second;
Octagon_group candidate = current, candidate_factor = current_factor;
for(int i = 0; i < 8; i++) {
candidate = gens[i]*current*gens[(i + 4) % 8];
if(IsCanonical(candidate) == true && visited.find(candidate) == visited.end()) {
candidate_factor = gens[i]*current_factor;
dfs_with_info(pair<HyperbolicOctagonGroup, HyperbolicOctagonGroup>(candidate, candidate_factor), visited);
dfs_with_info(pair<Octagon_group, Octagon_group>(candidate, candidate_factor), visited);
}
}
}
void dfs_with_info(const HyperbolicOctagonGroup& origin,
map<HyperbolicOctagonGroup, HyperbolicOctagonGroup>& visited)
void dfs_with_info(const Octagon_group& origin,
map<Octagon_group, Octagon_group>& visited)
{
assert(IsCanonical(origin));
HyperbolicOctagonGroup id = HyperbolicOctagonGroup(Element(SqrtField(1, 0), SqrtField(0, 0)),
Element(SqrtField(0, 0), SqrtField(0, 0)));
pair<HyperbolicOctagonGroup, HyperbolicOctagonGroup> new_pair(origin, id);
Octagon_group id = Octagon_group(Element(Sqrt_field(1, 0), Sqrt_field(0, 0)),
Element(Sqrt_field(0, 0), Sqrt_field(0, 0)));
pair<Octagon_group, Octagon_group> new_pair(origin, id);
dfs_with_info(new_pair, visited);
}
@ -374,21 +667,21 @@ public:
double x, y;
};
HyperbolicOctagonGroup m;
Octagon_group m;
IntersectionNumber(const HyperbolicOctagonGroup& m_) : m(m_)
IntersectionNumber(const Octagon_group& m_) : m(m_)
{}
long operator() () const
{
set<HyperbolicOctagonGroup> visited;
set<HyperbolicOctagonGroup>::iterator it, it2;
set<Octagon_group> visited;
set<Octagon_group>::iterator it, it2;
map<long, long> nb_map;
map<long, long>::iterator mit;
dfs(m, visited);
set<pair< HyperbolicOctagonGroup, HyperbolicOctagonGroup> > common;
set<pair< Octagon_group, Octagon_group> > common;
for(it = visited.begin(); it != visited.end(); ++it) {
for(it2 = it; it2 != visited.end(); ++it2) {
if(*it == *it2) {
@ -417,12 +710,12 @@ public:
}
void count_nb(const HyperbolicOctagonGroup& m1, const HyperbolicOctagonGroup& m2, set<pair< HyperbolicOctagonGroup, HyperbolicOctagonGroup> >& visited) const
void count_nb(const Octagon_group& m1, const Octagon_group& m2, set<pair< Octagon_group, Octagon_group> >& visited) const
{
typedef pair<HyperbolicOctagonGroup, HyperbolicOctagonGroup> matrix_pair;
typedef pair<Octagon_group, Octagon_group> matrix_pair;
visited.insert(matrix_pair(m1, m2));
HyperbolicOctagonGroup c1 = m1, c2 = m2;
Octagon_group c1 = m1, c2 = m2;
for(int i = 0; i < 8; i++) {
c1 = gens[i]*m1*gens[(i + 4) % 8];
c2 = gens[i]*m2*gens[(i + 4) % 8];
@ -435,7 +728,7 @@ public:
//private:
// check whether two axis have intersection
bool haveIntersection(const HyperbolicOctagonGroup& m1, const HyperbolicOctagonGroup& m2) const
bool haveIntersection(const Octagon_group& m1, const Octagon_group& m2) const
{
Point p1, p2;
intersectWithInfinity(m1, p1, p2);
@ -451,12 +744,12 @@ public:
return (sign1 * sign2 < 0);
}
void intersectWithInfinity(const HyperbolicOctagonGroup& m, Point& p1, Point& p2) const
void intersectWithInfinity(const Octagon_group& m, Point& p1, Point& p2) const
{
Element a = m.A, b = m.B, factor = m.factor;
Element four = Element(SqrtField(4, 0), SqrtField(0, 0));
Element two = Element(SqrtField(2, 0), SqrtField(0, 0));
Element four = Element(Sqrt_field(4, 0), Sqrt_field(0, 0));
Element two = Element(Sqrt_field(2, 0), Sqrt_field(0, 0));
Element D = (a - conj(a))*(a - conj(a));
D += four*b*conj(b)*factor;
@ -481,17 +774,17 @@ public:
};
void Delete(const set<HyperbolicOctagonGroup>& canonical_set, vector<HyperbolicOctagonGroup>& output)
void Delete(const set<Octagon_group>& canonical_set, vector<Octagon_group>& output)
{
set<HyperbolicOctagonGroup> redundant;
set<Octagon_group> redundant;
set<HyperbolicOctagonGroup>::iterator it;
set<Octagon_group>::iterator it;
for(it = canonical_set.begin(); it != canonical_set.end(); ++it) {
if(redundant.find(*it) != redundant.end()) {
continue;
}
set<HyperbolicOctagonGroup> visited;
set<Octagon_group> visited;
dfs(*it, visited);
visited.erase(*it);
@ -500,16 +793,16 @@ void Delete(const set<HyperbolicOctagonGroup>& canonical_set, vector<HyperbolicO
}
}
void generate_unique_words(vector<HyperbolicOctagonGroup>& output, double threshold = 10, int word_length = 13)
void generate_unique_words(vector<Octagon_group>& output, double threshold = 10, int word_length = 13)
{
get_generators(gens);
set<HyperbolicOctagonGroup> unique_words;
vector<HyperbolicOctagonGroup> temp;
set<Octagon_group> unique_words;
vector<Octagon_group> temp;
generate_words(unique_words, temp, word_length, threshold);
double l = 0;
set<HyperbolicOctagonGroup>::iterator uit;
set<Octagon_group>::iterator uit;
for(uit = unique_words.begin(); uit != unique_words.end(); ++uit) {
l = uit->length();
if(0. < l && l < threshold) {
@ -521,14 +814,14 @@ void generate_unique_words(vector<HyperbolicOctagonGroup>& output, double thresh
}
// words that correspond to union of 1-cycles
void generate_words_union_1_cycles(vector<HyperbolicOctagonGroup>& out)
void generate_words_union_1_cycles(vector<Octagon_group>& out)
{
if(gens.size() == 0) {
get_generators(gens);
}
HyperbolicOctagonGroup f[4] = {gens[0], gens[5], gens[2], gens[7]};
Octagon_group f[4] = {gens[0], gens[5], gens[2], gens[7]};
HyperbolicOctagonGroup F[8] = {
Octagon_group F[8] = {
f[0]*f[0].inverse(),
f[0],
f[0]*f[1],
@ -555,7 +848,7 @@ void generate_words_union_1_cycles(vector<HyperbolicOctagonGroup>& out)
}
counter++;
HyperbolicOctagonGroup Tr = F[i]*F[k].inverse()*F[j];
Octagon_group Tr = F[i]*F[k].inverse()*F[j];
// check that Tr != Id
if(Tr.length() > 2.) {
out.push_back(Tr);

View File

@ -1,256 +0,0 @@
// Copyright (c) 2010 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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/candidate-packages/Triangulation_2/include/CGAL/Delaunay_triangulation_2.h $
// $Id: Delaunay_triangulation_2.h 57509 2010-07-15 09:14:09Z sloriot $
//
//
// Author(s) : Mikhail Bogdanov
#ifndef CGAL_PERIODIC_4_DELAUNAY_HYPERBOLIC_TRIANGULATION_2_H
#define CGAL_PERIODIC_4_DELAUNAY_HYPERBOLIC_TRIANGULATION_2_H
#include <vector>
// I needed to use a non-reserved word for this thing, there were problems when I (iiordano) (stupidly) used TYPE
#define CLEARLY_MY_TYPE 2 // 1 = Cross, 2 = Diametric
#define USE_TEST_THINGS 0 // 1 = True, 0 = False
#if USE_TEST_THINGS == 1
#include <CGAL/Periodic_4_hyperbolic_triangulation_2.h>
#else
#include <CGAL/Delaunay_triangulation_2.h>
#endif
/*
#if CLEARLY_MY_TYPE == 1
#include <CGAL/Cross_translations.h>
#else
#include <CGAL/Diametric_translations.h>
#endif
*/
//#include <CGAL/Periodic_2_hyperbolic_triangulation_dummy.h>
namespace CGAL {
template < class Gt,
class Tds = Triangulation_data_structure_2 <
Triangulation_vertex_base_2<Gt> > >
#if USE_TEST_THINGS == 1
class Periodic_4_Delaunay_hyperbolic_triangulation_2 : public Periodic_4_hyperbolic_triangulation_2<Gt,Tds>
#else
class Periodic_4_Delaunay_hyperbolic_triangulation_2 : public Delaunay_triangulation_2<Gt,Tds>
#endif
{
public:
typedef Periodic_4_Delaunay_hyperbolic_triangulation_2<Gt, Tds> Self;
#if USE_TEST_THINGS == 1
typedef Periodic_4_hyperbolic_triangulation_2<Gt,Tds> Base;
#else
typedef Delaunay_triangulation_2<Gt,Tds> Base;
#endif
typedef typename Base::Vertex_handle Vertex_handle;
typedef typename Base::Face_handle Face_handle;
typedef typename Base::Edge Edge;
typedef typename Base::Locate_type Locate_type;
typedef typename Base::Finite_edges_iterator Finite_edges_iterator;
typedef typename Base::Face_circulator Face_circulator;
typedef Gt Geom_traits;
typedef typename Geom_traits::FT FT;
typedef typename Geom_traits::Point_2 Point_2;
typedef typename Geom_traits::Segment_2 Segment;
//void insert_dummy_points(std::vector<typename GT::Point_2>& );
void Set_recursion_depth(int new_depth) {
this->recursion_depth = new_depth;
}
#ifndef CGAL_CFG_USING_BASE_MEMBER_BUG_2
using Base::tds;
#endif
/*
Periodic_4_Delaunay_hyperbolic_triangulation_2(const Gt& gt = Gt())
#if USE_TEST_THINGS == 1
: Periodic_4_hyperbolic_triangulation_2<Gt,Tds>(gt)
#else
: Delaunay_triangulation_2<Gt,Tds>(gt)
#endif
{
recursion_depth = 0;
}
Periodic_4_Delaunay_hyperbolic_triangulation_2(const Periodic_4_Delaunay_hyperbolic_triangulation_2<Gt,Tds> &tr)
#if USE_TEST_THINGS == 1
: Periodic_4_hyperbolic_triangulation_2<Gt,Tds>(tr)
#else
: Delaunay_triangulation_2<Gt,Tds>(tr)
#endif
{ CGAL_triangulation_postcondition( this->is_valid() ); }
*/
/************************ INSERT OVERLOADS **************************/
/*
Vertex_handle insert(const Point_2 &p,
Face_handle start = Face_handle() )
{
std::vector<Point_2> copies;
Vertex_handle vh = Base::insert(p, start);
recursive_translate(g, copies, p, recursion_depth);
for(int i = 0; i < copies.size(); i++) {
vh = Base::insert(copies[i], start);
}
return vh;
}
Vertex_handle insert(const Point_2& p,
typename Base::Locate_type lt,
Face_handle loc, int li )
{
return Base::insert(p, lt, loc, li);
}
template < class InputIterator >
std::ptrdiff_t
insert(InputIterator first, InputIterator last)
{
return Base::insert(first, last);
}
*/
Object
dual(const Finite_edges_iterator& ei) const {
return this->dual(*ei);
}
Object
dual(const Edge &e) const {
// default implementation
//assert(false);
return make_object(e);
}
// Clears the triangulation and initializes it again.
void clear() {
tds().clear();
init_tds();
}
private:
/*
void recursive_translate(
#if CLEARLY_MY_TYPE == 1
Cross_translations<Gt> g,
#else
Diametric_translations<Gt> g,
#endif
std::vector<Point_2>& points,
Point_2 o,
int depth,
int start = -1,
int end = -1)
{
if (depth > 0) {
if (start == -1 && end == -1) {
int start = points.size();
int end = start + 8;
Point_2 subject = o;
// Add points in the order indicated by the group -- not necessary, but seems logical
points.push_back( g.a().DoAction(subject) );
points.push_back( g.b().inverse().DoAction(subject) );
points.push_back( g.c().DoAction(subject) );
points.push_back( g.d().inverse().DoAction(subject) );
points.push_back( g.a().inverse().DoAction(subject) );
points.push_back( g.b().DoAction(subject) );
points.push_back( g.c().inverse().DoAction(subject) );
points.push_back( g.d().DoAction(subject) );
recursive_translate(g, points, o, depth - 1, start, end);
}
else
{
int my_start = points.size();
int my_end = start;
for (int i = start; i <= end; i++){
Point_2 subject = points[i];
points.push_back( g.a().DoAction(subject) );
points.push_back( g.b().inverse().DoAction(subject) );
points.push_back( g.c().DoAction(subject) );
points.push_back( g.d().inverse().DoAction(subject) );
points.push_back( g.a().inverse().DoAction(subject) );
points.push_back( g.b().DoAction(subject) );
points.push_back( g.c().inverse().DoAction(subject) );
points.push_back( g.d().DoAction(subject) );
my_end += 8;
}
recursive_translate(g, points, o, depth - 1, my_start, my_end);
}
}
}
*/
// Initializes the triangulation data structure
void init_tds() {
this->_infinite_vertex = tds().insert_first();
}
void paste_together_opposite_sides(const std::vector<Vertex_handle>& on_vertex, const std::vector<Vertex_handle>& on_boundary);
// The following variable defines how many copies to insert on the Poincaré disk (for visualisation purposes only!)
int recursion_depth;
/*
#if CLEARLY_MY_TYPE == 1 // This means that we must do Cross-translations (alternative identification)
Cross_translations<Gt> g;
#else
Diametric_translations<Gt> g;
#endif
*/
};
} // namespace CGAL
//#include <Periodic_2_hyperbolic_triangulation_dummy.h>
#endif // CGAL_PERIODIC_4_DELAUNAY_HYPERBOLIC_TRIANGULATION_2_H

View File

@ -37,7 +37,7 @@ class Periodic_4_construct_hyperbolic_point_2 : public Construct_point_2_base
public:
typedef typename Kernel::Point_2 Point;
typedef HyperbolicOctagonGroup Offset;
typedef HyperbolicOctagonGroup Offset;
typedef typename Kernel::Circle_2 Circle_2;
typedef Point result_type;
@ -45,10 +45,6 @@ public:
Periodic_4_construct_hyperbolic_point_2(const Circle_2 & dom) : _dom(dom) { }
Point operator() ( const Point& p, const Offset& o ) const {
/*
return Point( p.x()+(_dom.xmax()-_dom.xmin())*o.x(),
p.y()+(_dom.ymax()-_dom.ymin())*o.y(),
p.z()+(_dom.zmax()-_dom.zmin())*o.z()); */
pair<double, double> pt = o.apply(to_double(p.x()), to_double(p.y()));
Point r = Point(pt.first, pt.second);

View File

@ -1,10 +1,9 @@
// Copyright (c) 2006-2009 INRIA Sophia-Antipolis (France).
// Copyright (c) 2016 INRIA Nancy - Grand Est (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.
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
@ -12,85 +11,197 @@
// 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$
//
// $URL: $
// $Id: $
//
// Author(s) : Nico Kruithof <Nico.Kruithof@sophia.inria.fr>
// Manuel Caroli <Manuel.Caroli@sophia.inria.fr>
//
// Author(s) : Iordan Iordanov
#ifndef CGAL_PERIODIC_4_HYPERBOLIC_DELAUNAY_TRIANGULATION_TRAITS_2_H
#define CGAL_PERIODIC_4_HYPERBOLIC_DELAUNAY_TRIANGULATION_TRAITS_2_H
//#include <CGAL/basic.h>
#include <CGAL/Traits_with_hyperbolic_offsets_adaptor.h>
#include <CGAL/Periodic_4_construct_hyperbolic_point_2.h>
#include <CGAL/Periodic_4_hyperbolic_triangulation_traits_2.h>
#include <CGAL/Hyperbolic_octagon_group.h>
#include <CGAL/Point_2.h>
#include <CGAL/Segment_2.h>
#include <CGAL/Triangle_2.h>
#include <CGAL/Line_2.h>
#include <CGAL/Ray_2.h>
#include <CGAL/predicates_on_points_2.h>
#include <CGAL/basic_constructions_2.h>
#include <CGAL/distance_predicates_2.h>
namespace CGAL {
#include <CGAL/Regular_triangulation_filtered_traits_2.h>
#include <CGAL/Triangulation_hyperbolic_traits_2.h>
#include "boost/tuple/tuple.hpp"
#include "boost/variant.hpp"
namespace CGAL {
template< class R >
class Periodic_4_hyperbolic_Delaunay_triangulation_traits_2 {
template < class THT2 >
class Periodic_4_hyperbolic_Delaunay_triangulation_traits_base_2
: public Periodic_3_triangulation_traits_base_3<THT2>
{
public:
typedef THT2 K;
typedef HyperbolicOctagonGroup Offset;
typedef Periodic_4_hyperbolic_triangulation_traits_base_2< K > Base;
typedef Periodic_4_hyperbolic_Delaunay_triangulation_traits_base_2< K > Self;
typedef typename Base::RT RT;
typedef typename Base::FT FT;
typedef typename Base::Point_2 Point_2;
typedef typename Base::Vector_2 Vector_2;
//typedef typename Base::Periodic_4_offset_2 Periodic_4_offset_2;
typedef R Kernel;
// The next typedef is there for backward compatibility
// Some users take their point type from the traits class.
// Before this type was Point
typedef Point_2 Point;
typedef Periodic_4_hyperbolic_Delaunay_triangulation_traits_2<R>
Self;
typedef typename Base::Segment_2 Segment_2;
typedef typename Base::Triangle_2 Triangle_2;
typedef Triangulation_hyperbolic_traits_2<R> Base;
// Delaunay specific predicates
typedef Traits_with_offsets_adaptor<Self,
typename K::Side_of_oriented_circle_2>
Side_of_oriented_circle_2;
typedef Traits_with_offsets_adaptor<Self, typename K::Compare_distance_2>
Compare_distance_2;
typedef Traits_with_offsets_adaptor<Self,
typename K::Side_of_bounded_disc_2>
Side_of_bounded_disc_2;
// Basic types
typedef typename Base::RT RT;
typedef typename Base::FT FT;
typedef typename Base::Point_2 Point_2;
typedef Point_2 Point; // Compatibility issues
typedef typename Base::Vector_2 Vector_2;
typedef typename Base::Triangle_2 Triangle_2;
typedef typename Base::Line_2 Line_2;
typedef typename Base::Ray_2 Ray_2;
typedef typename Base::Vector_3 Vector_3;
typedef typename Base::Point_3 Point_3;
typedef typename Base::Angle_2 Angle_2;
typedef typename Base::Iso_rectangle_2 Iso_rectangle_2;
typedef typename Base::Circle_2 Circle_2;
typedef typename Base::Arc_2 Arc_2;
typedef typename Base::Line_segment_2 Line_segment_2;
typedef typename Base::Segment_2 Segment_2;
typedef typename Base::Euclidean_line_2 Euclidean_line_2;
// Delaunay specific constructions
typedef Traits_with_hyperbolic_offsets_adaptor<Self,
typename K::Construct_circumcenter_2>
Construct_circumcenter_2;
// Predicates and comparisons
typedef typename Base::Less_x_2 Less_x_2;
typedef typename Base::Less_y_2 Less_y_2;
typedef typename Base::Compare_x_2 Compare_x_2;
typedef typename Base::Compare_y_2 Compare_y_2;
typedef typename Base::Orientation_2 Orientation_2;
typedef typename Base::Side_of_oriented_circle_2 Side_of_oriented_circle_2;
typedef typename Base::Compare_distance_2 Compare_distance_2;
typedef typename Base::Compute_squared_distance_2 Compute_squared_distance_2;
// Operations
Side_of_oriented_circle_2
side_of_oriented_circle_2_object() const {
return Side_of_oriented_circle_2(&this->_domain);
}
Compare_distance_2
compare_distance_2_object() const {
return Compare_distance_2(&this->_domain);
}
Side_of_bounded_disc_2
side_of_bounded_disc_2_object() const {
return Side_of_bounded_disc_2(&this->_domain);
}
Construct_circumcenter_2
construct_circumcenter_2_object() const {
return Construct_circumcenter_2(&this->_domain);
}
};
// Constructions
typedef typename Base::Construct_bisector_2 Construct_bisector_2;
typedef typename Base::Construct_hyperbolic_bisector_2 Construct_hyperbolic_bisector_2;
typedef typename Base::Construct_triangle_2 Construct_triangle_2;
typedef typename Base::Construct_direction_2 Construct_direction_2;
typedef typename Base::Construct_midpoint_2 Construct_midpoint_2;
typedef typename Base::Construct_circumcenter_2 Construct_circumcenter_2;
typedef typename Base::Construct_segment_2 Construct_segment_2;
typedef typename Base::Construct_ray_2 Construct_ray_2;
typedef typename Base::Is_hyperbolic Is_hyperbolic;
template < typename K >
class Periodic_4_hyperbolic_Delaunay_triangulation_traits_2;
private:
Circle_2 _domain;
} //namespace CGAL
public:
Periodic_4_hyperbolic_Delaunay_triangulation_traits_2() :
_domain(Point_2(0, 0), 1*1)
{}
Periodic_4_hyperbolic_Delaunay_triangulation_traits_2(FT r) :
_domain(Point_2(0, 0), r*r)
{}
Periodic_4_hyperbolic_Delaunay_triangulation_traits_2(const Periodic_4_hyperbolic_Delaunay_triangulation_traits_2 & other) :
_domain(other._domain)
{}
Periodic_4_hyperbolic_Delaunay_triangulation_traits_2 &operator=(const Periodic_4_hyperbolic_Delaunay_triangulation_traits_2 &)
{
return *this;
}
Construct_circumcenter_2
construct_circumcenter_2_object() const {
return Construct_circumcenter_2(_domain);
}
Construct_segment_2
construct_segment_2_object() const {
return Construct_segment_2(_domain);
}
Construct_midpoint_2
construct_midpoint_2_object() const {
return Construct_midpoint_2(&_domain);
}
Less_x_2
less_x_2_object() const {
return Less_x_2();
}
Less_y_2
less_y_2_object() const {
return Less_y_2();
}
Compare_x_2
compare_x_2_object() const {
return Compare_x_2();
}
Compare_y_2
compare_y_2_object() const {
return Compare_y_2();
}
Orientation_2
orientation_2_object() const {
return Orientation_2();
}
Side_of_oriented_circle_2
side_of_oriented_circle_2_object() const {
return Side_of_oriented_circle_2();
}
Construct_hyperbolic_bisector_2
construct_hyperbolic_bisector_2_object() const {
return Construct_hyperbolic_bisector_2(_domain);
}
Construct_bisector_2
construct_bisector_2_object() const {
return Construct_bisector_2();
}
Compare_distance_2
compare_distance_2_object() const {
return Compare_distance_2();
}
Construct_triangle_2
construct_triangle_2_object() const {
return Construct_triangle_2();
}
Construct_direction_2
construct_direction_2_object() const {
return Construct_direction_2();
}
Construct_ray_2
construct_ray_2_object() const {
return Construct_ray_2(_domain);
}
Is_hyperbolic
Is_hyperbolic_object() const {
return Is_hyperbolic();
}
}; // class Periodic_4_hyperbolic_Delaunay_triangulation_traits_2
} // namespace CGAL
#endif // CGAL_PERIODIC_4_HYPERBOLIC_DELAUNAY_TRIANGULATION_TRAITS_2_H

View File

@ -1,243 +0,0 @@
// Copyright (c) 2010 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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/candidate-packages/Triangulation_2/include/CGAL/Delaunay_triangulation_2.h $
// $Id: Delaunay_triangulation_2.h 57509 2010-07-15 09:14:09Z sloriot $
//
//
// Author(s) : Mikhail Bogdanov
#ifndef CGAL_PERIODIC_4_HYPERBOLIC_TRIANGULATION_DUMMY_H
#define CGAL_PERIODIC_4_HYPERBOLIC_TRIANGULATION_DUMMY_H
#include <CGAL/Regular_triangulation_filtered_traits_2.h>
#include <CGAL/Aff_transformation_2.h>
// Added by Iordanov
/*
#if CLEARLY_MY_TYPE == 1
#include <CGAL/Cross_translations.h>
#else
#include <CGAL/Diametric_translations.h>
#endif
*/
namespace CGAL {
// this class might to be moved to hyperbolic traits
template<class GT>
class Construct_reflection
{
typedef typename GT::Point_2 Point_2;
typedef typename GT::Circle_2 Circle_2;
typedef typename GT::Vector_2 Vector_2;
typedef typename GT::FT FT;
typedef typename GT::Compute_squared_distance_2 Compute_squared_distance_2;
typedef typename GT::Construct_vector_2 Construct_vector_2;
typedef typename GT::Construct_scaled_vector_2 Construct_scaled_vector_2;
typedef typename GT::Construct_translated_point_2 Construct_translated_point_2;
typedef CGAL::Regular_triangulation_filtered_traits_2<GT> Rtr_2;
typedef typename Rtr_2::Construct_weighted_circumcenter_2 Construct_weighted_circumcenter_2;
typedef typename Rtr_2::Weighted_point_2 Weighted_point_2;
typedef typename Rtr_2::Bare_point Bare_point;
public:
Construct_reflection(const Circle_2& c = Circle_2(Point_2(0.0, 0.0), 1.)): _unit_circle(c)
{
}
// exact arithmetic! very nice!
Point_2 operator ()(const Point_2& p, const Point_2& q, const Point_2& r) const
{
typedef typename GT::Collinear_2 Collinear_2;
if(Collinear_2()(p, q, _unit_circle.center())){
assert(false);
}
Weighted_point_2 wp(p);
Weighted_point_2 wq(q);
Weighted_point_2 wo(_unit_circle.center(), _unit_circle.squared_radius());
Bare_point center = Construct_weighted_circumcenter_2()(wp, wo, wq);
FT radius = Compute_squared_distance_2()(p, center);
FT dist = Compute_squared_distance_2()(r,center);
Vector_2 vect = Construct_vector_2()(center,r);
vect = Construct_scaled_vector_2()(vect,radius/dist);
Point_2 image = Construct_translated_point_2()(center,vect);
return image;
}
private:
const Circle_2& _unit_circle;
};
template<class GT>
typename GT::Point_2 apply_rotation(const typename GT::Point_2& p)
{
// Note Iordan: This is rotation by \pi/4 -- the second and third argument are the values of cos(\theta) and sin(\theta), respectively
CGAL::Aff_transformation_2<GT> rotate(CGAL::ROTATION, std::sqrt(0.5), std::sqrt(0.5));
return rotate(p);
}
template<class GT>
void compute_dummy_points( std::vector<typename GT::Point_2>& inner_points,
std::vector<typename GT::Point_2>& points_on_boundary,
std::vector<typename GT::Point_2>& points_on_vertex)
{
assert(inner_points.size() == 0);
assert(points_on_boundary.size() == 0);
assert(points_on_vertex.size() == 0);
typedef typename GT::Kernel K;
typedef typename GT::Point_2 Point_2;
double phi = CGAL_PI / 8.;
double psi = CGAL_PI / 3.;
double rho = std::sqrt(cos(psi)*cos(psi) - sin(phi)*sin(phi));
const Point_2 o(0.0, 0.0);
const Point_2 a(cos(phi)*cos(phi + psi)/rho, sin(phi)*cos(phi + psi)/rho);
const Point_2 b(a.x(), -a.y());
inner_points.push_back(a);
Point_2 c = Construct_reflection<K>()(a, b, o);
Point_2 d = Construct_reflection<K>()(a, c, b);
//inner_points.push_back(d);
Point_2 e = Construct_reflection<K>()(d, c, a);
Point_2 f = Construct_reflection<K>()(d, e, c);
int size = inner_points.size();
for(int i = 0; i < 7; i++) {
for(int j = 0; j < size; j++) {
inner_points.push_back(apply_rotation<K>(inner_points[i*size + j]));
}
}
inner_points.push_back(o);
points_on_boundary.push_back(c);
for(int i = 1; i < 4; i++) {
points_on_boundary.push_back(apply_rotation<K>(points_on_boundary[i-1]));
}
points_on_vertex.push_back(apply_rotation<K>(f));
}
/*
template<class GT>
void recursive_translate(Diametric_translations<GT> g,
std::vector<typename GT::Point_2>& points,
int depth,
int start,
int end) {
if (depth > 0) {
int my_start = points.size();
int my_end = start;
for (int i = start; i <= end; i++){
typename GT::Point_2 subject = points[i];
points.push_back( g.a().DoAction(subject) );
points.push_back( g.b().inverse().DoAction(subject) );
points.push_back( g.c().DoAction(subject) );
points.push_back( g.d().inverse().DoAction(subject) );
points.push_back( g.a().inverse().DoAction(subject) );
points.push_back( g.b().DoAction(subject) );
points.push_back( g.c().inverse().DoAction(subject) );
points.push_back( g.d().DoAction(subject) );
my_end += 8;
}
recursive_translate(g, points, depth - 1, my_start, my_end);
}
}
template<class GT>
void recursive_translate(Diametric_translations<GT> g,
std::vector<typename GT::Point_2>& points,
typename GT::Point_2 subject,
int depth) {
if (depth > 0) {
int start = points.size();
int end = start + 8;
// Add points in the order indicated by the group -- not necessary, but seems logical
points.push_back( g.a().DoAction(subject) );
points.push_back( g.b().inverse().DoAction(subject) );
points.push_back( g.c().DoAction(subject) );
points.push_back( g.d().inverse().DoAction(subject) );
points.push_back( g.a().inverse().DoAction(subject) );
points.push_back( g.b().DoAction(subject) );
points.push_back( g.c().inverse().DoAction(subject) );
points.push_back( g.d().DoAction(subject) );
recursive_translate(g, points, depth - 1, start, end);
}
}
*/
template < class GT, class TDS >
void Delaunay_hyperbolic_triangulation_2<GT, TDS>::insert_dummy_points(std::vector<typename GT::Point_2>& all_points) {
//clear();
std::vector<typename GT::Point_2> inner_points, points_on_boundary, points_on_vertex;
compute_dummy_points<GT>(inner_points, points_on_boundary, points_on_vertex);
/*std::vector<typename GT::Point_2>*/ all_points = inner_points;
for (int i = 0; i < points_on_boundary.size(); i++) {
all_points.push_back(points_on_boundary[i]);
}
for (int i = 0; i < points_on_vertex.size(); i++) {
all_points.push_back(points_on_vertex[i]);
}
std::cout << "All points length: " << all_points.size() << std::endl;
//for (int i = 0; i < all_points.size(); i++) {
// processInput(all_points[i]);
//}
//Base::insert(all_points.begin(), all_points.end());
/*
Diametric_translations<GT> g;
std::vector<Point_2> copies;
for (int i = 0; i < all_points.size(); i++) {
recursive_translate(g, copies, all_points[i], recursion_depth);
}
std::cout << "Copies length: " << copies.size() << std::endl;
Base::insert(copies.begin(), copies.end());
*/
}
} // namespace CGAL
#endif // CGAL_PERIODIC_4_HYPERBOLIC_TRIANGULATION_DUMMY_H

View File

@ -1,123 +0,0 @@
// Copyright (c) 2006-2009 INRIA Sophia-Antipolis (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$
//
//
// Author(s) : Nico Kruithof <Nico.Kruithof@sophia.inria.fr>
// Manuel Caroli <Manuel.Caroli@sophia.inria.fr>
#ifndef CGAL_PERIODIC_4_HYPERBOLIC_TRIANGULATION_TRAITS_2_H
#define CGAL_PERIODIC_4_HYPERBOLIC_TRIANGULATION_TRAITS_2_H
#include <CGAL/Traits_with_hyperbolic_offsets_adaptor.h>
#include <CGAL/Triangulation_hyperbolic_traits_2.h>
#include <CGAL/Square_root_2_field.h>
#include <CGAL/Hyperbolic_octagon_group.h>
#include <CGAL/Periodic_4_construct_hyperbolic_point_2.h>
namespace CGAL {
template < class THT2 >
class Periodic_4_hyperbolic_triangulation_traits_base_2
: public THT2
{
public:
typedef THT2 K;
typedef HyperbolicOctagonGroup Offset;
typedef Periodic_4_hyperbolic_triangulation_traits_base_2< K > Self;
typedef typename K::RT RT;
typedef typename K::FT FT;
typedef typename K::Point_2 Point_2;
//typedef typename K::Vector_3 Vector_3;
typedef Offset Periodic_4_hyperbolic_offset_2;
typedef typename K::Circle_2 Circle_2;
// The next typedef is there for backward compatibility
// Some users take their point type from the traits class.
// Before this type was Point
typedef Point_2 Point;
// Triangulation predicates
typedef Traits_with_hyperbolic_offsets_adaptor<Self, typename K::Compare_xy_2>
Compare_xy_2;
typedef Traits_with_hyperbolic_offsets_adaptor<Self, typename K::Orientation_2>
Orientation_2;
// Triangulation constructions
typedef Periodic_4_construct_hyperbolic_point_2<Self, typename K::Construct_point_2>
Construct_hyperbolic_point_2;
typedef Traits_with_hyperbolic_offsets_adaptor<Self, typename K::Construct_segment_2>
Construct_segment_2;
typedef Traits_with_hyperbolic_offsets_adaptor<Self, typename K::Construct_triangle_2>
Construct_hyperbolic_triangle_2;
// Access
void set_domain(const Circle_2& domain) {
_domain = domain;
}
Circle_2 get_domain() const {
return _domain;
}
// Operations
Compare_xy_2
compare_xy_2_object() const {
return Compare_xy_2(&_domain);
}
Orientation_2
orientation_2_object() const {
return Orientation_2(&_domain);
}
Construct_hyperbolic_point_2
construct_hyperbolic_point_2_object() const {
return Construct_point_2(_domain);
}
Construct_segment_2
construct_segment_2_object() const {
return Construct_segment_2(&_domain);
}
protected:
Circle_2 _domain;
};
namespace future_release
{
template < typename K >
class Periodic_4_hyperbolic_triangulation_traits_2;
}
} //namespace CGAL
#include <CGAL/Periodic_3_Delaunay_triangulation_traits_3.h>
namespace CGAL
{
template < typename K >
class Periodic_4_hyperbolic_Delaunay_triangulation_traits_2;
}
#endif // CGAL_PERIODIC_4_HYPERBOLIC_TRIANGULATION_TRAITS_2_H

View File

@ -22,19 +22,19 @@
#include <CGAL/Qt/PainterOstream.h>
#include <CGAL/Triangulation_hyperbolic_traits_2.h>
#include <CGAL/Periodic_4_hyperbolic_Delaunay_triangulation_traits_2.h>
namespace CGAL{
namespace Qt {
template <typename K>
class PainterOstream<Triangulation_hyperbolic_traits_2<K> > : public PainterOstream<K> {
class PainterOstream<Periodic_4_hyperbolic_Delaunay_triangulation_traits_2<K> > : public PainterOstream<K> {
public:
typedef PainterOstream<K> Base;
typedef PainterOstream<Triangulation_hyperbolic_traits_2<K> > Self;
typedef PainterOstream<Periodic_4_hyperbolic_Delaunay_triangulation_traits_2<K> > Self;
typedef Triangulation_hyperbolic_traits_2<K> Gt;
typedef Periodic_4_hyperbolic_Delaunay_triangulation_traits_2<K> Gt;
private:
typedef typename Gt::Segment_2 Segment_2;

View File

@ -36,7 +36,7 @@ template < class K, class Functor_ >
typedef K Kernel;
typedef Functor_ Functor;
typedef typename Kernel::Point_3 Point;
typedef typename Kernel::Point_2 Point;
typedef HyperbolicOctagonGroup Offset;
public:
@ -86,7 +86,7 @@ public:
protected:
Point pp(const Point &p, const Offset &o) const {
return Construct_point_3(*_domain)(p,o);
return Construct_point_2(*_domain)(p,o);
}
public:
const Circle_2* _domain;