Added new demo, changes in the folder structure, minor modifications to the code

This commit is contained in:
Iordan Iordanov 2016-02-24 10:44:26 +01:00
parent 10540c2931
commit 7bef92b6d9
62 changed files with 7859 additions and 761 deletions

View File

@ -0,0 +1,38 @@
# Created by the script cgal_create_cmake_script
# This is the CMake script for compiling a CGAL application.
project (Periodic_4_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 2.8.11)
if(POLICY CMP0043)
cmake_policy(SET CMP0043 OLD)
endif()
find_package(CGAL COMPONENTS Qt5)
include(${CGAL_USE_FILE})
find_package(Qt5 QUIET COMPONENTS Widgets)
include_directories (BEFORE ../../include include)
# ui files, created with Qt Designer
qt5_wrap_ui( uis Periodic_4_hyperbolic_triangulation_2.ui )
# qrc files (resources files, that contain icons, at least)
qt5_add_resources ( RESOURCE_FILES resources/Periodic_4_hyperbolic_triangulation_2.qrc )
# cpp files
add_executable ( Periodic_4_Dirichlet_region_demo Periodic_4_Dirichlet_region_demo.cpp )
qt5_use_modules( Periodic_4_Dirichlet_region_demo Widgets)
add_to_cached_list( CGAL_EXECUTABLE_TARGETS Periodic_4_Dirichlet_region_demo )
target_link_libraries( Periodic_4_Dirichlet_region_demo ${CGAL_LIBRARIES} ${QT_LIBRARIES} ${CGAL_QT_LIBRARIES} )

View File

@ -0,0 +1,742 @@
#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_Delaunay_hyperbolic_triangulation_2.h> */
#include <CGAL/Triangulation_hyperbolic_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/Sqrt_field.h>
#include <CGAL/Octagon_matrix.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> >
/* typedef CGAL::Periodic_4_Delaunay_hyperbolic_triangulation_2< K, CGAL::Triangulation_data_structure_2<Vb, Fb> > */
Delaunay;
typedef Delaunay::Vertex_handle Vertex_handle;
//typedef CGAL::Delaunay_hyperbolic_triangulation_2<K> Delaunay;
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;
void apply_unique_words(std::vector<Point>& points, Point input = Point(0, 0), double threshold = 20 , int word_length = 6, double d = .999)
{
static vector<OctagonMatrix> 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<OctagonMatrix> 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);
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);
// // 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:
// QRect viewerRect = graphicsView->mapFromScene(scene.sceneRect()).boundingRect();
// std::cout << "resolution before " << viewerRect.width() << " " << viewerRect.height() << std::endl;
// // shear 230 230
//this->graphicsView->shear(407, 407);
//this->graphicsView->shear(10, 10);
// viewerRect = graphicsView->mapFromSthis->graphicsView->rotate(90);cene(scene.sceneRect()).boundingRect();
// std::cout << "resolution after " << viewerRect.width() << " " << viewerRect.height() << std::endl;
// // Turn the vertical axis upside down
//this->graphicsView->matrix().scale(1, -1);
//this->graphicsView->scale(10, 10);
//this->graphicsView->centerOn(0.0, 0.0);
//this->graphicsView->translate(1.0, -20.0);
this->graphicsView->shear(230, 230);
this->graphicsView->rotate(90);
// // 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/*_G*/(points, p);;
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/*_G*/(points, current_point, 6, 4);
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_Dirichlet_region_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

@ -0,0 +1,10 @@
<RCC>
<qresource prefix="/cgal/help" >
<file>about_CGAL.html</file>
</qresource>
<qresource prefix="/cgal/logos">
<file alias="CGAL.gif" >cgal_logo_ipe_2013.png</file>
<file alias="CGAL.png" >cgal_logo_ipe_2013.png</file>
<file alias="cgal_icon" >cgal_logo.xpm</file>
</qresource>
</RCC>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@ -0,0 +1,12 @@
<RCC>
<qresource prefix="/cgal/Actions" >
<file>conflict_zone.png</file>
<file>moving_point.png</file>
<file>triangulation.png</file>
<file>circumcenter.png</file>
</qresource>
<qresource prefix="/cgal/help" >
<file alias="about_CGAL.html">about_CGAL.html</file>
<file>about_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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

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>

View File

@ -0,0 +1,13 @@
<RCC>
<qresource prefix="/cgal/Actions">
<file>G2.png</file>
<file>G4.png</file>
<file>G8.png</file>
<file>G16.png</file>
<file>G.png</file>
<file>a.png</file>
<file>b.png</file>
<file>c.png</file>
<file>d.png</file>
</qresource>
</RCC>

View File

@ -0,0 +1,6 @@
<RCC>
<qresource prefix="/cgal/Triangulation_2" >
<file>Delaunay_triangulation_2.png</file>
<file>Voronoi_diagram_2.png</file>
</qresource>
</RCC>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1,24 @@
/* XPM */
const char * demoicon_xpm[] = {
/* columns rows colors chars-per-pixel */
"16 16 3 1",
" c None",
". c #FFFF00",
"+ c #000000",
/* pixels */
"................",
"...++++...++++..",
"..+....+.+....+.",
"..+......+......",
"..+......+..+++.",
"..+......+....+.",
"..+....+.+....+.",
"...++++...++++..",
"................",
"...++++...+.....",
"..+....+..+.....",
"..+....+..+.....",
"..++++++..+.....",
"..+....+..+.....",
"..+....+..+++++.",
"................"};

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

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: 1.4 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1,5 @@
The following files have been copied from Qt Free Edition version 4.4:
fileNew.png
fileOpen.png
fileSave.png,
fit-page-32.png

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: 3.2 KiB

View File

@ -31,14 +31,8 @@ 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} )

View File

@ -4,7 +4,7 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
//#include <CGAL/Delaunay_hyperbolic_triangulation_2.h>
#include <Periodic_2_Delaunay_hyperbolic_triangulation_2.h>
#include <CGAL/Periodic_4_Delaunay_hyperbolic_triangulation_2.h>
#include <CGAL/Triangulation_hyperbolic_traits_2.h>
// to be deleted
@ -37,13 +37,13 @@
#include "ui_Periodic_4_hyperbolic_triangulation_2.h"
#include <CGAL/Qt/DemosMainWindow.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel R;
typedef CGAL::Triangulation_hyperbolic_traits_2<R> K;
typedef CGAL::Exact_predicates_inexact_constructions_kernel R;
typedef CGAL::Triangulation_hyperbolic_traits_2<R> K;
typedef K::Point_2 Point_2;
typedef K::Iso_rectangle_2 Iso_rectangle_2;
typedef K::Point_2 Point_2;
typedef K::Iso_rectangle_2 Iso_rectangle_2;
typedef CGAL::Periodic_2_Delaunay_hyperbolic_triangulation_2<K> Delaunay;
typedef CGAL::Periodic_4_Delaunay_hyperbolic_triangulation_2<K> Delaunay;
class MainWindow :
public CGAL::Qt::DemosMainWindow,
@ -52,18 +52,18 @@ class MainWindow :
Q_OBJECT
private:
Delaunay dt;
QGraphicsEllipseItem* disk;
QGraphicsScene scene;
Delaunay dt;
QGraphicsEllipseItem* disk;
QGraphicsScene scene;
CGAL::Qt::TriangulationGraphicsItem<Delaunay> * dgi;
CGAL::Qt::VoronoiGraphicsItem<Delaunay> * vgi;
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;
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();

View File

