Commit for the modifications regarding the initial implementation of the _real_ triangulation of the Bolza surface. For the time being only contains the initialization with the dummy points and a simple test. The demo that existed has been moved into a subdirectory (see the file readme.txt)
|
|
@ -1,37 +1,42 @@
|
|||
# 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)
|
||||
project (Playground)
|
||||
|
||||
# Find includes in corresponding build directories
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
# Instruct CMake to run moc automatically when needed.
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
#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)
|
||||
find_package(CGAL QUIET COMPONENTS Core)
|
||||
include(${CGAL_USE_FILE})
|
||||
|
||||
find_package(Qt5 QUIET COMPONENTS Widgets)
|
||||
|
||||
include_directories (BEFORE ../../../Hyperbolic_triangulation_2/include ../../include include)
|
||||
find_package( Boost REQUIRED )
|
||||
include_directories(${Boost_INCLUDE_DIRS})
|
||||
|
||||
include_directories (BEFORE ../../../Hyperbolic_triangulation_2/include ../../../Hyperbolic_triangulation_2/demo/Hyperbolic_triangulation_2/include ../../include include)
|
||||
|
||||
# ui files, created with Qt Designer
|
||||
qt5_wrap_ui( uis Periodic_4_hyperbolic_triangulation_2.ui )
|
||||
#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 )
|
||||
#qt5_add_resources ( RESOURCE_FILES resources/Periodic_4_hyperbolic_triangulation_2.qrc )
|
||||
|
||||
|
||||
# cpp files
|
||||
|
||||
add_executable ( Periodic_4_hyperbolic_Delaunay_triangulation_2_demo Periodic_4_hyperbolic_Delaunay_triangulation_2_demo.cpp )
|
||||
qt5_use_modules( Periodic_4_hyperbolic_Delaunay_triangulation_2_demo Widgets)
|
||||
add_to_cached_list( CGAL_EXECUTABLE_TARGETS Periodic_4_hyperbolic_Delaunay_triangulation_2_demo )
|
||||
target_link_libraries( Periodic_4_hyperbolic_Delaunay_triangulation_2_demo ${CGAL_LIBRARIES} ${QT_LIBRARIES} ${CGAL_QT_LIBRARIES} )
|
||||
add_executable ( Playground playground.cpp )
|
||||
add_executable ( Triangulation triangulation.cpp )
|
||||
#qt5_use_modules( Playground Widgets )
|
||||
target_link_libraries( Playground ${CGAL_LIBRARIES} )
|
||||
target_link_libraries( Triangulation ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES} ${Boost_LIBRARIES} )
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
# 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 ../../../Hyperbolic_triangulation_2/include ../../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_hyperbolic_Delaunay_triangulation_2_demo Periodic_4_hyperbolic_Delaunay_triangulation_2_demo.cpp )
|
||||
qt5_use_modules( Periodic_4_hyperbolic_Delaunay_triangulation_2_demo Widgets)
|
||||
add_to_cached_list( CGAL_EXECUTABLE_TARGETS Periodic_4_hyperbolic_Delaunay_triangulation_2_demo )
|
||||
target_link_libraries( Periodic_4_hyperbolic_Delaunay_triangulation_2_demo ${CGAL_LIBRARIES} ${QT_LIBRARIES} ${CGAL_QT_LIBRARIES} )
|
||||
|
||||
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 7.5 KiB |
|
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 6.6 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 768 B After Width: | Height: | Size: 768 B |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 7.9 KiB |
|
Before Width: | Height: | Size: 7.4 KiB After Width: | Height: | Size: 7.4 KiB |
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
|
|
@ -1,397 +0,0 @@
|
|||
/********************************************************************************
|
||||
** Form generated from reading UI file 'Hyperbolic_translations_2.ui'
|
||||
**
|
||||
** Created by: Qt User Interface Compiler version 4.8.7
|
||||
**
|
||||
** WARNING! All changes made in this file will be lost when recompiling UI file!
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef UI_PERIODIC_4_HYPERBOLIC_DELAUNAY_TRIANGULATION_H
|
||||
#define UI_PERIODIC_4_HYPERBOLIC_DELAUNAY_TRIANGULATION_H
|
||||
|
||||
#if QT_VERSION >= 0x050000
|
||||
|
||||
#include <QVariant>
|
||||
#include <QAction>
|
||||
#include <QApplication>
|
||||
#include <QButtonGroup>
|
||||
#include <QGraphicsView>
|
||||
#include <QGridLayout>
|
||||
#include <QHeaderView>
|
||||
#include <QMainWindow>
|
||||
#include <QMenu>
|
||||
#include <QMenuBar>
|
||||
#include <QStatusBar>
|
||||
#include <QToolBar>
|
||||
#include <QWidget>
|
||||
|
||||
#else
|
||||
|
||||
#include <QtCore/QVariant>
|
||||
#include <QtGui/QAction>
|
||||
#include <QtGui/QApplication>
|
||||
#include <QtGui/QButtonGroup>
|
||||
#include <QtGui/QGraphicsView>
|
||||
#include <QtGui/QGridLayout>
|
||||
#include <QtGui/QHeaderView>
|
||||
#include <QtGui/QMainWindow>
|
||||
#include <QtGui/QMenu>
|
||||
#include <QtGui/QMenuBar>
|
||||
#include <QtGui/QStatusBar>
|
||||
#include <QtGui/QToolBar>
|
||||
#include <QtGui/QWidget>
|
||||
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class Ui_Periodic_4_hyperbolic_Delaunay_triangulation_2
|
||||
{
|
||||
public:
|
||||
QAction *actionAbout;
|
||||
QAction *actionAboutCGAL;
|
||||
QAction *actionQuit;
|
||||
QAction *actionInsertRandomPoints;
|
||||
QAction *actionMovingPoint;
|
||||
QAction *actionInsertPoint;
|
||||
QAction *actionClear;
|
||||
QAction *actionInsertPointOnFundamentalSide;
|
||||
QAction *actionInsertPointOnAxis;
|
||||
QAction *actionInsertOrigin;
|
||||
QAction *actionInsertDummyPoints;
|
||||
QAction *actionModifyDepth;
|
||||
QAction *actionShowVoronoi;
|
||||
QAction *actionShowDelaunay;
|
||||
QAction *actionLoadPoints;
|
||||
QAction *actionSavePoints;
|
||||
QAction *actionCircumcenter;
|
||||
QAction *actionRecenter;
|
||||
QAction *actionShowConflictZone;
|
||||
QAction *actionDo_translation_a;
|
||||
QAction *actionDo_translation_b;
|
||||
QAction *actionDo_translation_c;
|
||||
QAction *actionDo_translation_d;
|
||||
QAction *actionG;
|
||||
QAction *actionG2;
|
||||
QAction *actionG4;
|
||||
QAction *actionG8;
|
||||
QAction *actionG16;
|
||||
QWidget *centralwidget;
|
||||
QGridLayout *gridLayout;
|
||||
QGraphicsView *graphicsView;
|
||||
QStatusBar *statusbar;
|
||||
QToolBar *fileToolBar;
|
||||
QToolBar *toolBar;
|
||||
QMenuBar *menubar;
|
||||
QMenu *menuFile;
|
||||
QMenu *menuEdit;
|
||||
QMenu *menuTools;
|
||||
|
||||
void setupUi(QMainWindow *Periodic_4_hyperbolic_Delaunay_triangulation_2)
|
||||
{
|
||||
if (Periodic_4_hyperbolic_Delaunay_triangulation_2->objectName().isEmpty())
|
||||
Periodic_4_hyperbolic_Delaunay_triangulation_2->setObjectName(QString::fromUtf8("Periodic_4_hyperbolic_Delaunay_triangulation_2"));
|
||||
Periodic_4_hyperbolic_Delaunay_triangulation_2->resize(800, 600);
|
||||
QIcon icon;
|
||||
icon.addFile(QString::fromUtf8(":/cgal/logos/cgal_icon"), QSize(), QIcon::Normal, QIcon::Off);
|
||||
Periodic_4_hyperbolic_Delaunay_triangulation_2->setWindowIcon(icon);
|
||||
actionAbout = new QAction(Periodic_4_hyperbolic_Delaunay_triangulation_2);
|
||||
actionAbout->setObjectName(QString::fromUtf8("actionAbout"));
|
||||
actionAboutCGAL = new QAction(Periodic_4_hyperbolic_Delaunay_triangulation_2);
|
||||
actionAboutCGAL->setObjectName(QString::fromUtf8("actionAboutCGAL"));
|
||||
actionQuit = new QAction(Periodic_4_hyperbolic_Delaunay_triangulation_2);
|
||||
actionQuit->setObjectName(QString::fromUtf8("actionQuit"));
|
||||
actionInsertRandomPoints = new QAction(Periodic_4_hyperbolic_Delaunay_triangulation_2);
|
||||
actionInsertRandomPoints->setObjectName(QString::fromUtf8("actionInsertRandomPoints"));
|
||||
|
||||
actionInsertPointOnAxis = new QAction(Periodic_4_hyperbolic_Delaunay_triangulation_2);
|
||||
actionInsertPointOnAxis->setObjectName(QString::fromUtf8("actionInsertPointOnAxis"));
|
||||
|
||||
actionInsertPointOnFundamentalSide = new QAction(Periodic_4_hyperbolic_Delaunay_triangulation_2);
|
||||
actionInsertPointOnFundamentalSide->setObjectName(QString::fromUtf8("actionInsertPointOnFundamentalSide"));
|
||||
|
||||
actionInsertOrigin = new QAction(Periodic_4_hyperbolic_Delaunay_triangulation_2);
|
||||
actionInsertOrigin->setObjectName(QString::fromUtf8("actionInsertOrigin"));
|
||||
actionInsertDummyPoints = new QAction(Periodic_4_hyperbolic_Delaunay_triangulation_2);
|
||||
actionInsertDummyPoints->setObjectName(QString::fromUtf8("actionInsertDummyPoints"));
|
||||
actionModifyDepth = new QAction(Periodic_4_hyperbolic_Delaunay_triangulation_2);
|
||||
actionModifyDepth->setObjectName(QString::fromUtf8("actionModifyDepth"));
|
||||
actionMovingPoint = new QAction(Periodic_4_hyperbolic_Delaunay_triangulation_2);
|
||||
actionMovingPoint->setObjectName(QString::fromUtf8("actionMovingPoint"));
|
||||
actionMovingPoint->setCheckable(true);
|
||||
QIcon icon1;
|
||||
icon1.addFile(QString::fromUtf8(":/cgal/Actions/icons/moving_point.png"), QSize(), QIcon::Normal, QIcon::Off);
|
||||
actionMovingPoint->setIcon(icon1);
|
||||
actionInsertPoint = new QAction(Periodic_4_hyperbolic_Delaunay_triangulation_2);
|
||||
actionInsertPoint->setObjectName(QString::fromUtf8("actionInsertPoint"));
|
||||
actionInsertPoint->setCheckable(true);
|
||||
actionInsertPoint->setChecked(false);
|
||||
QIcon icon2;
|
||||
icon2.addFile(QString::fromUtf8(":/cgal/Input/inputPoint.png"), QSize(), QIcon::Normal, QIcon::Off);
|
||||
actionInsertPoint->setIcon(icon2);
|
||||
actionClear = new QAction(Periodic_4_hyperbolic_Delaunay_triangulation_2);
|
||||
actionClear->setObjectName(QString::fromUtf8("actionClear"));
|
||||
QIcon icon3;
|
||||
icon3.addFile(QString::fromUtf8(":/cgal/fileToolbar/fileNew.png"), QSize(), QIcon::Normal, QIcon::Off);
|
||||
actionClear->setIcon(icon3);
|
||||
actionShowVoronoi = new QAction(Periodic_4_hyperbolic_Delaunay_triangulation_2);
|
||||
actionShowVoronoi->setObjectName(QString::fromUtf8("actionShowVoronoi"));
|
||||
actionShowVoronoi->setCheckable(true);
|
||||
actionShowVoronoi->setChecked(false);
|
||||
QIcon icon4;
|
||||
icon4.addFile(QString::fromUtf8(":/cgal/Triangulation_2/Voronoi_diagram_2.png"), QSize(), QIcon::Normal, QIcon::Off);
|
||||
actionShowVoronoi->setIcon(icon4);
|
||||
actionShowDelaunay = new QAction(Periodic_4_hyperbolic_Delaunay_triangulation_2);
|
||||
actionShowDelaunay->setObjectName(QString::fromUtf8("actionShowDelaunay"));
|
||||
actionShowDelaunay->setCheckable(true);
|
||||
QIcon icon5;
|
||||
icon5.addFile(QString::fromUtf8(":/cgal/Actions/icons/triangulation.png"), QSize(), QIcon::Normal, QIcon::Off);
|
||||
actionShowDelaunay->setIcon(icon5);
|
||||
actionLoadPoints = new QAction(Periodic_4_hyperbolic_Delaunay_triangulation_2);
|
||||
actionLoadPoints->setObjectName(QString::fromUtf8("actionLoadPoints"));
|
||||
QIcon icon6;
|
||||
icon6.addFile(QString::fromUtf8(":/cgal/fileToolbar/fileOpen.png"), QSize(), QIcon::Normal, QIcon::Off);
|
||||
actionLoadPoints->setIcon(icon6);
|
||||
actionSavePoints = new QAction(Periodic_4_hyperbolic_Delaunay_triangulation_2);
|
||||
actionSavePoints->setObjectName(QString::fromUtf8("actionSavePoints"));
|
||||
QIcon icon7;
|
||||
icon7.addFile(QString::fromUtf8(":/cgal/fileToolbar/fileSave.png"), QSize(), QIcon::Normal, QIcon::Off);
|
||||
actionSavePoints->setIcon(icon7);
|
||||
actionCircumcenter = new QAction(Periodic_4_hyperbolic_Delaunay_triangulation_2);
|
||||
actionCircumcenter->setObjectName(QString::fromUtf8("actionCircumcenter"));
|
||||
actionCircumcenter->setCheckable(true);
|
||||
QIcon icon8;
|
||||
icon8.addFile(QString::fromUtf8(":/cgal/Actions/icons/circumcenter.png"), QSize(), QIcon::Normal, QIcon::Off);
|
||||
actionCircumcenter->setIcon(icon8);
|
||||
actionRecenter = new QAction(Periodic_4_hyperbolic_Delaunay_triangulation_2);
|
||||
actionRecenter->setObjectName(QString::fromUtf8("actionRecenter"));
|
||||
QIcon icon9;
|
||||
icon9.addFile(QString::fromUtf8(":/cgal/Input/zoom-best-fit"), QSize(), QIcon::Normal, QIcon::Off);
|
||||
actionRecenter->setIcon(icon9);
|
||||
actionShowConflictZone = new QAction(Periodic_4_hyperbolic_Delaunay_triangulation_2);
|
||||
actionShowConflictZone->setObjectName(QString::fromUtf8("actionShowConflictZone"));
|
||||
actionShowConflictZone->setCheckable(true);
|
||||
QIcon icon10;
|
||||
icon10.addFile(QString::fromUtf8(":/cgal/Actions/icons/conflict_zone.png"), QSize(), QIcon::Normal, QIcon::Off);
|
||||
actionShowConflictZone->setIcon(icon10);
|
||||
actionDo_translation_a = new QAction(Periodic_4_hyperbolic_Delaunay_triangulation_2);
|
||||
actionDo_translation_a->setObjectName(QString::fromUtf8("actionDo_translation_a"));
|
||||
actionDo_translation_a->setCheckable(true);
|
||||
QIcon icon11;
|
||||
icon11.addFile(QString::fromUtf8(":/cgal/Actions/icons/a.png"), QSize(), QIcon::Normal, QIcon::Off);
|
||||
actionDo_translation_a->setIcon(icon11);
|
||||
actionDo_translation_b = new QAction(Periodic_4_hyperbolic_Delaunay_triangulation_2);
|
||||
actionDo_translation_b->setObjectName(QString::fromUtf8("actionDo_translation_b"));
|
||||
actionDo_translation_b->setCheckable(true);
|
||||
QIcon icon12;
|
||||
icon12.addFile(QString::fromUtf8(":/cgal/Actions/icons/b.png"), QSize(), QIcon::Normal, QIcon::Off);
|
||||
actionDo_translation_b->setIcon(icon12);
|
||||
actionDo_translation_c = new QAction(Periodic_4_hyperbolic_Delaunay_triangulation_2);
|
||||
actionDo_translation_c->setObjectName(QString::fromUtf8("actionDo_translation_c"));
|
||||
actionDo_translation_c->setCheckable(true);
|
||||
QIcon icon13;
|
||||
icon13.addFile(QString::fromUtf8(":/cgal/Actions/icons/c.png"), QSize(), QIcon::Normal, QIcon::Off);
|
||||
actionDo_translation_c->setIcon(icon13);
|
||||
actionDo_translation_d = new QAction(Periodic_4_hyperbolic_Delaunay_triangulation_2);
|
||||
actionDo_translation_d->setObjectName(QString::fromUtf8("actionDo_translation_d"));
|
||||
actionDo_translation_d->setCheckable(true);
|
||||
QIcon icon14;
|
||||
icon14.addFile(QString::fromUtf8(":/cgal/Actions/icons/d.png"), QSize(), QIcon::Normal, QIcon::Off);
|
||||
actionDo_translation_d->setIcon(icon14);
|
||||
actionG = new QAction(Periodic_4_hyperbolic_Delaunay_triangulation_2);
|
||||
actionG->setObjectName(QString::fromUtf8("actionG"));
|
||||
actionG->setCheckable(true);
|
||||
QIcon icon15;
|
||||
icon15.addFile(QString::fromUtf8(":/cgal/Actions/icons/G.png"), QSize(), QIcon::Normal, QIcon::Off);
|
||||
actionG->setIcon(icon15);
|
||||
actionG2 = new QAction(Periodic_4_hyperbolic_Delaunay_triangulation_2);
|
||||
actionG2->setObjectName(QString::fromUtf8("actionG2"));
|
||||
actionG2->setCheckable(true);
|
||||
QIcon icon16;
|
||||
icon16.addFile(QString::fromUtf8(":/cgal/Actions/icons/G2.png"), QSize(), QIcon::Normal, QIcon::Off);
|
||||
actionG2->setIcon(icon16);
|
||||
actionG4 = new QAction(Periodic_4_hyperbolic_Delaunay_triangulation_2);
|
||||
actionG4->setObjectName(QString::fromUtf8("actionG4"));
|
||||
actionG4->setCheckable(true);
|
||||
QIcon icon17;
|
||||
icon17.addFile(QString::fromUtf8(":/cgal/Actions/icons/G4.png"), QSize(), QIcon::Normal, QIcon::Off);
|
||||
actionG4->setIcon(icon17);
|
||||
actionG8 = new QAction(Periodic_4_hyperbolic_Delaunay_triangulation_2);
|
||||
actionG8->setObjectName(QString::fromUtf8("actionG8"));
|
||||
actionG8->setCheckable(true);
|
||||
QIcon icon18;
|
||||
icon18.addFile(QString::fromUtf8(":/cgal/Actions/icons/G8.png"), QSize(), QIcon::Normal, QIcon::Off);
|
||||
actionG8->setIcon(icon18);
|
||||
actionG16 = new QAction(Periodic_4_hyperbolic_Delaunay_triangulation_2);
|
||||
actionG16->setObjectName(QString::fromUtf8("actionG16"));
|
||||
actionG16->setCheckable(true);
|
||||
QIcon icon19;
|
||||
icon19.addFile(QString::fromUtf8(":/cgal/Actions/icons/G16.png"), QSize(), QIcon::Normal, QIcon::Off);
|
||||
actionG16->setIcon(icon19);
|
||||
centralwidget = new QWidget(Periodic_4_hyperbolic_Delaunay_triangulation_2);
|
||||
centralwidget->setObjectName(QString::fromUtf8("centralwidget"));
|
||||
gridLayout = new QGridLayout(centralwidget);
|
||||
gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
|
||||
graphicsView = new QGraphicsView(centralwidget);
|
||||
graphicsView->setObjectName(QString::fromUtf8("graphicsView"));
|
||||
graphicsView->setFocusPolicy(Qt::StrongFocus);
|
||||
graphicsView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||||
graphicsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||||
graphicsView->setTransformationAnchor(QGraphicsView::NoAnchor);
|
||||
|
||||
gridLayout->addWidget(graphicsView, 0, 0, 1, 1);
|
||||
|
||||
Periodic_4_hyperbolic_Delaunay_triangulation_2->setCentralWidget(centralwidget);
|
||||
statusbar = new QStatusBar(Periodic_4_hyperbolic_Delaunay_triangulation_2);
|
||||
statusbar->setObjectName(QString::fromUtf8("statusbar"));
|
||||
Periodic_4_hyperbolic_Delaunay_triangulation_2->setStatusBar(statusbar);
|
||||
fileToolBar = new QToolBar(Periodic_4_hyperbolic_Delaunay_triangulation_2);
|
||||
fileToolBar->setObjectName(QString::fromUtf8("fileToolBar"));
|
||||
Periodic_4_hyperbolic_Delaunay_triangulation_2->addToolBar(Qt::TopToolBarArea, fileToolBar);
|
||||
toolBar = new QToolBar(Periodic_4_hyperbolic_Delaunay_triangulation_2);
|
||||
toolBar->setObjectName(QString::fromUtf8("toolBar"));
|
||||
Periodic_4_hyperbolic_Delaunay_triangulation_2->addToolBar(Qt::TopToolBarArea, toolBar);
|
||||
menubar = new QMenuBar(Periodic_4_hyperbolic_Delaunay_triangulation_2);
|
||||
menubar->setObjectName(QString::fromUtf8("menubar"));
|
||||
menubar->setGeometry(QRect(0, 0, 800, 22));
|
||||
menuFile = new QMenu(menubar);
|
||||
menuFile->setObjectName(QString::fromUtf8("menuFile"));
|
||||
menuEdit = new QMenu(menubar);
|
||||
menuEdit->setObjectName(QString::fromUtf8("menuEdit"));
|
||||
menuTools = new QMenu(menubar);
|
||||
menuTools->setObjectName(QString::fromUtf8("menuTools"));
|
||||
Periodic_4_hyperbolic_Delaunay_triangulation_2->setMenuBar(menubar);
|
||||
|
||||
fileToolBar->addAction(actionClear);
|
||||
fileToolBar->addAction(actionLoadPoints);
|
||||
fileToolBar->addAction(actionSavePoints);
|
||||
toolBar->addAction(actionInsertPoint);
|
||||
toolBar->addAction(actionDo_translation_a);
|
||||
toolBar->addAction(actionDo_translation_b);
|
||||
toolBar->addAction(actionDo_translation_c);
|
||||
toolBar->addAction(actionDo_translation_d);
|
||||
toolBar->addAction(actionMovingPoint);
|
||||
toolBar->addAction(actionCircumcenter);
|
||||
toolBar->addAction(actionShowConflictZone);
|
||||
toolBar->addSeparator();
|
||||
toolBar->addAction(actionShowDelaunay);
|
||||
toolBar->addAction(actionShowVoronoi);
|
||||
toolBar->addSeparator();
|
||||
toolBar->addAction(actionRecenter);
|
||||
menubar->addAction(menuFile->menuAction());
|
||||
menubar->addAction(menuEdit->menuAction());
|
||||
menubar->addAction(menuTools->menuAction());
|
||||
menuFile->addSeparator();
|
||||
menuFile->addAction(actionClear);
|
||||
menuFile->addAction(actionLoadPoints);
|
||||
menuFile->addAction(actionSavePoints);
|
||||
menuFile->addSeparator();
|
||||
menuFile->addAction(actionQuit);
|
||||
menuEdit->addAction(actionInsertRandomPoints);
|
||||
menuEdit->addAction(actionInsertPointOnFundamentalSide);
|
||||
menuEdit->addAction(actionInsertPointOnAxis);
|
||||
menuEdit->addAction(actionInsertOrigin);
|
||||
menuEdit->addAction(actionInsertDummyPoints);
|
||||
menuEdit->addAction(actionModifyDepth);
|
||||
menuTools->addAction(actionInsertPoint);
|
||||
menuTools->addAction(actionDo_translation_a);
|
||||
menuTools->addAction(actionDo_translation_b);
|
||||
menuTools->addAction(actionDo_translation_c);
|
||||
menuTools->addAction(actionDo_translation_d);
|
||||
menuTools->addAction(actionG);
|
||||
menuTools->addAction(actionG2);
|
||||
menuTools->addAction(actionG4);
|
||||
menuTools->addAction(actionG8);
|
||||
menuTools->addAction(actionG16);
|
||||
menuTools->addAction(actionMovingPoint);
|
||||
menuTools->addAction(actionCircumcenter);
|
||||
menuTools->addAction(actionShowConflictZone);
|
||||
menuTools->addSeparator();
|
||||
menuTools->addAction(actionShowDelaunay);
|
||||
menuTools->addAction(actionShowVoronoi);
|
||||
menuTools->addSeparator();
|
||||
menuTools->addAction(actionRecenter);
|
||||
|
||||
retranslateUi(Periodic_4_hyperbolic_Delaunay_triangulation_2);
|
||||
|
||||
QMetaObject::connectSlotsByName(Periodic_4_hyperbolic_Delaunay_triangulation_2);
|
||||
} // setupUi
|
||||
|
||||
void retranslateUi(QMainWindow *Periodic_4_hyperbolic_Delaunay_triangulation_2)
|
||||
{
|
||||
Periodic_4_hyperbolic_Delaunay_triangulation_2->setWindowTitle(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "CGAL Periodic hyperbolic Delaunay Triangulation", 0));
|
||||
actionAbout->setText(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "&About", 0));
|
||||
actionAboutCGAL->setText(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "About &CGAL", 0));
|
||||
actionQuit->setText(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "&Quit", 0));
|
||||
actionQuit->setShortcut(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "Ctrl+Q", 0));
|
||||
actionInsertRandomPoints->setText(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "&Insert random points", 0));
|
||||
actionInsertRandomPoints->setShortcut(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "Ctrl+I", 0));
|
||||
|
||||
actionInsertPointOnAxis->setText(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "Insert point on Y-axis", 0));
|
||||
actionInsertPointOnFundamentalSide->setText(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "Insert point on side of D_o", 0));
|
||||
|
||||
actionInsertOrigin->setText(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "Insert Origin", 0));
|
||||
actionInsertOrigin->setShortcut(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "Ctrl+Alt+O", 0));
|
||||
actionInsertDummyPoints->setText(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "Insert dummy points", 0));
|
||||
actionInsertDummyPoints->setShortcut(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "Ctrl+Alt+D", 0));
|
||||
actionModifyDepth->setText(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "&Modify recursion depth", 0));
|
||||
actionModifyDepth->setShortcut(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "Ctrl+M", 0));
|
||||
actionMovingPoint->setText(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "&Simulate insertion", 0));
|
||||
#ifndef QT_NO_TOOLTIP
|
||||
actionMovingPoint->setToolTip(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "Simulate Insertion", "The comment"));
|
||||
#endif // QT_NO_TOOLTIP
|
||||
#ifndef QT_NO_STATUSTIP
|
||||
actionMovingPoint->setStatusTip(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "Move mouse with left button pressed to see where point would be inserted", "and its comment"));
|
||||
#endif // QT_NO_STATUSTIP
|
||||
#ifndef QT_NO_WHATSTHIS
|
||||
actionMovingPoint->setWhatsThis(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "whats this", "what"));
|
||||
#endif // QT_NO_WHATSTHIS
|
||||
actionInsertPoint->setText(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "&Insert Point", 0));
|
||||
#ifndef QT_NO_TOOLTIP
|
||||
actionInsertPoint->setToolTip(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "Insert Point", 0));
|
||||
#endif // QT_NO_TOOLTIP
|
||||
#ifndef QT_NO_STATUSTIP
|
||||
actionInsertPoint->setStatusTip(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "Left: Insert vtx", 0));
|
||||
#endif // QT_NO_STATUSTIP
|
||||
actionClear->setText(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "&Clear", 0));
|
||||
actionClear->setShortcut(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "Ctrl+C", 0));
|
||||
actionShowVoronoi->setText(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "Show &Voronoi Diagram", 0));
|
||||
actionShowVoronoi->setShortcut(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "Ctrl+V", 0));
|
||||
actionShowDelaunay->setText(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "Show &Delaunay Triangulation", 0));
|
||||
actionShowDelaunay->setShortcut(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "Ctrl+D", 0));
|
||||
actionLoadPoints->setText(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "&Load Points...", 0));
|
||||
actionLoadPoints->setShortcut(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "Ctrl+L", 0));
|
||||
actionSavePoints->setText(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "&Save Points...", 0));
|
||||
actionSavePoints->setShortcut(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "Ctrl+S", 0));
|
||||
actionCircumcenter->setText(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "&Circumcenter", 0));
|
||||
#ifndef QT_NO_TOOLTIP
|
||||
actionCircumcenter->setToolTip(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "Draw circumcenter", 0));
|
||||
#endif // QT_NO_TOOLTIP
|
||||
actionRecenter->setText(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "Re¢er the viewport", 0));
|
||||
actionRecenter->setShortcut(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "Ctrl+R", 0));
|
||||
actionShowConflictZone->setText(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "Show Conflict Zone", 0));
|
||||
actionDo_translation_a->setText(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "Do translation \"a\"", 0));
|
||||
actionDo_translation_b->setText(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "Do translation \"b\"", 0));
|
||||
actionDo_translation_c->setText(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "Do translation \"c\"", 0));
|
||||
actionDo_translation_d->setText(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "Do translation \"d\"", 0));
|
||||
actionG->setText(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "G", 0));
|
||||
actionG2->setText(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "G2", 0));
|
||||
actionG4->setText(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "G4", 0));
|
||||
actionG8->setText(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "G8", 0));
|
||||
actionG16->setText(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "G16", 0));
|
||||
fileToolBar->setWindowTitle(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "File Tools", 0));
|
||||
toolBar->setWindowTitle(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "Visualization Tools", 0));
|
||||
menuFile->setTitle(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "&File", 0));
|
||||
menuEdit->setTitle(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "&Edit", 0));
|
||||
menuTools->setTitle(QApplication::translate("Periodic_4_hyperbolic_Delaunay_triangulation_2", "&Tools", 0));
|
||||
} // retranslateUi
|
||||
|
||||
};
|
||||
|
||||
namespace Ui {
|
||||
class Periodic_4_hyperbolic_Delaunay_triangulation_2: public Ui_Periodic_4_hyperbolic_Delaunay_triangulation_2 {};
|
||||
} // namespace Ui
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // UI_PERIODIC_4_HYPERBOLIC_DELAUNAY_TRIANGULATION_H
|
||||
|
|
@ -0,0 +1,650 @@
|
|||
|
||||
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
|
||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||
#include <CGAL/Periodic_4_hyperbolic_Delaunay_triangulation_2.h>
|
||||
#include <CGAL/Periodic_4_hyperbolic_Delaunay_triangulation_traits_2.h>
|
||||
#include <CGAL/Square_root_2_field.h>
|
||||
#include <CGAL/Hyperbolic_octagon_translation_matrix.h>
|
||||
//#include <CGAL/Periodic_4_hyperbolic_offset.h>
|
||||
//#include <CGAL/Periodic_4_hyperbolic_offset_holder.h>
|
||||
#include <CGAL/Aff_transformation_2.h>
|
||||
|
||||
#include <CGAL/Hyperbolic_word_4.h>
|
||||
|
||||
|
||||
typedef CGAL::Exact_predicates_exact_constructions_kernel R;
|
||||
typedef CGAL::Periodic_4_hyperbolic_Delaunay_triangulation_traits_2<R> K;
|
||||
typedef K::FT FT;
|
||||
typedef K::Point_2 Point;
|
||||
typedef K::Segment_2 Segment_2;
|
||||
typedef K::Arc_2 Arc_2;
|
||||
typedef K::Line_segment_2 Line_segment_2;
|
||||
typedef K::Circle_2 Circle;
|
||||
//typedef std::vector<int> Index_sequence;
|
||||
//typedef std::pair<Hyperbolic_octagon_translation_matrix, Index_sequence> Word;
|
||||
|
||||
typedef K::Construct_hyperbolic_bisector_2 Construct_hyperbolic_bisector_2;
|
||||
|
||||
using namespace std;
|
||||
|
||||
const string names[] = { "a",
|
||||
"\\bar{b}",
|
||||
"c",
|
||||
"\\bar{d}",
|
||||
"\\bar{a}",
|
||||
"b",
|
||||
"\\bar{c}",
|
||||
"d" };
|
||||
|
||||
void recurr(vector<Hyperbolic_octagon_translation_matrix>& v, vector<string>& w, vector<Hyperbolic_octagon_translation_matrix> g, int depth = 1) {
|
||||
if (depth > 1) {
|
||||
|
||||
recurr(v, w, g, depth-1);
|
||||
|
||||
vector<Hyperbolic_octagon_translation_matrix> tmp;
|
||||
vector<string> tmpw;
|
||||
for (int i = 0; i < v.size(); i++) {
|
||||
tmp.push_back(v[i]);
|
||||
tmpw.push_back(w[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < tmp.size(); i++) {
|
||||
for (int j = 0; j < g.size(); j++) {
|
||||
v.push_back(tmp[i]*g[j]);
|
||||
w.push_back(tmpw[i]+names[j]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < g.size(); i++) {
|
||||
v.push_back(g[i]);
|
||||
w.push_back(names[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
void recurr(vector<Index_sequence>& idx, int depth = 1) {
|
||||
if (depth > 1) {
|
||||
recurr(idx, depth - 1);
|
||||
|
||||
vector<Index_sequence> tmp;
|
||||
for (int i = 0; i < idx.size(); i++) {
|
||||
tmp.push_back(idx[i]);
|
||||
}
|
||||
for (int i = 0; i < tmp.size(); i++) {
|
||||
for (int j = 0; j < 8; j++) {
|
||||
Index_sequence tt = tmp[i];
|
||||
tt.push_back(j);
|
||||
idx.push_back(tt);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < 8; i++) {
|
||||
Index_sequence tmp;
|
||||
tmp.push_back(i);
|
||||
idx.push_back(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
void export_words_tex(vector<string> w, vector<Hyperbolic_octagon_translation_matrix> v, string filename) {
|
||||
|
||||
ofstream fcout;
|
||||
fcout.open(filename);
|
||||
|
||||
fcout << "\\documentclass{report}" << endl;
|
||||
fcout << endl;
|
||||
fcout << "\\usepackage{fullpage}" << endl;
|
||||
fcout << "\\usepackage{a4wide}" << endl;
|
||||
fcout << "\\usepackage{longtable}" << endl;
|
||||
fcout << endl;
|
||||
fcout << "\\setlength{\\parindent}{0cm}" << endl;
|
||||
fcout << endl;
|
||||
fcout << "\\begin{document}" << endl;
|
||||
fcout << endl;
|
||||
fcout << "\\begin{center}" << endl;
|
||||
fcout << " \\begin{longtable}{l|l|l|l}" << endl;
|
||||
for (int i = 0; i < w.size()-1; i++) {
|
||||
fcout << " " << i << " & $" << w[i] << "$ & " << v[i].length() << " & " << v[i] << " \\\\" << endl;
|
||||
}
|
||||
int i = w.size()-1;
|
||||
fcout << " " << i << " & " << w[i] << " & " << v[i].length() << " & " << v[i] << endl;
|
||||
fcout << " \\end{longtable}" << endl;
|
||||
fcout << "\\end{center}" << endl;
|
||||
fcout << endl;
|
||||
fcout << "\\end{document}" << endl;
|
||||
|
||||
fcout.close();
|
||||
}
|
||||
|
||||
|
||||
void export_words_tex(map<Hyperbolic_octagon_translation_matrix,string> m, string filename) {
|
||||
|
||||
ofstream fcout;
|
||||
fcout.open(filename);
|
||||
|
||||
fcout << "\\documentclass{report}" << endl;
|
||||
fcout << endl;
|
||||
fcout << "\\usepackage{fullpage}" << endl;
|
||||
fcout << "\\usepackage{a4wide}" << endl;
|
||||
fcout << "\\usepackage{longtable}" << endl;
|
||||
fcout << endl;
|
||||
fcout << "\\setlength{\\parindent}{0cm}" << endl;
|
||||
fcout << endl;
|
||||
fcout << "\\begin{document}" << endl;
|
||||
fcout << endl;
|
||||
fcout << "\\begin{center}" << endl;
|
||||
fcout << " \\begin{longtable}{l|l|l|l}" << endl;
|
||||
|
||||
int i = 0;
|
||||
for (std::map<Hyperbolic_octagon_translation_matrix, string>::iterator it = m.begin(); it != m.end(); it++) {
|
||||
fcout << " " << i++ << " & $" << it->second << "$ & " << it->first.length() << " & " << it->first << " \\\\" << endl;
|
||||
}
|
||||
|
||||
fcout << " \\end{longtable}" << endl;
|
||||
fcout << "\\end{center}" << endl;
|
||||
fcout << endl;
|
||||
fcout << "\\end{document}" << endl;
|
||||
|
||||
fcout.close();
|
||||
}
|
||||
|
||||
void export_words_tex(map<string,Hyperbolic_octagon_translation_matrix> m, string filename) {
|
||||
|
||||
ofstream fcout;
|
||||
fcout.open(filename);
|
||||
|
||||
fcout << "\\documentclass{report}" << endl;
|
||||
fcout << endl;
|
||||
fcout << "\\usepackage{fullpage}" << endl;
|
||||
fcout << "\\usepackage{a4wide}" << endl;
|
||||
fcout << "\\usepackage{longtable}" << endl;
|
||||
fcout << endl;
|
||||
fcout << "\\setlength{\\parindent}{0cm}" << endl;
|
||||
fcout << endl;
|
||||
fcout << "\\begin{document}" << endl;
|
||||
fcout << endl;
|
||||
fcout << "\\begin{center}" << endl;
|
||||
fcout << " \\begin{longtable}{l|l|l|l}" << endl;
|
||||
|
||||
int i = 0;
|
||||
for (std::map<string, Hyperbolic_octagon_translation_matrix>::iterator it = m.begin(); it != m.end(); it++) {
|
||||
fcout << " " << i++ << " & $" << it->first << "$ & " << it->second.length() << " & " << it->second << " \\\\" << endl;
|
||||
}
|
||||
|
||||
fcout << " \\end{longtable}" << endl;
|
||||
fcout << "\\end{center}" << endl;
|
||||
fcout << endl;
|
||||
fcout << "\\end{document}" << endl;
|
||||
|
||||
fcout.close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
double edist2(double x, double y) {
|
||||
return (x*x + y*y);
|
||||
}
|
||||
|
||||
double norm2(pair<double, double> p) {
|
||||
return sqrt(edist2(p.first, p.second));
|
||||
}
|
||||
|
||||
double dot(pair<double, double> p1, pair<double, double> p2) {
|
||||
return (p1.first*p2.first + p1.second*p2.second);
|
||||
}
|
||||
|
||||
double angle(pair<double, double> p1, pair<double, double> p2) {
|
||||
return acos( dot(p1, p2) / norm2(p1) / norm2(p2) );
|
||||
}
|
||||
|
||||
|
||||
double hdistorigin(pair<double, double> p) {
|
||||
double r = norm2(p);
|
||||
return 2*atanh(r);
|
||||
}
|
||||
|
||||
double hdisthcos(pair<double, double> p1, pair<double, double> p2) {
|
||||
double hd1 = hdistorigin(p1);
|
||||
double hd2 = hdistorigin(p2);
|
||||
double theta = angle(p1, p2);
|
||||
|
||||
return acosh( cosh(hd1)*cosh(hd2) - sinh(hd1)*sinh(hd2)*cos(theta) );
|
||||
}
|
||||
|
||||
|
||||
Hyperbolic_octagon_translation_matrix offset_word_4(int index, vector<Hyperbolic_octagon_translation_matrix> gens) {
|
||||
Hyperbolic_octagon_translation_matrix r;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
r = r * gens[index];
|
||||
index = (index + 5) % 8;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
|
||||
vector<Hyperbolic_octagon_translation_matrix> g;
|
||||
get_generators(g);
|
||||
|
||||
Point v0 (sqrt(sqrt(2.) + 1.) / 2. , -sqrt(sqrt(2.) - 1.) / 2.); // v_0
|
||||
Point s1 (sqrt(sqrt(2.) - 1.) / 2. , sqrt(sqrt(2.) - 1.) / 2.); // μ(s_1)
|
||||
|
||||
Point av0 = g[DIRECTION_A_BAR].apply(v0);
|
||||
Point as1 = g[DIRECTION_A_BAR].apply(s1);
|
||||
Point mp (0.5*av0.x() + 0.5*as1.x(), 0.5*av0.y() + 0.5*as1.y());
|
||||
|
||||
cout << mp << endl;
|
||||
|
||||
|
||||
/*
|
||||
for (int i = 0; i < 8; i++) {
|
||||
Hyperbolic_octagon_translation_matrix m = offset_word_4(i, g);
|
||||
Point p = m.apply(Point(0,0));
|
||||
//cout << "With offset " << i << ": " << p << endl;
|
||||
cout << p.x() << ", " << p.y() << ";" << endl;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
std::vector<Point> pts;
|
||||
|
||||
pts.push_back(Point(FT( 0.776887), FT( -0.321797))); // 23
|
||||
pts.push_back(Point(FT( 0.643594), FT( 0.000000))); // 22
|
||||
pts.push_back(Point(FT( 0.455090), FT( 0.455090))); // 21
|
||||
pts.push_back(Point(FT( 0.000000), FT( 0.643594))); // 13
|
||||
pts.push_back(Point(FT( -0.455090), FT( 0.455090))); // 4
|
||||
pts.push_back(Point(FT( -0.374741), FT( 0.155223))); // 6
|
||||
pts.push_back(Point(FT( -0.374741), FT( -0.155223))); // 5
|
||||
pts.push_back(Point(FT( -0.155223), FT( -0.374741))); // 9
|
||||
pts.push_back(Point(FT( 0.155223), FT( -0.374741))); // 14
|
||||
pts.push_back(Point(FT( 0.374741), FT( -0.155223))); // 18
|
||||
pts.push_back(Point(FT( 0.374741), FT( 0.155223))); // 19
|
||||
pts.push_back(Point(FT( 0.155223), FT( 0.374741))); // 15
|
||||
pts.push_back(Point(FT( -0.155223), FT( 0.374741))); // 10
|
||||
pts.push_back(Point(FT( 0.000000), FT( 0.000000))); // 12
|
||||
|
||||
for (int i = 0; i < pts.size(); i++) {
|
||||
cout << pts[i] << endl;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
pts.push_back(Point(FT( -0.776887), FT( -0.321797))); // 0
|
||||
pts.push_back(Point(FT( -0.776887), FT( 0.321797))); // 1
|
||||
pts.push_back(Point(FT( -0.643594), FT( 0.000000))); // 2
|
||||
pts.push_back(Point(FT( -0.455090), FT( -0.455090))); // 3
|
||||
pts.push_back(Point(FT( -0.321797), FT( -0.776887))); // 7
|
||||
pts.push_back(Point(FT( -0.321797), FT( 0.776887))); // 8
|
||||
pts.push_back(Point(FT( 0.000000), FT( -0.643594))); // 11
|
||||
pts.push_back(Point(FT( 0.321797), FT( -0.776887))); // 16
|
||||
pts.push_back(Point(FT( 0.321797), FT( 0.776887))); // 17
|
||||
pts.push_back(Point(FT( 0.455090), FT( -0.455090))); // 20
|
||||
pts.push_back(Point(FT( 0.776887), FT( 0.321797))); // 24
|
||||
*/
|
||||
|
||||
/*
|
||||
cout << "Point[" << 23 << "] = " << pts[23] << ", image = " << (g[DIRECTION_A_BAR]).apply(pts[23]) << endl;
|
||||
cout << "Point[" << 23 << "] = " << pts[23] << ", image = " << (g[DIRECTION_B_BAR]*g[DIRECTION_A_BAR]).apply(pts[23]) << endl;
|
||||
cout << "Point[" << 23 << "] = " << pts[23] << ", image = " << (g[DIRECTION_C_BAR]*g[DIRECTION_B_BAR]*g[DIRECTION_A_BAR]).apply(pts[23]) << endl;
|
||||
cout << "Point[" << 23 << "] = " << pts[23] << ", image = " << (g[DIRECTION_D_BAR]*g[DIRECTION_C_BAR]*g[DIRECTION_B_BAR]*g[DIRECTION_A_BAR]).apply(pts[23]) << endl;
|
||||
cout << "Point[" << 23 << "] = " << pts[23] << ", image = " << (g[DIRECTION_B_BAR]*g[DIRECTION_C_BAR]*g[DIRECTION_D_BAR]).apply(pts[23]) << endl;
|
||||
cout << "Point[" << 23 << "] = " << pts[23] << ", image = " << (g[DIRECTION_C_BAR]*g[DIRECTION_D_BAR]).apply(pts[23]) << endl;
|
||||
cout << "Point[" << 23 << "] = " << pts[23] << ", image = " << (g[DIRECTION_D_BAR]).apply(pts[23]) << endl;
|
||||
*/
|
||||
|
||||
//pair<double, double> O(0,0);
|
||||
|
||||
/*
|
||||
pair<double, double> O(-0.3218, 0.7769);
|
||||
|
||||
Hyperbolic_octagon_translation_matrix t = g[DIRECTION_A];
|
||||
|
||||
pair<double, double> image = t.apply(O.first, O.second);
|
||||
cout << "$" << t.label << "$ & " << t.length() << " & " << hdistorigin(image) << " & " << hdisthcos(O, image) << "\\\\" << endl;
|
||||
t = t*g[DIRECTION_B];
|
||||
image = t.apply(O.first, O.second);
|
||||
cout << "$" << t.label << "$ & " << t.length() << " & " << hdistorigin(image) << " & " << hdisthcos(O, image) << "\\\\" << endl;
|
||||
t = t*g[DIRECTION_C];
|
||||
image = t.apply(O.first, O.second);
|
||||
cout << "$" << t.label << "$ & " << t.length() << " & " << hdistorigin(image) << " & " << hdisthcos(O, image) << "\\\\" << endl;
|
||||
t = t*g[DIRECTION_D];
|
||||
image = t.apply(O.first, O.second);
|
||||
cout << "$" << t.label << "$ & " << t.length() << " & " << hdistorigin(image) << " & " << hdisthcos(O, image) << "\\\\" << endl;
|
||||
t = t*g[DIRECTION_A_BAR];
|
||||
image = t.apply(O.first, O.second);
|
||||
cout << "$" << t.label << "$ & " << t.length() << " & " << hdistorigin(image) << " & " << hdisthcos(O, image) << "\\\\" << endl;
|
||||
t = t*g[DIRECTION_B_BAR];
|
||||
image = t.apply(O.first, O.second);
|
||||
cout << "$" << t.label << "$ & " << t.length() << " & " << hdistorigin(image) << " & " << hdisthcos(O, image) << "\\\\" << endl;
|
||||
t = t*g[DIRECTION_C_BAR];
|
||||
image = t.apply(O.first, O.second);
|
||||
cout << "$" << t.label << "$ & " << t.length() << " & " << hdistorigin(image) << " & " << hdisthcos(O, image) << "\\\\" << endl;
|
||||
t = t*g[DIRECTION_D_BAR];
|
||||
image = t.apply(O.first, O.second);
|
||||
cout << "$" << t.label << "$ & " << t.length() << " & " << hdistorigin(image) << " & " << hdisthcos(O, image) << "\\\\" << endl;
|
||||
*/
|
||||
|
||||
/*
|
||||
typedef unsigned short int Int;
|
||||
std::vector<Int> v;
|
||||
v.push_back(3);
|
||||
v.push_back(6);
|
||||
v.push_back(1);
|
||||
|
||||
Word seq(v);
|
||||
|
||||
seq.append(4);
|
||||
|
||||
cout << seq << endl;
|
||||
|
||||
std::string str = seq.get_string();
|
||||
cout << str << endl;
|
||||
|
||||
cout << "size() = " << seq.size() << endl;
|
||||
cout << "is_identity() = " << (seq.is_identity() ? "true" : "false") << endl;
|
||||
|
||||
Word w;
|
||||
Dehn_reduce_word(w, seq);
|
||||
cout << "Reduced word: " << w << endl;*/
|
||||
|
||||
/*
|
||||
vector<Hyperbolic_octagon_translation_matrix> gens;
|
||||
get_generators(gens);
|
||||
|
||||
Point O(0,0);
|
||||
Point aO = gens[0].apply(O);
|
||||
Point ovbO = gens[1].apply(O);
|
||||
|
||||
cout << "Origin: " << O << endl;
|
||||
cout << "Image by a: " << aO << endl;
|
||||
cout << "Image by \\bar{b}: " << ovbO << endl;
|
||||
|
||||
Circle Poincare( Point(0, 0), 1*1 );
|
||||
|
||||
|
||||
Point CenterA ( FT( sqrt((sqrt(2.) + 1.) / 2.) ), FT(0.) );
|
||||
FT Radius2 ( (sqrt(2.) - 1.) / 2. );
|
||||
|
||||
CGAL::Aff_transformation_2<K> rotate(CGAL::ROTATION, std::sqrt(0.5), std::sqrt(0.5));
|
||||
|
||||
Circle DomainA ( CenterA, Radius2 );
|
||||
Circle DomainBb( rotate(CenterA), Radius2 );
|
||||
|
||||
|
||||
Point p(FT(atof(argv[1])), FT(atof(argv[2])));
|
||||
FT x(abs(p.x()));
|
||||
FT y(abs(p.y()));
|
||||
|
||||
if (y > x) {
|
||||
FT tmp = x;
|
||||
x = y;
|
||||
y = tmp;
|
||||
}
|
||||
|
||||
Point t(x, y);
|
||||
|
||||
CGAL::Bounded_side bs1 = Poincare.bounded_side(t);
|
||||
CGAL::Bounded_side bs2 = DomainA.bounded_side(t);
|
||||
CGAL::Bounded_side bs3 = DomainBb.bounded_side(t);
|
||||
|
||||
bool inside = true;
|
||||
inside = inside && (bs1 == CGAL::ON_BOUNDED_SIDE);
|
||||
inside = inside && (bs2 == CGAL::ON_UNBOUNDED_SIDE);
|
||||
inside = inside && (bs3 == CGAL::ON_UNBOUNDED_SIDE);
|
||||
|
||||
cout << "Point " << p << " is " << (inside ? "" : "NOT ") << "inside the fundamental domain!" << endl;
|
||||
|
||||
*/
|
||||
//cout << "Segment is here! Getting Arc..." << endl;
|
||||
|
||||
//if (Arc_2* arc = boost::get<Arc_2>(&seg)) {
|
||||
// cout << "Yey!" << endl;
|
||||
//}
|
||||
|
||||
//Arc_2 arc = boost::get<Arc_2>(seg);
|
||||
|
||||
//cout << "We got the Arc!" << endl;
|
||||
|
||||
|
||||
//K::Side_of_oriented_circle_2 soc = K::Side_of_oriented_circle_2();
|
||||
//soc(seg, O);
|
||||
|
||||
/*
|
||||
vector<Hyperbolic_octagon_translation_matrix> g;
|
||||
get_generators(g);
|
||||
|
||||
pair<double, double> p(0.23, -0.31);
|
||||
vector< pair<double, double> > img;
|
||||
vector<double> dist;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
img.push_back( g[i].apply(p.first, p.second) );
|
||||
dist.push_back( hdist(p, img[i]) );
|
||||
|
||||
cout << "dist[" << i << "] = " << dist[i] << endl;
|
||||
|
||||
}
|
||||
|
||||
cout << endl;
|
||||
|
||||
vector< pair<double, double> > img2;
|
||||
vector<double> dist2;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
img2.push_back( g[0].apply(img[i].first, img[i].second) );
|
||||
dist2.push_back( hdist(img[i], img2[i]) );
|
||||
|
||||
cout << "dist2[" << i << "] = " << dist2[i] << endl;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
vector<Index_sequence> cmb;
|
||||
recurr(cmb, atoi(argv[1]));
|
||||
|
||||
vector<Hyperbolic_octagon_translation_matrix> trans;
|
||||
|
||||
CGAL::Periodic_4_hyperbolic_offset_holder oh;
|
||||
|
||||
cout << "Translating..." << endl;
|
||||
oh.Translate(trans, cmb);
|
||||
cout << "Done!" << endl;
|
||||
|
||||
cout << "Working with Offset holder..." << endl;
|
||||
oh.Insert(cmb);
|
||||
cout << "Done!" << endl;
|
||||
|
||||
vector<Hyperbolic_octagon_translation_matrix> tw;
|
||||
vector<Index_sequence> tiw;
|
||||
oh.Get_unique_words(tiw, tw);
|
||||
|
||||
set<Hyperbolic_octagon_translation_matrix> sidx;
|
||||
for (int i = 0; i < trans.size(); i++) {
|
||||
sidx.insert(trans[i]);
|
||||
}
|
||||
|
||||
cout << endl;
|
||||
cout << "Count of all words: " << cmb.size() << endl;
|
||||
cout << "Count of Dehn subs: " << oh.size() << endl;
|
||||
cout << "Size reduction: " << (1.0 - (double)oh.size()/(double)cmb.size())*100.0 << "%" << endl;
|
||||
cout << endl;
|
||||
cout << "Count of all translations: " << trans.size() << endl;
|
||||
cout << "Count of set translations: " << sidx.size() << endl;
|
||||
cout << "Size reduction: " << (1.0 - (double)sidx.size()/(double)trans.size())*100.0 << "%" << endl;
|
||||
|
||||
|
||||
cout << endl << "Duplicates" << endl << "-------------------------" << endl;
|
||||
for (int i = 0; i < tw.size() - 1; i++) {
|
||||
for (int j = i+1; j < tw.size(); j++) {
|
||||
if (tw[i] == tw[j]) {
|
||||
cout << "word[" << i << "] = " << tiw[i] << " and word[" << j << "] " << tiw[j] << ", matrix is " << tw[i] << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
//vector<Hyperbolic_octagon_translation_matrix> g;
|
||||
//get_generators(g);
|
||||
|
||||
/*
|
||||
|
||||
Hyperbolic_octagon_translation_matrix id = (g[DIRECTION_A]*g[DIRECTION_B]*g[DIRECTION_C]*g[DIRECTION_D])*(g[DIRECTION_A_BAR]*g[DIRECTION_B_BAR]*g[DIRECTION_C_BAR]*g[DIRECTION_D_BAR]);
|
||||
cout << "Identity: " << id << endl;
|
||||
cout << "Label: " << id.label << endl;
|
||||
|
||||
|
||||
vector< pair<double, double> > img;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
img.push_back( g[i].apply(0,0) );
|
||||
cout << "img[" << i << "] = " << img[i].first << ", " << img[i].second << endl;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
Hyperbolic_octagon_translation_matrix t = ( g[6]*g[1]*g[4] );
|
||||
cout << t << endl;
|
||||
Hyperbolic_octagon_translation_matrix s = ( g[7]*g[4]*g[1]*g[6]*g[3] );
|
||||
cout << s << endl;
|
||||
*/
|
||||
|
||||
/*
|
||||
Hyperbolic_octagon_translation_matrix t = (g[6]*g[1]*g[4]*g[7]*g[0]*g[3]);
|
||||
cout << t << endl;
|
||||
Hyperbolic_octagon_translation_matrix s = (g[0]*g[5]*g[2]*g[7]*g[4]*g[1]*g[6]*g[3]*g[6]*g[1]*g[4]*g[7]*g[1]*g[5]*g[0]*g[3]);
|
||||
cout << s << endl;
|
||||
*/
|
||||
|
||||
/*
|
||||
idx.push_back(DIRECTION_B);
|
||||
idx.push_back(DIRECTION_C);
|
||||
idx.push_back(DIRECTION_D);
|
||||
idx.push_back(DIRECTION_A_BAR);
|
||||
idx.push_back(DIRECTION_B_BAR);
|
||||
idx.push_back(DIRECTION_C_BAR);
|
||||
idx.push_back(DIRECTION_D_BAR);
|
||||
idx.push_back(DIRECTION_A);
|
||||
idx.push_back(DIRECTION_C_BAR);
|
||||
idx.push_back(DIRECTION_A_BAR);
|
||||
idx.push_back(DIRECTION_D);
|
||||
idx.push_back(DIRECTION_C);
|
||||
idx.push_back(DIRECTION_B);
|
||||
idx.push_back(DIRECTION_A);
|
||||
idx.push_back(DIRECTION_D_BAR);
|
||||
idx.push_back(DIRECTION_B_BAR);
|
||||
*/
|
||||
|
||||
/* vector<Hyperbolic_octagon_translation_matrix> vi; */
|
||||
|
||||
/*
|
||||
std::vector<int> idx;
|
||||
|
||||
|
||||
idx.push_back(DIRECTION_A);
|
||||
idx.push_back(DIRECTION_B);
|
||||
idx.push_back(DIRECTION_C);
|
||||
idx.push_back(DIRECTION_D);
|
||||
idx.push_back(DIRECTION_A_BAR);
|
||||
idx.push_back(DIRECTION_B_BAR);
|
||||
idx.push_back(DIRECTION_C_BAR);
|
||||
idx.push_back(DIRECTION_D_BAR);
|
||||
idx.push_back(DIRECTION_C_BAR);
|
||||
idx.push_back(DIRECTION_B_BAR);
|
||||
idx.push_back(DIRECTION_A_BAR);
|
||||
idx.push_back(DIRECTION_D);
|
||||
idx.push_back(DIRECTION_B_BAR);
|
||||
idx.push_back(DIRECTION_B);
|
||||
idx.push_back(DIRECTION_A);
|
||||
idx.push_back(DIRECTION_D_BAR);
|
||||
|
||||
|
||||
|
||||
|
||||
idx.push_back(DIRECTION_B);
|
||||
idx.push_back(DIRECTION_C);
|
||||
idx.push_back(DIRECTION_D);
|
||||
idx.push_back(DIRECTION_A_BAR);
|
||||
idx.push_back(DIRECTION_B_BAR);
|
||||
idx.push_back(DIRECTION_C_BAR);
|
||||
idx.push_back(DIRECTION_D_BAR);
|
||||
idx.push_back(DIRECTION_A);
|
||||
idx.push_back(DIRECTION_C_BAR);
|
||||
idx.push_back(DIRECTION_A_BAR);
|
||||
idx.push_back(DIRECTION_D);
|
||||
idx.push_back(DIRECTION_C);
|
||||
idx.push_back(DIRECTION_B);
|
||||
idx.push_back(DIRECTION_A);
|
||||
idx.push_back(DIRECTION_D_BAR);
|
||||
idx.push_back(DIRECTION_B_BAR);
|
||||
|
||||
|
||||
|
||||
|
||||
std::vector<int> dw;
|
||||
Dehn_reduce_word(dw, idx);
|
||||
|
||||
CGAL::Periodic_4_hyperbolic_offset io(idx);
|
||||
CGAL::Periodic_4_hyperbolic_offset fo(dw);
|
||||
|
||||
Word iw, fw;
|
||||
|
||||
io.Get_word(iw);
|
||||
fo.Get_word(fw);
|
||||
|
||||
cout << "Initial sequence: ";
|
||||
for (int i = 0; i < idx.size(); i++) {
|
||||
cout << idx[i] << " ";
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
cout << "Final sequence: ";
|
||||
for (int i = 0; i < dw.size(); i++) {
|
||||
cout << dw[i] << " ";
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
cout << "Initial word: " << iw << endl;
|
||||
cout << "Final word: " << fw << endl;
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
cout << endl << "Initial word: ";
|
||||
Hyperbolic_octagon_translation_matrix t = vi[0].first;
|
||||
cout << vi[0].second << ", ";
|
||||
for (int i = 1; i < vi.size(); i++) {
|
||||
cout << vi[i].second << ", ";
|
||||
t = t * vi[i].first;
|
||||
}
|
||||
cout << endl << "Equivalent matrix: " << t << endl << endl;
|
||||
|
||||
vector<Hyperbolic_octagon_translation_matrix> di;
|
||||
Apply_Dehn(di, vi);
|
||||
cout << "Dehn's word: ";
|
||||
Hyperbolic_octagon_translation_matrix s = di[0].first;
|
||||
cout << di[0].second << ", ";
|
||||
for (int i = 1; i < di.size(); i++) {
|
||||
cout << di[i].second << ", ";
|
||||
s = s * di[i].first;
|
||||
}
|
||||
cout << endl << "Equivalent matrix: " << s << endl << endl;
|
||||
|
||||
cout << "Equivalence achieved: " << (t == s ? "YES" : "NO") << endl;
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
This directory currently contains test programs and _not_ a real demo.
|
||||
The file playground.cpp is used to execute various tests and verifications and changes constantly.
|
||||
The file triangulation.cpp is a small driver to verify modifications on the hyperbolic (Delaunay) triangulation.
|
||||
Over time the layout of the directory will change and a real demo will be build. For archiving purposes, the demo that previously existed here has been moved to the subfolder 'backup'.
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
|
||||
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <boost/random/linear_congruential.hpp>
|
||||
#include <boost/random/uniform_smallint.hpp>
|
||||
#include <boost/random/variate_generator.hpp>
|
||||
|
||||
#include <CGAL/Periodic_4_hyperbolic_triangulation_2.h>
|
||||
#include <CGAL/Periodic_4_hyperbolic_Delaunay_triangulation_2.h>
|
||||
#include <CGAL/Periodic_4_hyperbolic_Delaunay_triangulation_traits_2.h>
|
||||
#include <CGAL/Periodic_4_hyperbolic_triangulation_dummy_14.h>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/CORE_Expr.h>
|
||||
#include <CGAL/Cartesian.h>
|
||||
#include <CGAL/determinant.h>
|
||||
|
||||
|
||||
typedef CORE::Expr NT;
|
||||
typedef CGAL::Cartesian<NT> Kernel;
|
||||
typedef CGAL::Periodic_4_hyperbolic_Delaunay_triangulation_traits_2<Kernel> Traits;
|
||||
typedef CGAL::Periodic_4_hyperbolic_Delaunay_triangulation_2<Traits> Triangulation;
|
||||
|
||||
typedef Triangulation::Point_2 Point_2;
|
||||
typedef Triangulation::Face_handle Face_handle;
|
||||
typedef Triangulation::Vertex_handle Vertex_handle;
|
||||
typedef Triangulation::Locate_type Locate_type;
|
||||
typedef Traits::FT FT;
|
||||
typedef std::set<Face_handle>::iterator face_iterator;
|
||||
|
||||
|
||||
int main(void) {
|
||||
|
||||
Triangulation tr;
|
||||
tr.insert_dummy_points();
|
||||
std::cout << "Dummy points are locked and loaded!" << std::endl;
|
||||
Locate_type lt;
|
||||
int li;
|
||||
|
||||
// This is the barycenter of face 10
|
||||
Point_2 query = Point_2(FT(-0.59841), FT(-0.15901));
|
||||
Face_handle fh = tr.locate( query, lt, li );
|
||||
cout << "Point " << query << " is located in face " << fh->get_number();
|
||||
cout << (lt == Locate_type::EDGE ? " [EDGE]" : (lt == Locate_type::VERTEX ? " [VERTEX]" : " [FACE]")) << endl;
|
||||
|
||||
std::set<Face_handle> faces_in_conflict;
|
||||
tr.find_in_conflict(query, fh, faces_in_conflict);
|
||||
for (face_iterator it = faces_in_conflict.begin(); it != faces_in_conflict.end(); it++) {
|
||||
cout << "Face in conflict: " << (*it)->get_number() << endl;
|
||||
}
|
||||
|
||||
cout << endl;
|
||||
faces_in_conflict.clear();
|
||||
|
||||
// This is the midpoint of edge (0, 1) in face 11
|
||||
Point_2 query2(FT(-0.61599), FT(-0.38844));
|
||||
fh = tr.locate( query2, lt, li );
|
||||
cout << "Point " << query2 << " is located in face " << fh->get_number();
|
||||
cout << (lt == Locate_type::EDGE ? " [EDGE]" : (lt == Locate_type::VERTEX ? " [VERTEX]" : " [FACE]")) << endl;
|
||||
tr.find_in_conflict(query2, fh, faces_in_conflict);
|
||||
cout << "Faces in conflict: ";
|
||||
for (face_iterator it = faces_in_conflict.begin(); it != faces_in_conflict.end(); it++) {
|
||||
cout << (*it)->get_number() << ", ";
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
cout << endl;
|
||||
faces_in_conflict.clear();
|
||||
|
||||
// This is vertex(0) of face 11
|
||||
Point_2 query3(FT(-0.776887), FT(-0.321797));
|
||||
fh = tr.locate( query3, lt, li );
|
||||
cout << "Point " << query3 << " is located in face " << fh->get_number();
|
||||
cout << (lt == Locate_type::EDGE ? " [EDGE]" : (lt == Locate_type::VERTEX ? " [VERTEX]" : " [FACE]")) << endl;
|
||||
tr.find_in_conflict(query3, fh, faces_in_conflict);
|
||||
cout << "Faces in conflict: ";
|
||||
for (face_iterator it = faces_in_conflict.begin(); it != faces_in_conflict.end(); it++) {
|
||||
cout << (*it)->get_number() << ", ";
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
cout << endl;
|
||||
faces_in_conflict.clear();
|
||||
|
||||
// This is the origin (duh)
|
||||
Point_2 query4(FT(0), FT(0));
|
||||
fh = tr.locate( query4, lt, li );
|
||||
cout << "Point " << query4 << " is located in face " << fh->get_number();
|
||||
cout << (lt == Locate_type::EDGE ? " [EDGE]" : (lt == Locate_type::VERTEX ? " [VERTEX]" : " [FACE]")) << endl;
|
||||
tr.find_in_conflict(query4, fh, faces_in_conflict);
|
||||
cout << "Faces in conflict: ";
|
||||
for (face_iterator it = faces_in_conflict.begin(); it != faces_in_conflict.end(); it++) {
|
||||
cout << (*it)->get_number() << ", ";
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
cout << endl << "Triangulation is valid: " << (tr.is_valid() ? "TRUE" : "FALSE") << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -17,9 +17,6 @@
|
|||
#ifndef CGAL_HYPERBOLIC_OCTAGON_TRANSLATION_MATRIX_H
|
||||
#define CGAL_HYPERBOLIC_OCTAGON_TRANSLATION_MATRIX_H
|
||||
|
||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||
#include <CGAL/Periodic_4_hyperbolic_Delaunay_triangulation_traits_2.h>
|
||||
|
||||
#include <complex>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
|
@ -30,10 +27,20 @@
|
|||
#include <string>
|
||||
#include <fstream>
|
||||
|
||||
typedef CGAL::Exact_predicates_exact_constructions_kernel R;
|
||||
typedef CGAL::Periodic_4_hyperbolic_Delaunay_triangulation_traits_2<R> K;
|
||||
typedef K::FT FT;
|
||||
typedef K::Point_2 Point;
|
||||
#include <CGAL/Square_root_2_field.h>
|
||||
#include <CGAL/number_utils.h>
|
||||
|
||||
typedef unsigned short int Word_idx_type;
|
||||
|
||||
|
||||
template <class Word_idx_type>
|
||||
std::ostream& operator<<(std::ostream& s, const std::vector<Word_idx_type>& o) {
|
||||
for (int i = 0; i < o.size(); i++) {
|
||||
s << o[i];
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
template<class Square_root_2_field>
|
||||
class Hyperbolic_octagon_translation_matrix_base
|
||||
|
|
@ -43,20 +50,20 @@ public:
|
|||
static Square_root_2_field factor; // The multiplicative factor present in the general formula: sqrt(2) - 1
|
||||
|
||||
typedef Hyperbolic_octagon_translation_matrix_base<Square_root_2_field> Self;
|
||||
typedef complex<Square_root_2_field> Matrix_element;
|
||||
typedef std::complex<Square_root_2_field> Matrix_element;
|
||||
|
||||
Matrix_element A;
|
||||
Matrix_element B;
|
||||
string label;
|
||||
std::string label;
|
||||
|
||||
Hyperbolic_octagon_translation_matrix_base(const Matrix_element& A_, const Matrix_element& B_,
|
||||
const string& label_ = string("") ) :
|
||||
const std::string& label_ = std::string("") ) :
|
||||
A( A_ ), B( B_ ), label( label_ ) {}
|
||||
|
||||
Hyperbolic_octagon_translation_matrix_base() :
|
||||
A( Matrix_element(1,0) ), B( Matrix_element(0,0) ), label( string("") ) {}
|
||||
A( Matrix_element(1,0) ), B( Matrix_element(0,0) ), label( std::string("") ) {}
|
||||
|
||||
string merge_labels(const Self& rh) const
|
||||
std::string merge_labels(const Self& rh) const
|
||||
{
|
||||
return label + "*" + rh.label;
|
||||
}
|
||||
|
|
@ -70,7 +77,7 @@ public:
|
|||
Self inverse() const
|
||||
{
|
||||
Self inv = Self(conj(A), -B);
|
||||
string inv_label;
|
||||
std::string inv_label;
|
||||
for(long i = label.size() - 1; i >= 0; i--) {
|
||||
if(label[i] >= 'a' && label[i] <= 'd') {
|
||||
inv_label.push_back('\\');
|
||||
|
|
@ -142,17 +149,17 @@ public:
|
|||
return norm(A) - factor * norm(B);
|
||||
}
|
||||
|
||||
static complex<double> toComplexDouble(Matrix_element M) //const
|
||||
static std::complex<double> toComplexDouble(Matrix_element M) //const
|
||||
{
|
||||
Square_root_2_field rl = real(M);
|
||||
Square_root_2_field img = imag(M);
|
||||
|
||||
return complex<double>(rl.l + sqrt(2.)*rl.r, img.l + sqrt(2.)*img.r);
|
||||
return std::complex<double>(rl.l + sqrt(2.)*rl.r, img.l + sqrt(2.)*img.r);
|
||||
}
|
||||
|
||||
pair<double, double> apply(double x, double y)
|
||||
std::pair<double, double> apply(double x, double y)
|
||||
{
|
||||
typedef complex<double> Cmpl;
|
||||
typedef std::complex<double> Cmpl;
|
||||
Cmpl Aa = toComplexDouble(A);
|
||||
Cmpl Bb = toComplexDouble(B);
|
||||
|
||||
|
|
@ -160,14 +167,17 @@ public:
|
|||
|
||||
Cmpl z(x, y);
|
||||
Cmpl res = (Aa*z + ax*Bb)/(ax*(conj(Bb)*z) + conj(Aa));
|
||||
return pair<double, double>(real(res), imag(res));
|
||||
return std::pair<double, double>(real(res), imag(res));
|
||||
}
|
||||
|
||||
|
||||
template<class Point>
|
||||
Point apply(Point p) {
|
||||
pair<double, double> arg = apply(to_double(p.x()), to_double(p.y()));
|
||||
return Point(FT(arg.first), FT(arg.second));
|
||||
pair<double, double> arg = apply(CGAL::to_double(p.x()), CGAL::to_double(p.y()));
|
||||
return Point(arg.first, arg.second);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -176,9 +186,9 @@ template<class Square_root_2_field>
|
|||
Square_root_2_field Hyperbolic_octagon_translation_matrix_base<Square_root_2_field>::factor = Square_root_2_field(-1, 1);
|
||||
|
||||
// just to give an order(ing)
|
||||
template<class Int>
|
||||
bool operator < (const complex<Square_root_2_field<Int> >& lh,
|
||||
const complex<Square_root_2_field<Int> >& rh)
|
||||
template<typename Int>
|
||||
bool operator < (const std::complex<Square_root_2_field<Int> >& lh,
|
||||
const std::complex<Square_root_2_field<Int> >& rh)
|
||||
{
|
||||
if (real(lh) < real(rh)) {
|
||||
return true;
|
||||
|
|
@ -219,7 +229,7 @@ bool operator == (const Hyperbolic_octagon_translation_matrix_base<Square_root_2
|
|||
}
|
||||
|
||||
template<class Square_root_2_field>
|
||||
ostream& operator<<(ostream& os, const Hyperbolic_octagon_translation_matrix_base<Square_root_2_field>& m)
|
||||
std::ostream& operator<<(std::ostream& os, const Hyperbolic_octagon_translation_matrix_base<Square_root_2_field>& m)
|
||||
{
|
||||
os << m.A << " " << m.B;
|
||||
return os;
|
||||
|
|
@ -245,13 +255,13 @@ enum Direction {
|
|||
|
||||
|
||||
|
||||
void get_generators(vector<Hyperbolic_octagon_translation_matrix>& gens)
|
||||
void get_generators(std::vector<Hyperbolic_octagon_translation_matrix>& gens)
|
||||
{
|
||||
// This is a in the matrix, equal to sqrt(2) + 1
|
||||
Matrix_element A = Matrix_element(Sqrt_field(1, 1), Sqrt_field(0, 0));
|
||||
|
||||
// This vector holds all other Matrix_elements, results of the exponentials for various k
|
||||
vector<Matrix_element> B(8, Matrix_element(Sqrt_field(0, 0), Sqrt_field(0, 0)));
|
||||
std::vector<Matrix_element> B(8, Matrix_element(Sqrt_field(0, 0), Sqrt_field(0, 0)));
|
||||
|
||||
// Corrected ordering (initial ordering is present in backup file)
|
||||
B[DIRECTION_A] = A * Matrix_element(Sqrt_field( 0, 1), Sqrt_field( 0, 0));
|
||||
|
|
@ -263,7 +273,7 @@ void get_generators(vector<Hyperbolic_octagon_translation_matrix>& gens)
|
|||
B[DIRECTION_C_BAR] = A * Matrix_element(Sqrt_field( 0, 0), Sqrt_field( 0, -1));
|
||||
B[DIRECTION_D_BAR] = A * Matrix_element(Sqrt_field(-1, 0), Sqrt_field( 1, 0));
|
||||
|
||||
string labels[8] = {string("a"), string("\\bar{b}"), string("c"), string("\\bar{d}"),
|
||||
std::string labels[8] = {string("a"), string("\\bar{b}"), string("c"), string("\\bar{d}"),
|
||||
string("\\bar{a}"), string("b"), string("\\bar{c}"), string("d")};
|
||||
for(int i = 0; i < 8; i++) {
|
||||
gens.push_back(Hyperbolic_octagon_translation_matrix(A, B[i], labels[i]));
|
||||
|
|
@ -279,9 +289,9 @@ void get_generators(vector<Hyperbolic_octagon_translation_matrix>& gens)
|
|||
|
||||
|
||||
// Check whether two Matrix_elements of the group are inverse of each other
|
||||
bool Dehn_are_inverse(int x, int y) {
|
||||
int idx = x % 4;
|
||||
int idy = y % 4;
|
||||
bool Dehn_are_inverse(Word_idx_type x, Word_idx_type y) {
|
||||
Word_idx_type idx = x % 4;
|
||||
Word_idx_type idy = y % 4;
|
||||
bool r = ((idx == idy) && (x != y));
|
||||
return r;
|
||||
}
|
||||
|
|
@ -289,12 +299,12 @@ void get_generators(vector<Hyperbolic_octagon_translation_matrix>& gens)
|
|||
|
||||
|
||||
// Recursively eliminate neighboring inverse Matrix_elements present in the word
|
||||
void Dehn_simplify_adjacent_inverses(vector<int>& w) {
|
||||
vector<int> t;
|
||||
void Dehn_simplify_adjacent_inverses(vector<Word_idx_type>& w) {
|
||||
vector<Word_idx_type> t;
|
||||
bool reduced = false;
|
||||
int N = w.size();
|
||||
Word_idx_type N = w.size();
|
||||
if (N > 1) {
|
||||
for (int i = 0; i < N-1; i++) {
|
||||
for (Word_idx_type i = 0; i < N-1; i++) {
|
||||
if (!Dehn_are_inverse(w[i], w[i+1])) {
|
||||
t.push_back(w[i]);
|
||||
} else {
|
||||
|
|
@ -318,30 +328,30 @@ void get_generators(vector<Hyperbolic_octagon_translation_matrix>& gens)
|
|||
|
||||
|
||||
// Computes and returns the next index in the identity Matrix_element chain
|
||||
int Dehn_next_identity_index(int idx) {
|
||||
Word_idx_type Dehn_next_relation_index(Word_idx_type idx) {
|
||||
return ( (idx + 5) % 8 );
|
||||
}
|
||||
|
||||
|
||||
// Checks whether y is the next Matrix_element from x
|
||||
bool Dehn_is_next_identity_index(int x, int y) {
|
||||
return ( Dehn_next_identity_index(y) == x);
|
||||
bool Dehn_is_next_relation_index(Word_idx_type x, Word_idx_type y) {
|
||||
return ( Dehn_next_relation_index(y) == x);
|
||||
}
|
||||
|
||||
|
||||
// Given a word, find the largest subsequence of consecutive Matrix_elements it contains.
|
||||
// The sequence itself is placed in 'seq', while the index at which it starts is
|
||||
// the return argument of the function.
|
||||
int Dehn_longest_identity_subsequence(vector<int>& seq, vector<int> const w) {
|
||||
int start = 0;
|
||||
int mstart = 0;
|
||||
int end = 1;
|
||||
int max = 1;
|
||||
int len = 1;
|
||||
vector<int> tmp, mvec;
|
||||
Word_idx_type Dehn_longest_relation_subsequence(vector<Word_idx_type>& seq, vector<Word_idx_type> const w) {
|
||||
Word_idx_type start = 0;
|
||||
Word_idx_type mstart = 0;
|
||||
Word_idx_type end = 1;
|
||||
Word_idx_type max = 1;
|
||||
Word_idx_type len = 1;
|
||||
vector<Word_idx_type> tmp, mvec;
|
||||
tmp.push_back(w[0]);
|
||||
for (int i = 1; i < w.size(); i++) {
|
||||
if ( Dehn_is_next_identity_index( w[i], w[i-1] ) ) {
|
||||
for (Word_idx_type i = 1; i < w.size(); i++) {
|
||||
if ( Dehn_is_next_relation_index( w[i], w[i-1] ) ) {
|
||||
end++;
|
||||
len++;
|
||||
tmp.push_back(w[i]);
|
||||
|
|
@ -363,16 +373,16 @@ void get_generators(vector<Hyperbolic_octagon_translation_matrix>& gens)
|
|||
}
|
||||
|
||||
|
||||
int Dehn_identity_index_of_inverse(int x) {
|
||||
Word_idx_type Dehn_relation_index_of_inverse(Word_idx_type x) {
|
||||
return ((x + 4) % 8);
|
||||
}
|
||||
|
||||
|
||||
// Given a word, construct its inverse
|
||||
void Dehn_invert_word(vector<int>& w, vector<int> const original) {
|
||||
void Dehn_invert_word(vector<Word_idx_type>& w, vector<Word_idx_type> const original) {
|
||||
w.clear();
|
||||
for (int i = original.size() - 1; i >= 0; i--) {
|
||||
w.push_back( Dehn_identity_index_of_inverse(original[i]) );
|
||||
w.push_back( Dehn_relation_index_of_inverse(original[i]) );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -380,21 +390,21 @@ void get_generators(vector<Hyperbolic_octagon_translation_matrix>& gens)
|
|||
|
||||
// Given a sequence of consecutive indices, return the complementary set of consecutive indices in mod 8.
|
||||
// For instance, if start = 5 and end = 1, the output is the sequence 2, 3, 4
|
||||
void Dehn_complementary_identity_indices(vector<int>& v, int begin, int end) {
|
||||
vector<int> tmp;
|
||||
for (int i = Dehn_next_identity_index(end); i != begin; i = Dehn_next_identity_index(i)) {
|
||||
void Dehn_complementary_relation_indices(vector<Word_idx_type>& v, Word_idx_type begin, Word_idx_type end) {
|
||||
vector<Word_idx_type> tmp;
|
||||
for (Word_idx_type i = Dehn_next_relation_index(end); i != begin; i = Dehn_next_relation_index(i)) {
|
||||
tmp.push_back(i);
|
||||
}
|
||||
|
||||
for (int i = tmp.size() - 1; i >= 0; i--) {
|
||||
for (Word_idx_type i = tmp.size() - 1; i >= 0; i--) {
|
||||
v.push_back(tmp[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Dehn_complementary_identity_indices(vector<int>& v, vector<int> const original) {
|
||||
std::vector<int> tmp;
|
||||
Dehn_complementary_identity_indices(tmp, original[0], original[original.size() - 1]);
|
||||
void Dehn_complementary_relation_indices(vector<Word_idx_type>& v, vector<Word_idx_type> const original) {
|
||||
std::vector<Word_idx_type> tmp;
|
||||
Dehn_complementary_relation_indices(tmp, original[0], original[original.size() - 1]);
|
||||
for (int i = tmp.size() - 1; i >= 0; i--) {
|
||||
v.push_back(tmp[i]);
|
||||
}
|
||||
|
|
@ -404,7 +414,7 @@ void get_generators(vector<Hyperbolic_octagon_translation_matrix>& gens)
|
|||
// Given a word, identifies the longest subword consisting of consecutive Matrix_elements and substitutes
|
||||
// it with its equivalent shorter word. The search is executed in both the original word and its
|
||||
// inverse, and the substitution is made considering the longest subword from both cases.
|
||||
bool Dehn_replace_identity_subword(vector<int>& w, const vector<int> original) {
|
||||
bool Dehn_replace_relation_subword(vector<Word_idx_type>& w, const vector<Word_idx_type> original) {
|
||||
|
||||
bool replaced = false;
|
||||
|
||||
|
|
@ -414,23 +424,23 @@ void get_generators(vector<Hyperbolic_octagon_translation_matrix>& gens)
|
|||
}
|
||||
|
||||
// Look for longest subword forward
|
||||
vector<int> lfwd;
|
||||
int idxf = Dehn_longest_identity_subsequence(lfwd, original);
|
||||
int Nf = lfwd.size();
|
||||
vector<Word_idx_type> lfwd;
|
||||
Word_idx_type idxf = Dehn_longest_relation_subsequence(lfwd, original);
|
||||
Word_idx_type Nf = lfwd.size();
|
||||
|
||||
// Get inverse of the original word
|
||||
vector<int> inv;
|
||||
vector<Word_idx_type> inv;
|
||||
Dehn_invert_word(inv, original);
|
||||
|
||||
// Look for longest subword backwards
|
||||
vector<int> lbwd;
|
||||
int idxb = Dehn_longest_identity_subsequence(lbwd, inv);
|
||||
int Nb = lbwd.size();
|
||||
vector<Word_idx_type> lbwd;
|
||||
Word_idx_type idxb = Dehn_longest_relation_subsequence(lbwd, inv);
|
||||
Word_idx_type Nb = lbwd.size();
|
||||
|
||||
// Assign parameters based on results to homogenise the logic
|
||||
vector<int> word, sub;
|
||||
vector<Word_idx_type> word, sub;
|
||||
bool is_inverse;
|
||||
int N, idx;
|
||||
Word_idx_type N, idx;
|
||||
//cout << "Nb = " << Nb << ", Nf = " << Nf << endl;
|
||||
if (Nb > Nf) {
|
||||
word = inv;
|
||||
|
|
@ -450,19 +460,19 @@ void get_generators(vector<Hyperbolic_octagon_translation_matrix>& gens)
|
|||
// is by default equal to the identity Matrix_element and can be directly eliminated.
|
||||
while (N >= 8) {
|
||||
replaced = true;
|
||||
vector<int> ttt = word;
|
||||
vector<Word_idx_type> ttt = word;
|
||||
word.clear();
|
||||
for (int i = 0; i < idx; i++) {
|
||||
for (Word_idx_type i = 0; i < idx; i++) {
|
||||
word.push_back(ttt[i]);
|
||||
}
|
||||
for (int i = idx + 8; i < ttt.size(); i++) {
|
||||
for (Word_idx_type i = idx + 8; i < ttt.size(); i++) {
|
||||
word.push_back(ttt[i]);
|
||||
}
|
||||
w = word;
|
||||
|
||||
ttt = sub;
|
||||
sub.clear();
|
||||
for (int i = 8; i < ttt.size(); i++) {
|
||||
for (Word_idx_type i = 8; i < ttt.size(); i++) {
|
||||
sub.push_back(ttt[i]);
|
||||
}
|
||||
N -= 8;
|
||||
|
|
@ -474,28 +484,28 @@ void get_generators(vector<Hyperbolic_octagon_translation_matrix>& gens)
|
|||
// substitution becomes cyclic.
|
||||
if (N > 4) {
|
||||
replaced = true;
|
||||
vector<int> cmpl;
|
||||
Dehn_complementary_identity_indices(cmpl, sub);
|
||||
vector<Word_idx_type> cmpl;
|
||||
Dehn_complementary_relation_indices(cmpl, sub);
|
||||
|
||||
if(is_inverse) {
|
||||
vector<int> tmp;
|
||||
vector<Word_idx_type> tmp;
|
||||
Dehn_invert_word(tmp, cmpl);
|
||||
cmpl = tmp;
|
||||
}
|
||||
|
||||
for (int i = 0; i < idx; i++) {
|
||||
for (Word_idx_type i = 0; i < idx; i++) {
|
||||
w.push_back(word[i]);
|
||||
}
|
||||
for (int i = 0; i < cmpl.size(); i++) {
|
||||
for (Word_idx_type i = 0; i < cmpl.size(); i++) {
|
||||
w.push_back(cmpl[i]);
|
||||
}
|
||||
for (int i = N + idx; i < word.size(); i++) {
|
||||
for (Word_idx_type i = N + idx; i < word.size(); i++) {
|
||||
w.push_back(word[i]);
|
||||
}
|
||||
} else if (N == 4) {
|
||||
if (is_inverse) {
|
||||
vector<int> tmp;
|
||||
Dehn_invert_word(tmp, w);
|
||||
vector<Word_idx_type> tmp;
|
||||
Dehn_invert_word(tmp, word);
|
||||
w = tmp;
|
||||
replaced = true;
|
||||
}
|
||||
|
|
@ -503,7 +513,7 @@ void get_generators(vector<Hyperbolic_octagon_translation_matrix>& gens)
|
|||
|
||||
// If we have been working with the inverse of the original, the result has to be inverted.
|
||||
if (is_inverse) {
|
||||
vector<int> tmp;
|
||||
vector<Word_idx_type> tmp;
|
||||
Dehn_invert_word(tmp, w);
|
||||
w = tmp;
|
||||
}
|
||||
|
|
@ -512,19 +522,17 @@ void get_generators(vector<Hyperbolic_octagon_translation_matrix>& gens)
|
|||
}
|
||||
|
||||
|
||||
|
||||
// Applies Dehn's algorithm to a given word. The result is the equivalent ireducible word
|
||||
// of the original. The boolean return argument of the function indicates whether the
|
||||
// resulting equivalent irreducible word is the identity Matrix_element or not.
|
||||
bool Dehn_reduce_word(vector<int>& w, vector<int> const original) {
|
||||
bool Dehn_reduce_word(vector<Word_idx_type>& w, vector<Word_idx_type> const original) {
|
||||
bool is_identity = false;
|
||||
vector<int> tmp;
|
||||
vector<Word_idx_type> tmp;
|
||||
tmp = original;
|
||||
while (tmp.size() > 0) {
|
||||
Dehn_simplify_adjacent_inverses(tmp);
|
||||
vector<int> sub;
|
||||
bool replaced = Dehn_replace_identity_subword(sub, tmp);
|
||||
|
||||
vector<Word_idx_type> sub;
|
||||
bool replaced = Dehn_replace_relation_subword(sub, tmp);
|
||||
if (!replaced) {
|
||||
w = tmp;
|
||||
return false;
|
||||
|
|
@ -538,6 +546,20 @@ void get_generators(vector<Hyperbolic_octagon_translation_matrix>& gens)
|
|||
}
|
||||
|
||||
|
||||
// Applies Dehn's algorithm to a given word. The result is the equivalent ireducible word
|
||||
// of the original. The boolean return argument of the function indicates whether the
|
||||
// resulting equivalent irreducible word is the identity Matrix_element or not.
|
||||
// Overload for generic type.
|
||||
template <class Word>
|
||||
bool Dehn_reduce_word(Word& w, Word const original) {
|
||||
|
||||
std::vector<Word_idx_type> in = original.get_vector();
|
||||
std::vector<Word_idx_type> out;
|
||||
bool result = Dehn_reduce_word(out, in);
|
||||
w = Word(out);
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/**************************************************************/
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,55 @@
|
|||
#ifndef HYPERBOLIC_TRANSLATION_INFO
|
||||
#define HYPERBOLIC_TRANSLATION_INFO
|
||||
|
||||
template<typename String>
|
||||
class Hyperbolic_translation_info
|
||||
{
|
||||
public:
|
||||
|
||||
Hyperbolic_translation_info() : color(0)
|
||||
{
|
||||
}
|
||||
|
||||
Hyperbolic_translation_info(const String& name, int new_color = 0)
|
||||
: name_of_translation(name), color(new_color)
|
||||
{
|
||||
}
|
||||
|
||||
void setString(const String& name)
|
||||
{
|
||||
name_of_translation = name;
|
||||
}
|
||||
|
||||
const String& toString() const
|
||||
{
|
||||
return name_of_translation;
|
||||
}
|
||||
|
||||
void setColor(int new_color)
|
||||
{
|
||||
color = new_color;
|
||||
}
|
||||
|
||||
int getColor() const
|
||||
{
|
||||
return color;
|
||||
}
|
||||
|
||||
private:
|
||||
String name_of_translation;
|
||||
|
||||
int color;
|
||||
};
|
||||
|
||||
template<typename String>
|
||||
Hyperbolic_translation_info<String> operator + (const Hyperbolic_translation_info<String>& l, const Hyperbolic_translation_info<String>& r)
|
||||
{
|
||||
Hyperbolic_translation_info<String> result;
|
||||
result.setString(l.toString() + r.toString());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif // HYPERBOLIC_TRANSLATION_INFO
|
||||
|
|
@ -0,0 +1,308 @@
|
|||
// Copyright (c) 1999-2004,2006-2009,2014-2016 INRIA Nancy - Grand Est (France).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org).
|
||||
// You can redistribute it and/or modify it under the terms of the GNU
|
||||
// Interal 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) : Iordan Iordanov <iordan.iordanov@loria.fr>
|
||||
|
||||
#ifndef CGAL_HYPERBOLIC_WORD_4
|
||||
#define CGAL_HYPERBOLIC_WORD_4
|
||||
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
#include <CGAL/Hyperbolic_octagon_translation_matrix.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template <class Int>
|
||||
class Hyperbolic_word_4 {
|
||||
private:
|
||||
Int w0 : 3;
|
||||
bool b0 : 1;
|
||||
|
||||
Int w1 : 3;
|
||||
bool b1 : 1;
|
||||
|
||||
Int w2 : 3;
|
||||
bool b2 : 1;
|
||||
|
||||
Int w3 : 3;
|
||||
bool b3 : 1;
|
||||
|
||||
public:
|
||||
|
||||
Hyperbolic_word_4() :
|
||||
w0(0), w1(0), w2(0), w3(0), b0(false), b1(false), b2(false), b3(false) {}
|
||||
|
||||
Hyperbolic_word_4(Int x) :
|
||||
w0(x), w1(0), w2(0), w3(0), b0(true), b1(false), b2(false), b3(false) {}
|
||||
|
||||
Hyperbolic_word_4(Int x, Int y) :
|
||||
w0(x), w1(y), w2(0), w3(0), b0(true), b1(true), b2(false), b3(false) {}
|
||||
|
||||
Hyperbolic_word_4(Int x, Int y, Int z) :
|
||||
w0(x), w1(y), w2(z), w3(0), b0(true), b1(true), b2(true), b3(false) {}
|
||||
|
||||
Hyperbolic_word_4(Int x, Int y, Int z, Int t) :
|
||||
w0(x), w1(y), w2(z), w3(t), b0(true), b1(true), b2(true), b3(true) {}
|
||||
|
||||
Hyperbolic_word_4(std::vector<Int> v) {
|
||||
switch(v.size()) {
|
||||
case 0:
|
||||
w0 = 0; b0 = false;
|
||||
w1 = 0; b1 = false;
|
||||
w2 = 0; b2 = false;
|
||||
w3 = 0; b3 = false;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
w0 = v[0]; b0 = true;
|
||||
w1 = 0; b1 = false;
|
||||
w2 = 0; b2 = false;
|
||||
w3 = 0; b3 = false;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
w0 = v[0]; b0 = true;
|
||||
w1 = v[1]; b1 = true;
|
||||
w2 = 0; b2 = false;
|
||||
w3 = 0; b3 = false;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
w0 = v[0]; b0 = true;
|
||||
w1 = v[1]; b1 = true;
|
||||
w2 = v[2]; b2 = true;
|
||||
w3 = 0; b3 = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
w0 = v[0]; b0 = true;
|
||||
w1 = v[1]; b1 = true;
|
||||
w2 = v[2]; b2 = true;
|
||||
w3 = v[3]; b3 = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void operator()(Int idx, Int val) {
|
||||
assert(idx >= 0 && idx <= 3);
|
||||
switch (idx) {
|
||||
case 0:
|
||||
w0 = val;
|
||||
b0 = true;
|
||||
break;
|
||||
case 1:
|
||||
w1 = val;
|
||||
b1 = true;
|
||||
break;
|
||||
case 2:
|
||||
w2 = val;
|
||||
b2 = true;
|
||||
break;
|
||||
default:
|
||||
b3 = true;
|
||||
w3 = val;
|
||||
}
|
||||
}
|
||||
|
||||
Int operator()(Int i) const {
|
||||
assert(i >= 0 && i <= 3);
|
||||
switch (i) {
|
||||
case 0:
|
||||
return w0;
|
||||
case 1:
|
||||
return w1;
|
||||
case 2:
|
||||
return w2;
|
||||
default:
|
||||
return w3;
|
||||
}
|
||||
}
|
||||
|
||||
bool b(Int i) const {
|
||||
assert(i >= 0 && i <= 3);
|
||||
switch (i) {
|
||||
case 0:
|
||||
return b0;
|
||||
case 1:
|
||||
return b1;
|
||||
case 2:
|
||||
return b2;
|
||||
default:
|
||||
return b3;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Int size() const {
|
||||
if (b0 == false) {
|
||||
return 0;
|
||||
} else {
|
||||
if (b1 == false) {
|
||||
return 1;
|
||||
} else {
|
||||
if (b2 == false) {
|
||||
return 2;
|
||||
} else {
|
||||
if (b3 == false) {
|
||||
return 3;
|
||||
} else {
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void append(Int val) {
|
||||
if (b0 == false) {
|
||||
w0 = val;
|
||||
b0 = true;
|
||||
}
|
||||
else if (b1 == false) {
|
||||
w1 = val;
|
||||
b1 = true;
|
||||
}
|
||||
else if (b2 == false) {
|
||||
w2 = val;
|
||||
b2 = true;
|
||||
}
|
||||
else if (b3 == false) {
|
||||
w3 = val;
|
||||
b3 = true;
|
||||
}
|
||||
else {
|
||||
// Cannot append -- everything is full.
|
||||
// TODO: find a better way to handle this.
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Int> get_vector() const {
|
||||
std::vector<Int> v;
|
||||
if (b0) {
|
||||
v.push_back(w0);
|
||||
}
|
||||
if (b1) {
|
||||
v.push_back(w1);
|
||||
}
|
||||
if (b2) {
|
||||
v.push_back(w2);
|
||||
}
|
||||
if (b3) {
|
||||
v.push_back(w3);
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
bool is_identity() const {
|
||||
return ( b0 == false );
|
||||
}
|
||||
|
||||
std::string get_string() const {
|
||||
std::string s = "";
|
||||
|
||||
if (b0) {
|
||||
s += w0 + '0';
|
||||
}
|
||||
|
||||
if (b1) {
|
||||
s += w1 + '0';
|
||||
}
|
||||
|
||||
if (b2) {
|
||||
s += w2 + '0';
|
||||
}
|
||||
|
||||
if (b3) {
|
||||
s += w3 + '0';
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
Hyperbolic_octagon_translation_matrix get_matrix() const {
|
||||
std::vector<Hyperbolic_octagon_translation_matrix> Ints;
|
||||
get_generators(Ints);
|
||||
Hyperbolic_octagon_translation_matrix m;
|
||||
if (b0) {
|
||||
m = Ints[w0];
|
||||
if (b1) {
|
||||
m = m * Ints[w1];
|
||||
if (b2) {
|
||||
m = m * Ints[w2];
|
||||
if (b3) {
|
||||
m = m * Ints[w3];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
template<class Point>
|
||||
Point apply(Point pt) const {
|
||||
Hyperbolic_octagon_translation_matrix m = get_matrix();
|
||||
Point res = m.apply(pt);
|
||||
return res;
|
||||
}
|
||||
|
||||
Hyperbolic_word_4<Int> operator*(const Hyperbolic_word_4<Int>& rh) const {
|
||||
assert(this->size() + rh->size() < 5);
|
||||
Hyperbolic_word_4<Int> w;
|
||||
for (Int i = 0; i < this->size(); i++) {
|
||||
w.append(this->operator()(i));
|
||||
}
|
||||
for (Int i = 0; i < rh.size(); i++) {
|
||||
w.append(rh(i));
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
template <class Int>
|
||||
ostream& operator<<(ostream& s, const Hyperbolic_word_4<Int>& o) {
|
||||
for (Int i = 0; i < 4; i++) {
|
||||
if (o.b(i)) {
|
||||
s << o(i);
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
// just to give an order(ing)
|
||||
template<class Int>
|
||||
bool operator < (const Hyperbolic_word_4<Int>& lh,
|
||||
const Hyperbolic_word_4<Int>& rh)
|
||||
{
|
||||
std::string vl = lh.get_string();
|
||||
std::string vr = rh.get_string();
|
||||
|
||||
return vl < vr;
|
||||
}
|
||||
|
||||
} // namespace CGAL
|
||||
|
||||
#endif // CGAL_HYPERBOLIC_WORD_4
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
// Copyright (c) 1999-2004,2006-2009,2014-2015 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) : Monique Teillaud <Monique.Teillaud@sophia.inria.fr>
|
||||
// Sylvain Pion <Sylvain.Pion@sophia.inria.fr>
|
||||
// Andreas Fabri <Andreas.Fabri@sophia.inria.fr>
|
||||
// Nico Kruithof <Nico.Kruithof@sophia.inria.fr>
|
||||
// Manuel Caroli <Manuel.Caroli@sophia.inria.fr>
|
||||
// Aymeric Pellé <Aymeric.Pelle@sophia.inria.fr>
|
||||
#ifndef CGAL_PERIODIC_4_CONSTRUCT_HYPERBOLIC_POINT_2_H
|
||||
#define CGAL_PERIODIC_4_CONSTRUCT_HYPERBOLIC_POINT_2_H
|
||||
|
||||
#include <CGAL/Square_root_2_field.h>
|
||||
#include <CGAL/Hyperbolic_octagon_translation.h>
|
||||
|
||||
namespace CGAL
|
||||
{
|
||||
template < typename K, typename Construct_point_2_base>
|
||||
class Periodic_4_construct_hyperbolic_point_2 : public Construct_point_2_base
|
||||
{
|
||||
typedef K Kernel;
|
||||
|
||||
public:
|
||||
typedef typename Kernel::Point_2 Point;
|
||||
typedef std::vector<int> Word;
|
||||
typedef typename Kernel::Circle_2 Circle_2;
|
||||
|
||||
typedef Point result_type;
|
||||
|
||||
Periodic_4_construct_hyperbolic_point_2(const Circle_2 & dom) : _dom(dom) { }
|
||||
|
||||
Point operator() ( const Point& p, const Word& w ) const {
|
||||
pair<double, double> pt = w.apply(to_double(p.x()), to_double(p.y()));
|
||||
Point r = Point(pt.first, pt.second);
|
||||
|
||||
// Do we need this? I (iiordano) think it's a good idea...
|
||||
assert( _dom.has_on_bounded_side(r) );
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
private:
|
||||
Circle_2 _dom;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -21,61 +21,173 @@
|
|||
#define CGAL_PERIODIC_4_HYPERBOLIC_DELAUNAY_TRIANGULATION_2_H
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include <CGAL/Square_root_2_field.h>
|
||||
#include <CGAL/Hyperbolic_octagon_translation_matrix.h>
|
||||
#include <CGAL/Delaunay_hyperbolic_triangulation_2.h>
|
||||
#include <CGAL/Periodic_4_hyperbolic_triangulation_2.h>
|
||||
#include <CGAL/Periodic_4_hyperbolic_triangulation_ds_vertex_base_2.h>
|
||||
#include <CGAL/Periodic_4_hyperbolic_triangulation_ds_face_base_2.h>
|
||||
#include <CGAL/Hyperbolic_word_4.h>
|
||||
|
||||
|
||||
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 Periodic_4_hyperbolic_Delaunay_triangulation_2 : public Delaunay_hyperbolic_triangulation_2<Gt, Tds> {
|
||||
template < class GT,
|
||||
class TDS = Triangulation_data_structure_2<
|
||||
Triangulation_vertex_base_with_info_2<Hyperbolic_translation_info<std::string>, GT, Periodic_4_hyperbolic_triangulation_ds_vertex_base_2<GT> >,
|
||||
Triangulation_face_base_with_info_2<Periodic_4_hyperbolic_face_info_2, GT, Periodic_4_hyperbolic_triangulation_ds_face_base_2<> >
|
||||
>
|
||||
>
|
||||
class Periodic_4_hyperbolic_Delaunay_triangulation_2 :
|
||||
public Periodic_4_hyperbolic_triangulation_2<GT, TDS> {
|
||||
|
||||
typedef Periodic_4_hyperbolic_Delaunay_triangulation_2<GT, TDS> Self;
|
||||
typedef Periodic_4_hyperbolic_triangulation_2<GT, TDS> Base;
|
||||
|
||||
public:
|
||||
typedef Delaunay_hyperbolic_triangulation_2<Gt, Tds> Base;
|
||||
typedef Periodic_4_hyperbolic_Delaunay_triangulation_2<Gt, Tds> Self;
|
||||
typedef typename Base::Locate_type Locate_type;
|
||||
typedef typename Base::Geometric_traits Geometric_traits;
|
||||
typedef typename Base::Triangulation_data_structure Triangulation_data_structure;
|
||||
typedef typename Base::Int Int;
|
||||
typedef typename Base::Offset Offset;
|
||||
typedef typename Base::Circle_2 Circle_2;
|
||||
typedef Circle_2 Circle;
|
||||
typedef typename Base::Point_2 Point_2;
|
||||
typedef Point_2 Point;
|
||||
typedef typename Base::Segment_2 Segment_2;
|
||||
typedef Segment_2 Segment;
|
||||
typedef typename Base::Triangle_2 Triangle_2;
|
||||
typedef Triangle_2 Triangle;
|
||||
|
||||
typedef typename Base::Periodic_point Periodic_point;
|
||||
typedef typename Base::Periodic_segment Periodic_segment;
|
||||
typedef typename Base::Periodic_triangle Periodic_triangle;
|
||||
|
||||
typedef typename Base::Vertex Vertex;
|
||||
typedef typename Base::Edge Edge;
|
||||
typedef typename Base::Face Face;
|
||||
|
||||
typedef typename Base::Face_base Face_base;
|
||||
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;
|
||||
|
||||
typedef typename Base::Edge_circulator Edge_circulator;
|
||||
typedef typename Base::size_type size_type;
|
||||
typedef typename Base::difference_type difference_type;
|
||||
|
||||
typedef typename Base::Face_iterator Face_iterator;
|
||||
typedef typename Base::Edge_iterator Edge_iterator;
|
||||
typedef typename Base::Vertex_iterator Vertex_iterator;
|
||||
typedef typename Base::Face_circulator Face_circulator;
|
||||
typedef typename Base::Edge_circulator Edge_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 Face_iterator All_faces_iterator;
|
||||
typedef Edge_iterator All_edges_iterator;
|
||||
typedef Vertex_iterator All_vertices_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;
|
||||
typedef Face_iterator Finite_faces_iterator;
|
||||
typedef Edge_iterator Finite_edges_iterator;
|
||||
typedef Vertex_iterator Finite_vertices_iterator;
|
||||
|
||||
// Periodic stuff
|
||||
typedef Hyperbolic_octagon_translation_matrix Offset;
|
||||
typedef std::pair<Point, Offset> Periodic_point;
|
||||
typedef array< std::pair<Point,Offset>, 2> Periodic_segment;
|
||||
typedef array< std::pair<Point,Offset>, 3> Periodic_triangle;
|
||||
typedef Periodic_4_hyperbolic_triangulation_unique_vertex_iterator_2<Self>
|
||||
Unique_vertex_iterator;
|
||||
|
||||
private:
|
||||
typedef typename GT::FT FT;
|
||||
typedef std::pair< Vertex_handle, Offset > Virtual_vertex;
|
||||
typedef std::map<Vertex_handle, Virtual_vertex> Virtual_vertex_map;
|
||||
typedef typename Virtual_vertex_map::const_iterator Virtual_vertex_map_it;
|
||||
typedef std::map<Vertex_handle, std::vector<Vertex_handle > >
|
||||
Virtual_vertex_reverse_map;
|
||||
typedef typename Virtual_vertex_reverse_map::const_iterator
|
||||
Virtual_vertex_reverse_map_it;
|
||||
typedef Triple< Vertex_handle, Vertex_handle, Vertex_handle >
|
||||
Vertex_triple;
|
||||
|
||||
public:
|
||||
typedef Periodic_4_hyperbolic_triangulation_triangle_iterator_2<Self>
|
||||
Periodic_triangle_iterator;
|
||||
typedef Periodic_4_hyperbolic_triangulation_segment_iterator_2<Self>
|
||||
Periodic_segment_iterator;
|
||||
typedef Periodic_4_hyperbolic_triangulation_point_iterator_2<Self>
|
||||
Periodic_point_iterator;
|
||||
|
||||
typedef Point value_type;
|
||||
typedef const value_type& const_reference;
|
||||
typedef Tag_false Weighted_tag;
|
||||
|
||||
private:
|
||||
Geometric_traits _gt;
|
||||
Triangulation_data_structure _tds;
|
||||
Circle _domain;
|
||||
|
||||
|
||||
Periodic_4_hyperbolic_Delaunay_triangulation_2(const Gt& gt = Gt())
|
||||
: Delaunay_hyperbolic_triangulation_2<Gt,Tds>(gt) {}
|
||||
|
||||
Periodic_4_hyperbolic_Delaunay_triangulation_2(
|
||||
const Delaunay_hyperbolic_triangulation_2<Gt,Tds> &tr)
|
||||
: Delaunay_hyperbolic_triangulation_2<Gt,Tds>(tr) {
|
||||
CGAL_triangulation_postcondition( this->is_valid() );
|
||||
void init_tds() {
|
||||
_tds.set_dimension(-2);
|
||||
v_offsets.reserve(14);
|
||||
}
|
||||
|
||||
void insert_dummy_points(std::vector<typename Gt::Point_2>&);
|
||||
protected:
|
||||
mutable std::vector<Vertex_handle> v_offsets;
|
||||
|
||||
};
|
||||
public:
|
||||
|
||||
Periodic_4_hyperbolic_Delaunay_triangulation_2(Geometric_traits gt) :
|
||||
_gt(gt), _domain( Circle_2(Point(0,0), 1*1) ), _tds() {
|
||||
init_tds();
|
||||
}
|
||||
|
||||
Periodic_4_hyperbolic_Delaunay_triangulation_2(
|
||||
const Circle_2 domain = Circle_2(Point_2(FT(0),FT(0)), FT(1*1)),
|
||||
const Geometric_traits > = Geometric_traits() ) :
|
||||
_gt(gt), _domain(domain), _tds() {
|
||||
//_gt.set_domain(_domain);
|
||||
init_tds();
|
||||
}
|
||||
|
||||
Periodic_4_hyperbolic_Delaunay_triangulation_2(const Periodic_4_hyperbolic_Delaunay_triangulation_2& tr) :
|
||||
_gt(tr.geom_traits()),
|
||||
_domain(tr._domain) {
|
||||
CGAL_triangulation_expensive_postcondition(*this == tr);
|
||||
}
|
||||
|
||||
|
||||
Vertex_handle insert(const Point &p,
|
||||
Face_handle start = Face_handle() );
|
||||
|
||||
Vertex_handle insert(const Point& p,
|
||||
Locate_type lt,
|
||||
Face_handle loc, int li );
|
||||
|
||||
template < class InputIterator >
|
||||
std::ptrdiff_t insert(InputIterator first,
|
||||
InputIterator last,
|
||||
bool is_large_point_set = true);
|
||||
|
||||
|
||||
}; // class Periodic_4_hyperbolic_Delaunay_triangulation_2
|
||||
|
||||
|
||||
template < class Gt, class Tds >
|
||||
inline
|
||||
typename Periodic_4_hyperbolic_Delaunay_triangulation_2<Gt, Tds>::Vertex_handle
|
||||
Periodic_4_hyperbolic_Delaunay_triangulation_2<Gt, Tds>::
|
||||
insert(const Point &p, Face_handle start)
|
||||
{
|
||||
std::cout << "Inseritng now! Yeah!" << std::endl;
|
||||
return Vertex_handle();
|
||||
}
|
||||
|
||||
|
||||
template < class Gt, class Tds >
|
||||
inline
|
||||
typename Periodic_4_hyperbolic_Delaunay_triangulation_2<Gt, Tds>::Vertex_handle
|
||||
Periodic_4_hyperbolic_Delaunay_triangulation_2<Gt, Tds>::
|
||||
insert(const Point &p, Locate_type lt, Face_handle loc, int li)
|
||||
{
|
||||
std::cout << "Inseritng now! Right!" << std::endl;
|
||||
return Vertex_handle();
|
||||
}
|
||||
|
||||
|
||||
} // namespace CGAL
|
||||
|
|
|
|||
|
|
@ -1,259 +0,0 @@
|
|||
// Copyright (c) 2010 INRIA Sophia-Antipolis (France).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org); you may redistribute it under
|
||||
// the terms of the Q Public License version 1.0.
|
||||
// See the file LICENSE.QPL distributed with CGAL.
|
||||
//
|
||||
// Licensees holding a valid commercial license may use this file in
|
||||
// accordance with the commercial license agreement provided with the software.
|
||||
//
|
||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/candidate-packages/Triangulation_2/include/CGAL/Delaunay_triangulation_2.h $
|
||||
// $Id: Delaunay_triangulation_2.h 57509 2010-07-15 09:14:09Z sloriot $
|
||||
//
|
||||
//
|
||||
// Author(s) : Mikhail Bogdanov
|
||||
|
||||
#ifndef CGAL_PERIODIC_4_HYPERBOLIC_DELAUNAY_TRIANGULATION_DUMMY_H
|
||||
#define CGAL_PERIODIC_4_HYPERBOLIC_DELAUNAY_TRIANGULATION_DUMMY_H
|
||||
|
||||
#include <CGAL/Regular_triangulation_filtered_traits_2.h>
|
||||
#include <CGAL/Aff_transformation_2.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
// this class might to be moved to hyperbolic traits
|
||||
template<class GT>
|
||||
class Construct_reflection
|
||||
{
|
||||
typedef typename GT::Point_2 Point_2;
|
||||
typedef typename GT::Circle_2 Circle_2;
|
||||
typedef typename GT::Vector_2 Vector_2;
|
||||
typedef typename GT::FT FT;
|
||||
|
||||
typedef typename GT::Compute_squared_distance_2 Compute_squared_distance_2;
|
||||
typedef typename GT::Construct_vector_2 Construct_vector_2;
|
||||
typedef typename GT::Construct_scaled_vector_2 Construct_scaled_vector_2;
|
||||
typedef typename GT::Construct_translated_point_2 Construct_translated_point_2;
|
||||
|
||||
typedef CGAL::Regular_triangulation_filtered_traits_2<GT> Rtr_2;
|
||||
typedef typename Rtr_2::Construct_weighted_circumcenter_2 Construct_weighted_circumcenter_2;
|
||||
typedef typename Rtr_2::Weighted_point_2 Weighted_point_2;
|
||||
typedef typename Rtr_2::Bare_point Bare_point;
|
||||
|
||||
public:
|
||||
Construct_reflection(const Circle_2& c = Circle_2(Point_2(0.0, 0.0), 1.)): _unit_circle(c)
|
||||
{
|
||||
}
|
||||
|
||||
// exact arithmetic! very nice!
|
||||
Point_2 operator ()(const Point_2& p, const Point_2& q, const Point_2& r) const
|
||||
{
|
||||
typedef typename GT::Collinear_2 Collinear_2;
|
||||
if(Collinear_2()(p, q, _unit_circle.center())){
|
||||
assert(false);
|
||||
}
|
||||
Weighted_point_2 wp(p);
|
||||
Weighted_point_2 wq(q);
|
||||
Weighted_point_2 wo(_unit_circle.center(), _unit_circle.squared_radius());
|
||||
|
||||
Bare_point center = Construct_weighted_circumcenter_2()(wp, wo, wq);
|
||||
FT radius = Compute_squared_distance_2()(p, center);
|
||||
FT dist = Compute_squared_distance_2()(r,center);
|
||||
Vector_2 vect = Construct_vector_2()(center,r);
|
||||
vect = Construct_scaled_vector_2()(vect,radius/dist);
|
||||
Point_2 image = Construct_translated_point_2()(center,vect);
|
||||
return image;
|
||||
}
|
||||
|
||||
private:
|
||||
const Circle_2& _unit_circle;
|
||||
};
|
||||
|
||||
template<class GT>
|
||||
typename GT::Point_2 apply_rotation(const typename GT::Point_2& p)
|
||||
{
|
||||
// Note Iordan: This is rotation by \pi/4 -- the second and third argument are the values of cos(\theta) and sin(\theta), respectively
|
||||
CGAL::Aff_transformation_2<GT> rotate(CGAL::ROTATION, std::sqrt(0.5), std::sqrt(0.5));
|
||||
|
||||
return rotate(p);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template<class GT>
|
||||
void compute_dummy_points( std::vector<typename GT::Point_2>& inner_points,
|
||||
std::vector<typename GT::Point_2>& points_on_boundary,
|
||||
std::vector<typename GT::Point_2>& points_on_vertex)
|
||||
{
|
||||
|
||||
typedef typename GT::FT FT;
|
||||
typedef typename GT::Point_2 Point_2;
|
||||
|
||||
typedef Aff_transformation_2<GT> Transformation;
|
||||
//Transformation rotate(ROTATION, 1./sqrt(2.), 1./sqrt(2.));
|
||||
Transformation rotate(ROTATION, 1., 0.); // Rotation by pi
|
||||
//Transformation rotate_pi8(ROTATION, sin(CGAL_PI/8.), cos(CGAL_PI/8.)); // Rotation by pi/8
|
||||
|
||||
points_on_vertex.push_back(Point_2( sqrt(sqrt(2.) + 1.)/ 2. , - sqrt(sqrt(2.) - 1.)/ 2.) ); // v_0
|
||||
points_on_boundary.push_back(Point_2( sqrt(sqrt(2.) - 1.), 0.)); // μ(s_0)
|
||||
points_on_boundary.push_back(Point_2( sqrt( (sqrt(2.) - 1.) / 2.) , sqrt( (sqrt(2.) - 1.) / 2.)) ); // μ(s_1)
|
||||
points_on_boundary.push_back(Point_2(0., sqrt(sqrt(2.) - 1.))); // μ(s_2)
|
||||
points_on_boundary.push_back(Point_2(-sqrt( (sqrt(2.) - 1.) / 2.), sqrt( (sqrt(2.) - 1.) / 2.)) ); // μ(s_3)
|
||||
|
||||
Point_2 a0((2. + sqrt(2.) - sqrt(6.))/(4.*sqrt(sqrt(2.) - 1.)), (sqrt(2.) - 2.*sqrt(3.) + sqrt(6.)) / (4.*sqrt(sqrt(2.) - 1.)));
|
||||
|
||||
/* Consistency reasons (has to be corresponding to vertex 5 of the figure) */
|
||||
//
|
||||
a0 = rotate(a0);
|
||||
a0 = rotate(a0);
|
||||
a0 = rotate(a0);
|
||||
|
||||
inner_points.push_back(a0);
|
||||
for (int k = 1; k < 8; k++) {
|
||||
a0 = rotate(a0);
|
||||
inner_points.push_back(a0);
|
||||
}
|
||||
|
||||
inner_points.push_back(Point_2( 0., 0. ));
|
||||
|
||||
/*
|
||||
assert(inner_points.size() == 0);
|
||||
assert(points_on_boundary.size() == 0);
|
||||
assert(points_on_vertex.size() == 0);
|
||||
|
||||
typedef typename GT::Kernel K;
|
||||
typedef typename GT::Point_2 Point_2;
|
||||
|
||||
double phi = CGAL_PI / 8.;
|
||||
double psi = CGAL_PI / 3.;
|
||||
double rho = std::sqrt(cos(psi)*cos(psi) - sin(phi)*sin(phi));
|
||||
|
||||
const Point_2 o(0.0, 0.0);
|
||||
const Point_2 a(cos(phi)*cos(phi + psi)/rho, sin(phi)*cos(phi + psi)/rho);
|
||||
const Point_2 b(a.x(), -a.y());
|
||||
|
||||
inner_points.push_back(b);
|
||||
Point_2 c = Construct_reflection<K>()(a, b, o);
|
||||
Point_2 d = Construct_reflection<K>()(a, c, b);
|
||||
//inner_points.push_back(d);
|
||||
Point_2 e = Construct_reflection<K>()(d, c, a);
|
||||
Point_2 f = Construct_reflection<K>()(d, e, c);
|
||||
|
||||
int size = inner_points.size();
|
||||
for(int i = 0; i < 7; i++) {
|
||||
for(int j = 0; j < size; j++) {
|
||||
inner_points.push_back(apply_rotation<K>(inner_points[i*size + j]));
|
||||
}
|
||||
}
|
||||
inner_points.push_back(o);
|
||||
|
||||
Point_2 cr = c;
|
||||
Point_2 fr = f;
|
||||
for (int i = 0; i < 2; i++) {
|
||||
cr = apply_rotation<K>(cr);
|
||||
fr = apply_rotation<K>(fr);
|
||||
}
|
||||
|
||||
points_on_boundary.push_back(cr);
|
||||
for(int i = 1; i < 4; i++) {
|
||||
points_on_boundary.push_back(apply_rotation<K>(points_on_boundary[i-1]));
|
||||
}
|
||||
|
||||
|
||||
points_on_vertex.push_back(apply_rotation<K>(fr));
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
template<class GT>
|
||||
void recursive_translate(Diametric_translations<GT> g,
|
||||
std::vector<typename GT::Point_2>& points,
|
||||
int depth,
|
||||
int start,
|
||||
int end) {
|
||||
|
||||
if (depth > 0) {
|
||||
int my_start = points.size();
|
||||
int my_end = start;
|
||||
|
||||
for (int i = start; i <= end; i++){
|
||||
typename GT::Point_2 subject = points[i];
|
||||
points.push_back( g.a().DoAction(subject) );
|
||||
points.push_back( g.b().inverse().DoAction(subject) );
|
||||
points.push_back( g.c().DoAction(subject) );
|
||||
points.push_back( g.d().inverse().DoAction(subject) );
|
||||
points.push_back( g.a().inverse().DoAction(subject) );
|
||||
points.push_back( g.b().DoAction(subject) );
|
||||
points.push_back( g.c().inverse().DoAction(subject) );
|
||||
points.push_back( g.d().DoAction(subject) );
|
||||
my_end += 8;
|
||||
}
|
||||
|
||||
recursive_translate(g, points, depth - 1, my_start, my_end);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<class GT>
|
||||
void recursive_translate(Diametric_translations<GT> g,
|
||||
std::vector<typename GT::Point_2>& points,
|
||||
typename GT::Point_2 subject,
|
||||
int depth) {
|
||||
|
||||
if (depth > 0) {
|
||||
int start = points.size();
|
||||
int end = start + 8;
|
||||
|
||||
// Add points in the order indicated by the group -- not necessary, but seems logical
|
||||
points.push_back( g.a().DoAction(subject) );
|
||||
points.push_back( g.b().inverse().DoAction(subject) );
|
||||
points.push_back( g.c().DoAction(subject) );
|
||||
points.push_back( g.d().inverse().DoAction(subject) );
|
||||
points.push_back( g.a().inverse().DoAction(subject) );
|
||||
points.push_back( g.b().DoAction(subject) );
|
||||
points.push_back( g.c().inverse().DoAction(subject) );
|
||||
points.push_back( g.d().DoAction(subject) );
|
||||
|
||||
recursive_translate(g, points, depth - 1, start, end);
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
template < class Gt, class Tds >
|
||||
void Periodic_4_hyperbolic_Delaunay_triangulation_2<Gt, Tds>::
|
||||
insert_dummy_points(std::vector<typename Gt::Point_2>& all_points) {
|
||||
|
||||
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);
|
||||
all_points = inner_points;
|
||||
|
||||
|
||||
for (int i = 0; i < points_on_boundary.size(); i++) {
|
||||
all_points.push_back(points_on_boundary[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < points_on_vertex.size(); i++) {
|
||||
all_points.push_back(points_on_vertex[i]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::cout << "All points length: " << all_points.size() << std::endl;
|
||||
|
||||
}
|
||||
|
||||
} // namespace CGAL
|
||||
|
||||
#endif // CGAL_PERIODIC_4_HYPERBOLIC_DELAUNAY_TRIANGULATION_DUMMY_H
|
||||
|
||||
|
|
@ -31,24 +31,114 @@
|
|||
#include <CGAL/distance_predicates_2.h>
|
||||
#include <CGAL/Aff_transformation_2.h>
|
||||
#include <CGAL/Regular_triangulation_filtered_traits_2.h>
|
||||
#include <CGAL/Triangulation_hyperbolic_traits_2.h>
|
||||
#include "../../../Hyperbolic_triangulation_2/include/CGAL/Triangulation_hyperbolic_traits_2.h"
|
||||
#include "boost/tuple/tuple.hpp"
|
||||
#include "boost/variant.hpp"
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
|
||||
template < class K, class Predicate_ >
|
||||
class Hyperbolic_traits_with_offsets_2_adaptor
|
||||
{
|
||||
typedef K Kernel;
|
||||
typedef Predicate_ Predicate;
|
||||
|
||||
typedef typename Kernel::Point_2 Point;
|
||||
typedef Hyperbolic_word_4<unsigned short int> Offset;
|
||||
|
||||
// Use the construct_point_2 predicate from the kernel to convert the periodic points to Euclidean points
|
||||
typedef typename Kernel::Construct_point_2 Construct_point_2;
|
||||
public:
|
||||
typedef typename Kernel::Circle_2 Circle_2;
|
||||
|
||||
public:
|
||||
typedef typename Predicate::result_type result_type;
|
||||
|
||||
Hyperbolic_traits_with_offsets_2_adaptor(const Circle_2 * dom) : _domain(dom) { }
|
||||
|
||||
result_type operator()(const Point& p0, const Point& p1,
|
||||
const Offset& o0, const Offset& o1) const
|
||||
{
|
||||
return Predicate()(pp(p0, o0), pp(p1, o1));
|
||||
}
|
||||
result_type operator()(const Point& p0, const Point& p1, const Point& p2,
|
||||
const Offset& o0, const Offset& o1, const Offset& o2) const
|
||||
{
|
||||
return Predicate()(pp(p0, o0), pp(p1, o1), pp(p2, o2));
|
||||
}
|
||||
result_type operator()(const Point& p0, const Point& p1,
|
||||
const Point& p2, const Point& p3,
|
||||
const Offset& o0, const Offset& o1,
|
||||
const Offset& o2, const Offset& o3) const
|
||||
{
|
||||
return Predicate()(pp(p0, o0), pp(p1, o1), pp(p2, o2), pp(p3, o3));
|
||||
}
|
||||
|
||||
result_type operator()(const Point& p0, const Point& p1) const
|
||||
{
|
||||
return Predicate()(p0, p1);
|
||||
}
|
||||
result_type operator()(const Point& p0, const Point& p1,
|
||||
const Point& p2) const
|
||||
{
|
||||
return Predicate()(p0, p1, p2);
|
||||
}
|
||||
result_type operator()(const Point& p0, const Point& p1,
|
||||
const Point& p2, const Point& p3) const
|
||||
{
|
||||
return Predicate()(p0, p1, p2, p3);
|
||||
}
|
||||
|
||||
private:
|
||||
Point pp(const Point &p, const Offset &o) const
|
||||
{
|
||||
return o.apply(p);
|
||||
}
|
||||
public:
|
||||
const Circle_2* _domain;
|
||||
};
|
||||
|
||||
|
||||
|
||||
template < typename K, typename Construct_point_base>
|
||||
class Periodic_4_hyperbolic_construct_point_2 : public Construct_point_base
|
||||
{
|
||||
typedef K Kernel;
|
||||
|
||||
public:
|
||||
typedef typename Kernel::Point_2 Point;
|
||||
typedef typename Kernel::Offset Offset;
|
||||
typedef typename Kernel::Circle_2 Circle_2;
|
||||
|
||||
typedef Point result_type;
|
||||
|
||||
Periodic_4_hyperbolic_construct_point_2(const Circle_2 & dom) : _dom(dom) { }
|
||||
|
||||
Point operator() ( const Point& p, const Offset& o ) const
|
||||
{
|
||||
return o.apply(p);
|
||||
}
|
||||
|
||||
private:
|
||||
Circle_2 _dom;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
template< class R >
|
||||
class Periodic_4_hyperbolic_Delaunay_triangulation_traits_2 {
|
||||
|
||||
public:
|
||||
|
||||
typedef R Kernel;
|
||||
typedef R K;
|
||||
typedef typename R::Kernel_base Kernel_base;
|
||||
typedef typename R::Direction_2 Direction_2;
|
||||
|
||||
typedef Periodic_4_hyperbolic_Delaunay_triangulation_traits_2<R>
|
||||
Self;
|
||||
|
||||
typedef Triangulation_hyperbolic_traits_2<R> Base;
|
||||
|
||||
// Basic types
|
||||
|
|
@ -70,26 +160,30 @@ public:
|
|||
typedef typename Base::Segment_2 Segment_2;
|
||||
typedef typename Base::Euclidean_line_2 Euclidean_line_2;
|
||||
|
||||
// Predicates and comparisons
|
||||
typedef typename Base::Less_x_2 Less_x_2;
|
||||
typedef typename Base::Less_y_2 Less_y_2;
|
||||
typedef typename Base::Compare_x_2 Compare_x_2;
|
||||
typedef typename Base::Compare_y_2 Compare_y_2;
|
||||
typedef typename Base::Orientation_2 Orientation_2;
|
||||
typedef typename Base::Side_of_oriented_circle_2 Side_of_oriented_circle_2;
|
||||
typedef typename Base::Compare_distance_2 Compare_distance_2;
|
||||
typedef typename Base::Compute_squared_distance_2 Compute_squared_distance_2;
|
||||
|
||||
// Constructions
|
||||
typedef typename Base::Construct_bisector_2 Construct_bisector_2;
|
||||
typedef typename Base::Construct_hyperbolic_bisector_2 Construct_hyperbolic_bisector_2;
|
||||
typedef typename Base::Construct_triangle_2 Construct_triangle_2;
|
||||
typedef typename Base::Construct_direction_2 Construct_direction_2;
|
||||
typedef typename Base::Construct_midpoint_2 Construct_midpoint_2;
|
||||
typedef typename Base::Construct_circumcenter_2 Construct_circumcenter_2;
|
||||
typedef typename Base::Construct_segment_2 Construct_segment_2;
|
||||
typedef typename Base::Construct_ray_2 Construct_ray_2;
|
||||
typedef typename Base::Is_hyperbolic Is_hyperbolic;
|
||||
|
||||
typedef Hyperbolic_traits_with_offsets_2_adaptor<Self, typename K::Less_x_2> Less_x_2;
|
||||
typedef Hyperbolic_traits_with_offsets_2_adaptor<Self, typename K::Less_y_2> Less_y_2;
|
||||
typedef Hyperbolic_traits_with_offsets_2_adaptor<Self, typename K::Compare_x_2> Compare_x_2;
|
||||
typedef Hyperbolic_traits_with_offsets_2_adaptor<Self, typename K::Compare_y_2> Compare_y_2;
|
||||
typedef Hyperbolic_traits_with_offsets_2_adaptor<Self, typename K::Compare_xy_2> Compare_xy_2;
|
||||
typedef Hyperbolic_traits_with_offsets_2_adaptor<Self, typename K::Orientation_2> Orientation_2;
|
||||
typedef Hyperbolic_traits_with_offsets_2_adaptor<Self, typename K::Side_of_oriented_circle_2> Side_of_oriented_circle_2;
|
||||
typedef Hyperbolic_traits_with_offsets_2_adaptor<Self, typename K::Compute_squared_radius_2> Compute_squared_radius_2;
|
||||
typedef Hyperbolic_traits_with_offsets_2_adaptor<Self, typename K::Construct_center_2> Construct_center_2;
|
||||
typedef Hyperbolic_traits_with_offsets_2_adaptor<Self, typename K::Construct_circumcenter_2> Construct_circumcenter_2;
|
||||
typedef Hyperbolic_traits_with_offsets_2_adaptor<Self, typename K::Construct_bisector_2> Construct_bisector_2;
|
||||
typedef Periodic_4_hyperbolic_construct_point_2<Self, typename K::Construct_point_2> Construct_point_2;
|
||||
typedef Hyperbolic_traits_with_offsets_2_adaptor<Self, typename K::Construct_midpoint_2> Construct_midpoint_2;
|
||||
typedef Hyperbolic_traits_with_offsets_2_adaptor<Self, typename K::Compare_distance_2> Compare_distance_2;
|
||||
typedef Hyperbolic_traits_with_offsets_2_adaptor<Self, typename K::Construct_segment_2> Construct_segment_2;
|
||||
typedef Hyperbolic_traits_with_offsets_2_adaptor<Self, typename K::Construct_triangle_2> Construct_triangle_2;
|
||||
typedef Hyperbolic_traits_with_offsets_2_adaptor<Self, typename K::Construct_direction_2> Construct_direction_2;
|
||||
typedef Hyperbolic_traits_with_offsets_2_adaptor<Self, typename K::Construct_ray_2> Construct_ray_2;
|
||||
typedef Hyperbolic_traits_with_offsets_2_adaptor<Self,
|
||||
typename Base::Construct_hyperbolic_bisector_2> Construct_hyperbolic_bisector_2;
|
||||
typedef Hyperbolic_traits_with_offsets_2_adaptor<Self, typename Base::Is_hyperbolic> Is_hyperbolic;
|
||||
|
||||
private:
|
||||
Circle_2 _domain;
|
||||
|
|
@ -150,7 +244,7 @@ public:
|
|||
|
||||
Orientation_2
|
||||
orientation_2_object() const {
|
||||
return Orientation_2();
|
||||
return Orientation_2(&_domain);
|
||||
}
|
||||
|
||||
Side_of_oriented_circle_2
|
||||
|
|
@ -189,7 +283,7 @@ public:
|
|||
}
|
||||
|
||||
Is_hyperbolic
|
||||
Is_hyperbolic_object() const {
|
||||
is_hyperbolic_object() const {
|
||||
return Is_hyperbolic();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,78 +0,0 @@
|
|||
#ifndef CGAL_PERIODIC_4_HYPERBOLIC_OFFSET_H
|
||||
#define CGAL_PERIODIC_4_HYPERBOLIC_OFFSET_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <CGAL/Square_root_2_field.h>
|
||||
#include <CGAL/Hyperbolic_octagon_translation_matrix.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
typedef std::vector<int> Index_sequence;
|
||||
typedef std::pair<Hyperbolic_octagon_translation_matrix, Index_sequence> Word;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class Periodic_4_hyperbolic_offset {
|
||||
|
||||
private:
|
||||
Index_sequence _index_sequence;
|
||||
Hyperbolic_octagon_translation_matrix _Hyperbolic_octagon_translation_matrix;
|
||||
Word _word;
|
||||
std::vector<Hyperbolic_octagon_translation_matrix> _gens;
|
||||
|
||||
public:
|
||||
|
||||
Periodic_4_hyperbolic_offset(Index_sequence iw) {
|
||||
get_generators(_gens);
|
||||
_index_sequence = iw;
|
||||
|
||||
_Hyperbolic_octagon_translation_matrix = _gens[_index_sequence[0]];
|
||||
for (int i = 1; i < _index_sequence.size(); i++) {
|
||||
_Hyperbolic_octagon_translation_matrix = _Hyperbolic_octagon_translation_matrix * _gens[_index_sequence[i]];
|
||||
}
|
||||
|
||||
_word = Word(_Hyperbolic_octagon_translation_matrix, _index_sequence);
|
||||
}
|
||||
|
||||
void Get_word(Word& w) {
|
||||
w = Word(_word.first, _word.second);
|
||||
}
|
||||
|
||||
|
||||
pair<double, double> Apply_to(double x, double y) {
|
||||
return _Hyperbolic_octagon_translation_matrix.apply(x, y);
|
||||
}
|
||||
|
||||
|
||||
}; // class Periodic_4_hyperbolic_offset
|
||||
|
||||
|
||||
|
||||
} // namespace CGAL
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const CGAL::Index_sequence& w)
|
||||
{
|
||||
for (int i = 0; i < w.size() - 1; i++) {
|
||||
os << w[i] << " ";
|
||||
}
|
||||
os << w[w.size() - 1];
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const CGAL::Word& w)
|
||||
{
|
||||
os << w.first << ", ";
|
||||
for (int i = 0; i < w.second.size() - 1; i++) {
|
||||
os << w.second[i] << " ";
|
||||
}
|
||||
os << w.second[w.second.size() - 1];
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
#endif // CGAL_PERIODIC_4_HYPERBOLIC_OFFSET_H
|
||||
|
|
@ -0,0 +1,295 @@
|
|||
// Copyright (c) 1999-2016 INRIA Nancy - Grand Est (France).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org).
|
||||
// You can redistribute it and/or modify it under the terms of the GNU
|
||||
// General Public License as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// 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) : Monique Teillaud <Monique.Teillaud@sophia.inria.fr>
|
||||
// Iordan Iordanov <Iordan.Iordanov@loria.fr>
|
||||
|
||||
#ifndef CGAL_PERIODIC_4_HYPERBOLIC_TIANGULATION_DS_FACE_BASE_2
|
||||
#define CGAL_PERIODIC_4_HYPERBOLIC_TIANGULATION_DS_FACE_BASE_2
|
||||
|
||||
#include <CGAL/basic.h>
|
||||
#include <CGAL/Dummy_tds_2.h>
|
||||
#include <CGAL/triangulation_assertions.h>
|
||||
#include <CGAL/Hyperbolic_word_4.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template <typename TDS = void >
|
||||
class Periodic_4_hyperbolic_triangulation_ds_face_base_2 {
|
||||
public:
|
||||
typedef TDS Triangulation_data_structure;
|
||||
typedef typename TDS::Vertex_handle Vertex_handle;
|
||||
typedef typename TDS::Face_handle Face_handle;
|
||||
typedef typename TDS::Vertex Vertex;
|
||||
typedef typename TDS::Face Face;
|
||||
typedef unsigned short int Int;
|
||||
typedef Hyperbolic_word_4<Int> Offset;
|
||||
|
||||
template<typename TDS2>
|
||||
struct Rebind_TDS {
|
||||
typedef Periodic_4_hyperbolic_triangulation_ds_face_base_2<TDS2> Other;
|
||||
};
|
||||
|
||||
private:
|
||||
Face_handle N[3];
|
||||
Vertex_handle V[3];
|
||||
Offset o[3]; // Offsets for vertices
|
||||
Offset no[3]; // Offsets for neighboring faces (neighbor face i is opposite to vertex i)
|
||||
int face_number;
|
||||
|
||||
public:
|
||||
|
||||
Periodic_4_hyperbolic_triangulation_ds_face_base_2()
|
||||
#ifndef CGAL_CFG_NO_CPP0X_UNIFIED_INITIALIZATION_SYNTAX
|
||||
: o{Offset(), Offset(), Offset()}, no{Offset(), Offset(), Offset()}
|
||||
{}
|
||||
#else
|
||||
{
|
||||
set_offsets();
|
||||
}
|
||||
#endif
|
||||
|
||||
Periodic_4_hyperbolic_triangulation_ds_face_base_2(
|
||||
const Vertex_handle& v0, const Vertex_handle& v1,
|
||||
const Vertex_handle& v2)
|
||||
#ifndef CGAL_CFG_NO_CPP0X_UNIFIED_INITIALIZATION_SYNTAX
|
||||
: V{v0, v1, v2},
|
||||
o{Offset(), Offset(), Offset()}, no{Offset(), Offset(), Offset()}
|
||||
{
|
||||
set_neighbors();
|
||||
}
|
||||
#else
|
||||
{
|
||||
set_offsets();
|
||||
set_vertices(v0, v1, v2);
|
||||
set_neighbors();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
Periodic_4_hyperbolic_triangulation_ds_face_base_2(
|
||||
const Vertex_handle& v0, const Vertex_handle& v1,
|
||||
const Vertex_handle& v2, const Face_handle& n0,
|
||||
const Face_handle& n1, const Face_handle& n2)
|
||||
#ifndef CGAL_CFG_NO_CPP0X_UNIFIED_INITIALIZATION_SYNTAX
|
||||
: V{v0, v1, v2},
|
||||
N{n0, n1, n2},
|
||||
o{Offset(), Offset(), Offset()}, no{Offset(), Offset(), Offset()}
|
||||
{
|
||||
set_neighbors();
|
||||
}
|
||||
#else
|
||||
{
|
||||
set_offsets();
|
||||
set_vertices(v0, v1, v2);
|
||||
set_neighbors(n0, n1, n2);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// ACCESS
|
||||
|
||||
const Vertex_handle& vertex(int i) const {
|
||||
CGAL_triangulation_precondition( i >= 0 && i <= 2 );
|
||||
return V[i];
|
||||
}
|
||||
|
||||
|
||||
bool has_vertex(const Vertex_handle& v) const {
|
||||
return (V[0] == v) || (V[1] == v) || (V[2]== v);
|
||||
}
|
||||
|
||||
|
||||
int index(const Vertex_handle& v) const {
|
||||
if (v == V[0]) { return 0; }
|
||||
if (v == V[1]) { return 1; }
|
||||
CGAL_triangulation_assertion( v == V[2] );
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
const Face_handle& neighbor(int i) const {
|
||||
CGAL_triangulation_precondition( i >= 0 && i <= 2);
|
||||
return N[i];
|
||||
}
|
||||
|
||||
|
||||
bool has_neighbor(const Face_handle& n) const {
|
||||
return (N[0] == n) || (N[1] == n) || (N[2] == n);
|
||||
}
|
||||
|
||||
|
||||
bool has_neighbor(const Face_handle& n, int & i) const {
|
||||
if(n == N[0]){ i = 0; return true; }
|
||||
if(n == N[1]){ i = 1; return true; }
|
||||
if(n == N[2]){ i = 2; return true; }
|
||||
return false;
|
||||
}
|
||||
|
||||
int index(const Face_handle& n) const {
|
||||
if (n == N[0]) return 0;
|
||||
if (n == N[1]) return 1;
|
||||
CGAL_triangulation_assertion( n == N[2] );
|
||||
return 2;
|
||||
}
|
||||
|
||||
Offset offset(int i) const {
|
||||
CGAL_triangulation_precondition( i >= 0 && i <= 2 );
|
||||
return o[i];
|
||||
}
|
||||
|
||||
|
||||
Offset neighbor_offset(int i) const {
|
||||
CGAL_triangulation_precondition( i >= 0 && i <= 2 );
|
||||
return no[i];
|
||||
}
|
||||
|
||||
|
||||
// SETTING
|
||||
|
||||
void set_number(int n) {
|
||||
face_number = n;
|
||||
}
|
||||
|
||||
int get_number() {
|
||||
return face_number;
|
||||
}
|
||||
|
||||
void set_offsets() {
|
||||
o[0] = Offset();
|
||||
o[1] = Offset();
|
||||
o[2] = Offset();
|
||||
no[0] = Offset();
|
||||
no[1] = Offset();
|
||||
no[2] = Offset();
|
||||
}
|
||||
|
||||
void set_offsets(
|
||||
const Offset& o0, const Offset& o1,
|
||||
const Offset& o2)
|
||||
{
|
||||
o[0] = o0;
|
||||
o[1] = o1;
|
||||
o[2] = o2;
|
||||
}
|
||||
|
||||
void set_neighbor_face_offsets(
|
||||
const Offset& no0, const Offset& no1,
|
||||
const Offset& no2)
|
||||
{
|
||||
no[0] = no0;
|
||||
no[1] = no1;
|
||||
no[2] = no2;
|
||||
}
|
||||
|
||||
void set_offsets(
|
||||
const Offset& o0, const Offset& o1,
|
||||
const Offset& o2, const Offset& no0,
|
||||
const Offset& no1, const Offset& no2)
|
||||
{
|
||||
o[0] = o0;
|
||||
o[1] = o1;
|
||||
o[2] = o2;
|
||||
no[0] = no0;
|
||||
no[1] = no1;
|
||||
no[2] = no2;
|
||||
}
|
||||
|
||||
void set_vertices() {
|
||||
V[0] = V[1] = V[2] = Vertex_handle();
|
||||
}
|
||||
|
||||
void set_vertices(
|
||||
const Vertex_handle& v0, const Vertex_handle v1,
|
||||
const Vertex_handle& v2)
|
||||
{
|
||||
V[0] = v0;
|
||||
V[1] = v1;
|
||||
V[2] = v2;
|
||||
}
|
||||
|
||||
void set_neighbors() {
|
||||
N[0] = N[1] = N[2] = Face_handle();
|
||||
}
|
||||
|
||||
void set_neighbors(
|
||||
const Face_handle& n0, const Face_handle& n1,
|
||||
const Face_handle& n2)
|
||||
{
|
||||
N[0] = n0;
|
||||
N[1] = n1;
|
||||
N[2] = n2;
|
||||
}
|
||||
|
||||
// CHECKING
|
||||
|
||||
// the following trivial is_valid allows
|
||||
// the user of derived cell base classes
|
||||
// to add their own purpose checking
|
||||
|
||||
bool is_valid(bool, int) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
// For use by Compact_container.
|
||||
void * for_compact_container() const { return N[0].for_compact_container(); }
|
||||
void * & for_compact_container() { return N[0].for_compact_container(); }
|
||||
|
||||
};
|
||||
|
||||
|
||||
template < class TDS >
|
||||
inline
|
||||
std::istream&
|
||||
operator>>(std::istream &is, Periodic_4_hyperbolic_triangulation_ds_face_base_2<TDS> &)
|
||||
// non combinatorial information. Default = nothing
|
||||
{
|
||||
return is;
|
||||
}
|
||||
|
||||
template < class TDS >
|
||||
inline
|
||||
std::ostream&
|
||||
operator<<(std::ostream &os,
|
||||
const Periodic_4_hyperbolic_triangulation_ds_face_base_2<TDS> &)
|
||||
// non combinatorial information. Default = nothing
|
||||
{
|
||||
return os;
|
||||
}
|
||||
|
||||
// Specialization for void.
|
||||
template <>
|
||||
class Periodic_4_hyperbolic_triangulation_ds_face_base_2<void>
|
||||
{
|
||||
public:
|
||||
typedef Dummy_tds_2 Triangulation_data_structure;
|
||||
typedef Triangulation_data_structure::Vertex_handle Vertex_handle;
|
||||
typedef Triangulation_data_structure::Face_handle Face_handle;
|
||||
template <typename TDS2>
|
||||
struct Rebind_TDS {
|
||||
typedef Periodic_4_hyperbolic_triangulation_ds_face_base_2<TDS2> Other;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
} // namespace CGAL
|
||||
|
||||
|
||||
#endif // CGAL_PERIODIC_4_HYPERBOLIC_TIANGULATION_DS_FACE_BASE_2
|
||||
|
|
@ -0,0 +1,166 @@
|
|||
// Copyright (c) 1999-2016 INRIA Nancy - Grand Est (France).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org).
|
||||
// You can redistribute it and/or modify it under the terms of the GNU
|
||||
// General Public License as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// 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) : Monique Teillaud <Monique.Teillaud@sophia.inria.fr>
|
||||
// Iordan Iordanov <Iordan.Iordanov@loria.fr>
|
||||
|
||||
|
||||
#ifndef CGAL_PERIODIC_4_HYPERBOLIC_TRIANGULATION_DS_VERTEX_BASE_2_H
|
||||
#define CGAL_PERIODIC_4_HYPERBOLIC_TRIANGULATION_DS_VERTEX_BASE_2_H
|
||||
|
||||
#include <CGAL/basic.h>
|
||||
#include <CGAL/Dummy_tds_2.h>
|
||||
#include <CGAL/Hyperbolic_word_4.h>
|
||||
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template< typename GT, typename TDS = void >
|
||||
class Periodic_4_hyperbolic_triangulation_ds_vertex_base_2 {
|
||||
public:
|
||||
typedef TDS Triangulation_data_structure;
|
||||
typedef typename TDS::Vertex_handle Vertex_handle;
|
||||
typedef typename TDS::Face_handle Face_handle;
|
||||
typedef typename GT::Point_2 Point;
|
||||
//typedef unsigned short int Int;
|
||||
//typedef Hyperbolic_word_4<Int> Offset;
|
||||
|
||||
template <typename TDS2>
|
||||
struct Rebind_TDS {
|
||||
typedef Periodic_4_hyperbolic_triangulation_ds_vertex_base_2<GT, TDS2> Other;
|
||||
};
|
||||
|
||||
private:
|
||||
Face_handle _face;
|
||||
//Offset _off; // NO OFFSET HERE!!!!
|
||||
//bool _offset_flag;
|
||||
int _idx;
|
||||
Point _p;
|
||||
|
||||
public:
|
||||
Periodic_4_hyperbolic_triangulation_ds_vertex_base_2() :
|
||||
_face()
|
||||
{}
|
||||
|
||||
Periodic_4_hyperbolic_triangulation_ds_vertex_base_2(const Point & p) :
|
||||
_face(), _p(p)
|
||||
{}
|
||||
|
||||
Periodic_4_hyperbolic_triangulation_ds_vertex_base_2(const Point & p, Face_handle fh) :
|
||||
_face(fh), _p(p)
|
||||
{}
|
||||
|
||||
Periodic_4_hyperbolic_triangulation_ds_vertex_base_2(const Face_handle& fh) :
|
||||
_face(fh)
|
||||
{}
|
||||
|
||||
const Face_handle& face() {
|
||||
return _face;
|
||||
}
|
||||
|
||||
void set_idx(int idx) {
|
||||
_idx = idx;
|
||||
}
|
||||
|
||||
int idx() {
|
||||
return _idx;
|
||||
}
|
||||
|
||||
void set_face(const Face_handle& fh) {
|
||||
_face = fh;
|
||||
}
|
||||
|
||||
void set_point(const Point & p) { _p = p; }
|
||||
|
||||
const Point& point() const { return _p; }
|
||||
|
||||
// the non const version of point() is undocument
|
||||
// but needed to make the point iterator works
|
||||
// using Lutz projection scheme
|
||||
Point& point() { return _p; }
|
||||
|
||||
/*
|
||||
const Offset& offset() {
|
||||
return _off;
|
||||
}
|
||||
|
||||
void set_offset(const Offset& off) {
|
||||
_off = off;
|
||||
_offset_flag = true;
|
||||
}
|
||||
|
||||
void clear_offset() {
|
||||
_offset_flag = false;
|
||||
_off = Offset();
|
||||
}
|
||||
|
||||
bool get_offset_flag() const {
|
||||
return _offset_flag;
|
||||
}
|
||||
*/
|
||||
|
||||
// the following trivial is_valid allows
|
||||
// the user of derived face base classes
|
||||
// to add their own purpose checking
|
||||
bool is_valid(bool = false, int = 0) const {
|
||||
return face() != Face_handle();
|
||||
}
|
||||
|
||||
// For use by the Compact_container.
|
||||
void * for_compact_container() const {
|
||||
return _face.for_compact_container();
|
||||
}
|
||||
|
||||
void * & for_compact_container() {
|
||||
return _face.for_compact_container();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template < class TDS >
|
||||
inline
|
||||
std::istream&
|
||||
operator>>(std::istream &is, Periodic_4_hyperbolic_triangulation_ds_vertex_base_2<TDS> &) {
|
||||
return is;
|
||||
}
|
||||
|
||||
template < class TDS >
|
||||
inline
|
||||
std::ostream&
|
||||
operator<<(std::ostream &os, Periodic_4_hyperbolic_triangulation_ds_vertex_base_2<TDS> &) {
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
// Specialization vor 'void'
|
||||
template<typename GT>
|
||||
class Periodic_4_hyperbolic_triangulation_ds_vertex_base_2<GT, void> {
|
||||
public:
|
||||
typedef Dummy_tds_2 Triangulation_data_structure;
|
||||
typedef Triangulation_data_structure::Vertex_handle Vertex_handle;
|
||||
typedef Triangulation_data_structure::Face_handle Face_handle;
|
||||
struct Point {};
|
||||
template<typename TDS2>
|
||||
struct Rebind_TDS {
|
||||
typedef Periodic_4_hyperbolic_triangulation_ds_vertex_base_2<GT, TDS2> Other;
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace CGAL
|
||||
|
||||
#endif // CGAL_PERIODIC_4_HYPERBOLIC_TRIANGULATION_DS_VERTEX_BASE_2_H
|
||||
|
|
@ -0,0 +1,289 @@
|
|||
// Copyright (c) 2016 INRIA Nancy - Grand Est (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) : Iordan Iordanov
|
||||
|
||||
#ifndef CGAL_PERIODIC_4_HYPERBOLIC_TRIANGULATION_DUMMY_14_H
|
||||
#define CGAL_PERIODIC_4_HYPERBOLIC_TRIANGULATION_DUMMY_14_H
|
||||
|
||||
#include <CGAL/Aff_transformation_2.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template<class Point, class Face_handle>
|
||||
Point barycenter(Face_handle fh) {
|
||||
Point p0 = fh->offset(0).apply(fh->vertex(0)->point());
|
||||
Point p1 = fh->offset(1).apply(fh->vertex(1)->point());
|
||||
Point p2 = fh->offset(2).apply(fh->vertex(2)->point());
|
||||
return Point( (p0.x() + p1.x() + p2.x())/3, (p0.y() + p1.y() + p2.y())/3 );
|
||||
}
|
||||
|
||||
template<class Point, class Face_handle>
|
||||
Point midpoint(Face_handle fh, int i, int j) {
|
||||
Point p0 = fh->offset(i).apply(fh->vertex(i)->point());
|
||||
Point p1 = fh->offset(j).apply(fh->vertex(j)->point());
|
||||
return Point( (p0.x() + p1.x())/2, (p0.y() + p1.y())/2 );
|
||||
}
|
||||
|
||||
template<class Point, class Face_handle>
|
||||
Point vertex(Face_handle fh, int i) {
|
||||
Point p0 = fh->offset(i).apply(fh->vertex(i)->point());
|
||||
return Point( p0.x(), p0.y() );
|
||||
}
|
||||
|
||||
template < class GT, class TDS >
|
||||
inline std::vector<typename Periodic_4_hyperbolic_triangulation_2<GT, TDS>::Vertex_handle >
|
||||
Periodic_4_hyperbolic_triangulation_2<GT, TDS>::
|
||||
insert_dummy_points() {
|
||||
|
||||
typedef typename GT::FT FT;
|
||||
|
||||
typedef Aff_transformation_2<GT> Transformation;
|
||||
Transformation rotate(ROTATION, FT(1)/CGAL::sqrt(FT(2)), FT(1)/CGAL::sqrt(FT(2)));
|
||||
|
||||
|
||||
int fcount = 32; // Faces count
|
||||
int vcount = 14; // Vertices count
|
||||
|
||||
FT F0 = FT(0);
|
||||
FT F1 = FT(1);
|
||||
FT F2 = FT(2);
|
||||
|
||||
std::vector<typename GT::Point_2> pts;
|
||||
pts.push_back(Point(FT( CGAL::sqrt(CGAL::sqrt(F2) + F1)/ F2 ), - FT( CGAL::sqrt(CGAL::sqrt(F2) - F1)/ F2) )); // v_0
|
||||
pts.push_back(Point(FT( CGAL::sqrt(CGAL::sqrt(F2) - F1)), F0)); // μ(s_0)
|
||||
pts.push_back(Point(FT( CGAL::sqrt( (CGAL::sqrt(F2) - F1) / F2) ), FT(CGAL::sqrt( (CGAL::sqrt(F2) - F1) / F2)) )); // μ(s_1)
|
||||
pts.push_back(Point(F0, FT( CGAL::sqrt(CGAL::sqrt(F2) - F1)))); // μ(s_2)
|
||||
pts.push_back(Point(-FT(CGAL::sqrt( (CGAL::sqrt(F2) - F1) / F2)), FT(CGAL::sqrt( (CGAL::sqrt(F2) - F1) / F2)) )); // μ(s_3)
|
||||
|
||||
FT num_x = FT( F2 + CGAL::sqrt(F2) - CGAL::sqrt(FT(6)) );
|
||||
FT den_x = FT( FT(4)*CGAL::sqrt(CGAL::sqrt(F2) - F1) );
|
||||
FT xi = num_x/den_x;
|
||||
FT yi = FT( (CGAL::sqrt(F2) - F2*CGAL::sqrt(FT(3)) + CGAL::sqrt(FT(6))) / (FT(4)*CGAL::sqrt(CGAL::sqrt(F2) - F1)) );
|
||||
|
||||
Point a0(xi, yi);
|
||||
|
||||
/* Consistency reasons (has to be corresponding to vertex 5 of the figure) */
|
||||
a0 = rotate(a0);
|
||||
a0 = rotate(a0);
|
||||
a0 = rotate(a0);
|
||||
|
||||
pts.push_back(a0);
|
||||
for (int k = 1; k < 8; k++) {
|
||||
a0 = rotate(a0);
|
||||
pts.push_back(a0);
|
||||
}
|
||||
|
||||
pts.push_back(Point( FT(0), FT(0) ));
|
||||
|
||||
|
||||
int tri[32][3] = {
|
||||
{ 0, 1, 9}, // 0
|
||||
{ 1, 10, 9}, // 1
|
||||
{ 0, 10, 1}, // 2
|
||||
{ 0, 2, 10}, // 3
|
||||
{ 0, 11, 2}, // 4
|
||||
{ 0, 3, 11}, // 5
|
||||
{ 0, 12, 3}, // 6
|
||||
{ 0, 4, 12}, // 7
|
||||
{ 0, 5, 4}, // 8
|
||||
{ 0, 1, 5}, // 9
|
||||
{ 0, 6, 1}, // 10
|
||||
{ 0, 2, 6}, // 11
|
||||
{ 0, 7, 2}, // 12
|
||||
{ 0, 3, 7}, // 13
|
||||
{ 0, 8, 3}, // 14
|
||||
{ 0, 4, 8}, // 15
|
||||
{ 0, 9, 4}, // 16
|
||||
{ 2, 11, 10}, // 17
|
||||
{ 3, 12, 11}, // 18
|
||||
{ 4, 5, 12}, // 19
|
||||
{ 1, 6, 5}, // 20
|
||||
{ 2, 7, 6}, // 21
|
||||
{ 3, 8, 7}, // 22
|
||||
{ 4, 9, 8}, // 23
|
||||
{ 9, 10, 13}, // 24
|
||||
{ 10, 11, 13}, // 25
|
||||
{ 11, 12, 13}, // 26
|
||||
{ 5, 13, 12}, // 27
|
||||
{ 5, 6, 13}, // 28
|
||||
{ 6, 7, 13}, // 29
|
||||
{ 7, 8, 13}, // 30
|
||||
{ 8, 9, 13}, // 31
|
||||
};
|
||||
|
||||
|
||||
Offset off[32][3] = {
|
||||
{ Offset(), Offset(), Offset() }, // 0
|
||||
{ Offset(), Offset(), Offset() }, // 1
|
||||
{ Offset(1,6,3), Offset(), Offset() }, // 2
|
||||
{ Offset(1,6,3), Offset(), Offset() }, // 3
|
||||
{ Offset(1,4), Offset(), Offset() }, // 4
|
||||
{ Offset(1,4), Offset(), Offset() }, // 5
|
||||
{ Offset(3), Offset(), Offset() }, // 6
|
||||
{ Offset(3), Offset(), Offset() }, // 7
|
||||
{ Offset(3,6,1,4), Offset(), Offset() }, // 8
|
||||
{ Offset(3,6,1,4), Offset(4), Offset() }, // 9
|
||||
{ Offset(4), Offset(), Offset(4)}, // 10
|
||||
{ Offset(4), Offset(5), Offset() }, // 11
|
||||
{ Offset(6,3), Offset(), Offset(5)}, // 12
|
||||
{ Offset(6,3), Offset(6), Offset() }, // 13
|
||||
{ Offset(6,1,4), Offset(), Offset(6)}, // 14
|
||||
{ Offset(6,1,4), Offset(7), Offset() }, // 15
|
||||
{ Offset(), Offset(), Offset(7)}, // 16
|
||||
{ Offset(), Offset(), Offset() }, // 17
|
||||
{ Offset(), Offset(), Offset() }, // 18
|
||||
{ Offset(), Offset(), Offset() }, // 19
|
||||
{ Offset(4), Offset(), Offset() }, // 20
|
||||
{ Offset(5), Offset(), Offset() }, // 21
|
||||
{ Offset(6), Offset(), Offset() }, // 22
|
||||
{ Offset(7), Offset(), Offset() }, // 23
|
||||
{ Offset(), Offset(), Offset() }, // 24
|
||||
{ Offset(), Offset(), Offset() }, // 25
|
||||
{ Offset(), Offset(), Offset() }, // 26
|
||||
{ Offset(), Offset(), Offset() }, // 27
|
||||
{ Offset(), Offset(), Offset() }, // 28
|
||||
{ Offset(), Offset(), Offset() }, // 29
|
||||
{ Offset(), Offset(), Offset() }, // 30
|
||||
{ Offset(), Offset(), Offset() }, // 31
|
||||
};
|
||||
|
||||
Offset noff[32][3] = {
|
||||
{ Offset(), Offset(), Offset(0)}, // 0
|
||||
{ Offset(), Offset(), Offset() }, // 1
|
||||
{ Offset(), Offset(0), Offset() }, // 2
|
||||
{ Offset(), Offset(), Offset(1)}, // 3
|
||||
{ Offset(), Offset(1), Offset() }, // 4
|
||||
{ Offset(), Offset(), Offset(2)}, // 5
|
||||
{ Offset(), Offset(2), Offset() }, // 6
|
||||
{ Offset(), Offset(), Offset(3)}, // 7
|
||||
{ Offset(), Offset(3), Offset() }, // 8
|
||||
{ Offset(), Offset(), Offset(4)}, // 9
|
||||
{ Offset(), Offset(4), Offset() }, // 10
|
||||
{ Offset(), Offset(), Offset(5)}, // 11
|
||||
{ Offset(), Offset(5), Offset() }, // 12
|
||||
{ Offset(), Offset(), Offset(6)}, // 13
|
||||
{ Offset(), Offset(6), Offset() }, // 14
|
||||
{ Offset(), Offset(), Offset(7)}, // 15
|
||||
{ Offset(), Offset(7), Offset() }, // 16
|
||||
{ Offset(), Offset(), Offset() }, // 17
|
||||
{ Offset(), Offset(), Offset() }, // 18
|
||||
{ Offset(), Offset(), Offset() }, // 19
|
||||
{ Offset(), Offset(), Offset() }, // 20
|
||||
{ Offset(), Offset(), Offset() }, // 21
|
||||
{ Offset(), Offset(), Offset() }, // 22
|
||||
{ Offset(), Offset(), Offset() }, // 23
|
||||
{ Offset(), Offset(), Offset() }, // 24
|
||||
{ Offset(), Offset(), Offset() }, // 25
|
||||
{ Offset(), Offset(), Offset() }, // 26
|
||||
{ Offset(), Offset(), Offset() }, // 27
|
||||
{ Offset(), Offset(), Offset() }, // 28
|
||||
{ Offset(), Offset(), Offset() }, // 29
|
||||
{ Offset(), Offset(), Offset() }, // 30
|
||||
{ Offset(), Offset(), Offset() }, // 31
|
||||
};
|
||||
|
||||
int nbr[32][3] = {
|
||||
{ 1, 16, 10 }, // 0
|
||||
{ 24, 0, 2 }, // 1
|
||||
{ 1, 9, 3 }, // 2
|
||||
{ 17, 2, 12 }, // 3
|
||||
{ 17, 11, 5 }, // 4
|
||||
{ 18, 4, 14 }, // 5
|
||||
{ 18, 13, 7 }, // 6
|
||||
{ 19, 6, 16 }, // 7
|
||||
{ 19, 15, 9 }, // 8
|
||||
{ 20, 8, 2 }, // 9
|
||||
{ 20, 0, 11 }, // 10
|
||||
{ 21, 10, 4 }, // 11
|
||||
{ 21, 3, 13 }, // 12
|
||||
{ 22, 12, 6 }, // 13
|
||||
{ 22, 5, 15 }, // 14
|
||||
{ 23, 14, 8 }, // 15
|
||||
{ 23, 7, 0 }, // 16
|
||||
{ 25, 3, 4 }, // 17
|
||||
{ 26, 5, 6 }, // 18
|
||||
{ 27, 7, 8 }, // 19
|
||||
{ 28, 9, 10 }, // 20
|
||||
{ 29, 11, 12 }, // 21
|
||||
{ 30, 13, 14 }, // 22
|
||||
{ 31, 15, 16 }, // 23
|
||||
{ 25, 31, 1 }, // 24
|
||||
{ 26, 24, 17 }, // 25
|
||||
{ 27, 25, 18 }, // 26
|
||||
{ 26, 19, 28 }, // 27
|
||||
{ 29, 27, 20 }, // 28
|
||||
{ 30, 28, 21 }, // 29
|
||||
{ 31, 29, 22 }, // 30
|
||||
{ 24, 30, 23 }, // 31
|
||||
};
|
||||
|
||||
|
||||
Vertex_handle vertices[14];
|
||||
for (int i = 0; i < vcount; i++) {
|
||||
vertices[i] = _tds.create_vertex();
|
||||
vertices[i]->set_point(pts[i]);
|
||||
vertices[i]->set_idx(i);
|
||||
}
|
||||
|
||||
|
||||
Face_handle faces[32];
|
||||
for (int i = 0; i < fcount; i++) {
|
||||
int x, y, z;
|
||||
faces[i] = _tds.create_face(vertices[tri[i][0]], vertices[tri[i][1]], vertices[tri[i][2]]);
|
||||
faces[i]->set_number(i);
|
||||
}
|
||||
|
||||
|
||||
// This needs to be done AFTER the faces are created
|
||||
for (int i = 0; i < fcount; i++) {
|
||||
faces[i]->set_neighbors( faces[nbr[i][0]], faces[nbr[i][1]], faces[nbr[i][2]] );
|
||||
faces[i]->set_offsets( off[i][0], off[i][1], off[i][2] );
|
||||
faces[i]->set_neighbor_face_offsets(noff[i][0], noff[i][1], noff[i][2] );
|
||||
}
|
||||
|
||||
|
||||
vertices[ 0]->set_face(faces[ 0]);
|
||||
vertices[ 1]->set_face(faces[ 2]);
|
||||
vertices[ 2]->set_face(faces[ 4]);
|
||||
vertices[ 3]->set_face(faces[ 6]);
|
||||
vertices[ 4]->set_face(faces[ 8]);
|
||||
vertices[ 5]->set_face(faces[20]);
|
||||
vertices[ 6]->set_face(faces[21]);
|
||||
vertices[ 7]->set_face(faces[22]);
|
||||
vertices[ 8]->set_face(faces[23]);
|
||||
vertices[ 9]->set_face(faces[ 1]);
|
||||
vertices[10]->set_face(faces[17]);
|
||||
vertices[11]->set_face(faces[18]);
|
||||
vertices[12]->set_face(faces[19]);
|
||||
vertices[13]->set_face(faces[28]);
|
||||
|
||||
_tds.set_dimension(2);
|
||||
|
||||
std::vector<Vertex_handle> ret(vcount);
|
||||
for (int i = 0; i < vcount; i++) {
|
||||
ret.push_back(vertices[i]);
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace CGAL
|
||||
|
||||
#endif // CGAL_PERIODIC_4_HYPERBOLIC_TRIANGULATION_DUMMY_14_H
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 1997-2013 INRIA Sophia-Antipolis (France).
|
||||
// Copyright (c) 1999-2016 INRIA Nancy - Grand Est (France).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org).
|
||||
|
|
@ -15,35 +15,21 @@
|
|||
// $URL$
|
||||
// $Id$
|
||||
//
|
||||
// Author(s) : Nico Kruithof <Nico@nghk.nl>
|
||||
//
|
||||
// Author(s) : Monique Teillaud <Monique.Teillaud@sophia.inria.fr>
|
||||
// Iordan Iordanov <Iordan.Iordanov@loria.fr>
|
||||
|
||||
#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>
|
||||
#include <CGAL/iterator.h>
|
||||
|
||||
namespace CGAL
|
||||
{
|
||||
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.
|
||||
class Periodic_4_hyperbolic_triangulation_triangle_iterator_2 {
|
||||
|
||||
public:
|
||||
|
||||
|
|
@ -56,48 +42,37 @@ public:
|
|||
|
||||
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::Facet Facet;
|
||||
typedef typename T::Facet_iterator Facet_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) {}
|
||||
: _t(NULL), _it(it), _off() {}
|
||||
|
||||
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() )
|
||||
Periodic_4_hyperbolic_triangulation_triangle_iterator_2(const T * t, Iterator_type it = T::STORED)
|
||||
: _t(t), pos(_t->facets_begin()), _it(it), _off() {
|
||||
if (_it == T::UNIQUE || _it == T::UNIQUE_COVER_DOMAIN) {
|
||||
while (pos != _t->facets_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_4_hyperbolic_triangulation_triangle_iterator_2(const T* t, int, Iterator_type it = T::STORED)
|
||||
: _t(t), pos(_t->facets_end()), _it(it), _off() {}
|
||||
|
||||
Periodic_triangle_iterator& operator++()
|
||||
{
|
||||
switch (_it)
|
||||
{
|
||||
Periodic_triangle_iterator& operator++() {
|
||||
switch (_it) {
|
||||
case T::STORED:
|
||||
++pos;
|
||||
break;
|
||||
case T::UNIQUE:
|
||||
do
|
||||
{
|
||||
++pos;
|
||||
}
|
||||
while (pos != _t->faces_end() && !is_canonical());
|
||||
do { ++pos; } while (pos != _t->facets_end() && !is_canonical());
|
||||
break;
|
||||
case T::STORED_COVER_DOMAIN:
|
||||
case T::UNIQUE_COVER_DOMAIN:
|
||||
increment_domain();
|
||||
break;
|
||||
default:
|
||||
CGAL_triangulation_assertion(false);
|
||||
|
|
@ -105,23 +80,14 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
Periodic_triangle_iterator& operator--()
|
||||
{
|
||||
switch (_it)
|
||||
{
|
||||
Periodic_triangle_iterator& operator--() {
|
||||
switch (_it) {
|
||||
case T::STORED:
|
||||
--pos;
|
||||
break;
|
||||
case T::UNIQUE:
|
||||
do
|
||||
{
|
||||
--pos;
|
||||
}
|
||||
while (pos != _t->faces_begin() && !is_canonical());
|
||||
do { --pos; } while (pos != _t->facets_begin() && !is_canonical());
|
||||
break;
|
||||
case T::STORED_COVER_DOMAIN:
|
||||
case T::UNIQUE_COVER_DOMAIN:
|
||||
decrement_domain();
|
||||
};
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -142,7 +108,6 @@ public:
|
|||
|
||||
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;
|
||||
}
|
||||
|
|
@ -164,204 +129,52 @@ public:
|
|||
return &periodic_triangle;
|
||||
}
|
||||
|
||||
Face_iterator get_face() const
|
||||
Facet_iterator get_facet() const
|
||||
{
|
||||
return pos;
|
||||
}
|
||||
|
||||
private:
|
||||
const T* _t;
|
||||
Face_iterator pos; // current face.
|
||||
Facet_iterator pos; // current facet.
|
||||
Iterator_type _it;
|
||||
int _off; // current offset
|
||||
mutable Periodic_triangle periodic_triangle; // current triangle.
|
||||
Offset _off; // current offset
|
||||
mutable Periodic_triangle periodic_triangle; // 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()
|
||||
{
|
||||
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
|
||||
}
|
||||
return (off0.is_identity() && off1.is_identity() && off2.is_identity());
|
||||
}
|
||||
|
||||
// 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);
|
||||
void get_edge_offsets(Offset &off0, Offset &off1, Offset &off2) const {
|
||||
off0 = (pos+0)->second;
|
||||
off1 = (pos+1)->second;
|
||||
off2 = (pos+2)->second;
|
||||
}
|
||||
|
||||
// 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());
|
||||
Periodic_triangle construct_periodic_triangle() const {
|
||||
CGAL_triangulation_assertion(pos->first != typename T::Cell_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));
|
||||
return make_array(
|
||||
std::make_pair(pos->first->vertex(0)->point(),off0),
|
||||
std::make_pair(pos->first->vertex(1)->point(),off1),
|
||||
std::make_pair(pos->first->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.
|
||||
class Periodic_4_hyperbolic_triangulation_segment_iterator_2 {
|
||||
|
||||
public:
|
||||
|
||||
|
|
@ -382,14 +195,12 @@ public:
|
|||
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) {}
|
||||
: _t(NULL), _it(it), _off() {}
|
||||
|
||||
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)
|
||||
{
|
||||
: _t(t), pos(_t->edges_begin()), _it(it), _off() {
|
||||
if (_it == T::UNIQUE || _it == T::UNIQUE_COVER_DOMAIN) {
|
||||
while (pos != _t->edges_end() && !is_canonical() )
|
||||
++pos;
|
||||
}
|
||||
|
|
@ -398,25 +209,15 @@ public:
|
|||
// 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) {}
|
||||
: _t(t), pos(_t->edges_end()), _it(it), _off() {}
|
||||
|
||||
Periodic_segment_iterator& operator++()
|
||||
{
|
||||
switch (_it)
|
||||
{
|
||||
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();
|
||||
do { ++pos; } while (pos != _t->edges_end() && !is_canonical());
|
||||
break;
|
||||
default:
|
||||
CGAL_triangulation_assertion(false);
|
||||
|
|
@ -424,23 +225,14 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
Periodic_segment_iterator& operator--()
|
||||
{
|
||||
switch (_it)
|
||||
{
|
||||
Periodic_segment_iterator& operator--() {
|
||||
switch (_it) {
|
||||
case T::STORED:
|
||||
--pos;
|
||||
break;
|
||||
case T::UNIQUE:
|
||||
do
|
||||
{
|
||||
--pos;
|
||||
}
|
||||
while (pos != _t->edges_begin() && !is_canonical());
|
||||
do { --pos; } while (pos != _t->edges_begin() && !is_canonical());
|
||||
break;
|
||||
case T::STORED_COVER_DOMAIN:
|
||||
case T::UNIQUE_COVER_DOMAIN:
|
||||
decrement_domain();
|
||||
};
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -461,7 +253,6 @@ public:
|
|||
|
||||
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;
|
||||
}
|
||||
|
|
@ -491,174 +282,42 @@ private:
|
|||
const T* _t;
|
||||
Edge_iterator pos; // current edge.
|
||||
Iterator_type _it;
|
||||
int _off; // current offset
|
||||
Offset _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()
|
||||
{
|
||||
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
|
||||
}
|
||||
return (off0.is_identity() && off1.is_identity());
|
||||
}
|
||||
|
||||
// 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);
|
||||
void get_edge_offsets(Offset &off0, Offset &off1) const {
|
||||
off0 = (pos+0)->second;
|
||||
off1 = (pos+1)->second;
|
||||
}
|
||||
|
||||
// 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());
|
||||
Periodic_segment construct_periodic_segment() const {
|
||||
CGAL_triangulation_assertion(pos->first != typename T::Cell_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));
|
||||
std::make_pair(pos->first->vertex(0)->point(),off0),
|
||||
std::make_pair(pos->first->vertex(1)->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.
|
||||
class Periodic_4_hyperbolic_triangulation_point_iterator_2 {
|
||||
|
||||
public:
|
||||
typedef typename T::Periodic_point value_type;
|
||||
|
|
@ -669,7 +328,8 @@ public:
|
|||
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 Periodic_4_hyperbolic_triangulation_point_iterator_2<T>
|
||||
Periodic_point_iterator;
|
||||
|
||||
typedef typename T::Vertex Vertex;
|
||||
typedef typename T::Vertex_iterator Vertex_iterator;
|
||||
|
|
@ -680,37 +340,27 @@ public:
|
|||
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)
|
||||
{
|
||||
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)
|
||||
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)
|
||||
{
|
||||
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());
|
||||
do { ++pos; } while (pos != _t->vertices_end() && !is_canonical());
|
||||
break;
|
||||
default:
|
||||
CGAL_triangulation_assertion(false);
|
||||
|
|
@ -718,21 +368,15 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
Periodic_point_iterator& operator--()
|
||||
{
|
||||
switch (_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_begin() && !is_canonical());
|
||||
do { --pos; } while (pos != _t->vertices_begin() && !is_canonical());
|
||||
break;
|
||||
default:
|
||||
CGAL_triangulation_assertion(false);
|
||||
|
|
@ -756,7 +400,6 @@ public:
|
|||
|
||||
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;
|
||||
}
|
||||
|
|
@ -786,97 +429,63 @@ private:
|
|||
const T* _t;
|
||||
Vertex_iterator pos; // current vertex.
|
||||
Iterator_type _it;
|
||||
int _off; // current offset
|
||||
Offset _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());
|
||||
bool is_canonical() {
|
||||
return (pos.second.is_identity());
|
||||
}
|
||||
|
||||
Periodic_point construct_periodic_point() const
|
||||
{
|
||||
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);
|
||||
Offset off = pos->second;
|
||||
return std::make_pair(pos->point(),off);
|
||||
}
|
||||
};
|
||||
|
||||
namespace Periodic_4_hyperbolic_triangulation_2_internal
|
||||
{
|
||||
template <class T>
|
||||
class Domain_tester
|
||||
{
|
||||
class Domain_tester {
|
||||
const T *t;
|
||||
|
||||
public:
|
||||
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));
|
||||
bool operator()(const typename T::Vertex_iterator & v) const {
|
||||
return (!t->v.offset().is_identity());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Iterates over the vertices in a periodic triangulation that are
|
||||
// located inside the original cube.
|
||||
// located inside the original domain.
|
||||
// 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> >
|
||||
{
|
||||
: public Filter_iterator<typename T::Vertex_iterator, 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 Filter_iterator<Vertex_iterator, Domain_tester<T> > 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;
|
||||
}
|
||||
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();
|
||||
}
|
||||
operator Vertex_handle() const { return Base::base(); }
|
||||
};
|
||||
|
||||
} //namespace CGAL
|
||||
} // namespace CGAL
|
||||
|
||||
#endif // CGAL_PERIODIC_4_HYPERBOLIC_TRIANGULATION_ITERATORS_2_H
|
||||
|
|
@ -17,7 +17,7 @@ template <typename DT>
|
|||
class TriangulationConflictZone : public GraphicsViewInput
|
||||
{
|
||||
public:
|
||||
typedef typename DT::Geom_traits K;
|
||||
typedef typename DT::Geometric_traits K;
|
||||
typedef typename DT::Face_handle Face_handle;
|
||||
typedef typename DT::Point Point;
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ namespace Qt {
|
|||
template <typename T>
|
||||
class TriangulationGraphicsItem : public GraphicsItem
|
||||
{
|
||||
typedef typename T::Geom_traits Geom_traits;
|
||||
typedef typename T::Geometric_traits Geom_traits;
|
||||
public:
|
||||
TriangulationGraphicsItem(T* t_);
|
||||
|
||||
|
|
@ -165,7 +165,7 @@ TriangulationGraphicsItem<T>::drawAll(QPainter *painter)
|
|||
//delete
|
||||
QPen temp = painter->pen();
|
||||
QPen old = temp;
|
||||
temp.setWidthF(0.0035);
|
||||
temp.setWidthF(/*0.0035*/0.0025);
|
||||
painter->setPen(temp);
|
||||
//
|
||||
|
||||
|
|
@ -264,19 +264,19 @@ TriangulationGraphicsItem<T>::paintVertices(QPainter *painter)
|
|||
double py = to_double(it->point().y());
|
||||
double dist = px*px + py*py;
|
||||
if(dist > 0.25) {
|
||||
temp.setWidth(7);//6
|
||||
temp.setWidth(6);//6
|
||||
}
|
||||
if(dist > 0.64) {
|
||||
temp.setWidth(6);//5
|
||||
if(dist > 0.5) {
|
||||
temp.setWidth(5);//5
|
||||
}
|
||||
if(dist > 0.81) {
|
||||
temp.setWidth(6);//3
|
||||
if(dist > 0.7) {
|
||||
temp.setWidth(5);//3
|
||||
}
|
||||
if(dist > 0.92) {
|
||||
temp.setWidth(5);//3
|
||||
}
|
||||
if(dist > 0.98) {
|
||||
temp.setWidth(3);//3
|
||||
temp.setWidth(1);//3
|
||||
}
|
||||
painter->setPen(temp);
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ template <typename DT>
|
|||
class TriangulationPointInputAndConflictZone : public GraphicsViewInput
|
||||
{
|
||||
public:
|
||||
typedef typename DT::Geom_traits K;
|
||||
typedef typename DT::Geometric_traits K;
|
||||
typedef typename DT::Face_handle Face_handle;
|
||||
typedef typename DT::Point Point;
|
||||
|
||||
|
|
|
|||
|
|
@ -95,14 +95,14 @@ void
|
|||
VoronoiGraphicsItem<DT>::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget * /*w*/)
|
||||
{
|
||||
QRectF rect = option->exposedRect;
|
||||
PainterOstream<typename DT::Geom_traits> pos(painter, rect);
|
||||
PainterOstream<typename DT::Geometric_traits> pos(painter, rect);
|
||||
|
||||
painter->setPen(edgesPen());
|
||||
|
||||
// delete
|
||||
QPen temp = painter->pen();
|
||||
QPen old = temp;
|
||||
temp.setWidthF(0.01);
|
||||
temp.setWidthF(0.005);
|
||||
painter->setPen(temp);
|
||||
//
|
||||
|
||||
|
|
@ -111,8 +111,8 @@ VoronoiGraphicsItem<DT>::paint(QPainter *painter, const QStyleOptionGraphicsItem
|
|||
eit++){
|
||||
CGAL::Object o = dt->dual(eit);
|
||||
typename DT::Segment s;
|
||||
typename DT::Geom_traits::Ray_2 r;
|
||||
typename DT::Geom_traits::Line_2 l;
|
||||
typename DT::Geometric_traits::Ray_2 r;
|
||||
typename DT::Geometric_traits::Line_2 l;
|
||||
if(CGAL::assign(s,o)){
|
||||
pos << s;
|
||||
} else if(CGAL::assign(r,o)) {
|
||||
|
|
|
|||
|
|
@ -1,96 +0,0 @@
|
|||
// Copyright (c) 1999-2004,2006-2009,2014-2015 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) : Monique Teillaud <Monique.Teillaud@sophia.inria.fr>
|
||||
// Sylvain Pion <Sylvain.Pion@sophia.inria.fr>
|
||||
// Andreas Fabri <Andreas.Fabri@sophia.inria.fr>
|
||||
// Nico Kruithof <Nico.Kruithof@sophia.inria.fr>
|
||||
// Manuel Caroli <Manuel.Caroli@sophia.inria.fr>
|
||||
// Aymeric Pellé <Aymeric.Pelle@sophia.inria.fr>
|
||||
#ifndef CGAL_TRAITS_WITH_HYPERBOLIC_OFFSETS_ADAPTOR_H
|
||||
#define CGAL_TRAITS_WITH_HYPERBOLIC_OFFSETS_ADAPTOR_H
|
||||
|
||||
#include <CGAL/Square_root_2_field.h>
|
||||
#include <CGAL/Hyperbolic_octagon_group.h>
|
||||
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template < class K, class Functor_ >
|
||||
class Traits_with_hyperbolic_offsets_adaptor {
|
||||
typedef K Kernel;
|
||||
typedef Functor_ Functor;
|
||||
|
||||
typedef typename Kernel::Point_2 Point;
|
||||
typedef HyperbolicOctagonGroup Offset;
|
||||
|
||||
public:
|
||||
typedef typename Kernel::Circle_2 Circle_2;
|
||||
typedef typename Kernel::Construct_hyperbolic_point_2 Construct_hyperbolic_point_2;
|
||||
typedef typename Functor::result_type result_type;
|
||||
|
||||
Traits_with_hyperbolic_offsets_adaptor(const Circle_2 * dom) : _domain(dom) { }
|
||||
|
||||
result_type operator()(const Point& p0, const Point& p1,
|
||||
const Offset& o0, const Offset& o1) const {
|
||||
return Functor()(pp(p0,o0),pp(p1,o1));
|
||||
}
|
||||
result_type operator()(const Point& p0, const Point& p1, const Point& p2,
|
||||
const Offset& o0, const Offset& o1, const Offset& o2) const {
|
||||
return Functor()(pp(p0,o0),pp(p1,o1),pp(p2,o2));
|
||||
}
|
||||
result_type operator()(const Point& p0, const Point& p1,
|
||||
const Point& p2, const Point& p3,
|
||||
const Offset& o0, const Offset& o1,
|
||||
const Offset& o2, const Offset& o3) const {
|
||||
return Functor()(pp(p0,o0),pp(p1,o1),pp(p2,o2),pp(p3,o3));
|
||||
}
|
||||
result_type operator()(const Point& p0, const Point& p1,
|
||||
const Point& p2, const Point& p3, const Point& p4,
|
||||
const Offset& o0, const Offset& o1, const Offset& o2,
|
||||
const Offset& o3, const Offset& o4) const {
|
||||
return Functor()(pp(p0,o0),pp(p1,o1),pp(p2,o2),
|
||||
pp(p3,o3),pp(p4,o4));
|
||||
}
|
||||
|
||||
result_type operator()(const Point& p0, const Point& p1) const {
|
||||
return Functor()(p0, p1);
|
||||
}
|
||||
result_type operator()(const Point& p0, const Point& p1,
|
||||
const Point& p2) const {
|
||||
return Functor()(p0, p1, p2);
|
||||
}
|
||||
result_type operator()(const Point& p0, const Point& p1,
|
||||
const Point& p2, const Point& p3) const {
|
||||
return Functor()(p0, p1, p2, p3);
|
||||
}
|
||||
result_type operator()(const Point& p0, const Point& p1,
|
||||
const Point& p2, const Point& p3, const Point& p4) const {
|
||||
return Functor()(p0, p1, p2, p3, p4);
|
||||
}
|
||||
|
||||
protected:
|
||||
Point pp(const Point &p, const Offset &o) const {
|
||||
return Construct_point_2(*_domain)(p,o);
|
||||
}
|
||||
public:
|
||||
const Circle_2* _domain;
|
||||
};
|
||||
} // namespace CGAL
|
||||
|
||||
#endif /* CGAL_TRAITS_WITH_HYPERBOLIC_OFFSETS_ADAPTOR_H */
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
#ifndef TRANSLATION_INFO
|
||||
#define TRANSLATION_INFO
|
||||
|
||||
#include <CGAL/Hyperbolic_isometry_2.h>
|
||||
|
||||
template<typename String>
|
||||
class TranslationInfo
|
||||
{
|
||||
public:
|
||||
|
||||
TranslationInfo() : color(0)
|
||||
{
|
||||
}
|
||||
|
||||
TranslationInfo(const String& name, int new_color = 0)
|
||||
: name_of_translation(name), color(new_color)
|
||||
{
|
||||
}
|
||||
|
||||
void setString(const String& name)
|
||||
{
|
||||
name_of_translation = name;
|
||||
}
|
||||
|
||||
const String& toString() const
|
||||
{
|
||||
return name_of_translation;
|
||||
}
|
||||
|
||||
void setColor(int new_color)
|
||||
{
|
||||
color = new_color;
|
||||
}
|
||||
|
||||
int getColor() const
|
||||
{
|
||||
return color;
|
||||
}
|
||||
|
||||
private:
|
||||
String name_of_translation;
|
||||
|
||||
int color;
|
||||
};
|
||||
|
||||
template<typename String>
|
||||
TranslationInfo<String> operator + (const TranslationInfo<String>& l, const TranslationInfo<String>& r)
|
||||
{
|
||||
TranslationInfo<String> result;
|
||||
result.setString(l.toString() + r.toString());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename Gt, typename Info>
|
||||
class IsometryWithInfo : public CGAL::Hyperbolic_isometry_2<Gt>
|
||||
{
|
||||
public:
|
||||
typedef CGAL::Hyperbolic_isometry_2<Gt> Base;
|
||||
//typedef Base::Point Point;
|
||||
|
||||
IsometryWithInfo(const Base& base, const Info& new_info = Info()) : Base(base), _info(new_info)
|
||||
{
|
||||
}
|
||||
|
||||
IsometryWithInfo operator * (const IsometryWithInfo& other) const
|
||||
{
|
||||
Base base = this->Base::operator *(other);
|
||||
Info new_info = info() + other.info();
|
||||
|
||||
return IsometryWithInfo(base, new_info);
|
||||
}
|
||||
|
||||
const Info& info() const { return _info; }
|
||||
Info& info() { return _info; }
|
||||
|
||||
private:
|
||||
Info _info;
|
||||
};
|
||||
|
||||
#endif // TRANSLATION_INFO
|
||||
|
|
@ -1,208 +0,0 @@
|
|||
#ifndef CGAL_GROUP_OF_INDEX_2
|
||||
#define CGAL_GROUP_OF_INDEX_2
|
||||
|
||||
#include <Translations.h>
|
||||
|
||||
template<class Translation>
|
||||
class Group_of_index_2
|
||||
{
|
||||
public:
|
||||
typedef Element<Translation> Element_t;
|
||||
typedef typename Translation::FT FT;
|
||||
|
||||
typedef std::list<Element_t> List;
|
||||
typedef CGAL::Circulator_from_container<List> Circulator;
|
||||
typedef typename List::iterator List_iterator;
|
||||
typedef typename List::size_type Size_type;
|
||||
|
||||
typedef std::pair<Translation, int> Node;
|
||||
typedef std::vector<Node> Vector;
|
||||
|
||||
Group_of_index_2() : is_computed(false), l(&Translations<typename Translation::Geom_traits>::list())
|
||||
{
|
||||
}
|
||||
|
||||
void add_group(List* l_)
|
||||
{
|
||||
l = l_;
|
||||
|
||||
generate();
|
||||
}
|
||||
|
||||
List& list()
|
||||
{
|
||||
return l2;
|
||||
}
|
||||
|
||||
const List& list() const
|
||||
{
|
||||
return l2;
|
||||
}
|
||||
|
||||
/*
|
||||
template<class OutputIterator>
|
||||
OutputIterator group_of_index_2(OutputIterator oit) const
|
||||
{
|
||||
return std::copy(g2.begin(), g2.end(), oit);
|
||||
}*/
|
||||
|
||||
void generate()
|
||||
{
|
||||
if(!is_computed) {
|
||||
compute();
|
||||
refine();
|
||||
|
||||
is_computed = true;
|
||||
}
|
||||
}
|
||||
|
||||
List_iterator begin()
|
||||
{
|
||||
return l2.begin();
|
||||
}
|
||||
|
||||
List_iterator end()
|
||||
{
|
||||
return l2.end();
|
||||
}
|
||||
|
||||
Size_type number_of_elements() const
|
||||
{
|
||||
return l2.size();
|
||||
}
|
||||
|
||||
private:
|
||||
// the lists can not be copied.
|
||||
Group_of_index_2(const Group_of_index_2&);
|
||||
Group_of_index_2& operator= (const Group_of_index_2&) const;
|
||||
|
||||
bool is_computed;
|
||||
void compute();
|
||||
void compute_via_vector();
|
||||
|
||||
void refine(FT e = 0.000001);
|
||||
|
||||
List* l;
|
||||
List l2;
|
||||
Vector g;
|
||||
Vector g2;
|
||||
};
|
||||
|
||||
|
||||
template<class Translation>
|
||||
void Group_of_index_2<Translation>::refine(FT e)
|
||||
{
|
||||
typedef typename Translation::Geom_traits Gt;
|
||||
typedef typename Translation::complex complex;
|
||||
|
||||
Circulator begin(&l2);
|
||||
Circulator next = boost::next(begin);
|
||||
|
||||
if(begin == 0 || begin == next) {
|
||||
return;
|
||||
}
|
||||
|
||||
int steps_nb = l2.size();
|
||||
|
||||
for(int i = 0; i < steps_nb; i++, begin = next, next = boost::next(begin)) {
|
||||
complex dif_m = begin->g.m() - next->g.m();
|
||||
complex dif_n = begin->g.n() - next->g.n();
|
||||
|
||||
if(std::norm(dif_m) < e && std::norm(dif_n) < e) {
|
||||
l2.erase(begin->inverse.current_iterator());
|
||||
l2.erase(begin.current_iterator());
|
||||
|
||||
steps_nb--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class Translation>
|
||||
void Group_of_index_2<Translation>::compute_via_vector()
|
||||
{
|
||||
int nb = g.size();
|
||||
g2.resize(2*nb);
|
||||
|
||||
for(int i = 0; i < nb; i++) {
|
||||
int inv = g[i].second;
|
||||
int next_inv = (inv + 1) & nb-1;
|
||||
int prev_inv = (inv - 1) & nb-1;
|
||||
|
||||
g2[2*i].first = g[i].first*g[next_inv].first;
|
||||
// compute position of the inverse element of g2[2*i]
|
||||
int inv_pos = g[next_inv].second;
|
||||
g2[2*i].second = 2*inv_pos + 1;
|
||||
|
||||
g2[2*i + 1].first = g[i].first*g[prev_inv].first;
|
||||
// compute position of the inverse element of g2[2*i + 1]
|
||||
inv_pos = g[prev_inv].second;
|
||||
g2[2*i + 1].second = 2*inv_pos;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Translation>
|
||||
void Group_of_index_2<Translation>::compute()
|
||||
{
|
||||
typedef std::map<Element_t*, std::pair<Circulator, Circulator> > MapLtoL2;
|
||||
MapLtoL2 l_to_l2;
|
||||
typedef typename MapLtoL2::iterator Map_it;
|
||||
|
||||
l2.resize(2*l->size());
|
||||
|
||||
Circulator li(l);
|
||||
Circulator Next, Prev;
|
||||
Circulator l2i(&l2);
|
||||
|
||||
if(li == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// add g
|
||||
|
||||
do {
|
||||
Circulator item1 = l2i, item2 = boost::next(l2i);
|
||||
|
||||
Next = li->inverse;
|
||||
Next = boost::next(Next);
|
||||
item1->g = li->g * Next->g;
|
||||
|
||||
// aux value
|
||||
item1->inverse = Next->inverse;
|
||||
|
||||
Prev = li->inverse;
|
||||
Prev = boost::prior(Prev);
|
||||
item2->g = li->g * Prev->g;
|
||||
|
||||
// aux value
|
||||
item2->inverse = Prev->inverse;
|
||||
|
||||
l_to_l2.insert(std::make_pair(&*li, std::make_pair(item1, item2)));
|
||||
|
||||
li = boost::next(li);
|
||||
l2i = boost::next(l2i, 2);
|
||||
} while( li != Circulator( l ) );
|
||||
|
||||
// add inverse
|
||||
|
||||
int i = 0;
|
||||
l2i = Circulator(&l2);
|
||||
do {
|
||||
Map_it mit = l_to_l2.find(&*l2i->inverse);
|
||||
|
||||
assert(mit != l_to_l2.end());
|
||||
std::pair<Circulator, Circulator> val = mit->second;
|
||||
|
||||
if(i % 2 == 0) {
|
||||
l2i->inverse = val.second;
|
||||
} else {
|
||||
l2i->inverse = val.first;
|
||||
}
|
||||
|
||||
l2i++;
|
||||
i++;
|
||||
} while( l2i != Circulator( &l2 ) );
|
||||
}
|
||||
|
||||
#endif // CGAL_GROUP_OF_INDEX_2
|
||||
|
||||
|
|
@ -1,86 +0,0 @@
|
|||
#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);
|
||||
|
||||
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++) {
|
||||
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
|
||||
|
|
@ -1,183 +0,0 @@
|
|||
#ifndef CGAL_HYPERBOLIC_TRANSLATIONS_2_H
|
||||
#define CGAL_HYPERBOLIC_TRANSLATIONS_2_H
|
||||
|
||||
#include <CGAL/Hyperbolic_isometry_2.h>
|
||||
|
||||
template<typename Translation>
|
||||
struct Element
|
||||
{
|
||||
typedef typename std::list<Element> List;
|
||||
typedef CGAL::Circulator_from_container<List> Circulator;
|
||||
|
||||
Translation g;
|
||||
|
||||
// circulator iterator to an inverse translation in the list
|
||||
Circulator inverse;
|
||||
};
|
||||
|
||||
template<typename Gt>
|
||||
class Translations
|
||||
{
|
||||
public:
|
||||
typedef typename Gt::FT FT;
|
||||
typedef typename std::complex<FT> complex;
|
||||
typedef CGAL::Hyperbolic_isometry_2<Gt> Hyperbolic_isometry;
|
||||
|
||||
typedef Element<Hyperbolic_isometry> Element_t;
|
||||
typedef std::list<Element_t> List;
|
||||
typedef typename List::iterator List_iterator;
|
||||
typedef CGAL::Circulator_from_container<List> Circulator;
|
||||
|
||||
typedef std::pair<Hyperbolic_isometry, int> Node;
|
||||
typedef std::vector<Node> Vector;
|
||||
typedef typename Vector::iterator Vector_iterator;
|
||||
|
||||
|
||||
static Hyperbolic_isometry& a()
|
||||
{
|
||||
compute();
|
||||
return g[0].first;
|
||||
}
|
||||
|
||||
static Hyperbolic_isometry& b()
|
||||
{
|
||||
compute();
|
||||
return g[1].first;
|
||||
}
|
||||
|
||||
static Hyperbolic_isometry& c()
|
||||
{
|
||||
compute();
|
||||
return g[5].first;
|
||||
}
|
||||
|
||||
static Hyperbolic_isometry& d()
|
||||
{
|
||||
compute();
|
||||
return g[6].first;
|
||||
}
|
||||
|
||||
static const Vector& get_vector_of_translations()
|
||||
{
|
||||
compute();
|
||||
return g;
|
||||
}
|
||||
|
||||
static Vector_iterator vector_begin()
|
||||
{
|
||||
compute();
|
||||
return g.begin();
|
||||
}
|
||||
|
||||
static Vector_iterator vector_end()
|
||||
{
|
||||
compute();
|
||||
return g.end();
|
||||
}
|
||||
|
||||
static List_iterator list_begin()
|
||||
{
|
||||
compute();
|
||||
return l.begin();
|
||||
}
|
||||
|
||||
static List_iterator list_end()
|
||||
{
|
||||
compute();
|
||||
return l.end();
|
||||
}
|
||||
|
||||
static List& list()
|
||||
{
|
||||
compute();
|
||||
return l;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
static void compute_g()
|
||||
{
|
||||
const FT k1 = (FT(2) + CGAL::sqrt(2.))/FT(2);
|
||||
const FT k2 = CGAL::sqrt(CGAL::sqrt(2.));
|
||||
const FT k3 = (CGAL::sqrt(2.)*k2)/FT(2);
|
||||
|
||||
std::complex<FT> m(k1, k1);
|
||||
std::complex<FT> n(k2*k1, -k3);
|
||||
|
||||
g.resize(8);
|
||||
|
||||
// a
|
||||
g[0].first = Hyperbolic_isometry(conj(m), conj(n));
|
||||
g[0].second = 2;
|
||||
|
||||
// b
|
||||
g[3].first = Hyperbolic_isometry(m, -n);
|
||||
g[3].second = 1;
|
||||
// c
|
||||
g[4].first = Hyperbolic_isometry(conj(m), -conj(n));
|
||||
g[4].second = 6;
|
||||
// d
|
||||
g[7].first = Hyperbolic_isometry(m, n);
|
||||
g[7].second = 5;
|
||||
|
||||
int index = g[0].second;
|
||||
g[index].first = g[0].first.inverse();
|
||||
g[index].second = 0;
|
||||
|
||||
index = g[3].second;
|
||||
g[index].first = g[3].first.inverse();
|
||||
g[index].second = 3;
|
||||
|
||||
index = g[4].second;
|
||||
g[index].first = g[4].first.inverse();
|
||||
g[index].second = 4;
|
||||
|
||||
index = g[7].second;
|
||||
g[index].first = g[7].first.inverse();
|
||||
g[index].second = 7;
|
||||
}
|
||||
|
||||
|
||||
static void compute_l()
|
||||
{
|
||||
l.resize(g.size());
|
||||
|
||||
std::vector<Circulator> aux_list;
|
||||
aux_list.reserve(8);
|
||||
|
||||
for(List_iterator li = l.begin(); li != l.end(); li++) {
|
||||
aux_list.push_back( Circulator(&l, li) );
|
||||
}
|
||||
|
||||
for(typename List::size_type i = 0; i < aux_list.size(); i++) {
|
||||
aux_list[i]->g = g[i].first;
|
||||
aux_list[i]->inverse = aux_list[g[i].second];
|
||||
}
|
||||
}
|
||||
|
||||
static void compute()
|
||||
{
|
||||
static bool computed = false;
|
||||
if(!computed) {
|
||||
compute_g();
|
||||
compute_l();
|
||||
computed = true;
|
||||
}
|
||||
}
|
||||
|
||||
static Vector g;
|
||||
|
||||
static List l;
|
||||
};
|
||||
|
||||
// default initialization
|
||||
|
||||
template<typename Gt>
|
||||
typename Translations<Gt>::Vector
|
||||
Translations<Gt>::g;
|
||||
|
||||
template<typename Gt>
|
||||
typename Translations<Gt>::List
|
||||
Translations<Gt>::l;
|
||||
|
||||
#endif // CGAL_HYPERBOLIC_TRANSLATIONS_2_H
|
||||
|
|
@ -1,729 +0,0 @@
|
|||
// to compile with boost headers
|
||||
// g++ main.cpp -I /opt/local/include -o main
|
||||
|
||||
#include <complex>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <iterator>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <assert.h>
|
||||
//#include <unordered_set>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
|
||||
//#include <boost/optional.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
||||
template<class Int>
|
||||
class Sqrt_field
|
||||
{
|
||||
public:
|
||||
typedef Int Integer;
|
||||
|
||||
Int l;
|
||||
Int r;
|
||||
|
||||
public:
|
||||
Sqrt_field(Int l_ = 0, Int r_ = 0) : l(l_), r(r_) {}
|
||||
|
||||
Sqrt_field operator + (const Sqrt_field& rh) const
|
||||
{
|
||||
Sqrt_field temp = *this;
|
||||
temp += rh;
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
Sqrt_field& operator += (const Sqrt_field& rh)
|
||||
{
|
||||
l += rh.l;
|
||||
r += rh.r;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Sqrt_field& operator -= (const Sqrt_field& rh)
|
||||
{
|
||||
l -= rh.l;
|
||||
r -= rh.r;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Sqrt_field operator - (const Sqrt_field& rh) const
|
||||
{
|
||||
return Sqrt_field( l - rh.l, r - rh.r );
|
||||
}
|
||||
|
||||
Sqrt_field operator - () const
|
||||
{
|
||||
return Sqrt_field(-l, -r);
|
||||
}
|
||||
|
||||
Sqrt_field operator * (const Sqrt_field& rh) const
|
||||
{
|
||||
Sqrt_field temp = *this;
|
||||
temp *= rh;
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
Sqrt_field& operator *= (const Sqrt_field& rh)
|
||||
{
|
||||
Int l1 = l * rh.l + 2*r*rh.r;
|
||||
Int r1 = r*rh.l + l*rh.r;
|
||||
l = l1;
|
||||
r = r1;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Sqrt_field abs() const
|
||||
{
|
||||
if (l >= 0 && r >= 0) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
if (l <= 0 && r <= 0) {
|
||||
return Sqrt_field(-l, -r);
|
||||
}
|
||||
|
||||
if(l*l*l - 2*r*r*l >= 0) {
|
||||
return *this;
|
||||
}
|
||||
return Sqrt_field(-l, -r);
|
||||
}
|
||||
};
|
||||
|
||||
template<class Int>
|
||||
bool operator < (const Sqrt_field<Int>& lh, const Sqrt_field<Int>& rh)
|
||||
{
|
||||
if( (lh.l - rh.l)*(lh.l - rh.l) > 2*(rh.r - lh.r)*(rh.r - lh.r) ) {
|
||||
if ((lh.l - rh.l) < 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if( (lh.l - rh.l)*(lh.l - rh.l) < 2*(rh.r - lh.r)*(rh.r - lh.r) ) {
|
||||
if ((rh.r - lh.r) >= 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
/*
|
||||
if (lh.l < rh.l) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (lh.l == rh.l) {
|
||||
if (lh.r < rh.r) {
|
||||
return true;
|
||||
}
|
||||
}*/
|
||||
|
||||
return false;
|
||||
}
|
||||
/*Seems correct!
|
||||
template<class Int>
|
||||
bool operator > (const Sqrt_field<Int>& lh, const Sqrt_field<Int>& rh)
|
||||
{
|
||||
if( (lh.l - rh.l)*(lh.l - rh.l) > 2*(rh.r - lh.r)*(rh.r - lh.r) ) {
|
||||
if ((lh.l - rh.l) >= 0 && (rh.r - lh.r) >= 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if( (lh.l - rh.l)*(lh.l - rh.l) < 2*(rh.r - lh.r)*(rh.r - lh.r) ) {
|
||||
if ((lh.l - rh.l) <= 0 && (rh.r - lh.r) <= 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}*/
|
||||
|
||||
template<class Int>
|
||||
bool operator >= (const Sqrt_field<Int>& lh, const Sqrt_field<Int>& rh)
|
||||
{
|
||||
if( (lh.l - rh.l)*(lh.l - rh.l) >= 2*(rh.r - lh.r)*(rh.r - lh.r) ) {
|
||||
if ((lh.l - rh.l) >= 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if( (lh.l - rh.l)*(lh.l - rh.l) < 2*(rh.r - lh.r)*(rh.r - lh.r) ) {
|
||||
if ((rh.r - lh.r) < 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template<class Int>
|
||||
bool operator == (const Sqrt_field<Int>& lh, const Sqrt_field<Int>& rh)
|
||||
{
|
||||
return (lh.l == rh.l && lh.r == rh.r);
|
||||
}
|
||||
|
||||
template<class Int>
|
||||
bool operator != (const Sqrt_field<Int>& lh, const Sqrt_field<Int>& rh)
|
||||
{
|
||||
return !(lh == rh);
|
||||
}
|
||||
|
||||
template<class Int>
|
||||
Sqrt_field<Int> operator * (const Int& val, const Sqrt_field<Int>& rh)
|
||||
{
|
||||
Sqrt_field<Int> temp = rh;
|
||||
temp.l *= val;
|
||||
temp.r *= val;
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
template<class Int>
|
||||
ostream& operator<<(ostream& os, const Sqrt_field<Int>& nb)
|
||||
{
|
||||
os << nb.l << " " << nb.r;
|
||||
return os;
|
||||
}
|
||||
|
||||
// begin MT - added to please libc++
|
||||
template<class Int>
|
||||
bool isnan(const Sqrt_field<Int>& x)
|
||||
{
|
||||
return false; // MT TBD
|
||||
}
|
||||
|
||||
template<class Int>
|
||||
bool isinf(const Sqrt_field<Int>& x)
|
||||
{
|
||||
return false; // MT TBD
|
||||
}
|
||||
|
||||
template<class Int>
|
||||
Sqrt_field<Int> copysign(const Sqrt_field<Int>& x, const Sqrt_field<Int>& y)
|
||||
{
|
||||
if (y.abs()==y)
|
||||
{ return x;}
|
||||
return -x;
|
||||
}
|
||||
// end MT - added to please libc++
|
||||
|
||||
template<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;
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
# Created by the script cgal_create_cmake_script
|
||||
# This is the CMake script for compiling a CGAL application.
|
||||
|
||||
|
||||
project( Periodic_4_hyperbolic_triangulation_2_test )
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.10)
|
||||
|
||||
find_package(CGAL QUIET COMPONENTS Core )
|
||||
|
||||
if ( CGAL_FOUND )
|
||||
|
||||
include( ${CGAL_USE_FILE} )
|
||||
|
||||
include( CGAL_CreateSingleSourceCGALProgram )
|
||||
|
||||
include_directories (BEFORE "../../include")
|
||||
|
||||
create_single_source_cgal_program( "test_p4ht2_dummy_points.cpp" )
|
||||
|
||||
else()
|
||||
|
||||
message(STATUS "This program requires the CGAL library, and will not be compiled.")
|
||||
|
||||
endif()
|
||||
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
|
||||
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <boost/random/linear_congruential.hpp>
|
||||
#include <boost/random/uniform_smallint.hpp>
|
||||
#include <boost/random/variate_generator.hpp>
|
||||
|
||||
#include <CGAL/Periodic_4_hyperbolic_Delaunay_triangulation_2.h>
|
||||
#include <CGAL/Periodic_4_hyperbolic_Delaunay_triangulation_traits_2.h>
|
||||
#include <CGAL/Periodic_4_hyperbolic_triangulation_dummy_14.h>
|
||||
#include <CGAL/CORE_Expr.h>
|
||||
#include <CGAL/Cartesian.h>
|
||||
#include <CGAL/determinant.h>
|
||||
|
||||
|
||||
typedef CORE::Expr NT;
|
||||
typedef CGAL::Cartesian<NT> Kernel;
|
||||
typedef CGAL::Periodic_4_hyperbolic_Delaunay_triangulation_traits_2<Kernel> Traits;
|
||||
typedef CGAL::Periodic_4_hyperbolic_Delaunay_triangulation_2<Traits> Triangulation;
|
||||
|
||||
typedef Triangulation::Point_2 Point_2;
|
||||
typedef Triangulation::Face_handle Face_handle;
|
||||
typedef Triangulation::Vertex_handle Vertex_handle;
|
||||
typedef Triangulation::Locate_type Locate_type;
|
||||
|
||||
typedef std::pair<Vertex_handle, Vertex_handle> Edge;
|
||||
typedef unsigned short int Int;
|
||||
typedef CGAL::Hyperbolic_word_4<Int> Offset;
|
||||
typedef std::pair<Edge, bool> OEdge;
|
||||
typedef std::set<OEdge> OEdgeSet;
|
||||
typedef OEdgeSet::iterator OEI;
|
||||
|
||||
int ccw(int i) {
|
||||
return (i+1)%3;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
|
||||
Triangulation tr;
|
||||
tr.insert_dummy_points();
|
||||
|
||||
cout << "Triangulation successfully initialized with dummy points!" << endl;
|
||||
cout << "Number of vertices: " << tr.number_of_vertices() << endl;
|
||||
cout << "Number of faces: " << tr.number_of_faces() << endl;
|
||||
cout << "Number of edges: " << tr.number_of_edges() << endl;
|
||||
cout << "Expected edges (by Euler relation): " << tr.number_of_vertices() + tr.number_of_faces() + 2 << endl;
|
||||
|
||||
cout << "Triangulation is valid: " << (tr.is_valid(true) ? "YES" : "NO") << endl;
|
||||
|
||||
assert(tr.is_valid());
|
||||
|
||||
return 0;
|
||||
}
|
||||