@ -87,8 +87,10 @@ public:
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 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;
@ -493,8 +495,7 @@ public:
class Finite_faces_iterator
: public Filter_iterator<All_faces_iterator, Infinite_hyperbolic_tester>
{
typedef Filter_iterator<All_faces_iterator,
Infinite_hyperbolic_tester> Base;
typedef Filter_iterator<All_faces_iterator, Infinite_hyperbolic_tester> Base;
typedef Finite_faces_iterator Self;
public:
Finite_faces_iterator() : Base() {}
@ -526,7 +527,8 @@ public:
//Finite edges iterator
typedef Filter_iterator<All_edges_iterator,
Infinite_hyperbolic_tester> Finite_edges_iterator;
Infinite_hyperbolic_tester>
Finite_edges_iterator;
Finite_edges_iterator
finite_edges_begin() const
@ -587,7 +589,8 @@ public:
// both faces are finite
if(!is_infinite(f1) && !is_infinite(f2)) {
Segment s = this->geom_traits().construct_segment_2_object()(dual(f1),dual(f2));
Segment s = this->geom_traits().construct_segment_2_object()
(dual(f1),dual(f2));
return make_object(s);
}
@ -610,8 +613,14 @@ public:
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,8 +1,7 @@
#ifndef CGAL_HYPERBOLIC_DIAMETRIC_TRANSLATIONS_2_H
#define CGAL_HYPERBOLIC_DIAMETRIC_TRANSLATIONS_2_H
#include <CGAL/Hyperbolic_isometry_2.h>
#include <CGAL/Hyperbolic_isometry_2.h>
template<typename Gt>
class Diametric_translations

View File

@ -0,0 +1,81 @@
// 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

@ -0,0 +1,86 @@
#ifndef HYPERBOLIC_RANDOM_POINTS_IN_DISC_2
#define HYPERBOLIC_RANDOM_POINTS_IN_DISC_2
#include <boost/math/special_functions/acosh.hpp>
#include <CGAL/Random.h>
#include <CGAL/point_generators_2.h>
// Euclidean radius vector to hyperbolic raidus vector
template<class FT>
FT r_h(FT r_e)
{
return boost::math::acosh((1 + r_e*r_e)/(1 - r_e*r_e));
}
// hyperbolic raidus vector to Euclidean radius vector
template<class FT>
FT r_e(FT r_h)
{
FT dist = std::tanh(r_h/FT(2));
if(dist > 0) {
return dist;
}
return -dist;
}
// if seed = -1, then the seed will get a random value.
template<class Gt>
void Hyperbolic_random_points_in_disc_2(std::vector<typename Gt::Point_2>& output, int nb, int seed = 1, typename Gt::FT e = 0.0001)
{
typedef typename Gt::FT FT;
typedef typename Gt::Point_2 Point_2;
typedef typename Gt::Vector_2 Vector_2;
FT re = FT(1) - e;
FT rh = r_h(re);
typedef CGAL::Creator_uniform_2<FT, Point_2> Creator;
CGAL::Random rand;
if (seed != -1) {
rand = CGAL::Random(seed);
}
/* CGAL::Random_points_in_disc_2<Point_2, Creator> in_Euclidean_disk(rh, rand); */
CGAL::Random_points_in_disc_2<Point_2, Creator> in_Euclidean_disk(rh, rand);
std::vector<Point_2> pts;
pts.reserve(nb);
for(int i = 0; i < nb ; i++) {
pts.push_back(*in_Euclidean_disk);
in_Euclidean_disk++;
}
for(int i = 0; i < nb ; i++) {
std::cout << "Adding!" << std::endl;
Vector_2 v = Vector_2(Point_2(0, 0), pts[i]);
FT sq_dist = v.squared_length();
FT dist = CGAL::sqrt(sq_dist);
FT dist_in_disc = r_e(dist);
output.push_back(Point_2((pts[i].x()*dist_in_disc)/dist, (pts[i].y()*dist_in_disc)/dist));
}
}
template<class Gt>
void Random_points_in_disc_2(std::vector<typename Gt::Point_2>& output, int nb, int seed = 1, typename Gt::FT e = 0.0001)
{
typedef typename Gt::FT FT;
typedef typename Gt::Point_2 Point_2;
FT re = FT(1) - e;
typedef CGAL::Creator_uniform_2<FT, Point_2> Creator;
CGAL::Random rand(seed);
CGAL::Random_points_in_disc_2<Point_2, Creator> in_Euclidean_disk(re, rand);
for(int i = 0; i < nb ; i++) {
output.push_back(*in_Euclidean_disk);
in_Euclidean_disk++;
}
}
#endif // HYPERBOLIC_RANDOM_POINTS_IN_DISC_2

View File

@ -19,8 +19,8 @@ template<class Sqrt_field>
class Octagon_matrix
{
public:
typedef Octagon_matrix<Sqrt_field> Self;
typedef complex<Sqrt_field> Extended_field;
typedef Octagon_matrix<Sqrt_field> Self;
typedef complex<Sqrt_field> Extended_field;
Extended_field M11;
Extended_field M12;
@ -37,8 +37,8 @@ public:
Self operator*(const Self& rh) const
{
return Self( M11*rh.M11 + aux*M12*conj(rh.M12),
M11*rh.M12 + M12*conj(rh.M11), merge_labels(rh) );
return Self( M11*rh.M11 + factor*M12*conj(rh.M12),
M11*rh.M12 + M12*conj(rh.M11), merge_labels(rh) );
}
Self inverse() const
@ -79,6 +79,7 @@ public:
Sqrt_field BB2 = (B1 + B2)*k;
assert(BB2.l % 2 == 0 && BB2.r % 2 == 0);
BB1.l = BB1.l/2;
BB1.r = BB1.r/2;
BB2.l = BB2.l/2;
@ -109,7 +110,7 @@ public:
// determinant == 1
Extended_field det() const
{
return norm(M11) - aux * norm(M12);
return norm(M11) - factor * norm(M12);
}
static complex<double> toComplexDouble(Extended_field M) //const
@ -126,7 +127,7 @@ public:
Cmpl m11 = toComplexDouble(M11);
Cmpl m12 = toComplexDouble(M12);
double ax = sqrt(aux.l + sqrt(2.)*aux.r);
double ax = sqrt(factor.l + sqrt(2.)*factor.r);
Cmpl z(x, y);
Cmpl res = (m11*z + ax*m12)/(ax*(conj(m12)*z) + conj(m11));
@ -134,12 +135,12 @@ public:
}
//private:
static Sqrt_field aux;
static Sqrt_field factor;
};
template<class Sqrt_field>
Sqrt_field Octagon_matrix<Sqrt_field>::aux = Sqrt_field(-1, 1);
Sqrt_field Octagon_matrix<Sqrt_field>::factor = Sqrt_field(-1, 1);
// just to give an order(ing)
template<class Int>
@ -191,24 +192,67 @@ ostream& operator<<(ostream& os, const Octagon_matrix<Sqrt_field>& m)
return os;
}
typedef long long ll;
typedef Sqrt_field<ll> SqrtField;
typedef Octagon_matrix<SqrtField> OctagonMatrix;
typedef OctagonMatrix::Extended_field Entry;
typedef long long ll;
typedef Sqrt_field<ll> SqrtField;
typedef Octagon_matrix<SqrtField> OctagonMatrix;
typedef OctagonMatrix::Extended_field Entry;
enum Direction {
A = 0, // 0
InvB, // 1
C, // 2
InvD, // 3
InvA, // 4
B, // 5
InvC, // 6
D // 7
};
void get_generators(vector<OctagonMatrix>& gens)
{
// This is a in the matrix, equal to sqrt(2) + 1
Entry M11 = Entry(SqrtField(1, 1), SqrtField(0, 0));
// This vector should hold all other elements, results of the exponentials for various k
vector<Entry> M12(8, Entry(SqrtField(0, 0), SqrtField(0, 0)));
M12[0] = M11 * Entry(SqrtField(0, 1), SqrtField(0, 0));
M12[1] = M11 * Entry(SqrtField(1, 0), SqrtField(1, 0));
M12[2] = M11 * Entry(SqrtField(0, 0), SqrtField(0, 1));
M12[3] = M11 * Entry(SqrtField(-1, 0), SqrtField(1, 0));
M12[4] = M11 * Entry(SqrtField(0, -1), SqrtField(0, 0));
M12[5] = M11 * Entry(SqrtField(-1, 0), SqrtField(-1, 0));
M12[6] = M11 * Entry(SqrtField(0, 0), SqrtField(0, -1));
M12[7] = M11 * Entry(SqrtField(1, 0), SqrtField(-1, 0));
// Set everything manually
/*
M12[A] = M11 * Entry(SqrtField(0, 0), SqrtField(-1, 0));
M12[InvA] = M11 * Entry(SqrtField(0, 0), SqrtField(1, 0));
M12[B] = M11 * Entry(SqrtField(0, -1), SqrtField(0, 1));
M12[InvB] = M11 * Entry(SqrtField(0, 1), SqrtField(0, -1));
M12[C] = M11 * Entry(SqrtField(1, 0), SqrtField(0, 0));
M12[InvC] = M11 * Entry(SqrtField(-1, 0), SqrtField(0, 0));
M12[D] = M11 * Entry(SqrtField(0, -1), SqrtField(0, -1));
M12[InvD] = M11 * Entry(SqrtField(0, 1), SqrtField(0, 1));
*/
/*
Entry tmp = Entry(SqrtField(2, 2), SqrtField(0,0));
M12[A] = Entry(SqrtField(0, 0), SqrtField(-1, 0));
M12[InvA] = Entry(SqrtField(0, 0), SqrtField(1, 0));
M12[B] = Entry(SqrtField(-1, 0), SqrtField(1, 0));
M12[InvB] = Entry(SqrtField(1, 0), SqrtField(-1, 0));
M12[C] = Entry(SqrtField(-1, 0), SqrtField(0, 0));
M12[InvC] = Entry(SqrtField(1, 0), SqrtField(0, 0));
M12[D] = Entry(SqrtField(-1, 0), SqrtField(-1, 0));
M12[InvD] = Entry(SqrtField(1, 0), SqrtField(1, 0));
*/
M12[A] = M11 * Entry(SqrtField(0, 1), SqrtField(0, 0));
M12[InvB] = M11 * Entry(SqrtField(1, 0), SqrtField(1, 0));
M12[C] = M11 * Entry(SqrtField(0, 0), SqrtField(0, 1));
M12[InvD] = M11 * Entry(SqrtField(-1, 0), SqrtField(1, 0));
M12[InvA] = M11 * Entry(SqrtField(0, -1), SqrtField(0, 0));
M12[B] = M11 * Entry(SqrtField(-1, 0), SqrtField(-1, 0));
M12[InvC] = M11 * Entry(SqrtField(0, 0), SqrtField(0, -1));
M12[D] = M11 * Entry(SqrtField(1, 0), SqrtField(-1, 0));
string labels[8] = {string("a"), string("b^-1"), string("c"), string("d^-1"),
string("a^-1"), string("b"), string("c^-1"), string("d")};
@ -222,7 +266,7 @@ vector<OctagonMatrix> gens;
bool IsCanonical(const OctagonMatrix& m);
void generate_words( set<OctagonMatrix>& words, vector<OctagonMatrix>& prev, int depth )
void generate_words( set<OctagonMatrix>& words, vector<OctagonMatrix>& prev, int depth, double threshold )
{
if (depth == 1) {
for(int i = 0; i < 8; i++) {
@ -233,7 +277,7 @@ void generate_words( set<OctagonMatrix>& words, vector<OctagonMatrix>& prev, int
}
vector<OctagonMatrix> els;
generate_words( words, els, depth - 1);
generate_words( words, els, depth - 1, threshold);
OctagonMatrix temp = OctagonMatrix(Entry(), Entry());
ll size = els.size();
@ -242,7 +286,7 @@ void generate_words( set<OctagonMatrix>& words, vector<OctagonMatrix>& prev, int
for(int i = 0; i < 8; i++) {
temp = els[k]*gens[i];
if(temp.length() > 15.) {
if(temp.length() > threshold /*15.*/) {
continue;
}
@ -304,13 +348,13 @@ void dfs_with_info(const pair<OctagonMatrix, OctagonMatrix>& new_pair,
visited.insert(new_pair);
const OctagonMatrix& current = new_pair.first;
const OctagonMatrix& current_aux = new_pair.second;
OctagonMatrix candidate = current, candidate_aux = current_aux;
const OctagonMatrix& current_factor = new_pair.second;
OctagonMatrix 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_aux = gens[i]*current_aux;
dfs_with_info(pair<OctagonMatrix, OctagonMatrix>(candidate, candidate_aux), visited);
candidate_factor = gens[i]*current_factor;
dfs_with_info(pair<OctagonMatrix, OctagonMatrix>(candidate, candidate_factor), visited);
}
}
}
@ -418,20 +462,20 @@ bool haveIntersection(const OctagonMatrix& m1, const OctagonMatrix& m2) const
void intersectWithInfinity(const OctagonMatrix& m, Point& p1, Point& p2) const
{
Entry a = m.M11, b = m.M12, aux = m.aux;
Entry a = m.M11, b = m.M12, factor = m.factor;
Entry four = Entry(SqrtField(4, 0), SqrtField(0, 0));
Entry two = Entry(SqrtField(2, 0), SqrtField(0, 0));
Entry D = (a - conj(a))*(a - conj(a));
D += four*b*conj(b)*aux;
D += four*b*conj(b)*factor;
Entry T1 = conj(a) - a;
Entry T2 = two*conj(b);
complex<double> d = m.toComplexDouble(D);
complex<double> t1 = m.toComplexDouble(T1);
complex<double> t2 = m.toComplexDouble(T2);
complex<double> au = complex<double>(m.aux.l + sqrt(2.)*m.aux.r, 0);
complex<double> au = complex<double>(m.factor.l + sqrt(2.)*m.factor.r, 0);
complex<double> z1 = (t1 + sqrt(d))/(t2*sqrt(au));
complex<double> z2 = (t1 - sqrt(d))/(t2*sqrt(au));
@ -471,7 +515,7 @@ void generate_unique_words(vector<OctagonMatrix>& output, double threshold = 10,
set<OctagonMatrix> unique_words;
vector<OctagonMatrix> temp;
generate_words(unique_words, temp, word_length);
generate_words(unique_words, temp, word_length, threshold);
double l = 0;
set<OctagonMatrix>::iterator uit;
@ -532,3 +576,7 @@ void generate_words_union_1_cycles(vector<OctagonMatrix>& out)
}
#endif

View File

@ -17,22 +17,28 @@
//
// Author(s) : Mikhail Bogdanov
#ifndef CGAL_PERIODIC_2_DELAUNAY_HYPERBOLIC_TRIANGULATION_2_H
#define CGAL_PERIODIC_2_DELAUNAY_HYPERBOLIC_TRIANGULATION_2_H
#ifndef CGAL_PERIODIC_4_DELAUNAY_HYPERBOLIC_TRIANGULATION_2_H
#define CGAL_PERIODIC_4_DELAUNAY_HYPERBOLIC_TRIANGULATION_2_H
#include <vector>
#include <CGAL/Delaunay_triangulation_2.h>
// I needed to use a non-reserved word for this thing, there were problems when I (stupidly) used TYPE
#define CLEARLY_MY_TYPE 2 // 1 = Cross, 2 = Diametric
#define USE_TEST_THINGS 1 // 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 {
@ -40,26 +46,33 @@ namespace CGAL {
template < class Gt,
class Tds = Triangulation_data_structure_2 <
Triangulation_vertex_base_2<Gt> > >
class Periodic_2_Delaunay_hyperbolic_triangulation_2 : public Delaunay_triangulation_2<Gt,Tds>
#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_2_Delaunay_hyperbolic_triangulation_2<Gt, Tds> Self;
typedef Delaunay_triangulation_2<Gt,Tds> Base;
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::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 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;
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();
//void insert_dummy_points(std::vector<typename GT::Point_2>& );
void Set_recursion_depth(int new_depth) {
this->recursion_depth = new_depth;
@ -68,24 +81,32 @@ namespace CGAL {
#ifndef CGAL_CFG_USING_BASE_MEMBER_BUG_2
using Base::tds;
#endif
Periodic_2_Delaunay_hyperbolic_triangulation_2(const Gt& gt = Gt())
/*
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_2_Delaunay_hyperbolic_triangulation_2(const Periodic_2_Delaunay_hyperbolic_triangulation_2<Gt,Tds> &tr)
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() ); }
/*vector<Vertex_handle>*//*void insert_dummy_points() {}*/
*/
/************************ INSERT OVERLOADS **************************/
/*
Vertex_handle insert(const Point_2 &p,
Face_handle start = Face_handle() )
@ -96,6 +117,7 @@ namespace CGAL {
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);
}
@ -119,7 +141,9 @@ namespace CGAL {
return Base::insert(first, last);
}
*/
Object
dual(const Finite_edges_iterator& ei) const {
return this->dual(*ei);
@ -140,24 +164,29 @@ namespace CGAL {
private:
/*
void recursive_translate(
#if CLEARLY_MY_TYPE == 1 // This means that we must do Cross-translations (alternative identification)
#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,
int end)
int start = -1,
int end = -1)
{
if (depth > 0) {
int my_start = points.size();
int my_end = start;
for (int i = start; i <= end; i++){
Point_2 subject = points[i];
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) );
@ -166,46 +195,37 @@ namespace CGAL {
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, start, end);
}
else
{
int my_start = points.size();
int my_end = start;
recursive_translate(g, points, depth - 1, my_start, my_end);
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);
}
}
}
void recursive_translate(
#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
std::vector<Point_2>& points,
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);
}
}
*/
// Initializes the triangulation data structure
void init_tds() {
this->_infinite_vertex = tds().insert_first();
@ -215,15 +235,22 @@ namespace CGAL {
// 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_2_DELAUNAY_HYPERBOLIC_TRIANGULATION_2_H
#endif // CGAL_PERIODIC_4_DELAUNAY_HYPERBOLIC_TRIANGULATION_2_H

View File

@ -0,0 +1,570 @@
// 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 <CGAL/Hyperbolic_face_info_2.h>
#include <stack>
#include <set>
namespace CGAL {
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);
}
};
} //namespace CGAL
#endif // CGAL_DELAUNAY_HYPERBOLIC_TRIANGULATION_2_H

View File

@ -0,0 +1,182 @@
// Copyright (c) 1997-2013 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@nghk.nl>
#ifndef CGAL_PERIODIC_4_HYPERBOLIC_OFFSET_2_H
#define CGAL_PERIODIC_4_HYPERBOLIC_OFFSET_2_H
#include <CGAL/basic.h>
#include <CGAL/triangulation_assertions.h>
#include <CGAL/Cartesian.h>
namespace CGAL
{
/// The class Periodic_4_hyperbolic_offset_2 is a model of the concept Periodic_2Offset_2.
class Periodic_4_hyperbolic_offset_2
{
// template <class K2>
// friend std::ostream & operator<<(std::ostream &os,
// const Periodic_4_hyperbolic_offset_2 &off);
public:
/// Default constructor.
Periodic_4_hyperbolic_offset_2() : _offx(0), _offy(0) {}
/// Constructs the offset (x,y).
Periodic_4_hyperbolic_offset_2(int x, int y) : _offx(x), _offy(y) {}
/// Returns true if o is equal to (0,0).
inline bool is_null() const
{
return is_zero();
}
/// Returns true if o is equal to (0,0).
inline bool is_zero() const
{
return ((_offx | _offy) == 0);
}
/// Return the x-entry of o.
int& x()
{
return _offx;
}
/// Return the x-entry of o.
int x() const
{
return _offx;
}
/// Return the y-entry of o.
int& y()
{
return _offy;
}
/// Return the y-entry of o.
int y() const
{
return _offy;
}
/// Return the i-th entry of o.
int &operator[](int i)
{
if (i == 0) return _offx;
CGAL_triangulation_assertion(i == 1);
return _offy;
}
/// Return the i-th entry of o.
int operator[](int i) const
{
if (i == 0) return _offx;
CGAL_triangulation_assertion(i == 1);
return _offy;
}
/// Add o' to o using vector addition.
void operator+=(const Periodic_4_hyperbolic_offset_2 &other)
{
_offx += other._offx;
_offy += other._offy;
}
/// Subtract o' from o using vector subtraction.
void operator-=(const Periodic_4_hyperbolic_offset_2 &other)
{
_offx -= other._offx;
_offy -= other._offy;
}
/// Return the negative vector of o.
Periodic_4_hyperbolic_offset_2 operator-() const
{
return Periodic_4_hyperbolic_offset_2(-_offx, -_offy);
}
/// Return true if o' and o represent the same vector.
bool operator==(const Periodic_4_hyperbolic_offset_2 &other) const
{
return ((_offx == other._offx) &&
(_offy == other._offy));
}
/// Return true if o' and o do not represent the same vector.
bool operator!=(const Periodic_4_hyperbolic_offset_2 &other) const
{
return ((_offx != other._offx) ||
(_offy != other._offy));
}
/// Compare o and o' lexicographically.
bool operator<(const Periodic_4_hyperbolic_offset_2 &other) const
{
if (_offx != other._offx)
return (_offx < other._offx);
else
{
return (_offy < other._offy);
}
}
/// Return the vector sum of o and o'.
Periodic_4_hyperbolic_offset_2 operator+(const Periodic_4_hyperbolic_offset_2 &off2) const
{
return Periodic_4_hyperbolic_offset_2(_offx + off2.x(), _offy + off2.y());
}
/// Return the vector difference of o and o'.
Periodic_4_hyperbolic_offset_2 operator-(const Periodic_4_hyperbolic_offset_2 &off2) const
{
return Periodic_4_hyperbolic_offset_2(_offx - off2.x(), _offy - off2.y());
}
private:
int _offx, _offy;
};
template <class K>
inline typename K::Point_2 operator+(const typename K::Point_2 &p, const Periodic_4_hyperbolic_offset_2 &off)
{
return (off.is_null() ? p : typename K::Point_2(p.x() + off.x(), p.y() + off.y()));
}
/// Inputs an Periodic_4_hyperbolic_offset_2 from is.
inline std::ostream
&operator<<(std::ostream &os, const Periodic_4_hyperbolic_offset_2 &off)
{
if (is_ascii(os))
os << off.x() << " " << off.y();
else
{
write(os, off.x());
write(os, off.y());
}
return os;
}
/// Outputs an Periodic_4_hyperbolic_offset_2 to os.
inline std::istream
&operator>>(std::istream &is, Periodic_4_hyperbolic_offset_2 &off)
{
int x = 0, y = 0;
if (is_ascii(is))
is >> x >> y;
else
{
read(is, x);
read(is, y);
}
off = Periodic_4_hyperbolic_offset_2(x, y);
return is;
}
} //namespace CGAL
#endif // CGAL_PERIODIC_4_HYPERBOLIC_OFFSET_2_H

View File

@ -17,18 +17,20 @@
//
// Author(s) : Mikhail Bogdanov
#ifndef CGAL_PERIODIC_2_HYPERBOLIC_TRIANGULATION_DUMMY_H
#define CGAL_PERIODIC_2_HYPERBOLIC_TRIANGULATION_DUMMY_H
#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 {
@ -114,7 +116,7 @@ namespace CGAL {
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);
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);
@ -124,22 +126,20 @@ namespace CGAL {
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(apply_rotation<K>(inner_points[i*size + j]));
}
}
inner_points.push_back(o);
//points_on_boundary.push_back(c);
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_boundary.push_back(apply_rotation<K>(points_on_boundary[i-1]));
}
// points_on_vertex.push_back(apply_rotation<K>(f));
points_on_vertex.push_back(apply_rotation<K>(f));
}
/*
template<class GT>
void recursive_translate(Diametric_translations<GT> g,
@ -196,17 +196,17 @@ namespace CGAL {
}
}
*/
template < class GT, class TDS >
void Periodic_2_Delaunay_hyperbolic_triangulation_2<GT, TDS>::insert_dummy_points() {
clear();
void Delaunay_hyperbolic_triangulation_2<GT, TDS>::insert_dummy_points(std::vector<typename GT::Point_2>& all_points) {
//clear();
std::vector<Point_2> inner_points, points_on_boundary, points_on_vertex;
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<Point_2> all_points = inner_points;
/*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]);
@ -218,8 +218,13 @@ namespace CGAL {
std::cout << "All points length: " << all_points.size() << std::endl;
Base::insert(all_points.begin(), all_points.end());
//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++) {
@ -228,10 +233,11 @@ namespace CGAL {
std::cout << "Copies length: " << copies.size() << std::endl;
Base::insert(copies.begin(), copies.end());
*/
}
} // namespace CGAL
#endif // CGAL_PERIODIC_2_HYPERBOLIC_TRIANGULATION_DUMMY_H
#endif // CGAL_PERIODIC_4_HYPERBOLIC_TRIANGULATION_DUMMY_H

View File

@ -0,0 +1,882 @@
// Copyright (c) 1997-2013 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@nghk.nl>
#ifndef CGAL_PERIODIC_4_HYPERBOLIC_TRIANGULATION_ITERATORS_2_H
#define CGAL_PERIODIC_4_HYPERBOLIC_TRIANGULATION_ITERATORS_2_H
#include <CGAL/triangulation_assertions.h>
#include <CGAL/iterator.h>
#include <CGAL/array.h>
namespace CGAL
{
template < class T >
class Periodic_4_hyperbolic_triangulation_triangle_iterator_2
{
// Iterates over the primitives in a periodic triangulation.
// Options:
// - STORED: output each primitive from the Tds exactly once
// - UNIQUE: output exactly one periodic copy of each primitive, no matter
// whether the current tds stores a n-sheeted covering for n!=1.
// - STORED_COVER_DOMAIN: output each primitive whose intersection with the
// actually used periodic domain is non-zero.
// - UNIQUE_COVER_DOMAIN: output each primitive whose intersection
// with the original domain that the user has given is non-zero
//
// Comments:
// When computing in 1-sheeted covering, there will be no difference in the
// result of STORED and UNIQUE as well as STORED_COVER_DOMAIN and
// UNIQUE_COVER_DOMAIN.
public:
typedef typename T::Periodic_triangle value_type;
typedef const typename T::Periodic_triangle * pointer;
typedef const typename T::Periodic_triangle & reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef std::bidirectional_iterator_tag iterator_category;
typedef typename T::Periodic_triangle Periodic_triangle;
typedef Periodic_4_hyperbolic_triangulation_triangle_iterator_2<T> Periodic_triangle_iterator;
typedef typename T::Face Face;
typedef typename T::Face_iterator Face_iterator;
typedef typename T::Offset Offset;
typedef typename T::Iterator_type Iterator_type;
Periodic_4_hyperbolic_triangulation_triangle_iterator_2(Iterator_type it = T::STORED)
: _t(NULL), _it(it), _off(0) {}
Periodic_4_hyperbolic_triangulation_triangle_iterator_2(const T * t,
Iterator_type it = T::STORED)
: _t(t), pos(_t->faces_begin()), _it(it), _off(0)
{
if (_it == T::UNIQUE || _it == T::UNIQUE_COVER_DOMAIN)
{
while (pos != _t->faces_end() && !is_canonical() )
++pos;
}
}
// used to initialize the past-the-end iterator
Periodic_4_hyperbolic_triangulation_triangle_iterator_2(const T* t, int,
Iterator_type it = T::STORED)
: _t(t), pos(_t->faces_end()), _it(it), _off(0) {}
Periodic_triangle_iterator& operator++()
{
switch (_it)
{
case T::STORED:
++pos;
break;
case T::UNIQUE:
do
{
++pos;
}
while (pos != _t->faces_end() && !is_canonical());
break;
case T::STORED_COVER_DOMAIN:
case T::UNIQUE_COVER_DOMAIN:
increment_domain();
break;
default:
CGAL_triangulation_assertion(false);
};
return *this;
}
Periodic_triangle_iterator& operator--()
{
switch (_it)
{
case T::STORED:
--pos;
break;
case T::UNIQUE:
do
{
--pos;
}
while (pos != _t->faces_begin() && !is_canonical());
break;
case T::STORED_COVER_DOMAIN:
case T::UNIQUE_COVER_DOMAIN:
decrement_domain();
};
return *this;
}
Periodic_triangle_iterator operator++(int)
{
Periodic_triangle_iterator tmp(*this);
++(*this);
return tmp;
}
Periodic_triangle_iterator operator--(int)
{
Periodic_triangle_iterator tmp(*this);
--(*this);
return tmp;
}
bool operator==(const Periodic_triangle_iterator& ti) const
{
// We are only allowed to compare iterators of the same type.
CGAL_triangulation_assertion(_it == ti._it);
return _t == ti._t && pos == ti.pos && _off == ti._off;
}
bool operator!=(const Periodic_triangle_iterator& ti) const
{
return !(*this == ti);
}
reference operator*() const
{
periodic_triangle = construct_periodic_triangle();
return periodic_triangle;
}
pointer operator->() const
{
periodic_triangle = construct_periodic_triangle();
return &periodic_triangle;
}
Face_iterator get_face() const
{
return pos;
}
private:
const T* _t;
Face_iterator pos; // current face.
Iterator_type _it;
int _off; // current offset
mutable Periodic_triangle periodic_triangle; // current triangle.
private:
// check whether pos points onto a unique edge or not.
// If we are computing in 1-sheeted covering this should
// always be true.
bool is_canonical()
{
// fetch all offsets
Offset off0, off1, off2;
get_edge_offsets(off0, off1, off2);
if (_t->number_of_sheets() != make_array(1, 1))
{
// If there is one offset with entries larger than 1 then we are
// talking about a vertex that is too far away from the original
// domain to belong to a canonical triangle.
if (off0.x() > 1) return false;
if (off0.y() > 1) return false;
if (off1.x() > 1) return false;
if (off1.y() > 1) return false;
if (off2.x() > 1) return false;
if (off2.y() > 1) return false;
}
// If there is one direction of space for which all offsets are
// non-zero then the edge is not canonical because we can
// take the copy closer towards the origin in that direction.
int offx = off0.x() & off1.x() & off2.x();
int offy = off0.y() & off1.y() & off2.y();
return (offx == 0 && offy == 0);
}
// Artificial incrementation function that takes periodic
// copies into account.
void increment_domain()
{
int off = get_drawing_offsets();
CGAL_triangulation_assertion(_off <= off);
if (_off == off)
{
_off = 0;
do
{
++pos;
}
while (_it == T::UNIQUE_COVER_DOMAIN
&& pos != _t->faces_end() && !is_canonical());
}
else
{
do
{
++_off;
}
while ((((~_off) | off) & 3) != 3); // Increment until a valid
// offset has been found
}
}
// Artificial decrementation function that takes periodic
// copies into account.
void decrement_domain()
{
if (_off == 0)
{
if (pos == _t->faces_begin()) return;
do
{
--pos;
}
while (_it == T::UNIQUE_COVER_DOMAIN && !is_canonical());
_off = get_drawing_offsets();
}
else
{
int off = get_drawing_offsets();
do
{
--_off;
}
while ((((~_off) | off) & 3) != 3); // Decrement until a valid
// offset has been found
}
}
// Get the canonicalized offsets of an edge.
// This works in any cover that is encoded in _t->combine_offsets
void get_edge_offsets(Offset &off0, Offset &off1,
Offset &off2) const
{
Offset face_off0 = _t->int_to_off(pos->offset(0));
Offset face_off1 = _t->int_to_off(pos->offset(1));
Offset face_off2 = _t->int_to_off(pos->offset(2));
Offset diff_off((face_off0.x() == 1
&& face_off1.x() == 1
&& face_off2.x() == 1) ? -1 : 0,
(face_off0.y() == 1
&& face_off1.y() == 1
&& face_off2.y() == 1) ? -1 : 0);
off0 = _t->combine_offsets(_t->get_offset(pos, 0), diff_off);
off1 = _t->combine_offsets(_t->get_offset(pos, 1), diff_off);
off2 = _t->combine_offsets(_t->get_offset(pos, 2), diff_off);
}
// return an integer that encodes the translations which have to be
// applied to the edge *pos
int get_drawing_offsets()
{
Offset off0, off1, off2;
// Choose edges that are to be duplicated. These are edges that
// intersect the boundary of the periodic domain. In UNIQUE mode
// this means that the offset with respect to drawing should
// differ in some entries. Otherwise we consider the offsets
// internally stored inside the cell telling us that this cell
// wraps around the domain.
if (_it == T::UNIQUE_COVER_DOMAIN)
get_edge_offsets(off0, off1, off2);
else
{
CGAL_triangulation_assertion(_it == T::STORED_COVER_DOMAIN);
off0 = _t->int_to_off(pos->offset(0));
off1 = _t->int_to_off(pos->offset(1));
off2 = _t->int_to_off(pos->offset(2));
}
CGAL_triangulation_assertion(off0.x() == 0 || off0.x() == 1);
CGAL_triangulation_assertion(off0.y() == 0 || off0.y() == 1);
CGAL_triangulation_assertion(off1.x() == 0 || off1.x() == 1);
CGAL_triangulation_assertion(off1.y() == 0 || off1.y() == 1);
CGAL_triangulation_assertion(off2.x() == 0 || off2.x() == 1);
CGAL_triangulation_assertion(off2.y() == 0 || off2.y() == 1);
int offx = ( ((off0.x() == 0 && off1.x() == 0
&& off2.x() == 0)
|| (off0.x() == 1 && off1.x() == 1
&& off2.x() == 1)) ? 0 : 1);
int offy = ( ((off0.y() == 0 && off1.y() == 0
&& off2.y() == 0)
|| (off0.y() == 1 && off1.y() == 1
&& off2.y() == 1)) ? 0 : 1);
return( 2 * offx + offy );
}
Periodic_triangle construct_periodic_triangle() const
{
CGAL_triangulation_assertion(pos != typename T::Face_handle());
Offset off0, off1, off2;
get_edge_offsets(off0, off1, off2);
Offset transl_off = Offset((((_off >> 1) & 1) == 1 ? -1 : 0),
(((_off ) & 1) == 1 ? -1 : 0));
if (_it == T::STORED_COVER_DOMAIN)
{
off0 = _t->combine_offsets(off0, transl_off);
off1 = _t->combine_offsets(off1, transl_off);
off2 = _t->combine_offsets(off2, transl_off);
}
if (_it == T::UNIQUE_COVER_DOMAIN)
{
off0 += transl_off;
off1 += transl_off;
off2 += transl_off;
}
return make_array(std::make_pair(pos->vertex(0)->point(), off0),
std::make_pair(pos->vertex(1)->point(), off1),
std::make_pair(pos->vertex(2)->point(), off2));
}
};
template < class T >
class Periodic_4_hyperbolic_triangulation_segment_iterator_2
{
// Iterates over the primitives in a periodic triangulation.
// Options:
// - STORED: output each primitive from the Tds exactly once
// - UNIQUE: output exactly one periodic copy of each primitive, no matter
// whether the current tds stores a n-sheeted covering for n!=1.
// - STORED_COVER_DOMAIN: output each primitive whose intersection with the
// actually used periodic domain is non-zero.
// - UNIQUE_COVER_DOMAIN: output each primitive whose intersection
// with the original domain that the user has given is non-zero
//
// Comments:
// When computing in 1-sheeted covering, there will be no difference in the
// result of STORED and UNIQUE as well as STORED_COVER_DOMAIN and
// UNIQUE_COVER_DOMAIN.
public:
typedef typename T::Periodic_segment value_type;
typedef const typename T::Periodic_segment * pointer;
typedef const typename T::Periodic_segment & reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef std::bidirectional_iterator_tag iterator_category;
typedef typename T::Periodic_segment Periodic_segment;
typedef Periodic_4_hyperbolic_triangulation_segment_iterator_2<T>
Periodic_segment_iterator;
typedef typename T::Edge Edge;
typedef typename T::Edge_iterator Edge_iterator;
typedef typename T::Offset Offset;
typedef typename T::Iterator_type Iterator_type;
Periodic_4_hyperbolic_triangulation_segment_iterator_2(Iterator_type it = T::STORED)
: _t(NULL), _it(it), _off(0) {}
Periodic_4_hyperbolic_triangulation_segment_iterator_2(const T * t,
Iterator_type it = T::STORED)
: _t(t), pos(_t->edges_begin()), _it(it), _off(0)
{
if (_it == T::UNIQUE || _it == T::UNIQUE_COVER_DOMAIN)
{
while (pos != _t->edges_end() && !is_canonical() )
++pos;
}
}
// used to initialize the past-the-end iterator
Periodic_4_hyperbolic_triangulation_segment_iterator_2(const T* t, int,
Iterator_type it = T::STORED)
: _t(t), pos(_t->edges_end()), _it(it), _off(0) {}
Periodic_segment_iterator& operator++()
{
switch (_it)
{
case T::STORED:
++pos;
break;
case T::UNIQUE:
do
{
++pos;
}
while (pos != _t->edges_end() && !is_canonical());
break;
case T::STORED_COVER_DOMAIN:
case T::UNIQUE_COVER_DOMAIN:
increment_domain();
break;
default:
CGAL_triangulation_assertion(false);
};
return *this;
}
Periodic_segment_iterator& operator--()
{
switch (_it)
{
case T::STORED:
--pos;
break;
case T::UNIQUE:
do
{
--pos;
}
while (pos != _t->edges_begin() && !is_canonical());
break;
case T::STORED_COVER_DOMAIN:
case T::UNIQUE_COVER_DOMAIN:
decrement_domain();
};
return *this;
}
Periodic_segment_iterator operator++(int)
{
Periodic_segment_iterator tmp(*this);
++(*this);
return tmp;
}
Periodic_segment_iterator operator--(int)
{
Periodic_segment_iterator tmp(*this);
--(*this);
return tmp;
}
bool operator==(const Periodic_segment_iterator& ti) const
{
// We are only allowed to compare iterators of the same type.
CGAL_triangulation_assertion(_it == ti._it);
return _t == ti._t && pos == ti.pos && _off == ti._off;
}
bool operator!=(const Periodic_segment_iterator& ti) const
{
return !(*this == ti);
}
reference operator*() const
{
periodic_segment = construct_periodic_segment();
return periodic_segment;
}
pointer operator->() const
{
periodic_segment = construct_periodic_segment();
return &periodic_segment;
}
Edge_iterator get_edge() const
{
return pos;
}
private:
const T* _t;
Edge_iterator pos; // current edge.
Iterator_type _it;
int _off; // current offset
mutable Periodic_segment periodic_segment; // current segment.
private:
// check whether pos points onto a unique edge or not.
// If we are computing in 1-sheeted covering this should
// always be true.
bool is_canonical()
{
// fetch all offsets
Offset off0, off1;
get_edge_offsets(off0, off1);
if (_t->number_of_sheets() != make_array(1, 1))
{
// If there is one offset with entries larger than 1 then we are
// talking about a vertex that is too far away from the original
// domain to belong to a canonical triangle.
if (off0.x() > 1) return false;
if (off0.y() > 1) return false;
if (off1.x() > 1) return false;
if (off1.y() > 1) return false;
}
// If there is one direction of space for which all offsets are
// non-zero then the edge is not canonical because we can
// take the copy closer towards the origin in that direction.
int offx = off0.x() & off1.x();
int offy = off0.y() & off1.y();
return (offx == 0 && offy == 0);
}
// Artificial incrementation function that takes periodic
// copies into account.
void increment_domain()
{
int off = get_drawing_offsets();
CGAL_triangulation_assertion(_off <= off);
if (_off == off)
{
_off = 0;
do
{
++pos;
}
while (_it == T::UNIQUE_COVER_DOMAIN
&& pos != _t->edges_end() && !is_canonical());
}
else
{
do
{
++_off;
}
while ((((~_off) | off) & 3) != 3); // Increment until a valid
// offset has been found
}
}
// Artificial decrementation function that takes periodic
// copies into account.
void decrement_domain()
{
if (_off == 0)
{
if (pos == _t->edges_begin()) return;
do
{
--pos;
}
while (_it == T::UNIQUE_COVER_DOMAIN && !is_canonical());
_off = get_drawing_offsets();
}
else
{
int off = get_drawing_offsets();
do
{
--_off;
}
while ((((~_off) | off) & 3) != 3); // Decrement until a valid
// offset has been found
}
}
// Get the canonicalized offsets of an edge.
// This works in any cover that is encoded in _t->combine_offsets
void get_edge_offsets(Offset &off0, Offset &off1) const
{
Offset cell_off0 = _t->int_to_off(pos->first->offset(_t->cw(pos->second)));
Offset cell_off1 = _t->int_to_off(pos->first->offset(_t->ccw(pos->second)));
Offset diff_off((cell_off0.x() == 1 && cell_off1.x() == 1) ? -1 : 0,
(cell_off0.y() == 1 && cell_off1.y() == 1) ? -1 : 0);
off0 = _t->combine_offsets(_t->get_offset(pos->first, _t->cw(pos->second)),
diff_off);
off1 = _t->combine_offsets(_t->get_offset(pos->first, _t->ccw(pos->second)),
diff_off);
}
// return an integer that encodes the translations which have to be
// applied to the edge *pos
int get_drawing_offsets()
{
Offset off0, off1;
// Choose edges that are to be duplicated. These are edges that
// intersect the boundary of the periodic domain. In UNIQUE mode
// this means that the offset with respect to drawing should
// differ in some entries. Otherwise we consider the offsets
// internally stored inside the cell telling us that this cell
// wraps around the domain.
if (_it == T::UNIQUE_COVER_DOMAIN)
get_edge_offsets(off0, off1);
else
{
CGAL_triangulation_assertion(_it == T::STORED_COVER_DOMAIN);
off0 = _t->int_to_off(pos->first->offset(_t->cw(pos->second)));
off1 = _t->int_to_off(pos->first->offset(_t->ccw(pos->second)));
}
Offset diff_off = off0 - off1;
CGAL_triangulation_assertion(diff_off.x() >= -1 || diff_off.x() <= 1);
CGAL_triangulation_assertion(diff_off.y() >= -1 || diff_off.y() <= 1);
return( 2 * (diff_off.x() == 0 ? 0 : 1)
+ (diff_off.y() == 0 ? 0 : 1));
}
Periodic_segment construct_periodic_segment() const
{
CGAL_triangulation_assertion(pos->first != typename T::Face_handle());
Offset off0, off1;
get_edge_offsets(off0, off1);
Offset transl_off = Offset((((_off >> 1) & 1) == 1 ? -1 : 0),
(( _off & 1) == 1 ? -1 : 0));
if (_it == T::STORED_COVER_DOMAIN)
{
off0 = _t->combine_offsets(off0, transl_off);
off1 = _t->combine_offsets(off1, transl_off);
}
if (_it == T::UNIQUE_COVER_DOMAIN)
{
off0 += transl_off;
off1 += transl_off;
}
return make_array(
std::make_pair(pos->first->vertex(_t->cw(pos->second))->point(), off0),
std::make_pair(pos->first->vertex(_t->ccw(pos->second))->point(), off1));
}
};
template < class T >
class Periodic_4_hyperbolic_triangulation_point_iterator_2
{
// Iterates over the primitives in a periodic triangulation.
// Options:
// - STORED: output each primitive from the Tds exactly once
// - UNIQUE: output exactly one periodic copy of each primitive, no matter
// whether the current tds stores a n-sheeted covering for n!=1.
// - STORED_COVER_DOMAIN: output each primitive whose intersection with the
// actually used periodic domain is non-zero.
// - UNIQUE_COVER_DOMAIN: output each primitive whose intersection
// with the original domain that the user has given is non-zero
//
// Comments:
// When computing in 1-sheeted covering, there will be no difference in the
// result of STORED and UNIQUE as well as STORED_COVER_DOMAIN and
// UNIQUE_COVER_DOMAIN.
public:
typedef typename T::Periodic_point value_type;
typedef const typename T::Periodic_point * pointer;
typedef const typename T::Periodic_point & reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef std::bidirectional_iterator_tag iterator_category;
typedef typename T::Periodic_point Periodic_point;
typedef Periodic_4_hyperbolic_triangulation_point_iterator_2<T> Periodic_point_iterator;
typedef typename T::Vertex Vertex;
typedef typename T::Vertex_iterator Vertex_iterator;
typedef typename T::Offset Offset;
typedef typename T::Iterator_type Iterator_type;
Periodic_4_hyperbolic_triangulation_point_iterator_2(Iterator_type it = T::STORED)
: _t(NULL), _it(it) {}
Periodic_4_hyperbolic_triangulation_point_iterator_2(const T * t,
Iterator_type it = T::STORED)
: _t(t), pos(_t->vertices_begin()), _it(it)
{
if (_it == T::UNIQUE || _it == T::UNIQUE_COVER_DOMAIN)
{
while (pos != _t->vertices_end() && !is_canonical() )
++pos;
}
}
// used to initialize the past-the-end iterator
Periodic_4_hyperbolic_triangulation_point_iterator_2(const T* t, int,
Iterator_type it = T::STORED)
: _t(t), pos(_t->vertices_end()), _it(it) {}
Periodic_point_iterator& operator++()
{
switch (_it)
{
case T::STORED:
case T::STORED_COVER_DOMAIN:
++pos;
break;
case T::UNIQUE:
case T::UNIQUE_COVER_DOMAIN:
do
{
++pos;
}
while (pos != _t->vertices_end() && !is_canonical());
break;
default:
CGAL_triangulation_assertion(false);
};
return *this;
}
Periodic_point_iterator& operator--()
{
switch (_it)
{
case T::STORED:
case T::STORED_COVER_DOMAIN:
--pos;
break;
case T::UNIQUE:
case T::UNIQUE_COVER_DOMAIN:
do
{
--pos;
}
while (pos != _t->vertices_begin() && !is_canonical());
break;
default:
CGAL_triangulation_assertion(false);
};
return *this;
}
Periodic_point_iterator operator++(int)
{
Periodic_point_iterator tmp(*this);
++(*this);
return tmp;
}
Periodic_point_iterator operator--(int)
{
Periodic_point_iterator tmp(*this);
--(*this);
return tmp;
}
bool operator==(const Periodic_point_iterator& pi) const
{
// We are only allowed to compare iterators of the same type.
CGAL_triangulation_assertion(_it == pi._it);
return _t == pi._t && pos == pi.pos;
}
bool operator!=(const Periodic_point_iterator& pi) const
{
return !(*this == pi);
}
reference operator*() const
{
periodic_point = construct_periodic_point();
return periodic_point;
}
pointer operator->() const
{
periodic_point = construct_periodic_point();
return &periodic_point;
}
Vertex_iterator get_vertex() const
{
return pos;
}
private:
const T* _t;
Vertex_iterator pos; // current vertex.
Iterator_type _it;
int _off; // current offset
mutable Periodic_point periodic_point; // current point.
private:
// check whether pos points onto a vertex inside the original
// domain. If we are computing in 1-sheeted covering this should
// always be true.
bool is_canonical()
{
return (_t->get_offset(pos).is_null());
}
Periodic_point construct_periodic_point() const
{
CGAL_triangulation_assertion(pos != typename T::Vertex_handle());
Offset off = _t->get_offset(pos);
return std::make_pair(pos->point(), off);
}
};
namespace Periodic_4_hyperbolic_triangulation_2_internal
{
template <class T>
class Domain_tester
{
const T *t;
public:
Domain_tester() {}
Domain_tester(const T *tr) : t(tr) {}
bool operator()(const typename T::Vertex_iterator & v) const
{
return (t->get_offset(v) != typename T::Offset(0, 0));
}
};
}
// Iterates over the vertices in a periodic triangulation that are
// located inside the original cube.
// Derives from Filter_iterator in order to add a conversion to handle
//
// Comments:
// When computing in 1-sheeted covering, there will be no difference
// between a normal Vertex_iterator and this iterator
template <class T>
class Periodic_4_hyperbolic_triangulation_unique_vertex_iterator_2
: public Filter_iterator<typename T::Vertex_iterator, Periodic_4_hyperbolic_triangulation_2_internal::Domain_tester<T> >
{
typedef typename T::Vertex_handle Vertex_handle;
typedef typename T::Vertex_iterator Vertex_iterator;
typedef typename Periodic_4_hyperbolic_triangulation_2_internal::Domain_tester<T> Tester;
typedef Filter_iterator<Vertex_iterator, Tester > Base;
typedef Periodic_4_hyperbolic_triangulation_unique_vertex_iterator_2 Self;
public:
Periodic_4_hyperbolic_triangulation_unique_vertex_iterator_2() : Base() {}
Periodic_4_hyperbolic_triangulation_unique_vertex_iterator_2(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 Vertex_handle() const
{
return Base::base();
}
};
} //namespace CGAL
#endif // CGAL_PERIODIC_4_HYPERBOLIC_TRIANGULATION_ITERATORS_2_H

View File

@ -165,7 +165,7 @@ TriangulationGraphicsItem<T>::drawAll(QPainter *painter)
//delete
QPen temp = painter->pen();
QPen old = temp;
temp.setWidthF(/*0.0035*/0.0045);
temp.setWidthF(/*0.0035*/0.0025);
painter->setPen(temp);
//
@ -175,7 +175,14 @@ TriangulationGraphicsItem<T>::drawAll(QPainter *painter)
for(typename T::Finite_edges_iterator eit = t->finite_edges_begin();
eit != t->finite_edges_end();
++eit){
painterostream << t->segment(*eit);
//typename T::Vertex_handle vh = eit->first->finite_vertices_begin();
//std::cout << vh << std::endl;
//typename T::Geom_traits::Segment_2 sg = t->segment(*eit);
//std::cout << sg(0) << std::endl;
painterostream << t->segment(*eit);
}
}
@ -200,59 +207,50 @@ TriangulationGraphicsItem<T>::paintVertices(QPainter *painter)
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.));
switch (it->info().getColor()) {
case 0:
painter->setPen(QPen(::Qt::red, 3., ::Qt::SolidLine, ::Qt::RoundCap, ::Qt::RoundJoin));
break;
case 1:
painter->setPen(QPen(::Qt::green, 3., ::Qt::SolidLine, ::Qt::RoundCap, ::Qt::RoundJoin));
break;
case 2:
painter->setPen(QPen(::Qt::blue, 3., ::Qt::SolidLine, ::Qt::RoundCap, ::Qt::RoundJoin));
break;
case 3:
painter->setPen(QPen(::Qt::magenta, 3., ::Qt::SolidLine, ::Qt::RoundCap, ::Qt::RoundJoin));
break;
case 4:
painter->setPen(QPen(::Qt::darkGreen, 3., ::Qt::SolidLine, ::Qt::RoundCap, ::Qt::RoundJoin));
break;
case 5:
painter->setPen(QPen(::Qt::darkRed, 3., ::Qt::SolidLine, ::Qt::RoundCap, ::Qt::RoundJoin));
break;
case 6:
painter->setPen(QPen(::Qt::darkBlue, 3., ::Qt::SolidLine, ::Qt::RoundCap, ::Qt::RoundJoin));
break;
case 7:
painter->setPen(QPen(::Qt::darkYellow, 3., ::Qt::SolidLine, ::Qt::RoundCap, ::Qt::RoundJoin));
break;
case 8:
painter->setPen(QPen(::Qt::darkCyan, 3., ::Qt::SolidLine, ::Qt::RoundCap, ::Qt::RoundJoin));
break;
case 9:
painter->setPen(QPen(::Qt::yellow, 3., ::Qt::SolidLine, ::Qt::RoundCap, ::Qt::RoundJoin));
break;
case 10:
painter->setPen(QPen(::Qt::cyan, 3., ::Qt::SolidLine, ::Qt::RoundCap, ::Qt::RoundJoin));
break;
case 11:
painter->setPen(QPen(::Qt::black, 3., ::Qt::SolidLine, ::Qt::RoundCap, ::Qt::RoundJoin));
break;
case 12:
painter->setPen(QPen(::Qt::lightGray, 3., ::Qt::SolidLine, ::Qt::RoundCap, ::Qt::RoundJoin));
break;
default:
painter->setPen(QPen(::Qt::gray, 3., ::Qt::SolidLine, ::Qt::RoundCap, ::Qt::RoundJoin));
break;
}
//
@ -266,21 +264,21 @@ TriangulationGraphicsItem<T>::paintVertices(QPainter *painter)
double py = to_double(it->point().y());
double dist = px*px + py*py;
if(dist > 0.25) {
temp.setWidth(8);//6
temp.setWidth(6);//6
}
if(dist > 0.64) {
temp.setWidth(7);//5
temp.setWidth(4);//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);
if(dist > 0.92) {
temp.setWidth(2);//3
}
if(dist > 0.98) {
temp.setWidth(1);//3
}
painter->setPen(temp);
QPointF point = matrix.map(convert(it->point()));
painter->drawPoint(point);
@ -337,8 +335,10 @@ TriangulationGraphicsItem<T>::paint(QPainter *painter,
painter->setPen(this->edgesPen());
// painter->drawRect(boundingRect());
if ( t->dimension()<2 || option->exposedRect.contains(boundingRect()) ) {
std::cout << "Drawing all!" << std::endl;
drawAll(painter);
} else {
std::cout << "Else-ing!" << std::endl;
m_painter = painter;
painterostream = PainterOstream<Geom_traits>(painter);
CGAL::apply_to_range (*t,

View File

@ -213,521 +213,5 @@ Sqrt_field<Int> copysign(const Sqrt_field<Int>& x, const Sqrt_field<Int>& y)
}
// end MT - added to please libc++
#endiftemplate<class Sqrt_field>
class Octagon_matrix
{
public:
typedef Octagon_matrix<Sqrt_field> Self;
typedef complex<Sqrt_field> Extended_field;
Extended_field M11;
Extended_field M12;
string label;
Octagon_matrix(const Extended_field& M11_, const Extended_field& M12_,
const string& label_ = string("") ) :
M11(M11_), M12(M12_), label(label_) {}
string merge_labels(const Self& rh) const
{
return label + "*" + rh.label;
}
Self operator*(const Self& rh) const
{
return Self( M11*rh.M11 + aux*M12*conj(rh.M12),
M11*rh.M12 + M12*conj(rh.M11), merge_labels(rh) );
}
Self inverse() const
{
Self inv = Self(conj(M11), -M12);
string inv_label;
for(long i = label.size() - 1; i >= 0; i--) {
if(label[i] >= 'a' && label[i] <= 'd') {
inv_label.push_back(label[i]);
inv_label.push_back('^');
inv_label.push_back('-');
inv_label.push_back('1');
}
if(label[i] == '*') {
inv_label.push_back('*');
}
if(label[i] == '1') {
assert(i - 3 >= 0);
assert(label[i - 3] >= 'a' && label[i - 3] <= 'd');
inv_label.push_back(label[i - 3]);
i = i - 3;
}
}
inv.label = inv_label;
return inv;
}
// rotation \pi/4
Octagon_matrix rotate() const
{
Sqrt_field B1 = real(M12);
Sqrt_field B2 = imag(M12);
// sqrt(2)
Sqrt_field k = Sqrt_field(0, 1);
Sqrt_field BB1 = (B1 - B2)*k;
Sqrt_field BB2 = (B1 + B2)*k;
assert(BB2.l % 2 == 0 && BB2.r % 2 == 0);
BB1.l = BB1.l/2;
BB1.r = BB1.r/2;
BB2.l = BB2.l/2;
BB2.r = BB2.r/2;
return Octagon_matrix(M11, Extended_field(BB1, BB2));
}
Sqrt_field trace() const
{
return Sqrt_field(2, 0)*real(M11);
}
double length() const
{
typedef long double ld;
ld l = real(M11).l;
ld r = real(M11).r;
ld tr = l + sqrt(2.)*r;
if (tr < 0) {
tr = -tr;
}
return 2.*acosh(tr);
}
// determinant == 1
Extended_field det() const
{
return norm(M11) - aux * norm(M12);
}
static complex<double> toComplexDouble(Extended_field M) //const
{
Sqrt_field rl = real(M);
Sqrt_field img = imag(M);
return complex<double>(rl.l + sqrt(2.)*rl.r, img.l + sqrt(2.)*img.r);
}
pair<double, double> apply(double x, double y)
{
typedef complex<double> Cmpl;
Cmpl m11 = toComplexDouble(M11);
Cmpl m12 = toComplexDouble(M12);
double ax = sqrt(aux.l + sqrt(2.)*aux.r);
Cmpl z(x, y);
Cmpl res = (m11*z + ax*m12)/(ax*(conj(m12)*z) + conj(m11));
return pair<double, double>(real(res), imag(res));
}
//private:
static Sqrt_field aux;
};
template<class Sqrt_field>
Sqrt_field Octagon_matrix<Sqrt_field>::aux = Sqrt_field(-1, 1);
// just to give an order(ing)
template<class Int>
bool operator < (const complex<Sqrt_field<Int> >& lh,
const complex<Sqrt_field<Int> >& rh)
{
if (real(lh) < real(rh)) {
return true;
}
if (real(lh) == real(rh)) {
if (imag(lh) < imag(rh)) {
return true;
}
}
return false;
}
// just to order octagon_matrices
template<class Sqrt_field>
bool operator < (const Octagon_matrix<Sqrt_field>& lh,
const Octagon_matrix<Sqrt_field>& rh)
{
if (lh.M11 < rh.M11) {
return true;
}
if (lh.M11 == rh.M11 ) {
if (lh.M12 < rh.M12) {
return true;
}
}
return false;
}
template<class Sqrt_field>
bool operator == (const Octagon_matrix<Sqrt_field>& lh,
const Octagon_matrix<Sqrt_field>& rh)
{
return (lh.M11 == rh.M11 && lh.M12 == rh.M12);
}
template<class Sqrt_field>
ostream& operator<<(ostream& os, const Octagon_matrix<Sqrt_field>& m)
{
os << m.M11 << " " << m.M12;
return os;
}
typedef long long ll;
typedef Sqrt_field<ll> SqrtField;
typedef Octagon_matrix<SqrtField> OctagonMatrix;
typedef OctagonMatrix::Extended_field Entry;
void get_generators(vector<OctagonMatrix>& gens)
{
Entry M11 = Entry(SqrtField(1, 1), SqrtField(0, 0));
vector<Entry> M12(8, Entry(SqrtField(0, 0), SqrtField(0, 0)));
M12[0] = M11 * Entry(SqrtField(0, 1), SqrtField(0, 0));
M12[1] = M11 * Entry(SqrtField(1, 0), SqrtField(1, 0));
M12[2] = M11 * Entry(SqrtField(0, 0), SqrtField(0, 1));
M12[3] = M11 * Entry(SqrtField(-1, 0), SqrtField(1, 0));
M12[4] = M11 * Entry(SqrtField(0, -1), SqrtField(0, 0));
M12[5] = M11 * Entry(SqrtField(-1, 0), SqrtField(-1, 0));
M12[6] = M11 * Entry(SqrtField(0, 0), SqrtField(0, -1));
M12[7] = M11 * Entry(SqrtField(1, 0), SqrtField(-1, 0));
string labels[8] = {string("a"), string("b^-1"), string("c"), string("d^-1"),
string("a^-1"), string("b"), string("c^-1"), string("d")};
for(int i = 0; i < 8; i++) {
gens.push_back(OctagonMatrix(M11, M12[i], labels[i]));
}
}
// a, b, c, d, a^-1, b^-1, c^-1, d^-1
vector<OctagonMatrix> gens;
bool IsCanonical(const OctagonMatrix& m);
void generate_words( set<OctagonMatrix>& words, vector<OctagonMatrix>& prev, int depth )
{
if (depth == 1) {
for(int i = 0; i < 8; i++) {
words.insert( gens[i] );
prev.push_back( gens[i] );
}
return;
}
vector<OctagonMatrix> els;
generate_words( words, els, depth - 1);
OctagonMatrix temp = OctagonMatrix(Entry(), Entry());
ll size = els.size();
bool is_new = false;
for(ll k = 0; k < size; k++) {
for(int i = 0; i < 8; i++) {
temp = els[k]*gens[i];
if(temp.length() > 15.) {
continue;
}
is_new = words.insert(temp).second;
if(is_new == true) {
prev.push_back(temp);
}
}
}
}
// does the axis of a given matrix go through the fundamental octagon
bool IsCanonical(const OctagonMatrix& m)
{
OctagonMatrix temp = m;
// rotate while |B1| < |B2|
SqrtField B1, B2;
SqrtField C = SqrtField(-1, -1);
for(int i = 0; i < 8 && C != C.abs(); i++) {
B1 = real(temp.M12).abs();
B2 = imag(temp.M12).abs();
C = B1 - B2;
temp = temp.rotate();
}
assert(C == C.abs());
// (2 - sqrt(2))(|B1| + (sqrt(2) - 1)|B2|)
SqrtField right = SqrtField(2, -1)*(B1 + SqrtField(-1, 1)*B2);
// |A2|
SqrtField left = imag(temp.M11).abs();
// left <= right -> true
C = right - left;
return C == C.abs();
}
void dfs(const OctagonMatrix& m, set<OctagonMatrix>& visited)
{
assert(IsCanonical(m));
visited.insert(m);
OctagonMatrix 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()) {
dfs(candidate, visited);
}
}
}
// map<OctagonMatrix m, OctagonMatrix Aux>, m = Aux * origin * Aux^{-1}
void dfs_with_info(const pair<OctagonMatrix, OctagonMatrix>& new_pair,
map <OctagonMatrix, OctagonMatrix>& visited)
{
assert(IsCanonical(new_pair.first));
visited.insert(new_pair);
const OctagonMatrix& current = new_pair.first;
const OctagonMatrix& current_aux = new_pair.second;
OctagonMatrix candidate = current, candidate_aux = current_aux;
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_aux = gens[i]*current_aux;
dfs_with_info(pair<OctagonMatrix, OctagonMatrix>(candidate, candidate_aux), visited);
}
}
}
void dfs_with_info(const OctagonMatrix& origin,
map<OctagonMatrix, OctagonMatrix>& visited)
{
assert(IsCanonical(origin));
OctagonMatrix id = OctagonMatrix(Entry(SqrtField(1, 0), SqrtField(0, 0)),
Entry(SqrtField(0, 0), SqrtField(0, 0)));
pair<OctagonMatrix, OctagonMatrix> new_pair(origin, id);
dfs_with_info(new_pair, visited);
}
class IntersectionNumber
{
public:
struct Point
{
Point(double x_ = 0, double y_ = 0) : x(x_), y(y_) {}
double x, y;
};
OctagonMatrix m;
IntersectionNumber(const OctagonMatrix& m_) : m(m_)
{}
long operator() () const
{
set<OctagonMatrix> visited;
set<OctagonMatrix>::iterator it, it2;
map<long, long> nb_map;
map<long, long>::iterator mit;
dfs(m, visited);
set<pair< OctagonMatrix, OctagonMatrix> > common;
for(it = visited.begin(); it != visited.end(); ++it) {
for(it2 = it; it2 != visited.end(); ++it2) {
if(*it == *it2) {
continue;
}
if(haveIntersection(*it, *it2) == true) {
common.clear();
count_nb(*it, *it2, common);
mit = nb_map.find(common.size());
if(mit != nb_map.end()) {
mit->second += 1;
} else {
nb_map.insert(pair<long, long>(common.size(), 1));
}
}
}
}
long nb = 0;
for(mit = nb_map.begin(); mit != nb_map.end(); mit++) {
assert( mit->second % mit->first == 0 );
nb += mit->second/mit->first;
}
return nb;
}
void count_nb(const OctagonMatrix& m1, const OctagonMatrix& m2, set<pair< OctagonMatrix, OctagonMatrix> >& visited) const
{
typedef pair<OctagonMatrix, OctagonMatrix> matrix_pair;
visited.insert(matrix_pair(m1, m2));
OctagonMatrix 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];
if(IsCanonical(c1) == true && IsCanonical(c2) == true && visited.find(matrix_pair(c1, c2)) == visited.end()) {
count_nb(c1, c2, visited);
}
}
}
//private:
// check whether two axis have intersection
bool haveIntersection(const OctagonMatrix& m1, const OctagonMatrix& m2) const
{
Point p1, p2;
intersectWithInfinity(m1, p1, p2);
Point p3, p4;
intersectWithInfinity(m2, p3, p4);
// orientation test
double sign1 = (p1.x - p3.x)*(p2.y - p3.y) - (p1.y - p3.y)*(p2.x - p3.x);
double sign2 = (p1.x - p4.x)*(p2.y - p4.y) - (p1.y - p4.y)*(p2.x - p4.x);
assert( sign1 * sign2 != 0);
return (sign1 * sign2 < 0);
}
void intersectWithInfinity(const OctagonMatrix& m, Point& p1, Point& p2) const
{
Entry a = m.M11, b = m.M12, aux = m.aux;
Entry four = Entry(SqrtField(4, 0), SqrtField(0, 0));
Entry two = Entry(SqrtField(2, 0), SqrtField(0, 0));
Entry D = (a - conj(a))*(a - conj(a));
D += four*b*conj(b)*aux;
Entry T1 = conj(a) - a;
Entry T2 = two*conj(b);
complex<double> d = m.toComplexDouble(D);
complex<double> t1 = m.toComplexDouble(T1);
complex<double> t2 = m.toComplexDouble(T2);
complex<double> au = complex<double>(m.aux.l + sqrt(2.)*m.aux.r, 0);
complex<double> z1 = (t1 + sqrt(d))/(t2*sqrt(au));
complex<double> z2 = (t1 - sqrt(d))/(t2*sqrt(au));
p1 = Point(real(z1), imag(z1));
p2 = Point(real(z2), imag(z2));
assert(p1.x*p1.x + p1.y*p1.y > 0.99 && p1.x*p1.x + p1.y*p1.y < 1.01);
assert(p2.x*p2.x + p2.y*p2.y > 0.99 && p2.x*p2.x + p2.y*p2.y < 1.01);
}
};
void Delete(const set<OctagonMatrix>& canonical_set, vector<OctagonMatrix>& output)
{
set<OctagonMatrix> redundant;
set<OctagonMatrix>::iterator it;
for(it = canonical_set.begin(); it != canonical_set.end(); ++it) {
if(redundant.find(*it) != redundant.end()) {
continue;
}
set<OctagonMatrix> visited;
dfs(*it, visited);
visited.erase(*it);
redundant.insert(visited.begin(), visited.end());
output.push_back(*it);
}
}
void generate_unique_words(vector<OctagonMatrix>& output, double threshold = 10, int word_length = 13)
{
get_generators(gens);
set<OctagonMatrix> unique_words;
vector<OctagonMatrix> temp;
generate_words(unique_words, temp, word_length);
double l = 0;
set<OctagonMatrix>::iterator uit;
for(uit = unique_words.begin(); uit != unique_words.end(); ++uit) {
l = uit->length();
if(0. < l && l < threshold) {
output.push_back( *uit );
}
}
cout << "nb of unique words " << output.size() << endl;
}
// words that correspond to union of 1-cycles
void generate_words_union_1_cycles(vector<OctagonMatrix>& out)
{
if(gens.size() == 0) {
get_generators(gens);
}
OctagonMatrix f[4] = {gens[0], gens[5], gens[2], gens[7]};
OctagonMatrix F[8] = {
f[0]*f[0].inverse(),
f[0],
f[0]*f[1],
f[0]*f[1]*f[2],
f[0]*f[1]*f[2]*f[3],
f[3]*f[2]*f[1],
f[3]*f[2],
f[3]
};
long counter = 0;
for(int i = 1; i < 5; i++) {
for(int j = 0; j < 8; j++) {
for(int k = 0; k < 8; k++) {
if (j == k) {
continue;
}
// intersection
if ((0 < j && j < i) && (i < k)) {
continue;
}
if ((0 < k && k < i) && (i < j)) {
continue;
}
counter++;
OctagonMatrix Tr = F[i]*F[k].inverse()*F[j];
// check that Tr != Id
if(Tr.length() > 2.) {
out.push_back(Tr);
}
}
}
}
cout << counter << endl;
}
#endif // CGAL_PERIODIC_4_HYPERBOLIC_TRIANGULATION_SQRT_FIELD_H

View File

@ -32,7 +32,7 @@ public:
color = new_color;
}
int getColor() const
int getColor() const
{
return color;
}

View File

@ -38,44 +38,44 @@ namespace CGAL {
template < class R >
class Triangulation_hyperbolic_traits_2 {
public:
typedef Triangulation_hyperbolic_traits_2<R> Self;
typedef Triangulation_hyperbolic_traits_2<R> Self;
typedef R Kernel;
typedef R Kernel;
typedef R Rep;
typedef typename R::RT RT;
typedef typename R::Point_2 Point_2;
typedef typename R::Vector_2 Vector_2;
typedef typename R::Triangle_2 Triangle_2;
typedef typename R::Line_2 Line_2;
typedef typename R::Ray_2 Ray_2;
typedef R Rep;
typedef typename R::RT RT;
typedef typename R::Point_2 Point_2;
typedef typename R::Vector_2 Vector_2;
typedef typename R::Triangle_2 Triangle_2;
typedef typename R::Line_2 Line_2;
typedef typename R::Ray_2 Ray_2;
typedef typename R::Vector_3 Vector_3;
typedef typename R::Point_3 Point_3;
typedef typename R::Vector_3 Vector_3;
typedef typename R::Point_3 Point_3;
typedef typename R::Less_x_2 Less_x_2;
typedef typename R::Less_y_2 Less_y_2;
typedef typename R::Compare_x_2 Compare_x_2;
typedef typename R::Compare_y_2 Compare_y_2;
typedef typename R::Orientation_2 Orientation_2;
typedef typename R::Side_of_oriented_circle_2 Side_of_oriented_circle_2;
typedef typename R::Construct_bisector_2 Construct_bisector_2;
typedef typename R::Compare_distance_2 Compare_distance_2;
typedef typename R::Construct_triangle_2 Construct_triangle_2;
typedef typename R::Construct_direction_2 Construct_direction_2;
typedef typename R::Less_x_2 Less_x_2;
typedef typename R::Less_y_2 Less_y_2;
typedef typename R::Compare_x_2 Compare_x_2;
typedef typename R::Compare_y_2 Compare_y_2;
typedef typename R::Orientation_2 Orientation_2;
typedef typename R::Side_of_oriented_circle_2 Side_of_oriented_circle_2;
typedef typename R::Construct_bisector_2 Construct_bisector_2;
typedef typename R::Compare_distance_2 Compare_distance_2;
typedef typename R::Construct_triangle_2 Construct_triangle_2;
typedef typename R::Construct_direction_2 Construct_direction_2;
typedef typename R::Angle_2 Angle_2;
typedef typename R::Construct_midpoint_2 Construct_midpoint_2;
typedef typename R::Compute_squared_distance_2 Compute_squared_distance_2;
typedef typename R::Iso_rectangle_2 Iso_rectangle_2;
typedef typename R::Circle_2 Circle_2;
typedef typename R::Iso_rectangle_2 Iso_rectangle_2;
typedef typename R::Circle_2 Circle_2;
typedef boost::tuple<Circle_2, Point_2, Point_2> Arc_2;
typedef typename R::Segment_2 Line_segment_2;
typedef boost::variant<Arc_2, Line_segment_2> Segment_2;
typedef boost::tuple<Circle_2, Point_2, Point_2> Arc_2;
typedef typename R::Segment_2 Line_segment_2;
typedef boost::variant<Arc_2, Line_segment_2> Segment_2;
typedef typename R::Line_2 Euclidean_line_2;
typedef typename R::Line_2 Euclidean_line_2;
private:
// Poincaré disk

View File

@ -42,8 +42,10 @@ void Hyperbolic_random_points_in_disc_2(std::vector<typename Gt::Point_2>& outpu
if (seed != -1) {
rand = CGAL::Random(seed);
}
CGAL::Random_points_in_disc_2<Point_2, Creator> in_Euclidean_disk(rh, rand);
/*CGAL::Random_points_in_disc_2<Point_2, Creator> in_Euclidean_disk(rh, rand);*/
CGAL::Random_points_in_disc_2<Point_2, Creator> in_Euclidean_disk(rh);
std::vector<Point_2> pts;
pts.reserve(nb);
for(int i = 0; i < nb ; i++) {