move our experimental package with its history to its new branch
|
|
@ -0,0 +1,62 @@
|
|||
========== code
|
||||
--- sqrt
|
||||
check whether and when an exact type is needed for sqrt.
|
||||
- sqrt can be kept eg for demos
|
||||
- when needed, replace the inexact CGAL::sqrt by the new type
|
||||
replacing CGAL::Root_of_2, see
|
||||
CGAL::https://cgal.geometryfactory.com/CGAL/Members/wiki/Features/Unique_sqrt_extension
|
||||
|
||||
Done. std::sqrt is replaced by CGAL::sqrt everywhere,
|
||||
because it's used only for computation of the Voronoi diagram.
|
||||
|
||||
--- use the Circular_kernel?
|
||||
because Do_intersect is in the Circular_kernel
|
||||
|
||||
Done. CGAL::do_intersect is a solution.
|
||||
No need for the Circular_kernel.
|
||||
|
||||
--- iterators
|
||||
- Finite_faces_iterator should return only faces marked HYPERBOLIC
|
||||
- for edges, rename adjacent_face to incident_face
|
||||
|
||||
Done.
|
||||
|
||||
--- interface
|
||||
provide a complete interface, like for the Euclidean package (adapted
|
||||
to the hyperbolic case of course)
|
||||
|
||||
In progress.
|
||||
|
||||
--- make Constrained_delaunay_... work with Hyperbolic_triangulation_2
|
||||
--- make Mesh_2 work with Hyperbolic_triangulation_2
|
||||
O.Faugeras and his student are waiting for it.
|
||||
|
||||
========== documentation
|
||||
to be written, so that the package can be submitted to the EB
|
||||
|
||||
========== test-suite
|
||||
to be written
|
||||
|
||||
========== demo
|
||||
--- fix bugs:
|
||||
- conflict regions (when inserting or in mode 'show conflict zone)
|
||||
show Euclidean triangles instead of hyperbolic triangles
|
||||
- in mode 'draw circumcenter', some triangles that are not in the
|
||||
hyperbolic DT appear, with their circle intersecting the infinite
|
||||
line. They should not appear.
|
||||
|
||||
Done
|
||||
|
||||
- However, we could think to add a specific mode allowing to show
|
||||
triangles that are not hyperbolic. Not sure whether this is interesting.
|
||||
- cosmetic detail: the title of the demo should mention "hyperbolic"
|
||||
|
||||
--- PainterOstream
|
||||
Is it clean for CGAL to have a local file?
|
||||
|
||||
I have to ask Laurent to make some members of PainterOstream protected.
|
||||
It allows me to have a local file with partial specialization of
|
||||
the class PainterOstream.
|
||||
I have to discuss with Laurent.
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
# Created by the script cgal_create_cmake_script
|
||||
# This is the CMake script for compiling a CGAL application.
|
||||
|
||||
project (Hyperbolic_Triangulation_2_demo)
|
||||
|
||||
cmake_minimum_required(VERSION 2.4.5)
|
||||
|
||||
set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
|
||||
|
||||
if ( COMMAND cmake_policy )
|
||||
cmake_policy( SET CMP0003 NEW )
|
||||
endif()
|
||||
|
||||
find_package(CGAL COMPONENTS Qt4)
|
||||
include(${CGAL_USE_FILE})
|
||||
|
||||
set( QT_USE_QTXML TRUE )
|
||||
set( QT_USE_QTMAIN TRUE )
|
||||
set( QT_USE_QTSCRIPT TRUE )
|
||||
set( QT_USE_QTOPENGL TRUE )
|
||||
|
||||
find_package(Qt4)
|
||||
|
||||
include_directories (BEFORE ${CGAL_DIR}/demo/Triangulation_2)
|
||||
include_directories (BEFORE ../../include)
|
||||
# demos contain their own headers
|
||||
include_directories (BEFORE include)
|
||||
|
||||
if ( CGAL_FOUND AND CGAL_Qt4_FOUND AND QT4_FOUND )
|
||||
|
||||
include(${QT_USE_FILE})
|
||||
|
||||
#--------------------------------
|
||||
# The "Delaunay" demo: Delaunay_triangulation_2
|
||||
#--------------------------------
|
||||
# UI files (Qt Designer files)
|
||||
qt4_wrap_ui( DT_UI_FILES ${CGAL_DIR}/demo/Triangulation_2/Delaunay_triangulation_2.ui )
|
||||
|
||||
# qrc files (resources files, that contain icons, at least)
|
||||
qt4_add_resources ( DT_RESOURCE_FILES ${CGAL_DIR}/demo/Triangulation_2/Delaunay_triangulation_2.qrc )
|
||||
|
||||
# use the Qt MOC preprocessor on classes that derives from QObject
|
||||
qt4_generate_moc( "Hyperbolic_Delaunay_triangulation_2_demo.cpp" "${CMAKE_CURRENT_BINARY_DIR}/Hyperbolic_Delaunay_triangulation_2_demo.moc" )
|
||||
|
||||
# The executable itself.
|
||||
add_executable ( Hyperbolic_Delaunay_triangulation_2_demo Hyperbolic_Delaunay_triangulation_2_demo.cpp Hyperbolic_Delaunay_triangulation_2_demo.moc ${DT_UI_FILES} ${DT_RESOURCE_FILES} )
|
||||
|
||||
add_to_cached_list( CGAL_EXECUTABLE_TARGETS Hyperbolic_Delaunay_triangulation_2_demo )
|
||||
|
||||
# Link with Qt libraries
|
||||
target_link_libraries( Hyperbolic_Delaunay_triangulation_2_demo ${QT_LIBRARIES} )
|
||||
# Link with CGAL
|
||||
target_link_libraries( Hyperbolic_Delaunay_triangulation_2_demo ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES})
|
||||
|
||||
#--------------------------------
|
||||
# The "hyperbolic" demo: Hyperbolic_translations_2
|
||||
#--------------------------------
|
||||
# UI files (Qt Designer files)
|
||||
qt4_wrap_ui( DT_UI_FILES ui/Hyperbolic_translations_2.ui )
|
||||
|
||||
# qrc files (resources files, that contain icons, at least)
|
||||
qt4_add_resources ( DT_RESOURCE_FILES resources/Hyperbolic_translations_2.qrc )
|
||||
|
||||
# use the Qt MOC preprocessor on classes that derives from QObject
|
||||
qt4_generate_moc( "Hyperbolic_translations_2_demo.cpp" "${CMAKE_CURRENT_BINARY_DIR}/Hyperbolic_translations_2_demo.moc" )
|
||||
|
||||
# The executable itself.
|
||||
add_executable ( Hyperbolic_translations_2_demo Hyperbolic_translations_2_demo.cpp Hyperbolic_translations_2_demo.moc ${DT_UI_FILES} ${DT_RESOURCE_FILES} )
|
||||
|
||||
add_to_cached_list( CGAL_EXECUTABLE_TARGETS Hyperbolic_translations_2_demo )
|
||||
|
||||
# Link with Qt libraries
|
||||
target_link_libraries( Hyperbolic_translations_2_demo ${QT_LIBRARIES} )
|
||||
# Link with CGAL
|
||||
target_link_libraries( Hyperbolic_translations_2_demo ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES})
|
||||
|
||||
else()
|
||||
|
||||
message(STATUS "NOTICE: This demo requires CGAL and Qt4, and will not be compiled.")
|
||||
|
||||
endif()
|
||||
|
|
@ -0,0 +1,424 @@
|
|||
#include <fstream>
|
||||
|
||||
// CGAL headers
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||
#include <CGAL/Delaunay_hyperbolic_triangulation_2.h>
|
||||
#include <CGAL/Triangulation_hyperbolic_traits_2.h>
|
||||
|
||||
// to be deleted
|
||||
#include <CGAL/Qt/HyperbolicPainterOstream.h>
|
||||
//
|
||||
|
||||
#include <CGAL/point_generators_2.h>
|
||||
|
||||
// Qt headers
|
||||
#include <QtGui>
|
||||
#include <QString>
|
||||
#include <QActionGroup>
|
||||
#include <QFileDialog>
|
||||
#include <QInputDialog>
|
||||
#include <QGraphicsEllipseItem>
|
||||
|
||||
// GraphicsView items and event filters (input classes)
|
||||
#include "TriangulationCircumcircle.h"
|
||||
|
||||
#include "TriangulationMovingPoint.h"
|
||||
#include "TriangulationConflictZone.h"
|
||||
#include "TriangulationRemoveVertex.h"
|
||||
#include "TriangulationPointInputAndConflictZone.h"
|
||||
#include <CGAL/Qt/TriangulationGraphicsItem.h>
|
||||
#include <CGAL/Qt/VoronoiGraphicsItem.h>
|
||||
|
||||
// for viewportsBbox
|
||||
#include <CGAL/Qt/utility.h>
|
||||
|
||||
// the two base classes
|
||||
#include "ui_Delaunay_triangulation_2.h"
|
||||
#include <CGAL/Qt/DemosMainWindow.h>
|
||||
|
||||
typedef CGAL::Exact_predicates_exact_constructions_kernel R;
|
||||
typedef CGAL::Triangulation_hyperbolic_traits_2<R> K;
|
||||
|
||||
typedef K::Point_2 Point_2;
|
||||
typedef K::Iso_rectangle_2 Iso_rectangle_2;
|
||||
|
||||
typedef CGAL::Delaunay_hyperbolic_triangulation_2<K> Delaunay;
|
||||
|
||||
class MainWindow :
|
||||
public CGAL::Qt::DemosMainWindow,
|
||||
public Ui::Delaunay_triangulation_2
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
Delaunay dt;
|
||||
QGraphicsEllipseItem* disk;
|
||||
QGraphicsScene scene;
|
||||
|
||||
CGAL::Qt::TriangulationGraphicsItem<Delaunay> * dgi;
|
||||
CGAL::Qt::VoronoiGraphicsItem<Delaunay> * vgi;
|
||||
|
||||
CGAL::Qt::TriangulationMovingPoint<Delaunay> * mp;
|
||||
CGAL::Qt::TriangulationConflictZone<Delaunay> * cz;
|
||||
CGAL::Qt::TriangulationRemoveVertex<Delaunay> * trv;
|
||||
CGAL::Qt::TriangulationPointInputAndConflictZone<Delaunay> * pi;
|
||||
CGAL::Qt::TriangulationCircumcircle<Delaunay> *tcc;
|
||||
public:
|
||||
MainWindow();
|
||||
|
||||
public slots:
|
||||
|
||||
void processInput(CGAL::Object o);
|
||||
|
||||
void on_actionMovingPoint_toggled(bool checked);
|
||||
|
||||
void on_actionShowConflictZone_toggled(bool checked);
|
||||
|
||||
void on_actionCircumcenter_toggled(bool checked);
|
||||
|
||||
void on_actionShowDelaunay_toggled(bool checked);
|
||||
|
||||
void on_actionShowVoronoi_toggled(bool checked);
|
||||
|
||||
void on_actionInsertPoint_toggled(bool checked);
|
||||
|
||||
void on_actionInsertRandomPoints_triggered();
|
||||
|
||||
void on_actionLoadPoints_triggered();
|
||||
|
||||
void on_actionSavePoints_triggered();
|
||||
|
||||
void on_actionClear_triggered();
|
||||
|
||||
void on_actionRecenter_triggered();
|
||||
|
||||
virtual void open(QString fileName);
|
||||
|
||||
signals:
|
||||
void changed();
|
||||
};
|
||||
|
||||
|
||||
MainWindow::MainWindow()
|
||||
: DemosMainWindow()
|
||||
{
|
||||
setupUi(this);
|
||||
|
||||
this->graphicsView->setAcceptDrops(false);
|
||||
|
||||
// Add Poincaré disk
|
||||
qreal origin_x = 0, origin_y = 0, radius = 100, diameter = 2*radius;
|
||||
qreal left_top_corner_x = origin_x - radius;
|
||||
qreal left_top_corner_y = origin_y - radius;
|
||||
qreal width = diameter, height = diameter;
|
||||
|
||||
disk = new QGraphicsEllipseItem(left_top_corner_x, left_top_corner_y, width, height);
|
||||
scene.addItem(disk);
|
||||
|
||||
// Add a GraphicItem for the Delaunay triangulation
|
||||
dgi = new CGAL::Qt::TriangulationGraphicsItem<Delaunay>(&dt);
|
||||
|
||||
QObject::connect(this, SIGNAL(changed()),
|
||||
dgi, SLOT(modelChanged()));
|
||||
|
||||
dgi->setVerticesPen(QPen(Qt::red, 3, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
|
||||
scene.addItem(dgi);
|
||||
|
||||
// Add a GraphicItem for the Voronoi diagram
|
||||
vgi = new CGAL::Qt::VoronoiGraphicsItem<Delaunay>(&dt);
|
||||
|
||||
QObject::connect(this, SIGNAL(changed()),
|
||||
vgi, SLOT(modelChanged()));
|
||||
|
||||
vgi->setEdgesPen(QPen(Qt::blue, 0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
|
||||
scene.addItem(vgi);
|
||||
vgi->hide();
|
||||
|
||||
// Setup input handlers. They get events before the scene gets them
|
||||
// and the input they generate is passed to the triangulation with
|
||||
// the signal/slot mechanism
|
||||
pi = new CGAL::Qt::TriangulationPointInputAndConflictZone<Delaunay>(&scene, &dt, this );
|
||||
|
||||
QObject::connect(pi, SIGNAL(generate(CGAL::Object)),
|
||||
this, SLOT(processInput(CGAL::Object)));
|
||||
|
||||
mp = new CGAL::Qt::TriangulationMovingPoint<Delaunay>(&dt, this);
|
||||
// TriangulationMovingPoint<Delaunay> emits a modelChanged() signal each
|
||||
// time the moving point moves.
|
||||
// The following connection is for the purpose of emitting changed().
|
||||
QObject::connect(mp, SIGNAL(modelChanged()),
|
||||
this, SIGNAL(changed()));
|
||||
|
||||
trv = new CGAL::Qt::TriangulationRemoveVertex<Delaunay>(&dt, this);
|
||||
QObject::connect(trv, SIGNAL(modelChanged()),
|
||||
this, SIGNAL(changed()));
|
||||
|
||||
tcc = new CGAL::Qt::TriangulationCircumcircle<Delaunay>(&scene, &dt, this);
|
||||
tcc->setPen(QPen(Qt::red, 0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
|
||||
|
||||
cz = new CGAL::Qt::TriangulationConflictZone<Delaunay>(&scene, &dt, this);
|
||||
|
||||
//
|
||||
// Manual handling of actions
|
||||
//
|
||||
|
||||
QObject::connect(this->actionQuit, SIGNAL(triggered()),
|
||||
this, SLOT(close()));
|
||||
|
||||
// We put mutually exclusive actions in an QActionGroup
|
||||
QActionGroup* ag = new QActionGroup(this);
|
||||
ag->addAction(this->actionInsertPoint);
|
||||
ag->addAction(this->actionMovingPoint);
|
||||
ag->addAction(this->actionCircumcenter);
|
||||
ag->addAction(this->actionShowConflictZone);
|
||||
|
||||
// Check two actions
|
||||
this->actionInsertPoint->setChecked(true);
|
||||
this->actionShowDelaunay->setChecked(true);
|
||||
|
||||
//
|
||||
// Setup the scene and the view
|
||||
//
|
||||
scene.setItemIndexMethod(QGraphicsScene::NoIndex);
|
||||
scene.setSceneRect(left_top_corner_x, left_top_corner_y, width, height);
|
||||
this->graphicsView->setScene(&scene);
|
||||
this->graphicsView->setMouseTracking(true);
|
||||
|
||||
// Turn the vertical axis upside down
|
||||
this->graphicsView->matrix().scale(1, -1);
|
||||
|
||||
// The navigation adds zooming and translation functionality to the
|
||||
// QGraphicsView
|
||||
this->addNavigation(this->graphicsView);
|
||||
|
||||
this->setupStatusBar();
|
||||
this->setupOptionsMenu();
|
||||
this->addAboutDemo(":/cgal/help/about_Delaunay_triangulation_2.html");
|
||||
this->addAboutCGAL();
|
||||
|
||||
this->addRecentFiles(this->menuFile, this->actionQuit);
|
||||
connect(this, SIGNAL(openRecentFile(QString)),
|
||||
this, SLOT(open(QString)));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MainWindow::processInput(CGAL::Object o)
|
||||
{
|
||||
Point_2 p;
|
||||
if(CGAL::assign(p, o)){
|
||||
QPointF qp(CGAL::to_double(p.x()), CGAL::to_double(p.y()));
|
||||
|
||||
// note that if the point is on the boundary then the disk contains the point
|
||||
if(disk->contains(qp)){
|
||||
dt.insert(p);
|
||||
}
|
||||
}
|
||||
emit(changed());
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Qt Automatic Connections
|
||||
* http://doc.trolltech.com/4.4/designer-using-a-component.html#automatic-connections
|
||||
*
|
||||
* setupUi(this) generates connections to the slots named
|
||||
* "on_<action_name>_<signal_name>"
|
||||
*/
|
||||
void
|
||||
MainWindow::on_actionInsertPoint_toggled(bool checked)
|
||||
{
|
||||
if(checked){
|
||||
scene.installEventFilter(pi);
|
||||
scene.installEventFilter(trv);
|
||||
} else {
|
||||
scene.removeEventFilter(pi);
|
||||
scene.removeEventFilter(trv);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MainWindow::on_actionMovingPoint_toggled(bool checked)
|
||||
{
|
||||
|
||||
if(checked){
|
||||
scene.installEventFilter(mp);
|
||||
} else {
|
||||
scene.removeEventFilter(mp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MainWindow::on_actionShowConflictZone_toggled(bool checked)
|
||||
{
|
||||
|
||||
if(checked){
|
||||
scene.installEventFilter(cz);
|
||||
} else {
|
||||
scene.removeEventFilter(cz);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::on_actionCircumcenter_toggled(bool checked)
|
||||
{
|
||||
if(checked){
|
||||
scene.installEventFilter(tcc);
|
||||
tcc->show();
|
||||
} else {
|
||||
scene.removeEventFilter(tcc);
|
||||
tcc->hide();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MainWindow::on_actionShowDelaunay_toggled(bool checked)
|
||||
{
|
||||
dgi->setVisibleEdges(checked);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MainWindow::on_actionShowVoronoi_toggled(bool checked)
|
||||
{
|
||||
vgi->setVisible(checked);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MainWindow::on_actionClear_triggered()
|
||||
{
|
||||
dt.clear();
|
||||
emit(changed());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MainWindow::on_actionInsertRandomPoints_triggered()
|
||||
{
|
||||
QRectF rect = CGAL::Qt::viewportsBbox(&scene);
|
||||
CGAL::Qt::Converter<K> convert;
|
||||
Iso_rectangle_2 isor = convert(rect);
|
||||
CGAL::Random_points_in_iso_rectangle_2<Point_2> pg(isor.min(), isor.max());
|
||||
bool ok = false;
|
||||
const int number_of_points =
|
||||
QInputDialog::getInteger(this,
|
||||
tr("Number of random points"),
|
||||
tr("Enter number of random points"),
|
||||
100,
|
||||
0,
|
||||
std::numeric_limits<int>::max(),
|
||||
1,
|
||||
&ok);
|
||||
|
||||
if(!ok) {
|
||||
return;
|
||||
}
|
||||
|
||||
// wait cursor
|
||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||
std::vector<Point_2> points;
|
||||
points.reserve(number_of_points);
|
||||
for(int i = 0; i < number_of_points; ++i){
|
||||
points.push_back(*pg++);
|
||||
}
|
||||
dt.insert(points.begin(), points.end());
|
||||
// default cursor
|
||||
QApplication::restoreOverrideCursor();
|
||||
emit(changed());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MainWindow::on_actionLoadPoints_triggered()
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName(this,
|
||||
tr("Open Points file"),
|
||||
".");
|
||||
if(! fileName.isEmpty()){
|
||||
open(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MainWindow::open(QString fileName)
|
||||
{
|
||||
// wait cursor
|
||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||
std::ifstream ifs(qPrintable(fileName));
|
||||
|
||||
K::Point_2 p;
|
||||
std::vector<K::Point_2> points;
|
||||
while(ifs >> p) {
|
||||
points.push_back(p);
|
||||
}
|
||||
dt.insert(points.begin(), points.end());
|
||||
|
||||
// default cursor
|
||||
QApplication::restoreOverrideCursor();
|
||||
this->addToRecentFiles(fileName);
|
||||
actionRecenter->trigger();
|
||||
emit(changed());
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::on_actionSavePoints_triggered()
|
||||
{
|
||||
QString fileName = QFileDialog::getSaveFileName(this,
|
||||
tr("Save points"),
|
||||
".");
|
||||
if(! fileName.isEmpty()){
|
||||
std::ofstream ofs(qPrintable(fileName));
|
||||
for(Delaunay::Finite_vertices_iterator
|
||||
vit = dt.finite_vertices_begin(),
|
||||
end = dt.finite_vertices_end();
|
||||
vit!= end; ++vit)
|
||||
{
|
||||
ofs << vit->point() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MainWindow::on_actionRecenter_triggered()
|
||||
{
|
||||
this->graphicsView->setSceneRect(dgi->boundingRect());
|
||||
this->graphicsView->fitInView(dgi->boundingRect(), Qt::KeepAspectRatio);
|
||||
}
|
||||
|
||||
|
||||
#include "Hyperbolic_Delaunay_triangulation_2_demo.moc"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
app.setOrganizationDomain("geometryfactory.com");
|
||||
app.setOrganizationName("GeometryFactory");
|
||||
app.setApplicationName("Delaunay_triangulation_2 demo");
|
||||
|
||||
// Import resources from libCGALQt4.
|
||||
// See http://doc.trolltech.com/4.4/qdir.html#Q_INIT_RESOURCE
|
||||
Q_INIT_RESOURCE(File);
|
||||
Q_INIT_RESOURCE(Triangulation_2);
|
||||
Q_INIT_RESOURCE(Input);
|
||||
Q_INIT_RESOURCE(CGAL);
|
||||
|
||||
MainWindow mainWindow;
|
||||
mainWindow.show();
|
||||
|
||||
QStringList args = app.arguments();
|
||||
args.removeAt(0);
|
||||
Q_FOREACH(QString filename, args) {
|
||||
mainWindow.open(filename);
|
||||
}
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
|
@ -0,0 +1,713 @@
|
|||
#include <fstream>
|
||||
|
||||
// CGAL headers
|
||||
#include <CGAL/Triangulation_vertex_base_with_info_2.h>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||
#include <CGAL/Delaunay_hyperbolic_triangulation_2.h>
|
||||
#include <CGAL/Triangulation_hyperbolic_traits_2.h>
|
||||
|
||||
// to be deleted
|
||||
#include <CGAL/Qt/HyperbolicPainterOstream.h>
|
||||
//
|
||||
|
||||
#include <CGAL/point_generators_2.h>
|
||||
|
||||
// Maintain translations
|
||||
#include <TranslationInfo.h>
|
||||
#include <Translations.h>
|
||||
|
||||
// Qt headers
|
||||
#include <QtGui>
|
||||
#include <QString>
|
||||
#include <QActionGroup>
|
||||
#include <QFileDialog>
|
||||
#include <QInputDialog>
|
||||
#include <QGraphicsEllipseItem>
|
||||
|
||||
// experiment
|
||||
#include "GroupOfIndex2.h"
|
||||
#include "OriginalDomainNeighbors.h"
|
||||
//
|
||||
|
||||
// GraphicsView items and event filters (input classes)
|
||||
#include "PointTranslationWithInfo.h"
|
||||
#include "TriangulationCircumcircle.h"
|
||||
#include "TriangulationMovingPoint.h"
|
||||
#include "TriangulationConflictZone.h"
|
||||
#include "TriangulationRemoveVertex.h"
|
||||
#include "TriangulationPointInputAndConflictZone.h"
|
||||
#include <CGAL/Qt/TriangulationGraphicsItem.h>
|
||||
#include <CGAL/Qt/VoronoiGraphicsItem.h>
|
||||
|
||||
// for viewportsBbox
|
||||
#include <CGAL/Qt/utility.h>
|
||||
|
||||
// the two base classes
|
||||
#include "ui_Hyperbolic_translations_2.h"
|
||||
#include <CGAL/Qt/DemosMainWindow.h>
|
||||
|
||||
typedef CGAL::Exact_predicates_exact_constructions_kernel R;
|
||||
typedef CGAL::Triangulation_hyperbolic_traits_2<R> K;
|
||||
|
||||
typedef K::Point_2 Point_2;
|
||||
typedef K::Iso_rectangle_2 Iso_rectangle_2;
|
||||
typedef K Gt;
|
||||
|
||||
// keep the name of the translation for every vertex
|
||||
typedef TranslationInfo<std::wstring> Vb_info;
|
||||
|
||||
typedef CGAL::Triangulation_vertex_base_with_info_2< Vb_info, Gt > Vb;
|
||||
typedef CGAL::Triangulation_face_base_with_info_2 <CGAL::Hyperbolic_face_info_2, Gt > Fb;
|
||||
|
||||
typedef CGAL::Delaunay_hyperbolic_triangulation_2< Gt, CGAL::Triangulation_data_structure_2<Vb, Fb> > Delaunay;
|
||||
|
||||
class MainWindow :
|
||||
public CGAL::Qt::DemosMainWindow,
|
||||
public Ui::Delaunay_triangulation_2
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
Delaunay dt;
|
||||
QGraphicsEllipseItem* disk;
|
||||
QGraphicsScene scene;
|
||||
|
||||
CGAL::Qt::TriangulationGraphicsItem<Delaunay> * dgi;
|
||||
CGAL::Qt::VoronoiGraphicsItem<Delaunay> * vgi;
|
||||
|
||||
CGAL::Qt::TriangulationMovingPoint<Delaunay> * mp;
|
||||
CGAL::Qt::TriangulationConflictZone<Delaunay> * cz;
|
||||
CGAL::Qt::TriangulationRemoveVertex<Delaunay> * trv;
|
||||
CGAL::Qt::TriangulationPointInputAndConflictZone<Delaunay> * pi;
|
||||
CGAL::Qt::TriangulationCircumcircle<Delaunay> *tcc;
|
||||
|
||||
// hyperbolic translations
|
||||
typedef CGAL::Hyperbolic_isometry_2<Gt> Hyperbolic_isometry;
|
||||
typedef Hyperbolic_isometry::complex complex;
|
||||
|
||||
// storage of static data: translations a, b, c, d
|
||||
typedef Translations<Gt> Translations;
|
||||
typedef CGAL::Qt::PointTranslationWithInfo<Delaunay, Hyperbolic_isometry> PointTranslation;
|
||||
|
||||
PointTranslation *trs_a;
|
||||
PointTranslation *trs_b;
|
||||
PointTranslation *trs_c;
|
||||
PointTranslation *trs_d;
|
||||
|
||||
// experiment
|
||||
typedef CGAL::Qt::OriginalDomainNeighbors<Delaunay, Hyperbolic_isometry> OriginalDomainNeighbors;
|
||||
typedef Group_of_index_2<Hyperbolic_isometry> Group_of_index_2;
|
||||
|
||||
// delete later, for some experiments
|
||||
Group_of_index_2::List words;
|
||||
//
|
||||
|
||||
Group_of_index_2 g2;
|
||||
Group_of_index_2 g4;
|
||||
Group_of_index_2 g8;
|
||||
Group_of_index_2 g16;
|
||||
// extra groups, we can delete them
|
||||
Group_of_index_2 g32;
|
||||
Group_of_index_2 g64;
|
||||
Group_of_index_2 g128;
|
||||
Group_of_index_2 g256;
|
||||
Group_of_index_2 g512;
|
||||
Group_of_index_2 g1024;
|
||||
//
|
||||
OriginalDomainNeighbors *odn;
|
||||
OriginalDomainNeighbors *odn2;
|
||||
//
|
||||
public:
|
||||
MainWindow();
|
||||
|
||||
public slots:
|
||||
|
||||
void processInput(CGAL::Object o);
|
||||
|
||||
void on_actionMovingPoint_toggled(bool checked);
|
||||
|
||||
void on_actionDo_translation_a_toggled(bool checked);
|
||||
|
||||
void on_actionDo_translation_b_toggled(bool checked);
|
||||
|
||||
void on_actionDo_translation_c_toggled(bool checked);
|
||||
|
||||
void on_actionDo_translation_d_toggled(bool checked);
|
||||
|
||||
void on_actionG_toggled(bool checked);
|
||||
|
||||
void on_actionG2_toggled(bool checked);
|
||||
|
||||
void on_actionG4_toggled(bool checked);
|
||||
|
||||
void on_actionG8_toggled(bool checked);
|
||||
|
||||
void on_actionG16_toggled(bool checked);
|
||||
|
||||
void on_actionShowConflictZone_toggled(bool checked);
|
||||
|
||||
void on_actionCircumcenter_toggled(bool checked);
|
||||
|
||||
void on_actionShowDelaunay_toggled(bool checked);
|
||||
|
||||
void on_actionShowVoronoi_toggled(bool checked);
|
||||
|
||||
void on_actionInsertPoint_toggled(bool checked);
|
||||
|
||||
void on_actionInsertRandomPoints_triggered();
|
||||
|
||||
void on_actionLoadPoints_triggered();
|
||||
|
||||
void on_actionSavePoints_triggered();
|
||||
|
||||
void on_actionClear_triggered();
|
||||
|
||||
void on_actionRecenter_triggered();
|
||||
|
||||
virtual void open(QString fileName);
|
||||
|
||||
signals:
|
||||
void changed();
|
||||
};
|
||||
|
||||
|
||||
// delete
|
||||
bool inverses(int i, int j)
|
||||
{
|
||||
if((i == 0 && j == 2) || (i == 1 && j == 3) || (i == 4 && j == 6) || (i == 5 && j == 7)) {
|
||||
return true;
|
||||
}
|
||||
if((i == 2 && j == 0) || (i == 3 && j == 1) || (i == 6 && j == 4) || (i == 7 && j == 5)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template<class TList>
|
||||
void GenerateWordsOfLengthLessThan4(const TList& input, TList& output)
|
||||
{
|
||||
typename TList::value_type el;
|
||||
|
||||
std::copy(input.begin(), input.end(), std::insert_iterator<TList>(output, output.end()));
|
||||
|
||||
typename TList::const_iterator gi, gj, gk, gl;
|
||||
gi = input.begin();
|
||||
int i, j, k;
|
||||
for(i = 0, gi = input.begin(); gi != input.end(); i++, gi++) {
|
||||
for(j = 0, gj = input.begin(); gj != input.end(); j++, gj++) {
|
||||
if(inverses(i, j)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
el.g = gi->g * gj->g;
|
||||
output.push_back(el);
|
||||
}
|
||||
}
|
||||
|
||||
for(i = 0, gi = input.begin(); gi != input.end(); i++, gi++) {
|
||||
for(j = 0, gj = input.begin(); gj != input.end(); j++, gj++) {
|
||||
for(k = 0, gk = input.begin(); gk != input.end(); k++, gk++) {
|
||||
if(inverses(i, j) || inverses(j, k)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
el.g = gi->g * gj->g * gk->g;
|
||||
output.push_back(el);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
MainWindow::MainWindow()
|
||||
: DemosMainWindow(), dt(K(1))
|
||||
{
|
||||
setupUi(this);
|
||||
|
||||
this->graphicsView->setAcceptDrops(false);
|
||||
|
||||
// Add Poincaré disk
|
||||
qreal squared_radius = to_double(dt.geom_traits().unit_circle().squared_radius());
|
||||
qreal origin_x = 0, origin_y = 0, radius = CGAL::sqrt(squared_radius), diameter = 2*radius;
|
||||
qreal left_top_corner_x = origin_x - radius;
|
||||
qreal left_top_corner_y = origin_y - radius;
|
||||
qreal width = diameter, height = diameter;
|
||||
|
||||
disk = new QGraphicsEllipseItem(left_top_corner_x, left_top_corner_y, width, height);
|
||||
scene.addItem(disk);
|
||||
|
||||
// add the origin to the triangulation
|
||||
dt.insert(Point_2(0, 0));
|
||||
|
||||
// Add a GraphicItem for the Delaunay triangulation
|
||||
dgi = new CGAL::Qt::TriangulationGraphicsItem<Delaunay>(&dt);
|
||||
|
||||
QObject::connect(this, SIGNAL(changed()),
|
||||
dgi, SLOT(modelChanged()));
|
||||
|
||||
dgi->setVerticesPen(QPen(Qt::red, 3, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
|
||||
scene.addItem(dgi);
|
||||
|
||||
// Add a GraphicItem for the Voronoi diagram
|
||||
vgi = new CGAL::Qt::VoronoiGraphicsItem<Delaunay>(&dt);
|
||||
|
||||
QObject::connect(this, SIGNAL(changed()),
|
||||
vgi, SLOT(modelChanged()));
|
||||
|
||||
vgi->setEdgesPen(QPen(Qt::blue, 0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
|
||||
scene.addItem(vgi);
|
||||
vgi->hide();
|
||||
|
||||
// Setup input handlers. They get events before the scene gets them
|
||||
// and the input they generate is passed to the triangulation with
|
||||
// the signal/slot mechanism
|
||||
pi = new CGAL::Qt::TriangulationPointInputAndConflictZone<Delaunay>(&scene, &dt, this );
|
||||
|
||||
QObject::connect(pi, SIGNAL(generate(CGAL::Object)),
|
||||
this, SLOT(processInput(CGAL::Object)));
|
||||
|
||||
mp = new CGAL::Qt::TriangulationMovingPoint<Delaunay>(&dt, this);
|
||||
// TriangulationMovingPoint<Delaunay> emits a modelChanged() signal each
|
||||
// time the moving point moves.
|
||||
// The following connection is for the purpose of emitting changed().
|
||||
QObject::connect(mp, SIGNAL(modelChanged()),
|
||||
this, SIGNAL(changed()));
|
||||
|
||||
trv = new CGAL::Qt::TriangulationRemoveVertex<Delaunay>(&dt, this);
|
||||
QObject::connect(trv, SIGNAL(modelChanged()),
|
||||
this, SIGNAL(changed()));
|
||||
|
||||
tcc = new CGAL::Qt::TriangulationCircumcircle<Delaunay>(&scene, &dt, this);
|
||||
tcc->setPen(QPen(Qt::red, 0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
|
||||
|
||||
cz = new CGAL::Qt::TriangulationConflictZone<Delaunay>(&scene, &dt, this);
|
||||
|
||||
// initialization of translations
|
||||
trs_a = new PointTranslation(Translations::a(), scene, &dt, this);
|
||||
trs_b = new PointTranslation(Translations::b(), scene, &dt, this);
|
||||
trs_c = new PointTranslation(Translations::c(), scene, &dt, this);
|
||||
trs_d = new PointTranslation(Translations::d(), scene, &dt, this);
|
||||
|
||||
trs_a->info().setString(L"a");
|
||||
trs_b->info().setString(L"b");
|
||||
trs_c->info().setString(L"c");
|
||||
trs_d->info().setString(L"d");
|
||||
|
||||
QObject::connect(trs_a, SIGNAL(modelChanged()),
|
||||
this, SIGNAL(changed()));
|
||||
QObject::connect(trs_b, SIGNAL(modelChanged()),
|
||||
this, SIGNAL(changed()));
|
||||
QObject::connect(trs_c, SIGNAL(modelChanged()),
|
||||
this, SIGNAL(changed()));
|
||||
QObject::connect(trs_d, SIGNAL(modelChanged()),
|
||||
this, SIGNAL(changed()));
|
||||
|
||||
// experiment
|
||||
std::cout << "G: " << Translations::list().size() << std::endl;
|
||||
|
||||
g2.add_group(&Translations::list());
|
||||
std::cout << "G_2: " << g2.number_of_elements() << std::endl;
|
||||
|
||||
g4.add_group(&g2.list());
|
||||
std::cout << "G_4: " << g4.number_of_elements() << std::endl;
|
||||
|
||||
g8.add_group(&g4.list());
|
||||
std::cout << "G_8: " << g8.number_of_elements() << std::endl;
|
||||
|
||||
g16.add_group(&g8.list());
|
||||
std::cout << "G_16: " << g16.number_of_elements() << std::endl;
|
||||
|
||||
g32.add_group(&g16.list());
|
||||
std::cout << "G_32: " << g32.number_of_elements() << std::endl;
|
||||
|
||||
g64.add_group(&g32.list());
|
||||
std::cout << "G_64: " << g64.number_of_elements() << std::endl;
|
||||
|
||||
g128.add_group(&g64.list());
|
||||
std::cout << "G_128: " << g128.number_of_elements() << std::endl;
|
||||
|
||||
g256.add_group(&g128.list());
|
||||
std::cout << "G_256: " << g256.number_of_elements() << std::endl;
|
||||
|
||||
odn = new OriginalDomainNeighbors(scene, &dt, this);
|
||||
QObject::connect(odn, SIGNAL(modelChanged()),
|
||||
this, SIGNAL(changed()));
|
||||
|
||||
GenerateWordsOfLengthLessThan4(Translations::list(), words);
|
||||
//
|
||||
|
||||
//
|
||||
// Manual handling of actions
|
||||
//
|
||||
|
||||
QObject::connect(this->actionQuit, SIGNAL(triggered()),
|
||||
this, SLOT(close()));
|
||||
|
||||
// We put mutually exclusive actions in an QActionGroup
|
||||
QActionGroup* ag = new QActionGroup(this);
|
||||
ag->addAction(this->actionInsertPoint);
|
||||
ag->addAction(this->actionMovingPoint);
|
||||
ag->addAction(this->actionCircumcenter);
|
||||
ag->addAction(this->actionShowConflictZone);
|
||||
ag->addAction(this->actionDo_translation_a);
|
||||
ag->addAction(this->actionDo_translation_b);
|
||||
ag->addAction(this->actionDo_translation_c);
|
||||
ag->addAction(this->actionDo_translation_d);
|
||||
ag->addAction(this->actionG);
|
||||
ag->addAction(this->actionG2);
|
||||
ag->addAction(this->actionG4);
|
||||
ag->addAction(this->actionG8);
|
||||
ag->addAction(this->actionG16);
|
||||
|
||||
// Check two actions
|
||||
this->actionInsertPoint->setChecked(true);
|
||||
this->actionShowDelaunay->setChecked(true);
|
||||
|
||||
//
|
||||
// Setup the scene and the view
|
||||
//
|
||||
scene.setItemIndexMethod(QGraphicsScene::NoIndex);
|
||||
scene.setSceneRect(left_top_corner_x, left_top_corner_y, width, height);
|
||||
this->graphicsView->setScene(&scene);
|
||||
this->graphicsView->setMouseTracking(true);
|
||||
|
||||
// Turn the vertical axis upside down
|
||||
this->graphicsView->matrix().scale(1, -1);
|
||||
|
||||
// The navigation adds zooming and translation functionality to the
|
||||
// QGraphicsView
|
||||
this->addNavigation(this->graphicsView);
|
||||
|
||||
this->setupStatusBar();
|
||||
this->setupOptionsMenu();
|
||||
this->addAboutDemo(":/cgal/help/about_Delaunay_triangulation_2.html");
|
||||
this->addAboutCGAL();
|
||||
|
||||
this->addRecentFiles(this->menuFile, this->actionQuit);
|
||||
connect(this, SIGNAL(openRecentFile(QString)),
|
||||
this, SLOT(open(QString)));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MainWindow::processInput(CGAL::Object o)
|
||||
{
|
||||
Point_2 p;
|
||||
if(CGAL::assign(p, o)){
|
||||
QPointF qp(CGAL::to_double(p.x()), CGAL::to_double(p.y()));
|
||||
|
||||
// note that if the point is on the boundary then the disk contains the point
|
||||
//uncomment!
|
||||
//if(disk->contains(qp)){
|
||||
//dt.insert(p);
|
||||
//}
|
||||
|
||||
//delete
|
||||
if(disk->contains(qp)){
|
||||
std::cout << "inserted point " << p << std::endl;
|
||||
odn2 = new OriginalDomainNeighbors(scene, &dt, this, p, 1);
|
||||
QObject::connect(odn2, SIGNAL(modelChanged()), this, SIGNAL(changed()));
|
||||
|
||||
odn2->assign(g4.begin(), g4.end());
|
||||
odn2->assign(words.begin(), words.end());
|
||||
}
|
||||
}
|
||||
emit(changed());
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Qt Automatic Connections
|
||||
* http://doc.trolltech.com/4.4/designer-using-a-component.html#automatic-connections
|
||||
*
|
||||
* setupUi(this) generates connections to the slots named
|
||||
* "on_<action_name>_<signal_name>"
|
||||
*/
|
||||
void
|
||||
MainWindow::on_actionInsertPoint_toggled(bool checked)
|
||||
{
|
||||
if(checked){
|
||||
scene.installEventFilter(pi);
|
||||
scene.installEventFilter(trv);
|
||||
} else {
|
||||
scene.removeEventFilter(pi);
|
||||
scene.removeEventFilter(trv);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::on_actionDo_translation_a_toggled(bool checked)
|
||||
{
|
||||
if(checked){
|
||||
scene.installEventFilter(trs_a);
|
||||
trs_a->show();
|
||||
} else {
|
||||
scene.removeEventFilter(trs_a);
|
||||
trs_a->hide();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::on_actionDo_translation_b_toggled(bool checked)
|
||||
{
|
||||
if(checked){
|
||||
scene.installEventFilter(trs_b);
|
||||
trs_b->show();
|
||||
} else {
|
||||
scene.removeEventFilter(trs_b);
|
||||
trs_b->hide();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::on_actionDo_translation_c_toggled(bool checked)
|
||||
{
|
||||
if(checked){
|
||||
scene.installEventFilter(trs_c);
|
||||
trs_c->show();
|
||||
} else {
|
||||
scene.removeEventFilter(trs_c);
|
||||
trs_c->hide();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::on_actionDo_translation_d_toggled(bool checked)
|
||||
{
|
||||
if(checked){
|
||||
scene.installEventFilter(trs_d);
|
||||
trs_d->show();
|
||||
} else {
|
||||
scene.removeEventFilter(trs_d);
|
||||
trs_d->hide();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::on_actionG_toggled(bool checked)
|
||||
{
|
||||
if(checked){
|
||||
odn->assign(Translations::list_begin(), Translations::list_end());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::on_actionG2_toggled(bool checked)
|
||||
{
|
||||
if(checked){
|
||||
odn->assign(g2.begin(), g2.end());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::on_actionG4_toggled(bool checked)
|
||||
{
|
||||
if(checked){
|
||||
odn->assign(g4.begin(), g4.end());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::on_actionG8_toggled(bool checked)
|
||||
{
|
||||
if(checked){
|
||||
odn->assign(g8.begin(), g8.end());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::on_actionG16_toggled(bool checked)
|
||||
{
|
||||
if(checked){
|
||||
// odn->assign(g16.begin(), g16.end());
|
||||
|
||||
// Delete! Add all the words of length less than 4 + some words of length 4.
|
||||
odn->assign(g4.begin(), g4.end());
|
||||
odn->assign(words.begin(), words.end());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::on_actionMovingPoint_toggled(bool checked)
|
||||
{
|
||||
|
||||
if(checked){
|
||||
scene.installEventFilter(mp);
|
||||
} else {
|
||||
scene.removeEventFilter(mp);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::on_actionShowConflictZone_toggled(bool checked)
|
||||
{
|
||||
|
||||
if(checked){
|
||||
scene.installEventFilter(cz);
|
||||
} else {
|
||||
scene.removeEventFilter(cz);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::on_actionCircumcenter_toggled(bool checked)
|
||||
{
|
||||
if(checked){
|
||||
scene.installEventFilter(tcc);
|
||||
tcc->show();
|
||||
} else {
|
||||
scene.removeEventFilter(tcc);
|
||||
tcc->hide();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MainWindow::on_actionShowDelaunay_toggled(bool checked)
|
||||
{
|
||||
dgi->setVisibleEdges(checked);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MainWindow::on_actionShowVoronoi_toggled(bool checked)
|
||||
{
|
||||
vgi->setVisible(checked);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MainWindow::on_actionClear_triggered()
|
||||
{
|
||||
dt.clear();
|
||||
emit(changed());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MainWindow::on_actionInsertRandomPoints_triggered()
|
||||
{
|
||||
QRectF rect = CGAL::Qt::viewportsBbox(&scene);
|
||||
CGAL::Qt::Converter<K> convert;
|
||||
Iso_rectangle_2 isor = convert(rect);
|
||||
CGAL::Random_points_in_iso_rectangle_2<Point_2> pg(isor.min(), isor.max());
|
||||
bool ok = false;
|
||||
const int number_of_points =
|
||||
QInputDialog::getInteger(this,
|
||||
tr("Number of random points"),
|
||||
tr("Enter number of random points"),
|
||||
100,
|
||||
0,
|
||||
std::numeric_limits<int>::max(),
|
||||
1,
|
||||
&ok);
|
||||
|
||||
if(!ok) {
|
||||
return;
|
||||
}
|
||||
|
||||
// wait cursor
|
||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||
std::vector<Point_2> points;
|
||||
points.reserve(number_of_points);
|
||||
for(int i = 0; i < number_of_points; ++i){
|
||||
points.push_back(*pg++);
|
||||
}
|
||||
dt.insert(points.begin(), points.end());
|
||||
// default cursor
|
||||
QApplication::restoreOverrideCursor();
|
||||
emit(changed());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MainWindow::on_actionLoadPoints_triggered()
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName(this,
|
||||
tr("Open Points file"),
|
||||
".");
|
||||
if(! fileName.isEmpty()){
|
||||
open(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MainWindow::open(QString fileName)
|
||||
{
|
||||
// wait cursor
|
||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||
std::ifstream ifs(qPrintable(fileName));
|
||||
|
||||
K::Point_2 p;
|
||||
std::vector<K::Point_2> points;
|
||||
while(ifs >> p) {
|
||||
points.push_back(p);
|
||||
}
|
||||
dt.insert(points.begin(), points.end());
|
||||
|
||||
// default cursor
|
||||
QApplication::restoreOverrideCursor();
|
||||
this->addToRecentFiles(fileName);
|
||||
actionRecenter->trigger();
|
||||
emit(changed());
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::on_actionSavePoints_triggered()
|
||||
{
|
||||
QString fileName = QFileDialog::getSaveFileName(this,
|
||||
tr("Save points"),
|
||||
".");
|
||||
if(! fileName.isEmpty()){
|
||||
std::ofstream ofs(qPrintable(fileName));
|
||||
for(Delaunay::Finite_vertices_iterator
|
||||
vit = dt.finite_vertices_begin(),
|
||||
end = dt.finite_vertices_end();
|
||||
vit!= end; ++vit)
|
||||
{
|
||||
ofs << vit->point() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MainWindow::on_actionRecenter_triggered()
|
||||
{
|
||||
this->graphicsView->setSceneRect(dgi->boundingRect());
|
||||
this->graphicsView->fitInView(dgi->boundingRect(), Qt::KeepAspectRatio);
|
||||
}
|
||||
|
||||
|
||||
#include "Hyperbolic_translations_2_demo.moc"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
app.setOrganizationDomain("geometryfactory.com");
|
||||
app.setOrganizationName("GeometryFactory");
|
||||
app.setApplicationName("Delaunay_triangulation_2 demo");
|
||||
|
||||
// Import resources from libCGALQt4.
|
||||
// See http://doc.trolltech.com/4.4/qdir.html#Q_INIT_RESOURCE
|
||||
Q_INIT_RESOURCE(File);
|
||||
Q_INIT_RESOURCE(Triangulation_2);
|
||||
Q_INIT_RESOURCE(Input);
|
||||
Q_INIT_RESOURCE(CGAL);
|
||||
|
||||
MainWindow mainWindow;
|
||||
mainWindow.show();
|
||||
|
||||
QStringList args = app.arguments();
|
||||
args.removeAt(0);
|
||||
Q_FOREACH(QString filename, args) {
|
||||
mainWindow.open(filename);
|
||||
}
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
|
@ -0,0 +1,208 @@
|
|||
#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;
|
||||
typedef typename Translation::FT FT;
|
||||
|
||||
typedef std::list<Element> 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*, 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
|
||||
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
|
||||
#ifndef CGAL_QT_ORIGINAL_DOMAIN_NEIGHBORS
|
||||
#define CGAL_QT_ORIGINAL_DOMAIN_NEIGHBORS
|
||||
|
||||
#include <CGAL/circulator.h>
|
||||
|
||||
#include <CGAL/Qt/GraphicsViewInput.h>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QEvent>
|
||||
|
||||
#include <PointGraphicsItem.h>
|
||||
|
||||
namespace CGAL {
|
||||
namespace Qt {
|
||||
|
||||
template <typename DT, typename Translation>
|
||||
class OriginalDomainNeighbors : public GraphicsViewInput
|
||||
{
|
||||
public:
|
||||
typedef typename DT::Face_handle Face_handle;
|
||||
typedef typename DT::Vertex_handle Vertex_handle;
|
||||
typedef typename DT::Point Point;
|
||||
|
||||
OriginalDomainNeighbors(QGraphicsScene& scene_, DT * dt_, QObject* parent, Point p_, int color);
|
||||
|
||||
template <typename InputIterator>
|
||||
void assign(InputIterator begin, InputIterator end)
|
||||
{
|
||||
insert(begin, end);
|
||||
}
|
||||
|
||||
protected:
|
||||
template <typename InputIterator>
|
||||
void insert(InputIterator begin, InputIterator end);
|
||||
|
||||
Point do_point_translation(const Translation& translation) const;
|
||||
virtual Vertex_handle insert_point(const Point& p);
|
||||
|
||||
private:
|
||||
DT * dt;
|
||||
|
||||
// center of original domain
|
||||
Point p;
|
||||
int color;
|
||||
};
|
||||
|
||||
|
||||
template <typename DT, typename Translation>
|
||||
OriginalDomainNeighbors<DT, Translation>::OriginalDomainNeighbors(QGraphicsScene& ,
|
||||
DT * dt_,
|
||||
QObject* parent,
|
||||
Point p_ = Point(0, 0),
|
||||
int color_ = 0)
|
||||
: GraphicsViewInput(parent), dt(dt_), p(p_), color(color_)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
template <typename DT, typename Translation>
|
||||
template <typename InputIterator>
|
||||
void
|
||||
OriginalDomainNeighbors<DT, Translation>::insert(InputIterator begin, InputIterator end)
|
||||
{
|
||||
insert_point(p);
|
||||
|
||||
for(InputIterator it = begin; it != end; ++it) {
|
||||
Translation t = it->g;
|
||||
Point neighbor = do_point_translation(it->g);
|
||||
|
||||
insert_point(neighbor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename DT, typename Translation>
|
||||
typename OriginalDomainNeighbors<DT, Translation>::Point
|
||||
OriginalDomainNeighbors<DT, Translation>::do_point_translation(const Translation& translation) const
|
||||
{
|
||||
return translation.DoAction(p);
|
||||
}
|
||||
|
||||
|
||||
template <typename DT, typename Translation>
|
||||
typename OriginalDomainNeighbors<DT, Translation>::Vertex_handle
|
||||
OriginalDomainNeighbors<DT, Translation>::insert_point(const Point& p)
|
||||
{
|
||||
Vertex_handle v = dt->insert(p);
|
||||
v->info().setColor(color);
|
||||
|
||||
emit(modelChanged());
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Qt
|
||||
} // namespace CGAL
|
||||
|
||||
#endif // CGAL_QT_ORIGINAL_DOMAIN_NEIGHBORS
|
||||
|
|
@ -0,0 +1,151 @@
|
|||
#ifndef CGAL_QT_POINT_GRAPHICS_ITEM_H
|
||||
#define CGAL_QT_POINT_GRAPHICS_ITEM_H
|
||||
|
||||
#include <CGAL/Bbox_2.h>
|
||||
#include <CGAL/Qt/GraphicsItem.h>
|
||||
#include <CGAL/Qt/Converter.h>
|
||||
|
||||
#include <QGraphicsScene>
|
||||
#include <QPainter>
|
||||
#include <QStyleOption>
|
||||
|
||||
namespace CGAL {
|
||||
namespace Qt {
|
||||
|
||||
template <typename T>
|
||||
class PointGraphicsItem : public GraphicsItem
|
||||
{
|
||||
public:
|
||||
typedef typename T::Point Point;
|
||||
typedef typename T::Geom_traits Geom_traits;
|
||||
|
||||
PointGraphicsItem(Point p = Point());
|
||||
|
||||
void modelChanged();
|
||||
|
||||
public:
|
||||
|
||||
QRectF boundingRect() const;
|
||||
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
|
||||
void setPoint(const Point& p)
|
||||
{
|
||||
m_p = p;
|
||||
|
||||
updateBoundingBox();
|
||||
update();
|
||||
}
|
||||
|
||||
Point getPoint() const
|
||||
{
|
||||
return m_p;
|
||||
}
|
||||
|
||||
const QPen& vertexPen() const
|
||||
{
|
||||
return vertex_pen;
|
||||
}
|
||||
|
||||
void setVertexPen(const QPen& pen)
|
||||
{
|
||||
vertex_pen = pen;
|
||||
}
|
||||
|
||||
void paintOneVertex(const Point& point) const;
|
||||
|
||||
protected:
|
||||
void updateBoundingBox();
|
||||
void paintVertex(QPainter* painter, const Point& point) const;
|
||||
|
||||
QPainter* m_painter;
|
||||
|
||||
Point m_p;
|
||||
|
||||
CGAL::Bbox_2 bb;
|
||||
bool bb_initialized;
|
||||
QRectF bounding_rect;
|
||||
|
||||
QPen vertex_pen;
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
PointGraphicsItem<T>::PointGraphicsItem(Point p)
|
||||
: m_painter(0), m_p(p), bb(0,0,0,0), bb_initialized(false)
|
||||
{
|
||||
setVertexPen(QPen(::Qt::green, 3.));
|
||||
|
||||
updateBoundingBox();
|
||||
setZValue(3);
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
QRectF
|
||||
PointGraphicsItem<T>::boundingRect() const
|
||||
{
|
||||
return bounding_rect;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
PointGraphicsItem<T>::modelChanged()
|
||||
{
|
||||
updateBoundingBox();
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
PointGraphicsItem<T>::paintOneVertex(const Point& p) const
|
||||
{
|
||||
pointVertex(m_painter, p);
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
PointGraphicsItem<T>::paintVertex(QPainter *painter, const Point& p) const
|
||||
{
|
||||
Converter<Geom_traits> convert;
|
||||
|
||||
painter->setPen(this->vertexPen());
|
||||
QMatrix matrix = painter->matrix();
|
||||
painter->resetMatrix();
|
||||
painter->drawPoint(matrix.map(convert(p)));
|
||||
painter->setMatrix(matrix);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
PointGraphicsItem<T>::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
|
||||
QWidget * /*widget*/)
|
||||
{
|
||||
painter->setPen(this->vertexPen());
|
||||
|
||||
paintVertex(painter, m_p);
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
PointGraphicsItem<T>::updateBoundingBox()
|
||||
{
|
||||
bb = m_p.bbox();
|
||||
bb_initialized = true;
|
||||
|
||||
bounding_rect = QRectF(bb.xmin(),
|
||||
bb.ymin(),
|
||||
bb.xmax()-bb.xmin(),
|
||||
bb.ymax()-bb.ymin());
|
||||
}
|
||||
|
||||
} // namespace Qt
|
||||
|
||||
} // namespace CGAL
|
||||
|
||||
#endif // CGAL_QT_POINT_GRAPHICS_ITEM_H
|
||||
|
||||
|
|
@ -0,0 +1,172 @@
|
|||
|
||||
#ifndef CGAL_QT_POINT_TRANSLATION
|
||||
#define CGAL_QT_POINT_TRANSLATION
|
||||
|
||||
#include <CGAL/Qt/GraphicsViewInput.h>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QEvent>
|
||||
|
||||
#include <PointGraphicsItem.h>
|
||||
|
||||
namespace CGAL {
|
||||
namespace Qt {
|
||||
|
||||
template <typename DT, typename Translation>
|
||||
class PointTranslation : public GraphicsViewInput
|
||||
{
|
||||
public:
|
||||
typedef typename DT::Face_handle Face_handle;
|
||||
typedef typename DT::Vertex_handle Vertex_handle;
|
||||
typedef typename DT::Point Point;
|
||||
|
||||
PointTranslation(const Translation& translation_, QGraphicsScene& scene_, DT * dt_, QObject* parent);
|
||||
|
||||
void show();
|
||||
void hide();
|
||||
|
||||
protected:
|
||||
Point do_point_translation() const;
|
||||
virtual Vertex_handle insert_point(const Point& p);
|
||||
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent *event);
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
|
||||
bool eventFilter(QObject *obj, QEvent *event);
|
||||
|
||||
Translation translation;
|
||||
Vertex_handle chosen_vertex;
|
||||
|
||||
private:
|
||||
void highlight_chosen_vertex();
|
||||
|
||||
DT * dt;
|
||||
|
||||
QGraphicsScene& scene;
|
||||
QGraphicsEllipseItem* circle;
|
||||
|
||||
// highlight the chosen vertex
|
||||
PointGraphicsItem<DT>* highlight_point;
|
||||
};
|
||||
|
||||
|
||||
template <typename DT, typename Translation>
|
||||
PointTranslation<DT, Translation>::PointTranslation(const Translation& translation_,
|
||||
QGraphicsScene& scene_,
|
||||
DT * dt_,
|
||||
QObject* parent)
|
||||
: GraphicsViewInput(parent), translation(translation_), dt(dt_), scene(scene_)
|
||||
{
|
||||
highlight_point = new PointGraphicsItem<DT>();
|
||||
highlight_point->hide();
|
||||
|
||||
// scene is the holder of the added item
|
||||
scene.addItem(highlight_point);
|
||||
}
|
||||
|
||||
|
||||
template <typename DT, typename Translation>
|
||||
void
|
||||
PointTranslation<DT, Translation>::show()
|
||||
{
|
||||
highlight_point->show();
|
||||
}
|
||||
|
||||
|
||||
template <typename DT, typename Translation>
|
||||
void
|
||||
PointTranslation<DT, Translation>::hide()
|
||||
{
|
||||
highlight_point->hide();
|
||||
}
|
||||
|
||||
template <typename DT, typename Translation>
|
||||
typename PointTranslation<DT, Translation>::Point
|
||||
PointTranslation<DT, Translation>::do_point_translation() const
|
||||
{
|
||||
return translation.DoAction(chosen_vertex->point());
|
||||
}
|
||||
|
||||
|
||||
template <typename DT, typename Translation>
|
||||
typename PointTranslation<DT, Translation>::Vertex_handle
|
||||
PointTranslation<DT, Translation>::insert_point(const Point& p)
|
||||
{
|
||||
Vertex_handle v = dt->insert(p, chosen_vertex->face());
|
||||
|
||||
emit(modelChanged());
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
template <typename DT, typename Translation>
|
||||
void
|
||||
PointTranslation<DT, Translation>::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if(chosen_vertex == Vertex_handle() ||
|
||||
event->modifiers() != 0 ||
|
||||
event->button() != ::Qt::LeftButton) {
|
||||
return;
|
||||
}
|
||||
|
||||
// translate chosen point
|
||||
Point translated_point = do_point_translation();
|
||||
// insert to the triangulation
|
||||
insert_point(translated_point);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <typename DT, typename Translation>
|
||||
void
|
||||
PointTranslation<DT, Translation>::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
Point scene_pos = Point(event->scenePos().x(), event->scenePos().y());
|
||||
|
||||
Face_handle start_face = Face_handle();
|
||||
if(chosen_vertex != Vertex_handle()) {
|
||||
start_face = chosen_vertex->face();
|
||||
}
|
||||
|
||||
Vertex_handle new_chosen_vertex = dt->nearest_vertex(scene_pos, start_face);
|
||||
|
||||
// highlight the vertex if only it's been changed
|
||||
if(new_chosen_vertex != chosen_vertex) {
|
||||
chosen_vertex = new_chosen_vertex;
|
||||
highlight_chosen_vertex();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename DT, typename Translation>
|
||||
bool
|
||||
PointTranslation<DT, Translation>::eventFilter(QObject *obj, QEvent *event)
|
||||
{ if (event->type() == QEvent::GraphicsSceneMousePress) {
|
||||
QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
|
||||
mousePressEvent(mouseEvent);
|
||||
return true;
|
||||
} else if (event->type() == QEvent::GraphicsSceneMouseMove) {
|
||||
QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
|
||||
mouseMoveEvent(mouseEvent);
|
||||
return false; // do not eat move event!
|
||||
} else{
|
||||
// standard event processing
|
||||
return QObject::eventFilter(obj, event);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename DT, typename Translation>
|
||||
void
|
||||
PointTranslation<DT, Translation>::highlight_chosen_vertex()
|
||||
{
|
||||
assert(chosen_vertex != Vertex_handle());
|
||||
|
||||
highlight_point->setPoint(chosen_vertex->point());
|
||||
highlight_point->show();
|
||||
emit(modelChanged());
|
||||
}
|
||||
|
||||
|
||||
} // namespace Qt
|
||||
} // namespace CGAL
|
||||
|
||||
#endif // CGAL_QT_POINT_TRANSLATION
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
|
||||
#ifndef CGAL_QT_POINT_TRANSLATION_WITH_INFO
|
||||
#define CGAL_QT_POINT_TRANSLATION_WITH_INFO
|
||||
|
||||
#include <PointTranslation.h>
|
||||
|
||||
namespace CGAL {
|
||||
namespace Qt {
|
||||
|
||||
template <typename DT, typename Translation>
|
||||
class PointTranslationWithInfo : public PointTranslation<DT, Translation>
|
||||
{
|
||||
typedef PointTranslation<DT, Translation> Base;
|
||||
public:
|
||||
typedef typename DT::Face_handle Face_handle;
|
||||
typedef typename DT::Vertex_handle Vertex_handle;
|
||||
typedef typename DT::Point Point;
|
||||
|
||||
typedef typename DT::Vertex::Info Info;
|
||||
|
||||
PointTranslationWithInfo(const Translation& translation_, QGraphicsScene& scene_, DT * dt_, QObject* parent);
|
||||
|
||||
const Info& info() const { return _info; }
|
||||
Info& info() { return _info; }
|
||||
|
||||
protected:
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
|
||||
bool eventFilter(QObject *obj, QEvent *event);
|
||||
|
||||
virtual Vertex_handle insert_point(const Point& p);
|
||||
|
||||
Info compute_info() const;
|
||||
void add_info(Vertex_handle v) const;
|
||||
|
||||
void show_info(const QPointF& pos, Vertex_handle v) const;
|
||||
|
||||
private:
|
||||
Info _info;
|
||||
};
|
||||
|
||||
|
||||
template <typename DT, typename Translation>
|
||||
PointTranslationWithInfo<DT, Translation>::PointTranslationWithInfo(const Translation& translation_,
|
||||
QGraphicsScene& scene_,
|
||||
DT * dt_,
|
||||
QObject* parent)
|
||||
: Base(translation_, scene_, dt_, parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
template <typename DT, typename Translation>
|
||||
typename PointTranslationWithInfo<DT, Translation>::Info
|
||||
PointTranslationWithInfo<DT, Translation>::compute_info() const
|
||||
{
|
||||
return this->chosen_vertex->info() + info();
|
||||
}
|
||||
|
||||
|
||||
template <typename DT, typename Translation>
|
||||
void
|
||||
PointTranslationWithInfo<DT, Translation>::add_info(Vertex_handle v) const
|
||||
{
|
||||
Info new_info = compute_info();
|
||||
v->info().setString(new_info.toString());
|
||||
}
|
||||
|
||||
template <typename DT, typename Translation>
|
||||
void
|
||||
PointTranslationWithInfo<DT, Translation>::show_info(const QPointF& pos, Vertex_handle v) const
|
||||
{
|
||||
if(v == Vertex_handle()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const Info& vertex_info = this->chosen_vertex->info();
|
||||
|
||||
QToolTip::showText(pos.toPoint(), QString::fromStdWString(vertex_info.toString()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <typename DT, typename Translation>
|
||||
typename PointTranslationWithInfo<DT, Translation>::Vertex_handle
|
||||
PointTranslationWithInfo<DT, Translation>::insert_point(const Point& p)
|
||||
{
|
||||
Vertex_handle v = Base::insert_point(p);
|
||||
|
||||
add_info(v);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
template <typename DT, typename Translation>
|
||||
void
|
||||
PointTranslationWithInfo<DT, Translation>::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
|
||||
Base::mouseMoveEvent(event);
|
||||
|
||||
show_info(event->scenePos(), this->chosen_vertex);
|
||||
}
|
||||
|
||||
|
||||
template <typename DT, typename Translation>
|
||||
bool
|
||||
PointTranslationWithInfo<DT, Translation>::eventFilter(QObject *obj, QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::GraphicsSceneMouseMove) {
|
||||
QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
|
||||
mouseMoveEvent(mouseEvent);
|
||||
return false; // do not eat move event!
|
||||
}
|
||||
return Base::eventFilter(obj, event);
|
||||
}
|
||||
|
||||
|
||||
} // namespace Qt
|
||||
} // namespace CGAL
|
||||
|
||||
#endif // CGAL_QT_POINT_TRANSLATION_WITH_INFO
|
||||
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
template<typename String>
|
||||
class TranslationInfo
|
||||
{
|
||||
public:
|
||||
|
||||
TranslationInfo() : color(0)
|
||||
{
|
||||
}
|
||||
|
||||
TranslationInfo(const String& name)
|
||||
: name_of_translation(name), color(0)
|
||||
{
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
@ -0,0 +1,183 @@
|
|||
#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;
|
||||
typedef std::list<Element> 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[2].first;
|
||||
}
|
||||
|
||||
static Hyperbolic_isometry& d()
|
||||
{
|
||||
compute();
|
||||
return g[3].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
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<RCC>
|
||||
<qresource prefix="/cgal/Actions">
|
||||
<file>icons/G2.png</file>
|
||||
<file>icons/G4.png</file>
|
||||
<file>icons/G8.png</file>
|
||||
<file>icons/G16.png</file>
|
||||
<file>icons/G.png</file>
|
||||
<file>icons/a.png</file>
|
||||
<file>icons/b.png</file>
|
||||
<file>icons/c.png</file>
|
||||
<file>icons/d.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 852 B |
|
After Width: | Height: | Size: 844 B |
|
After Width: | Height: | Size: 740 B |
|
After Width: | Height: | Size: 818 B |
|
|
@ -0,0 +1,427 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<author>GeometryFactory</author>
|
||||
<class>Delaunay_triangulation_2</class>
|
||||
<widget class="QMainWindow" name="Delaunay_triangulation_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>600</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>CGAL Delaunay Triangulation</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="../../../../CGAL-3.8/demo/resources/CGAL.qrc">
|
||||
<normaloff>:/cgal/logos/cgal_icon</normaloff>:/cgal/logos/cgal_icon</iconset>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<layout class="QGridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QGraphicsView" name="graphicsView">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
</property>
|
||||
<property name="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOn</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOn</enum>
|
||||
</property>
|
||||
<property name="transformationAnchor">
|
||||
<enum>QGraphicsView::NoAnchor</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusbar"/>
|
||||
<widget class="QToolBar" name="fileToolBar">
|
||||
<property name="windowTitle">
|
||||
<string>File Tools</string>
|
||||
</property>
|
||||
<attribute name="toolBarArea">
|
||||
<enum>TopToolBarArea</enum>
|
||||
</attribute>
|
||||
<attribute name="toolBarBreak">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<addaction name="actionClear"/>
|
||||
<addaction name="actionLoadPoints"/>
|
||||
<addaction name="actionSavePoints"/>
|
||||
</widget>
|
||||
<widget class="QToolBar" name="toolBar">
|
||||
<property name="windowTitle">
|
||||
<string>Visualization Tools</string>
|
||||
</property>
|
||||
<attribute name="toolBarArea">
|
||||
<enum>TopToolBarArea</enum>
|
||||
</attribute>
|
||||
<attribute name="toolBarBreak">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<addaction name="actionInsertPoint"/>
|
||||
<addaction name="actionDo_translation_a"/>
|
||||
<addaction name="actionDo_translation_b"/>
|
||||
<addaction name="actionDo_translation_c"/>
|
||||
<addaction name="actionDo_translation_d"/>
|
||||
<addaction name="actionMovingPoint"/>
|
||||
<addaction name="actionCircumcenter"/>
|
||||
<addaction name="actionShowConflictZone"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionShowDelaunay"/>
|
||||
<addaction name="actionShowVoronoi"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionRecenter"/>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menubar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuFile">
|
||||
<property name="title">
|
||||
<string>&File</string>
|
||||
</property>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionClear"/>
|
||||
<addaction name="actionLoadPoints"/>
|
||||
<addaction name="actionSavePoints"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionQuit"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuEdit">
|
||||
<property name="title">
|
||||
<string>&Edit</string>
|
||||
</property>
|
||||
<addaction name="actionInsertRandomPoints"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuTools">
|
||||
<property name="title">
|
||||
<string>&Tools</string>
|
||||
</property>
|
||||
<addaction name="actionInsertPoint"/>
|
||||
<addaction name="actionDo_translation_a"/>
|
||||
<addaction name="actionDo_translation_b"/>
|
||||
<addaction name="actionDo_translation_c"/>
|
||||
<addaction name="actionDo_translation_d"/>
|
||||
<addaction name="actionG"/>
|
||||
<addaction name="actionG2"/>
|
||||
<addaction name="actionG4"/>
|
||||
<addaction name="actionG8"/>
|
||||
<addaction name="actionG16"/>
|
||||
<addaction name="actionMovingPoint"/>
|
||||
<addaction name="actionCircumcenter"/>
|
||||
<addaction name="actionShowConflictZone"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionShowDelaunay"/>
|
||||
<addaction name="actionShowVoronoi"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionRecenter"/>
|
||||
</widget>
|
||||
<addaction name="menuFile"/>
|
||||
<addaction name="menuEdit"/>
|
||||
<addaction name="menuTools"/>
|
||||
</widget>
|
||||
<action name="actionAbout">
|
||||
<property name="text">
|
||||
<string>&About</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionAboutCGAL">
|
||||
<property name="text">
|
||||
<string>About &CGAL</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionQuit">
|
||||
<property name="text">
|
||||
<string>&Quit</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+Q</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionInsertRandomPoints">
|
||||
<property name="text">
|
||||
<string>&Insert random points</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+I</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionMovingPoint">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../CGAL-3.8/demo/Triangulation_2/Delaunay_triangulation_2.qrc">
|
||||
<normaloff>:/cgal/Actions/icons/moving_point.png</normaloff>:/cgal/Actions/icons/moving_point.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Simulate insertion</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string comment="The comment">Simulate Insertion</string>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string comment="and its comment">Move mouse with left button pressed to see where point would be inserted</string>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string comment="what">whats this</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionInsertPoint">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../CGAL-3.8/demo/icons/Input.qrc">
|
||||
<normaloff>:/cgal/Input/inputPoint.png</normaloff>:/cgal/Input/inputPoint.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Insert Point</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Insert Point</string>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Left: Insert vtx</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionClear">
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../CGAL-3.8/demo/icons/File.qrc">
|
||||
<normaloff>:/cgal/fileToolbar/fileNew.png</normaloff>:/cgal/fileToolbar/fileNew.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Clear</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+C</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionShowVoronoi">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../CGAL-3.8/demo/icons/Triangulation_2.qrc">
|
||||
<normaloff>:/cgal/Triangulation_2/Voronoi_diagram_2.png</normaloff>:/cgal/Triangulation_2/Voronoi_diagram_2.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show &Voronoi Diagram</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+V</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionShowDelaunay">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../CGAL-3.8/demo/Triangulation_2/Delaunay_triangulation_2.qrc">
|
||||
<normaloff>:/cgal/Actions/icons/triangulation.png</normaloff>:/cgal/Actions/icons/triangulation.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show &Delaunay Triangulation</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+D</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionLoadPoints">
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../CGAL-3.8/demo/icons/File.qrc">
|
||||
<normaloff>:/cgal/fileToolbar/fileOpen.png</normaloff>:/cgal/fileToolbar/fileOpen.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Load Points...</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+L</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSavePoints">
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../CGAL-3.8/demo/icons/File.qrc">
|
||||
<normaloff>:/cgal/fileToolbar/fileSave.png</normaloff>:/cgal/fileToolbar/fileSave.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Save Points...</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+S</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCircumcenter">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../CGAL-3.8/demo/Triangulation_2/Delaunay_triangulation_2.qrc">
|
||||
<normaloff>:/cgal/Actions/icons/circumcenter.png</normaloff>:/cgal/Actions/icons/circumcenter.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Circumcenter</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Draw circumcenter</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionRecenter">
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../CGAL-3.8/demo/icons/Input.qrc">
|
||||
<normaloff>:/cgal/Input/zoom-best-fit</normaloff>:/cgal/Input/zoom-best-fit</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Re&center the viewport</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+R</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionShowConflictZone">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../CGAL-3.8/demo/Triangulation_2/Delaunay_triangulation_2.qrc">
|
||||
<normaloff>:/cgal/Actions/icons/conflict_zone.png</normaloff>:/cgal/Actions/icons/conflict_zone.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show Conflict Zone</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionDo_translation_a">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources/Hyperbolic_translations_2.qrc">
|
||||
<normaloff>:/cgal/Actions/icons/a.png</normaloff>:/cgal/Actions/icons/a.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Do translation "a"</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionDo_translation_b">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources/Hyperbolic_translations_2.qrc">
|
||||
<normaloff>:/cgal/Actions/icons/b.png</normaloff>:/cgal/Actions/icons/b.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Do translation "b"</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionDo_translation_c">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources/Hyperbolic_translations_2.qrc">
|
||||
<normaloff>:/cgal/Actions/icons/c.png</normaloff>:/cgal/Actions/icons/c.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Do translation "c"</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionDo_translation_d">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources/Hyperbolic_translations_2.qrc">
|
||||
<normaloff>:/cgal/Actions/icons/d.png</normaloff>:/cgal/Actions/icons/d.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Do translation "d"</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionG">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources/Hyperbolic_translations_2.qrc">
|
||||
<normaloff>:/cgal/Actions/icons/G.png</normaloff>:/cgal/Actions/icons/G.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>G</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionG2">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources/Hyperbolic_translations_2.qrc">
|
||||
<normaloff>:/cgal/Actions/icons/G2.png</normaloff>:/cgal/Actions/icons/G2.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>G2</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionG4">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources/Hyperbolic_translations_2.qrc">
|
||||
<normaloff>:/cgal/Actions/icons/G4.png</normaloff>:/cgal/Actions/icons/G4.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>G4</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionG8">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources/Hyperbolic_translations_2.qrc">
|
||||
<normaloff>:/cgal/Actions/icons/G8.png</normaloff>:/cgal/Actions/icons/G8.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>G8</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionG16">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources/Hyperbolic_translations_2.qrc">
|
||||
<normaloff>:/cgal/Actions/icons/G16.png</normaloff>:/cgal/Actions/icons/G16.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>G16</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../../../../CGAL-3.8/demo/Triangulation_2/Delaunay_triangulation_2.qrc"/>
|
||||
<include location="../../../../CGAL-3.8/demo/icons/File.qrc"/>
|
||||
<include location="../resources/Hyperbolic_translations_2.qrc"/>
|
||||
<include location="../../../../CGAL-3.8/demo/resources/CGAL.qrc"/>
|
||||
<include location="../../../../CGAL-3.8/demo/icons/Triangulation_2.qrc"/>
|
||||
<include location="../../../../CGAL-3.8/demo/icons/Input.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
|
||||
#include <CGAL/Triangulation_hyperbolic_traits_2.h>
|
||||
|
||||
#include <CGAL/Constrained_Delaunay_triangulation_2.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
||||
|
||||
typedef CGAL::Triangulation_hyperbolic_traits_2<K> Gt;
|
||||
|
||||
typedef CGAL::Triangulation_vertex_base_2<Gt> Vb;
|
||||
typedef CGAL::Constrained_triangulation_face_base_2<Gt> Fb;
|
||||
typedef CGAL::Triangulation_data_structure_2<Vb,Fb> TDS;
|
||||
// typedef CGAL::No_intersection_tag Itag;
|
||||
typedef CGAL::Constrained_Delaunay_triangulation_2<Gt, TDS> CDT;
|
||||
typedef CDT::Point Point;
|
||||
|
||||
int main()
|
||||
{
|
||||
CDT cdt;
|
||||
std::cout << "Inserting 8 constraints " << std::endl;
|
||||
|
||||
// cdt.insert_constraint( Point(-0.25, 0), Point(0, 0.25) );
|
||||
// cdt.insert_constraint( Point( 0, 0.25), Point(0.25, 0) );
|
||||
// cdt.insert_constraint( Point( 0.25, 0), Point(0, -0.25) );
|
||||
// cdt.insert_constraint( Point( 0, -0.25), Point(-0.25, 0) );
|
||||
|
||||
cdt.insert_constraint( Point(-0.85, 0), Point(-0.6, 0.6) );
|
||||
cdt.insert_constraint( Point( -0.6, 0.6), Point(0, 0.85) );
|
||||
cdt.insert_constraint( Point( 0, 0.85), Point(0.6, 0.6) );
|
||||
cdt.insert_constraint( Point( 0.6, 0.6), Point(0.85, 0) );
|
||||
cdt.insert_constraint( Point( 0.85, 0), Point(0.6, -0.6) );
|
||||
cdt.insert_constraint( Point( 0.6, -0.6), Point(0, -0.85) );
|
||||
cdt.insert_constraint( Point( 0, -0.85), Point(-0.6, -0.6) );
|
||||
cdt.insert_constraint( Point( -0.6, -0.6), Point(-0.85, 0) );
|
||||
|
||||
//cdt.insert( Point( 0, 0 ) );
|
||||
|
||||
// for (int i = 1; i < 6; ++i)
|
||||
// cdt.insert_constraint( Point(0,i), Point(6,i));
|
||||
// for (int j = 1; j < 6; ++j)
|
||||
// cdt.insert_constraint( Point(j,0), Point(j,6));
|
||||
|
||||
assert(cdt.is_valid());
|
||||
int count = 0;
|
||||
int edgesCount = 0;
|
||||
for (CDT::Finite_edges_iterator eit = cdt.finite_edges_begin();
|
||||
eit != cdt.finite_edges_end();
|
||||
++eit) {
|
||||
edgesCount++;
|
||||
if (cdt.is_constrained(*eit)) ++count;
|
||||
}
|
||||
std::cout << "The number of resulting constrained edges is ";
|
||||
std::cout << count << std::endl;
|
||||
std::cout << "Edges count: ";
|
||||
std::cout << edgesCount << std::endl;
|
||||
|
||||
int verticesCount = 0;
|
||||
for(CDT::Finite_vertices_iterator vit = cdt.finite_vertices_begin();
|
||||
vit != cdt.finite_vertices_end();
|
||||
++vit) {
|
||||
std::cout << (*vit).point().x() << " " << (*vit).point().y() << std::endl;
|
||||
verticesCount++;
|
||||
}
|
||||
std::cout << verticesCount << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
#include <fstream>
|
||||
|
||||
// CGAL headers
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||
|
||||
#include <CGAL/Delaunay_hyperbolic_triangulation_2.h>
|
||||
#include <CGAL/Triangulation_hyperbolic_traits_2.h>
|
||||
|
||||
#include <CGAL/Random.h>
|
||||
#include <CGAL/point_generators_2.h>
|
||||
#include <CGAL/Timer.h>
|
||||
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
||||
typedef CGAL::Triangulation_hyperbolic_traits_2<K> Gt;
|
||||
|
||||
typedef Gt::Point_2 Point_2;
|
||||
typedef Gt::Circle_2 Circle_2;
|
||||
typedef Gt::FT FT;
|
||||
|
||||
typedef CGAL::Delaunay_hyperbolic_triangulation_2<Gt> Dt;
|
||||
|
||||
int main()
|
||||
{
|
||||
CGAL::Timer timer;
|
||||
typedef CGAL::Creator_uniform_2<FT, Point_2> Creator;
|
||||
|
||||
FT r = 100;
|
||||
CGAL::Random_points_in_disc_2<Point_2, Creator> in_disc(r);
|
||||
|
||||
int n = 10000;
|
||||
std::vector<Point_2> pts;
|
||||
std::vector<Point_2>::iterator ip;
|
||||
|
||||
// Generating n random points
|
||||
for (int i=0 ; i < n ; i++) {
|
||||
pts.at(i) = *in_disc;
|
||||
in_disc++;
|
||||
}
|
||||
|
||||
timer.start();
|
||||
|
||||
Dt dt = Dt(Gt(r));
|
||||
|
||||
for(ip = pts.begin(); ip != pts.end(); ++ip) {
|
||||
dt.insert(*ip);
|
||||
}
|
||||
|
||||
timer.stop();
|
||||
|
||||
std::cout << "Number of points: " << n << std::endl;
|
||||
std::cout << "Time: " << timer.time() << std::endl;
|
||||
|
||||
timer.reset();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
|
||||
#include <CGAL/Triangulation_hyperbolic_traits_2.h>
|
||||
|
||||
#include <CGAL/Constrained_Delaunay_triangulation_2.h>
|
||||
#include <CGAL/Delaunay_mesher_2.h>
|
||||
#include <CGAL/Delaunay_mesh_face_base_2.h>
|
||||
#include <CGAL/Delaunay_mesh_size_criteria_2.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
||||
|
||||
typedef CGAL::Triangulation_hyperbolic_traits_2<K> Gt;
|
||||
|
||||
typedef CGAL::Triangulation_vertex_base_2<Gt> Vb;
|
||||
typedef CGAL::Delaunay_mesh_face_base_2<Gt> Fb;
|
||||
typedef CGAL::Triangulation_data_structure_2<Vb, Fb> Tds;
|
||||
typedef CGAL::Constrained_Delaunay_triangulation_2<Gt, Tds> CDT;
|
||||
typedef CGAL::Delaunay_mesh_size_criteria_2<CDT> Criteria;
|
||||
typedef CGAL::Delaunay_mesher_2<CDT, Criteria> Mesher;
|
||||
|
||||
typedef CDT::Vertex_handle Vertex_handle;
|
||||
typedef CDT::Point Point;
|
||||
|
||||
int main()
|
||||
{
|
||||
CDT cdt;
|
||||
|
||||
Vertex_handle va = cdt.insert(Point(-4,0));
|
||||
Vertex_handle vb = cdt.insert(Point(0,-1));
|
||||
Vertex_handle vc = cdt.insert(Point(4,0));
|
||||
Vertex_handle vd = cdt.insert(Point(0,1));
|
||||
cdt.insert(Point(2, 0.6));
|
||||
|
||||
cdt.insert_constraint(va, vb);
|
||||
cdt.insert_constraint(vb, vc);
|
||||
cdt.insert_constraint(vc, vd);
|
||||
cdt.insert_constraint(vd, va);
|
||||
|
||||
std::cout << "Number of vertices: " << cdt.number_of_vertices() << std::endl;
|
||||
|
||||
std::cout << "Meshing the triangulation with default criterias..."
|
||||
<< std::endl;
|
||||
|
||||
Mesher mesher(cdt);
|
||||
mesher.refine_mesh();
|
||||
|
||||
std::cout << "Number of vertices: " << cdt.number_of_vertices() << std::endl;
|
||||
|
||||
std::cout << "Meshing with new criterias..." << std::endl;
|
||||
// 0.125 is the default shape bound. It corresponds to abound 20.6 degree.
|
||||
// 0.5 is the upper bound on the length of the longuest edge.
|
||||
// See reference manual for Delaunay_mesh_size_traits_2<K>.
|
||||
mesher.set_criteria(Criteria(0.125, 0.5));
|
||||
mesher.refine_mesh();
|
||||
|
||||
std::cout << "Number of vertices: " << cdt.number_of_vertices() << std::endl;
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
|
||||
#include <CGAL/Triangulation_hyperbolic_traits_2.h>
|
||||
|
||||
#include <CGAL/Constrained_Delaunay_triangulation_2.h>
|
||||
#include <CGAL/Delaunay_mesher_2.h>
|
||||
#include <CGAL/Delaunay_mesh_face_base_2.h>
|
||||
#include <CGAL/Delaunay_mesh_size_criteria_2.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
||||
|
||||
typedef CGAL::Triangulation_hyperbolic_traits_2<K> Gt;
|
||||
|
||||
typedef CGAL::Triangulation_vertex_base_2<Gt> Vb;
|
||||
typedef CGAL::Delaunay_mesh_face_base_2<Gt> Fb;
|
||||
|
||||
typedef CGAL::Triangulation_data_structure_2<Vb, Fb> Tds;
|
||||
typedef CGAL::Constrained_Delaunay_triangulation_2<Gt, Tds> CDT;
|
||||
typedef CGAL::Delaunay_mesh_size_criteria_2<CDT> Criteria;
|
||||
|
||||
typedef CDT::Vertex_handle Vertex_handle;
|
||||
typedef CDT::Point Point;
|
||||
|
||||
int main()
|
||||
{
|
||||
CDT cdt;
|
||||
|
||||
/*
|
||||
Vertex_handle va = cdt.insert(Point(-4,0));
|
||||
Vertex_handle vb = cdt.insert(Point(0,-1));
|
||||
Vertex_handle vc = cdt.insert(Point(4,0));
|
||||
Vertex_handle vd = cdt.insert(Point(0,1));
|
||||
cdt.insert(Point(2, 0.6));
|
||||
|
||||
cdt.insert_constraint(va, vb);
|
||||
cdt.insert_constraint(vb, vc);
|
||||
cdt.insert_constraint(vc, vd);
|
||||
cdt.insert_constraint(vd, va);
|
||||
*/
|
||||
|
||||
cdt.insert_constraint( Point(-0.85, 0), Point(-0.6, 0.6) );
|
||||
cdt.insert_constraint( Point( -0.6, 0.6), Point(0, 0.85) );
|
||||
cdt.insert_constraint( Point( 0, 0.85), Point(0.6, 0.6) );
|
||||
cdt.insert_constraint( Point( 0.6, 0.6), Point(0.85, 0) );
|
||||
cdt.insert_constraint( Point( 0.85, 0), Point(0.6, -0.6) );
|
||||
cdt.insert_constraint( Point( 0.6, -0.6), Point(0, -0.85) );
|
||||
cdt.insert_constraint( Point( 0, -0.85), Point(-0.6, -0.6) );
|
||||
cdt.insert_constraint( Point( -0.6, -0.6), Point(-0.85, 0) );
|
||||
|
||||
std::cout << "Number of vertices: " << cdt.number_of_vertices() << std::endl;
|
||||
|
||||
std::cout << "Meshing the triangulation..." << std::endl;
|
||||
CGAL::refine_Delaunay_mesh_2(cdt, Criteria(0.125, 0.5));
|
||||
|
||||
std::cout << "Number of vertices: " << cdt.number_of_vertices() << std::endl;
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
|
||||
#include <CGAL/Triangulation_hyperbolic_traits_2.h>
|
||||
|
||||
#include <CGAL/Constrained_Delaunay_triangulation_2.h>
|
||||
#include <CGAL/Delaunay_mesher_2.h>
|
||||
#include <CGAL/Delaunay_mesh_face_base_2.h>
|
||||
#include <CGAL/Delaunay_mesh_size_criteria_2.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
||||
|
||||
typedef CGAL::Triangulation_hyperbolic_traits_2<K> Gt;
|
||||
|
||||
typedef CGAL::Triangulation_vertex_base_2<Gt> Vb;
|
||||
typedef CGAL::Delaunay_mesh_face_base_2<Gt> Fb;
|
||||
typedef CGAL::Triangulation_data_structure_2<Vb, Fb> Tds;
|
||||
typedef CGAL::Constrained_Delaunay_triangulation_2<Gt, Tds> CDT;
|
||||
typedef CGAL::Delaunay_mesh_size_criteria_2<CDT> Criteria;
|
||||
|
||||
typedef CDT::Vertex_handle Vertex_handle;
|
||||
typedef CDT::Point Point;
|
||||
|
||||
int main()
|
||||
{
|
||||
CDT cdt;
|
||||
Vertex_handle va = cdt.insert(Point(2,0));
|
||||
Vertex_handle vb = cdt.insert(Point(0,2));
|
||||
Vertex_handle vc = cdt.insert(Point(-2,0));
|
||||
Vertex_handle vd = cdt.insert(Point(0,-2));
|
||||
|
||||
cdt.insert_constraint(va, vb);
|
||||
cdt.insert_constraint(vb, vc);
|
||||
cdt.insert_constraint(vc, vd);
|
||||
cdt.insert_constraint(vd, va);
|
||||
|
||||
va = cdt.insert(Point(3,3));
|
||||
vb = cdt.insert(Point(-3,3));
|
||||
vc = cdt.insert(Point(-3,-3));
|
||||
vd = cdt.insert(Point(3,0-3));
|
||||
|
||||
cdt.insert_constraint(va, vb);
|
||||
cdt.insert_constraint(vb, vc);
|
||||
cdt.insert_constraint(vc, vd);
|
||||
cdt.insert_constraint(vd, va);
|
||||
|
||||
std::list<Point> list_of_seeds;
|
||||
|
||||
list_of_seeds.push_back(Point(0, 0));
|
||||
|
||||
std::cout << "Number of vertices: " << cdt.number_of_vertices() << std::endl;
|
||||
|
||||
std::cout << "Meshing the domain..." << std::endl;
|
||||
CGAL::refine_Delaunay_mesh_2(cdt, list_of_seeds.begin(), list_of_seeds.end(),
|
||||
Criteria());
|
||||
|
||||
std::cout << "Number of vertices: " << cdt.number_of_vertices() << std::endl;
|
||||
std::cout << "Number of finite faces: " << cdt.number_of_faces() << std::endl;
|
||||
int mesh_faces_counter = 0;
|
||||
for(CDT::Finite_faces_iterator fit = cdt.finite_faces_begin();
|
||||
fit != cdt.finite_faces_end(); ++fit)
|
||||
{
|
||||
if(fit->is_in_domain()) ++mesh_faces_counter;
|
||||
}
|
||||
std::cout << "Number of faces in the mesh domain: " << mesh_faces_counter << std::endl;
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
// CGAL headers
|
||||
|
||||
#include <CGAL/Random.h>
|
||||
#include <CGAL/point_generators_2.h>
|
||||
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
||||
|
||||
typedef K::Point_2 Point_2;
|
||||
typedef K::FT FT;
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
typedef CGAL::Creator_uniform_2<FT, Point_2> Creator;
|
||||
|
||||
FT r = 0;
|
||||
cout << "Please, enter radius of the disk:" << std::endl;
|
||||
cin >> r;
|
||||
assert(r > 0);
|
||||
|
||||
int nb = 0;
|
||||
cout << "Please, enter number of points:" << std::endl;
|
||||
cin >> nb;
|
||||
assert(nb >= 0);
|
||||
|
||||
CGAL::Random_points_in_disc_2<Point_2, Creator> in_disk(r);
|
||||
|
||||
vector<Point_2> pts(nb);
|
||||
|
||||
// file name
|
||||
string file_name("points.cin");
|
||||
|
||||
// output file
|
||||
ofstream output;
|
||||
output.open(file_name.c_str());
|
||||
|
||||
// write random points to the file
|
||||
for (int i=0 ; i < nb ; i++) {
|
||||
output << *in_disk << std::endl;
|
||||
in_disk++;
|
||||
}
|
||||
|
||||
output.close();
|
||||
|
||||
std::cout << "file name: " << file_name << std::endl;
|
||||
std::cout << "Done." << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
#include <fstream>
|
||||
|
||||
// CGAL headers
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
|
||||
#include <CGAL/Delaunay_triangulation_2.h>
|
||||
|
||||
#include <CGAL/Timer.h>
|
||||
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
||||
|
||||
typedef K::Point_2 Point_2;
|
||||
|
||||
typedef CGAL::Delaunay_triangulation_2<K> Dt;
|
||||
|
||||
int main()
|
||||
{
|
||||
CGAL::Timer timer;
|
||||
|
||||
std::vector<Point_2> pts;
|
||||
|
||||
std::ifstream f("points.cin");
|
||||
|
||||
Point_2 p;
|
||||
while(f >> p) {
|
||||
pts.push_back(p);
|
||||
}
|
||||
f.close();
|
||||
|
||||
timer.start();
|
||||
|
||||
Dt dt = Dt();
|
||||
|
||||
dt.insert(pts.begin(), pts.end());
|
||||
|
||||
timer.stop();
|
||||
|
||||
std::cout << "R^2" << std::endl;
|
||||
std::cout << "Number of points: " << dt.number_of_vertices() << std::endl;
|
||||
std::cout << "Time: " << timer.time() << std::endl;
|
||||
|
||||
timer.reset();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
#include <fstream>
|
||||
|
||||
// CGAL headers
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
|
||||
#include <CGAL/Delaunay_hyperbolic_triangulation_2.h>
|
||||
|
||||
#include <CGAL/Triangulation_hyperbolic_traits_2.h>
|
||||
|
||||
#include <CGAL/Timer.h>
|
||||
|
||||
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
||||
typedef CGAL::Triangulation_hyperbolic_traits_2<K> Gt;
|
||||
|
||||
typedef K::Point_2 Point_2;
|
||||
typedef K::FT FT;
|
||||
|
||||
typedef CGAL::Delaunay_hyperbolic_triangulation_2<Gt> HDt;
|
||||
|
||||
int main()
|
||||
{
|
||||
CGAL::Timer timer;
|
||||
|
||||
std::vector<Point_2> pts;
|
||||
|
||||
std::ifstream f("points.cin");
|
||||
|
||||
Point_2 p;
|
||||
while(f >> p) {
|
||||
pts.push_back(p);
|
||||
}
|
||||
f.close();
|
||||
|
||||
// Radius of the Poincare Disk
|
||||
FT r = 100;
|
||||
|
||||
timer.start();
|
||||
|
||||
HDt hdt = HDt(Gt(r));
|
||||
|
||||
hdt.insert(pts.begin(), pts.end());
|
||||
|
||||
timer.stop();
|
||||
|
||||
std::cout << "H^2" << std::endl;
|
||||
std::cout << "Number of points: " << hdt.number_of_vertices() << std::endl;
|
||||
std::cout << "Time: " << timer.time() << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
#include <fstream>
|
||||
|
||||
// CGAL headers
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
|
||||
#include <CGAL/Delaunay_hyperbolic_triangulation_2.h>
|
||||
|
||||
#include <CGAL/Triangulation_hyperbolic_traits_2.h>
|
||||
|
||||
#include <CGAL/Timer.h>
|
||||
|
||||
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
||||
typedef CGAL::Triangulation_hyperbolic_traits_2<K> Gt;
|
||||
|
||||
typedef K::Point_2 Point_2;
|
||||
typedef K::FT FT;
|
||||
|
||||
typedef CGAL::Delaunay_hyperbolic_triangulation_2<Gt> HDt;
|
||||
|
||||
int main()
|
||||
{
|
||||
CGAL::Timer timer;
|
||||
|
||||
std::vector<Point_2> pts;
|
||||
|
||||
std::ifstream f("points.cin");
|
||||
|
||||
Point_2 p;
|
||||
while(f >> p) {
|
||||
pts.push_back(p);
|
||||
}
|
||||
f.close();
|
||||
|
||||
// Radius of the Poincare Disk
|
||||
FT r = 100;
|
||||
|
||||
timer.start();
|
||||
|
||||
HDt hdt = HDt(Gt(r));
|
||||
|
||||
hdt.insert2(pts.begin(), pts.end());
|
||||
|
||||
timer.stop();
|
||||
|
||||
std::cout << "H^2" << std::endl;
|
||||
std::cout << "Number of points: " << hdt.number_of_vertices() << std::endl;
|
||||
std::cout << "Time: " << timer.time() << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
#include <fstream>
|
||||
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Triangulation_hyperbolic_traits_2.h>
|
||||
#include <CGAL/Triangulation_2.h>
|
||||
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
||||
|
||||
typedef CGAL::Triangulation_hyperbolic_traits_2<K> Gt;
|
||||
|
||||
typedef CGAL::Triangulation_2<Gt> Triangulation;
|
||||
typedef Triangulation::Vertex_circulator Vertex_circulator;
|
||||
typedef Triangulation::Point Point;
|
||||
|
||||
int main() {
|
||||
std::ifstream in("/Users/mbogdano/Projects/Hyperbolic_triangulation_2/examples/Hyperbolic_triangulation_2/data/triangulation.cin");
|
||||
std::istream_iterator<Point> begin(in);
|
||||
std::istream_iterator<Point> end;
|
||||
|
||||
Triangulation t;
|
||||
t.insert(begin, end);
|
||||
|
||||
Vertex_circulator vc = t.incident_vertices(t.infinite_vertex()),
|
||||
done(vc);
|
||||
if (vc != 0) {
|
||||
do { std::cout << vc->point() << std::endl;
|
||||
}while(++vc != done);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,674 @@
|
|||
// Copyright (c) 2010 INRIA Sophia-Antipolis (France).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org); you may redistribute it under
|
||||
// the terms of the Q Public License version 1.0.
|
||||
// See the file LICENSE.QPL distributed with CGAL.
|
||||
//
|
||||
// Licensees holding a valid commercial license may use this file in
|
||||
// accordance with the commercial license agreement provided with the software.
|
||||
//
|
||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/candidate-packages/Triangulation_2/include/CGAL/Delaunay_triangulation_2.h $
|
||||
// $Id: Delaunay_triangulation_2.h 57509 2010-07-15 09:14:09Z sloriot $
|
||||
//
|
||||
//
|
||||
// Author(s) : Mikhail Bogdanov
|
||||
|
||||
#ifndef CGAL_DELAUNAY_HYPERBOLIC_TRIANGULATION_2_H
|
||||
#define CGAL_DELAUNAY_HYPERBOLIC_TRIANGULATION_2_H
|
||||
|
||||
#include <CGAL/Triangulation_face_base_with_info_2.h>
|
||||
#include <CGAL/Delaunay_triangulation_2.h>
|
||||
|
||||
#include <stack>
|
||||
#include <set>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
class Hyperbolic_face_info_2
|
||||
{
|
||||
public:
|
||||
Hyperbolic_face_info_2() : _is_finite_invisible(false), _invisible_edge(UCHAR_MAX)
|
||||
{
|
||||
}
|
||||
|
||||
bool is_finite_invisible() const
|
||||
{
|
||||
return _is_finite_invisible;
|
||||
}
|
||||
|
||||
void set_finite_invisible(bool is_finite_invisible)
|
||||
{
|
||||
_is_finite_invisible = is_finite_invisible;
|
||||
}
|
||||
|
||||
// Supposed to be called before "get_invisible_edge"
|
||||
bool has_invisible_edge() const
|
||||
{
|
||||
return _invisible_edge <= 2;
|
||||
}
|
||||
|
||||
// Higly recommended to call "has_invisible_edge" before
|
||||
unsigned char get_invisible_edge() const
|
||||
{
|
||||
assert(_is_finite_invisible);
|
||||
assert(_invisible_edge <= 2);
|
||||
|
||||
return _invisible_edge;
|
||||
}
|
||||
|
||||
void set_invisible_edge(unsigned char invisible_edge)
|
||||
{
|
||||
assert(_is_finite_invisible);
|
||||
assert(invisible_edge <= 2);
|
||||
|
||||
_invisible_edge = invisible_edge;
|
||||
}
|
||||
|
||||
private:
|
||||
// a face is invisible if a circumscribing circle intersects the circle at infinity
|
||||
bool _is_finite_invisible;
|
||||
|
||||
// defined only if the face is finite and invisible
|
||||
unsigned char _invisible_edge;
|
||||
};
|
||||
|
||||
template < class Gt,
|
||||
class Tds = Triangulation_data_structure_2 <
|
||||
Triangulation_vertex_base_2<Gt>,
|
||||
Triangulation_face_base_with_info_2<Hyperbolic_face_info_2, Gt> > >
|
||||
class Delaunay_hyperbolic_triangulation_2 : public Delaunay_triangulation_2<Gt,Tds>
|
||||
{
|
||||
public:
|
||||
typedef Delaunay_hyperbolic_triangulation_2<Gt, Tds> Self;
|
||||
typedef Delaunay_triangulation_2<Gt,Tds> Base;
|
||||
|
||||
typedef Triangulation_face_base_with_info_2<Hyperbolic_face_info_2, Gt> Face_base;
|
||||
typedef typename Face_base::Info Face_info;
|
||||
|
||||
typedef typename Base::size_type size_type;
|
||||
|
||||
typedef typename Base::Vertex_handle Vertex_handle;
|
||||
typedef typename Base::Face_handle Face_handle;
|
||||
typedef typename Base::Edge Edge;
|
||||
|
||||
#ifndef CGAL_CFG_USING_BASE_MEMBER_BUG_2
|
||||
using Base::cw;
|
||||
using Base::ccw;
|
||||
using Base::geom_traits;
|
||||
#endif
|
||||
|
||||
typedef typename Base::Edge_circulator Edge_circulator;
|
||||
typedef typename Base::Face_circulator Face_circulator;
|
||||
typedef typename Base::Vertex_circulator Vertex_circulator;
|
||||
|
||||
typedef typename Base::All_vertices_iterator All_vertices_iterator;
|
||||
typedef typename Base::All_edges_iterator All_edges_iterator;
|
||||
typedef typename Base::All_faces_iterator All_faces_iterator;
|
||||
|
||||
typedef Gt Geom_traits;
|
||||
typedef typename Geom_traits::FT FT;
|
||||
typedef typename Geom_traits::Point_2 Point;
|
||||
typedef typename Geom_traits::Segment_2 Segment;
|
||||
|
||||
typedef typename Geom_traits::Triangulation_euclidean_traits_2 Euclidean_geom_traits;
|
||||
|
||||
/*
|
||||
#ifndef CGAL_CFG_USING_BASE_MEMBER_BUG_2
|
||||
using Triangulation::side_of_oriented_circle;
|
||||
using Triangulation::circumcenter;
|
||||
using Triangulation::collinear_between;
|
||||
using Triangulation::test_dim_down;
|
||||
using Triangulation::make_hole;
|
||||
using Triangulation::fill_hole_delaunay;
|
||||
using Triangulation::delete_vertex;
|
||||
#endif
|
||||
*/
|
||||
|
||||
Delaunay_hyperbolic_triangulation_2(const Gt& gt = Gt())
|
||||
: Delaunay_triangulation_2<Gt,Tds>(gt) {}
|
||||
|
||||
Delaunay_hyperbolic_triangulation_2(
|
||||
const Delaunay_hyperbolic_triangulation_2<Gt,Tds> &tr)
|
||||
: Delaunay_triangulation_2<Gt,Tds>(tr)
|
||||
{ CGAL_triangulation_postcondition( this->is_valid() );}
|
||||
|
||||
|
||||
void mark_star(Vertex_handle v) const
|
||||
{
|
||||
if(!is_star_bounded(v)) {
|
||||
mark_star_faces(v);
|
||||
}
|
||||
}
|
||||
|
||||
Vertex_handle insert(const Point &p,
|
||||
Face_handle start = Face_handle() )
|
||||
{
|
||||
Vertex_handle v = Base::insert(p, start);
|
||||
mark_star(v);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
Vertex_handle insert(const Point& p,
|
||||
typename Base::Locate_type lt,
|
||||
Face_handle loc, int li )
|
||||
{
|
||||
Vertex_handle v = Base::insert(p, lt, loc, li);
|
||||
mark_star(v);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
#ifndef CGAL_TRIANGULATION_2_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO
|
||||
template < class InputIterator >
|
||||
std::ptrdiff_t
|
||||
insert( InputIterator first, InputIterator last,
|
||||
typename boost::enable_if<
|
||||
boost::is_base_of<
|
||||
Point,
|
||||
typename std::iterator_traits<InputIterator>::value_type
|
||||
>
|
||||
>::type* = NULL
|
||||
)
|
||||
#else
|
||||
template < class InputIterator >
|
||||
std::ptrdiff_t
|
||||
insert(InputIterator first, InputIterator last)
|
||||
#endif //CGAL_TRIANGULATION_2_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO
|
||||
{
|
||||
size_type n = Base::insert(first, last);
|
||||
|
||||
mark_faces();
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
//test version of insert function
|
||||
|
||||
#ifndef CGAL_TRIANGULATION_2_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO
|
||||
template < class InputIterator >
|
||||
std::ptrdiff_t
|
||||
insert2( InputIterator first, InputIterator last,
|
||||
typename boost::enable_if<
|
||||
boost::is_base_of<
|
||||
Point,
|
||||
typename std::iterator_traits<InputIterator>::value_type
|
||||
>
|
||||
>::type* = NULL
|
||||
)
|
||||
#else
|
||||
template < class InputIterator >
|
||||
std::ptrdiff_t
|
||||
insert_2(InputIterator first, InputIterator last)
|
||||
#endif //CGAL_TRIANGULATION_2_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO
|
||||
{
|
||||
size_type n = this->number_of_vertices();
|
||||
|
||||
std::vector<Point> points (first, last);
|
||||
spatial_sort (points.begin(), points.end(), geom_traits());
|
||||
Face_handle f;
|
||||
for (typename std::vector<Point>::const_iterator p = points.begin(), end = points.end();
|
||||
p != end; ++p)
|
||||
f = insert (*p, f)->face();
|
||||
|
||||
return this->number_of_vertices() - n;
|
||||
}
|
||||
|
||||
bool is_infinite(Vertex_handle v) const
|
||||
{
|
||||
return Base::is_infinite(v);
|
||||
}
|
||||
|
||||
bool is_infinite(Face_handle f) const
|
||||
{
|
||||
return has_infinite_vertex(f) || is_finite_invisible(f);
|
||||
}
|
||||
|
||||
bool is_infinite(Face_handle f, int i) const
|
||||
{
|
||||
return has_infinite_vertex(f, i) || is_finite_invisible(f, i);
|
||||
}
|
||||
|
||||
bool is_infinite(const Edge& e) const
|
||||
{
|
||||
return is_infinite(e.first, e.second);
|
||||
}
|
||||
|
||||
bool is_infinite(const Edge_circulator& ec) const
|
||||
{
|
||||
return is_infinite(*ec);
|
||||
}
|
||||
|
||||
bool is_infinite(const All_edges_iterator& ei) const
|
||||
{
|
||||
return is_infinite(*ei);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
bool has_infinite_vertex(Face_handle f) const
|
||||
{
|
||||
return Base::is_infinite(f);
|
||||
}
|
||||
|
||||
bool has_infinite_vertex(Face_handle f, int i) const
|
||||
{
|
||||
return Base::is_infinite(f, i);
|
||||
}
|
||||
|
||||
bool has_infinite_vertex(const Edge& e) const
|
||||
{
|
||||
return Base::is_infinite(e);
|
||||
}
|
||||
|
||||
int get_finite_invisible_edge(Face_handle f) const
|
||||
{
|
||||
assert(is_finite_invisible(f));
|
||||
|
||||
return f->info().get_invisible_edge();
|
||||
}
|
||||
|
||||
bool is_finite_invisible(Face_handle f) const
|
||||
{
|
||||
return f->info().is_finite_invisible();
|
||||
}
|
||||
|
||||
bool is_finite_invisible(Face_handle f, int i) const
|
||||
{
|
||||
if(this->dimension() <= 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(is_finite_invisible(f) && get_finite_invisible_edge(f) == i) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// another incident face and corresponding index
|
||||
Face_handle f2 = f->neighbor(i);
|
||||
int i2 = f2->index(f);
|
||||
|
||||
if(is_finite_invisible(f2) && get_finite_invisible_edge(f2) == i2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool is_finite_invisible(const Edge& e) const
|
||||
{
|
||||
return is_finite_invisible(e.first, e.second);
|
||||
}
|
||||
|
||||
// Depth-first search (dfs) and marking of the finite invisible faces.
|
||||
void mark_faces() const
|
||||
{
|
||||
if(this->dimension() <= 1) return;
|
||||
|
||||
std::set<Face_handle> visited_faces;
|
||||
|
||||
// maintain a stack to be able to backtrack
|
||||
// to the most recent faces which neighbors are not visited
|
||||
std::stack<Face_handle> backtrack;
|
||||
|
||||
// start from a face with infinite vertex
|
||||
Face_handle start = Base::infinite_face();
|
||||
|
||||
// mark it as visited
|
||||
visited_faces.insert(start);
|
||||
|
||||
// put the element whom neighbors we are going to explore.
|
||||
backtrack.push(start);
|
||||
|
||||
// test whether a face is finite invisible or not
|
||||
Mark_face test(*this);
|
||||
|
||||
Face_handle current, next;
|
||||
Face_info face_info;
|
||||
|
||||
while(!backtrack.empty()) {
|
||||
// take a face
|
||||
current = backtrack.top();
|
||||
|
||||
// start visiting the neighbors
|
||||
int i = 0;
|
||||
for(; i < 3; i++) {
|
||||
next = current->neighbor(i);
|
||||
|
||||
// if a neighbor is already visited, then stop going deeper
|
||||
if(visited_faces.find(next) != visited_faces.end()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
visited_faces.insert(next);
|
||||
mark_face(next, test);
|
||||
|
||||
// go deeper if the neighbor is infinite
|
||||
if(is_infinite(next)) {
|
||||
backtrack.push(next);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if all the neighbors are already visited, then remove "current" face.
|
||||
if(i == 3) {
|
||||
backtrack.pop();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// check if a star is bounded by finite faces
|
||||
// TODO: rename this function name
|
||||
bool is_star_bounded(Vertex_handle v) const
|
||||
{
|
||||
if(this->dimension() <= 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Face_handle f = v->face();
|
||||
Face_handle next;
|
||||
int i;
|
||||
Face_handle start(f);
|
||||
|
||||
Face_handle opposite_face;
|
||||
|
||||
do {
|
||||
i = f->index(v);
|
||||
next = f->neighbor(ccw(i)); // turn ccw around v
|
||||
|
||||
opposite_face = f->neighbor(i);
|
||||
if(this->is_infinite(opposite_face)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
f = next;
|
||||
} while(next != start);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//use the function: insert_and_give_new_faces?
|
||||
|
||||
void mark_star_faces(Vertex_handle v) const
|
||||
{
|
||||
// TODO: think of it
|
||||
if(this->dimension() <= 1) return;
|
||||
|
||||
Face_handle f = v->face();
|
||||
Face_handle next;
|
||||
int i;
|
||||
Face_handle start(f);
|
||||
do {
|
||||
i = f->index(v);
|
||||
next = f->neighbor(ccw(i)); // turn ccw around v
|
||||
|
||||
mark_face(f);
|
||||
|
||||
f = next;
|
||||
} while(next != start);
|
||||
return;
|
||||
}
|
||||
|
||||
template<class Mark_face_test>
|
||||
void mark_face(const Face_handle& f, const Mark_face_test& test) const
|
||||
{
|
||||
if(has_infinite_vertex(f)) {
|
||||
return;
|
||||
}
|
||||
f->info() = test(f);
|
||||
}
|
||||
|
||||
void mark_face(const Face_handle& f) const
|
||||
{
|
||||
Mark_face test(*this);
|
||||
mark_face(f, test);
|
||||
}
|
||||
|
||||
class Mark_face
|
||||
{
|
||||
public:
|
||||
typedef typename Gt::Circle_2 Circle_2;
|
||||
|
||||
Mark_face(const Self& tr) :
|
||||
_tr(tr)
|
||||
{}
|
||||
|
||||
Face_info operator ()(const Face_handle& f) const
|
||||
{
|
||||
Face_info info;
|
||||
if(_tr.has_infinite_vertex(f)) {
|
||||
return info;
|
||||
}
|
||||
|
||||
construct_circumscribing_circle(f);
|
||||
|
||||
if (intersection_with_circle_at_infinity()) {
|
||||
|
||||
info.set_finite_invisible(true);
|
||||
info.set_invisible_edge(find_invisible_edge(f));
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void construct_circumscribing_circle(const Face_handle& f) const
|
||||
{
|
||||
//assert(_tr.has_infinite_vertex(f));
|
||||
|
||||
Point p1 = f->vertex(0)->point();
|
||||
Point p2 = f->vertex(1)->point();
|
||||
Point p3 = f->vertex(2)->point();
|
||||
|
||||
_circle = Circle_2(p1, p2, p3);
|
||||
}
|
||||
|
||||
bool intersection_with_circle_at_infinity() const
|
||||
{
|
||||
const Circle_2& unit_circle = _tr.geom_traits().unit_circle();
|
||||
|
||||
return CGAL::do_intersect(unit_circle, _circle);
|
||||
}
|
||||
|
||||
// assume that the circumscribing circle of a given face intersects
|
||||
// the circle at infinity
|
||||
unsigned char find_invisible_edge(const Face_handle& f) const
|
||||
{
|
||||
typedef Euclidean_geom_traits Egt;
|
||||
typedef typename Egt::Construct_circumcenter_2 Construct_circumcenter_2;
|
||||
typedef typename Egt::Direction_2 Direction_2;
|
||||
|
||||
assert(!_tr.has_infinite_vertex(f));
|
||||
|
||||
Point p0 = f->vertex(0)->point();
|
||||
Point p1 = f->vertex(1)->point();
|
||||
Point p2 = f->vertex(2)->point();
|
||||
|
||||
Point c = _circle.center();
|
||||
|
||||
Direction_2 d0(p0.x()-c.x(), p0.y()-c.y());
|
||||
Direction_2 d1(p1.x()-c.x(), p1.y()-c.y());
|
||||
Direction_2 d2(p2.x()-c.x(), p2.y()-c.y());
|
||||
|
||||
Direction_2 d(c.x(), c.y());
|
||||
|
||||
if(d.counterclockwise_in_between(d0, d1)) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
if(d.counterclockwise_in_between(d1, d2)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
Mark_face(const Mark_face&);
|
||||
Mark_face& operator= (const Mark_face&);
|
||||
|
||||
mutable Circle_2 _circle;
|
||||
|
||||
const Self& _tr;
|
||||
};
|
||||
|
||||
public:
|
||||
// This class is used to generate the Finite_*_iterators.
|
||||
class Infinite_hyperbolic_tester
|
||||
{
|
||||
const Self *t;
|
||||
public:
|
||||
Infinite_hyperbolic_tester() {}
|
||||
Infinite_hyperbolic_tester(const Self *tr) : t(tr) {}
|
||||
|
||||
bool operator()(const All_vertices_iterator & vit) const {
|
||||
return t->is_infinite(vit);
|
||||
}
|
||||
bool operator()(const All_faces_iterator & fit) const {
|
||||
return t->is_infinite(fit);
|
||||
}
|
||||
bool operator()(const All_edges_iterator & eit ) const {
|
||||
return t->is_infinite(eit);
|
||||
}
|
||||
};
|
||||
|
||||
Infinite_hyperbolic_tester
|
||||
infinite_hyperbolic_tester() const
|
||||
{
|
||||
return Infinite_hyperbolic_tester(this);
|
||||
}
|
||||
|
||||
//Finite faces iterator
|
||||
|
||||
class Finite_faces_iterator
|
||||
: public Filter_iterator<All_faces_iterator, Infinite_hyperbolic_tester>
|
||||
{
|
||||
typedef Filter_iterator<All_faces_iterator, Infinite_hyperbolic_tester> Base;
|
||||
typedef Finite_faces_iterator Self;
|
||||
public:
|
||||
Finite_faces_iterator() : Base() {}
|
||||
Finite_faces_iterator(const Base &b) : Base(b) {}
|
||||
Self & operator++() { Base::operator++(); return *this; }
|
||||
Self & operator--() { Base::operator--(); return *this; }
|
||||
Self operator++(int) { Self tmp(*this); ++(*this); return tmp; }
|
||||
Self operator--(int) { Self tmp(*this); --(*this); return tmp; }
|
||||
operator const Face_handle() const { return Base::base(); }
|
||||
};
|
||||
|
||||
Finite_faces_iterator
|
||||
finite_faces_begin() const
|
||||
{
|
||||
if ( this->dimension() < 2 )
|
||||
return finite_faces_end();
|
||||
return CGAL::filter_iterator(this->all_faces_end(),
|
||||
Infinite_hyperbolic_tester(this),
|
||||
this->all_faces_begin() );
|
||||
}
|
||||
|
||||
Finite_faces_iterator
|
||||
finite_faces_end() const
|
||||
{
|
||||
return CGAL::filter_iterator(this->all_faces_end(),
|
||||
Infinite_hyperbolic_tester(this) );
|
||||
}
|
||||
|
||||
//Finite edges iterator
|
||||
|
||||
typedef Filter_iterator<All_edges_iterator,
|
||||
Infinite_hyperbolic_tester>
|
||||
Finite_edges_iterator;
|
||||
|
||||
Finite_edges_iterator
|
||||
finite_edges_begin() const
|
||||
{
|
||||
if ( this->dimension() < 1 )
|
||||
return finite_edges_end();
|
||||
return CGAL::filter_iterator(this->all_edges_end(),
|
||||
infinite_hyperbolic_tester(),
|
||||
this->all_edges_begin());
|
||||
}
|
||||
|
||||
Finite_edges_iterator
|
||||
finite_edges_end() const
|
||||
{
|
||||
return CGAL::filter_iterator(this->all_edges_end(),
|
||||
infinite_hyperbolic_tester() );
|
||||
}
|
||||
|
||||
using Base::dual;
|
||||
|
||||
Object
|
||||
dual(const Finite_edges_iterator& ei) const
|
||||
{
|
||||
return this->dual(*ei);
|
||||
}
|
||||
|
||||
Object
|
||||
dual(const Edge &e) const
|
||||
{
|
||||
CGAL_triangulation_precondition (!this->is_infinite(e));
|
||||
|
||||
if(this->dimension() == 1) {
|
||||
const Point& p = (e.first)->vertex(cw(e.second))->point();
|
||||
const Point& q = (e.first)->vertex(ccw(e.second))->point();
|
||||
|
||||
// hyperbolic line
|
||||
Segment line = this->geom_traits().construct_hyperbolic_bisector_2_object()(p,q);
|
||||
return make_object(line);
|
||||
}
|
||||
|
||||
// incident faces
|
||||
Face_handle f1 = e.first;
|
||||
int i1 = e.second;
|
||||
|
||||
Face_handle f2 = f1->neighbor(i1);
|
||||
int i2 = f2->index(f1);
|
||||
|
||||
// boths faces are infinite, but the incident edge is finite
|
||||
if(is_infinite(f1) && is_infinite(f2)){
|
||||
const Point& p = (f1)->vertex(cw(i1))->point();
|
||||
const Point& q = (f1)->vertex(ccw(i1))->point();
|
||||
|
||||
// hyperbolic line
|
||||
Segment line = this->geom_traits().construct_hyperbolic_bisector_2_object()(p,q);
|
||||
return make_object(line);
|
||||
}
|
||||
|
||||
// both faces are finite
|
||||
if(!is_infinite(f1) && !is_infinite(f2)) {
|
||||
|
||||
Segment s = this->geom_traits().construct_segment_2_object()
|
||||
(dual(f1),dual(f2));
|
||||
|
||||
return make_object(s);
|
||||
}
|
||||
|
||||
// one of the incident faces is infinite
|
||||
Face_handle finite_face = f1;
|
||||
int i = i1;
|
||||
|
||||
if(is_infinite(f1)) {
|
||||
finite_face = f2;
|
||||
i = i2;
|
||||
}
|
||||
|
||||
const Point& p = finite_face->vertex(cw(i))->point();
|
||||
const Point& q = finite_face->vertex(ccw(i))->point();
|
||||
|
||||
// ToDo: Line or Segment?
|
||||
// hyperbolic line and ray
|
||||
Segment line = this->geom_traits().construct_hyperbolic_bisector_2_object()(p,q);
|
||||
Segment ray = this->geom_traits().construct_ray_2_object()(dual(finite_face), line);
|
||||
return make_object(ray);
|
||||
}
|
||||
};
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
#endif // CGAL_DELAUNAY_HYPERBOLIC_TRIANGULATION_2_H
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
// Copyright (c) 2011 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://mbogdanov@scm.gforge.inria.fr/svn/cgal/trunk/Triangulation_2/include/CGAL/Triangulation_hyperbolic_traits_2.h $
|
||||
// $Id: Hyperboloic_isometry_2.h 57323 2010-07-05 10:07:39Z sloriot $
|
||||
//
|
||||
//
|
||||
// Author(s) : Mikhail Bogdanov
|
||||
|
||||
#ifndef CGAL_HYPERBOLIC_ISOMETRY_2_H
|
||||
#define CGAL_HYPERBOLIC_ISOMETRY_2_H
|
||||
|
||||
#include <complex>
|
||||
|
||||
#include <CGAL/number_utils.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
/*
|
||||
z -> (m*z + n)/(conj(n)*z + conj(m))
|
||||
*/
|
||||
template<class Gt>
|
||||
class Hyperbolic_isometry_2
|
||||
{
|
||||
public:
|
||||
typedef Gt Geom_traits;
|
||||
typedef typename Gt::FT FT;
|
||||
typedef typename Gt::Point Point;
|
||||
typedef std::complex<FT> complex;
|
||||
|
||||
Hyperbolic_isometry_2(const complex& m = complex(1, 0), const complex& n = complex(0, 0))
|
||||
: m_(m), n_(n)
|
||||
{
|
||||
}
|
||||
|
||||
~Hyperbolic_isometry_2()
|
||||
{
|
||||
}
|
||||
|
||||
complex DoAction(const complex& z) const
|
||||
{
|
||||
return (m_*z + n_)/(std::conj(n_)*z + std::conj(m_));
|
||||
}
|
||||
|
||||
Point DoAction(const Point& p) const
|
||||
{
|
||||
complex z = complex(p.x(), p.y());
|
||||
complex result = DoAction(z);
|
||||
|
||||
return Point(result.real(), result.imag());
|
||||
}
|
||||
|
||||
Hyperbolic_isometry_2 inverse() const
|
||||
{
|
||||
return Hyperbolic_isometry_2(-std::conj(m_), n_);
|
||||
}
|
||||
|
||||
Hyperbolic_isometry_2 operator * (const Hyperbolic_isometry_2& other) const
|
||||
{
|
||||
return Hyperbolic_isometry_2(m_*other.m_ + n_*std::conj(other.n_), m_*other.n_ + n_*std::conj(other.m_));
|
||||
}
|
||||
|
||||
void file_output(std::ostream& os) const
|
||||
{
|
||||
os << m_ << " " << n_ << std::endl;
|
||||
}
|
||||
|
||||
complex m() const
|
||||
{
|
||||
return m_;
|
||||
}
|
||||
|
||||
complex n() const
|
||||
{
|
||||
return n_;
|
||||
}
|
||||
|
||||
private:
|
||||
complex m_;
|
||||
complex n_;
|
||||
};
|
||||
|
||||
template <class Gt>
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const Hyperbolic_isometry_2<Gt> &isometry)
|
||||
{
|
||||
isometry.file_output(os);
|
||||
return os;
|
||||
}
|
||||
|
||||
} // namespace CGAL
|
||||
|
||||
#endif // CGAL_HYPERBOLIC_ISOMETRY_2_H
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
// Copyright (c) 2011 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://mbogdanov@scm.gforge.inria.fr/svn/cgal/trunk/Triangulation_2/include/CGAL/Triangulation_hyperbolic_traits_2.h $
|
||||
// $Id: Triangulation_hyperbolic_traits_2.h 57323 2010-07-05 10:07:39Z sloriot $
|
||||
//
|
||||
//
|
||||
// Author(s) : Mikhail Bogdanov
|
||||
|
||||
#ifndef CGAL_HYPERBOLIC_PAINTER_OSTREAM_H
|
||||
#define CGAL_HYPERBOLIC_PAINTER_OSTREAM_H
|
||||
|
||||
#include <CGAL/Qt/PainterOstream.h>
|
||||
|
||||
#include <CGAL/Triangulation_hyperbolic_traits_2.h>
|
||||
|
||||
namespace CGAL{
|
||||
|
||||
namespace Qt {
|
||||
|
||||
template <typename K>
|
||||
class PainterOstream<Triangulation_hyperbolic_traits_2<K> > : public PainterOstream<K> {
|
||||
public:
|
||||
typedef PainterOstream<K> Base;
|
||||
typedef PainterOstream<Triangulation_hyperbolic_traits_2<K> > Self;
|
||||
|
||||
typedef Triangulation_hyperbolic_traits_2<K> Gt;
|
||||
|
||||
private:
|
||||
typedef typename Gt::Segment_2 Segment_2;
|
||||
typedef typename Gt::Line_segment_2 Line_segment_2;
|
||||
typedef typename Gt::Arc_2 Arc_2;
|
||||
//typedef typename Gt::Line_2 Line_2;
|
||||
|
||||
typedef typename K::Point_2 Point_2;
|
||||
typedef typename K::Circle_2 Circle_2;
|
||||
|
||||
public:
|
||||
PainterOstream(QPainter* p, QRectF rect = QRectF())
|
||||
: Base(p, rect), qp(p), convert(rect) {}
|
||||
|
||||
using Base::operator <<;
|
||||
|
||||
PainterOstream& operator << (const Segment_2& s)
|
||||
{
|
||||
if(const Line_segment_2* line_segment = boost::get<Line_segment_2>(&s)){
|
||||
operator << (*line_segment);
|
||||
return *this;
|
||||
}
|
||||
if(const Arc_2* arc = boost::get<Arc_2>(&s)){
|
||||
|
||||
const Circle_2& circle = arc->get<0>();
|
||||
const Point_2& center = circle.center();
|
||||
const Point_2& source = arc->get<1>();
|
||||
const Point_2& target = arc->get<2>();
|
||||
|
||||
double asource = std::atan2( -to_double(source.y() - center.y()),
|
||||
to_double(source.x() - center.x()));
|
||||
double atarget = std::atan2( -to_double(target.y() - center.y()),
|
||||
to_double(target.x() - center.x()));
|
||||
|
||||
std::swap(asource, atarget);
|
||||
double aspan = atarget - asource;
|
||||
|
||||
if(aspan < 0.)
|
||||
aspan += 2 * CGAL_PI;
|
||||
|
||||
const double coeff = 180*16/CGAL_PI;
|
||||
this->qp->drawArc(this->convert(circle.bbox()),
|
||||
(int)(asource * coeff),
|
||||
(int)(aspan * coeff));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
// ToDo: These objects must be deleted
|
||||
// Copies of these objects are in the base class.
|
||||
// We need access to the copies in the base class.
|
||||
QPainter* qp;
|
||||
Converter<K> convert;
|
||||
};
|
||||
|
||||
} //namespace Qt
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
#endif // CGAL_HYPERBOLIC_PAINTER_OSTREAM_H
|
||||
|
||||
|
|
@ -0,0 +1,309 @@
|
|||
// Copyright (c) 2008 GeometryFactory Sarl (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/trunk/GraphicsView/include/CGAL/Qt/TriangulationGraphicsItem.h $
|
||||
// $Id: TriangulationGraphicsItem.h 61414 2011-02-24 16:36:04Z sloriot $
|
||||
//
|
||||
//
|
||||
// Author(s) : Andreas Fabri <Andreas.Fabri@geometryfactory.com>
|
||||
// Laurent Rineau <Laurent.Rineau@geometryfactory.com>
|
||||
|
||||
#ifndef CGAL_QT_TRIANGULATION_GRAPHICS_ITEM_H
|
||||
#define CGAL_QT_TRIANGULATION_GRAPHICS_ITEM_H
|
||||
|
||||
#include <CGAL/Bbox_2.h>
|
||||
#include <CGAL/apply_to_range.h>
|
||||
#include <CGAL/Qt/PainterOstream.h>
|
||||
#include <CGAL/Qt/GraphicsItem.h>
|
||||
#include <CGAL/Qt/Converter.h>
|
||||
|
||||
#include <QGraphicsScene>
|
||||
#include <QPainter>
|
||||
#include <QStyleOption>
|
||||
|
||||
namespace CGAL {
|
||||
namespace Qt {
|
||||
|
||||
template <typename T>
|
||||
class TriangulationGraphicsItem : public GraphicsItem
|
||||
{
|
||||
typedef typename T::Geom_traits Geom_traits;
|
||||
public:
|
||||
TriangulationGraphicsItem(T* t_);
|
||||
|
||||
void modelChanged();
|
||||
|
||||
public:
|
||||
|
||||
QRectF boundingRect() const;
|
||||
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
|
||||
virtual void operator()(typename T::Face_handle fh);
|
||||
|
||||
const QPen& verticesPen() const
|
||||
{
|
||||
return vertices_pen;
|
||||
}
|
||||
|
||||
const QPen& edgesPen() const
|
||||
{
|
||||
return edges_pen;
|
||||
}
|
||||
|
||||
void setVerticesPen(const QPen& pen)
|
||||
{
|
||||
vertices_pen = pen;
|
||||
}
|
||||
|
||||
void setEdgesPen(const QPen& pen)
|
||||
{
|
||||
edges_pen = pen;
|
||||
}
|
||||
|
||||
bool visibleVertices() const
|
||||
{
|
||||
return visible_vertices;
|
||||
}
|
||||
|
||||
void setVisibleVertices(const bool b)
|
||||
{
|
||||
visible_vertices = b;
|
||||
update();
|
||||
}
|
||||
|
||||
bool visibleEdges() const
|
||||
{
|
||||
return visible_edges;
|
||||
}
|
||||
|
||||
void setVisibleEdges(const bool b)
|
||||
{
|
||||
visible_edges = b;
|
||||
update();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void drawAll(QPainter *painter);
|
||||
void paintVertices(QPainter *painter);
|
||||
void paintOneVertex(const typename T::Point& point);
|
||||
virtual void paintVertex(typename T::Vertex_handle vh);
|
||||
void updateBoundingBox();
|
||||
|
||||
T * t;
|
||||
QPainter* m_painter;
|
||||
PainterOstream<Geom_traits> painterostream;
|
||||
|
||||
typename T::Vertex_handle vh;
|
||||
typename T::Point p;
|
||||
CGAL::Bbox_2 bb;
|
||||
bool bb_initialized;
|
||||
QRectF bounding_rect;
|
||||
|
||||
QPen vertices_pen;
|
||||
QPen edges_pen;
|
||||
bool visible_edges;
|
||||
bool visible_vertices;
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
TriangulationGraphicsItem<T>::TriangulationGraphicsItem(T * t_)
|
||||
: t(t_), painterostream(0),
|
||||
bb(0,0,0,0), bb_initialized(false),
|
||||
visible_edges(true), visible_vertices(true)
|
||||
{
|
||||
setVerticesPen(QPen(::Qt::red, 3.));
|
||||
if(t->number_of_vertices() == 0){
|
||||
this->hide();
|
||||
}
|
||||
updateBoundingBox();
|
||||
setZValue(3);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
QRectF
|
||||
TriangulationGraphicsItem<T>::boundingRect() const
|
||||
{
|
||||
return bounding_rect;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
TriangulationGraphicsItem<T>::operator()(typename T::Face_handle fh)
|
||||
{
|
||||
if(visible_edges) {
|
||||
for (int i=0; i<3; i++) {
|
||||
if (fh < fh->neighbor(i) || t->is_infinite(fh->neighbor(i))){
|
||||
m_painter->setPen(this->edgesPen());
|
||||
painterostream << t->segment(fh,i);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(visible_vertices) {
|
||||
for (int i=0; i<3; i++) {
|
||||
paintVertex(fh->vertex(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
TriangulationGraphicsItem<T>::drawAll(QPainter *painter)
|
||||
{
|
||||
painterostream = PainterOstream<Geom_traits>(painter);
|
||||
|
||||
if(visibleEdges()) {
|
||||
for(typename T::Finite_edges_iterator eit = t->finite_edges_begin();
|
||||
eit != t->finite_edges_end();
|
||||
++eit){
|
||||
painterostream << t->segment(*eit);
|
||||
}
|
||||
}
|
||||
paintVertices(painter);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
TriangulationGraphicsItem<T>::paintVertices(QPainter *painter)
|
||||
{
|
||||
if(visibleVertices()) {
|
||||
Converter<Geom_traits> convert;
|
||||
|
||||
painter->setPen(verticesPen());
|
||||
QMatrix matrix = painter->matrix();
|
||||
painter->resetMatrix();
|
||||
for(typename T::Finite_vertices_iterator it = t->finite_vertices_begin();
|
||||
it != t->finite_vertices_end();
|
||||
it++){
|
||||
|
||||
// draw vertices with color storing in their info
|
||||
if(it->info().getColor() == 0) {
|
||||
painter->setPen(QPen(::Qt::red, 3.));
|
||||
}
|
||||
|
||||
if(it->info().getColor() == 1) {
|
||||
painter->setPen(QPen(::Qt::green, 3.));
|
||||
}
|
||||
//
|
||||
|
||||
QPointF point = matrix.map(convert(it->point()));
|
||||
painter->drawPoint(point);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
TriangulationGraphicsItem<T>::paintOneVertex(const typename T::Point& point)
|
||||
{
|
||||
Converter<Geom_traits> convert;
|
||||
|
||||
m_painter->setPen(this->verticesPen());
|
||||
QMatrix matrix = m_painter->matrix();
|
||||
m_painter->resetMatrix();
|
||||
m_painter->drawPoint(matrix.map(convert(point)));
|
||||
m_painter->setMatrix(matrix);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
TriangulationGraphicsItem<T>::paintVertex(typename T::Vertex_handle vh)
|
||||
{
|
||||
Converter<Geom_traits> convert;
|
||||
|
||||
m_painter->setPen(this->verticesPen());
|
||||
QMatrix matrix = m_painter->matrix();
|
||||
m_painter->resetMatrix();
|
||||
m_painter->drawPoint(matrix.map(convert(vh->point())));
|
||||
m_painter->setMatrix(matrix);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
TriangulationGraphicsItem<T>::paint(QPainter *painter,
|
||||
const QStyleOptionGraphicsItem *option,
|
||||
QWidget * /*widget*/)
|
||||
{
|
||||
painter->setPen(this->edgesPen());
|
||||
// painter->drawRect(boundingRect());
|
||||
if ( t->dimension()<2 || option->exposedRect.contains(boundingRect()) ) {
|
||||
drawAll(painter);
|
||||
} else {
|
||||
m_painter = painter;
|
||||
painterostream = PainterOstream<Geom_traits>(painter);
|
||||
CGAL::apply_to_range (*t,
|
||||
typename T::Point(option->exposedRect.left(),
|
||||
option->exposedRect.bottom()),
|
||||
typename T::Point(option->exposedRect.right(),
|
||||
option->exposedRect.top()),
|
||||
*this);
|
||||
}
|
||||
}
|
||||
|
||||
// We let the bounding box only grow, so that when vertices get removed
|
||||
// the maximal bbox gets refreshed in the GraphicsView
|
||||
template <typename T>
|
||||
void
|
||||
TriangulationGraphicsItem<T>::updateBoundingBox()
|
||||
{
|
||||
prepareGeometryChange();
|
||||
if(t->number_of_vertices() == 0){
|
||||
bb = Bbox_2(0,0,0,0);
|
||||
bb_initialized = false;
|
||||
return;
|
||||
} else if(! bb_initialized){
|
||||
bb = t->finite_vertices_begin()->point().bbox();
|
||||
bb_initialized = true;
|
||||
}
|
||||
|
||||
if(t->dimension() <2){
|
||||
for(typename T::Finite_vertices_iterator it = t->finite_vertices_begin();
|
||||
it != t->finite_vertices_end();
|
||||
++it){
|
||||
bb = bb + it->point().bbox();
|
||||
}
|
||||
} else {
|
||||
typename T::Vertex_handle inf = t->infinite_vertex();
|
||||
typename T::Vertex_circulator vc = t->incident_vertices(inf), done(vc);
|
||||
do {
|
||||
bb = bb + vc->point().bbox();
|
||||
++vc;
|
||||
} while(vc != done);
|
||||
}
|
||||
bounding_rect = QRectF(bb.xmin(),
|
||||
bb.ymin(),
|
||||
bb.xmax()-bb.xmin(),
|
||||
bb.ymax()-bb.ymin());
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
TriangulationGraphicsItem<T>::modelChanged()
|
||||
{
|
||||
if((t->number_of_vertices() == 0) ){
|
||||
this->hide();
|
||||
} else if((t->number_of_vertices() > 0) && (! this->isVisible())){
|
||||
this->show();
|
||||
}
|
||||
updateBoundingBox();
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
} // namespace Qt
|
||||
} // namespace CGAL
|
||||
|
||||
#endif // CGAL_QT_TRIANGULATION_GRAPHICS_ITEM_H
|
||||
|
|
@ -0,0 +1,424 @@
|
|||
// 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://mbogdanov@scm.gforge.inria.fr/svn/cgal/trunk/Triangulation_2/include/CGAL/Triangulation_hyperbolic_traits_2.h $
|
||||
// $Id: Triangulation_hyperbolic_traits_2.h 57323 2010-07-05 10:07:39Z sloriot $
|
||||
//
|
||||
//
|
||||
// Author(s) : Mikhail Bogdanov
|
||||
|
||||
#ifndef CGAL_TRIANGULATION_HYPERBOLIC_TRAITS_2_H
|
||||
#define CGAL_TRIANGULATION_HYPERBOLIC_TRAITS_2_H
|
||||
|
||||
#include <CGAL/Point_2.h>
|
||||
#include <CGAL/Segment_2.h>
|
||||
#include <CGAL/Triangle_2.h>
|
||||
#include <CGAL/Line_2.h>
|
||||
#include <CGAL/Ray_2.h>
|
||||
#include <CGAL/predicates_on_points_2.h>
|
||||
#include <CGAL/basic_constructions_2.h>
|
||||
#include <CGAL/distance_predicates_2.h>
|
||||
|
||||
#include <CGAL/Regular_triangulation_filtered_traits_2.h>
|
||||
#include "boost/tuple/tuple.hpp"
|
||||
#include "boost/variant.hpp"
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template < class R >
|
||||
class Triangulation_hyperbolic_traits_2 {
|
||||
public:
|
||||
typedef Triangulation_hyperbolic_traits_2<R> Self;
|
||||
|
||||
typedef R Triangulation_euclidean_traits_2;
|
||||
|
||||
typedef R Rep;
|
||||
typedef typename R::RT RT;
|
||||
typedef typename R::Point_2 Point_2;
|
||||
typedef typename R::Vector_2 Vector_2;
|
||||
typedef typename R::Triangle_2 Triangle_2;
|
||||
typedef typename R::Line_2 Line_2;
|
||||
typedef typename R::Ray_2 Ray_2;
|
||||
|
||||
typedef typename R::Less_x_2 Less_x_2;
|
||||
typedef typename R::Less_y_2 Less_y_2;
|
||||
typedef typename R::Compare_x_2 Compare_x_2;
|
||||
typedef typename R::Compare_y_2 Compare_y_2;
|
||||
typedef typename R::Orientation_2 Orientation_2;
|
||||
typedef typename R::Side_of_oriented_circle_2 Side_of_oriented_circle_2;
|
||||
typedef typename R::Construct_bisector_2 Construct_bisector_2;
|
||||
typedef typename R::Compare_distance_2 Compare_distance_2;
|
||||
typedef typename R::Construct_triangle_2 Construct_triangle_2;
|
||||
typedef typename R::Construct_direction_2 Construct_direction_2;
|
||||
|
||||
typedef typename R::Angle_2 Angle_2;
|
||||
typedef typename R::Construct_midpoint_2 Construct_midpoint_2;
|
||||
typedef typename R::Compute_squared_distance_2 Compute_squared_distance_2;
|
||||
|
||||
typedef typename R::Iso_rectangle_2 Iso_rectangle_2;
|
||||
typedef typename R::Circle_2 Circle_2;
|
||||
|
||||
typedef boost::tuple<Circle_2, Point_2, Point_2> Arc_2;
|
||||
typedef typename R::Segment_2 Line_segment_2;
|
||||
typedef boost::variant<Arc_2, Line_segment_2> Segment_2;
|
||||
|
||||
typedef typename R::Line_2 Euclidean_line_2;
|
||||
|
||||
private:
|
||||
// Poincaré disk
|
||||
const Circle_2 _unit_circle;
|
||||
|
||||
public:
|
||||
const Circle_2& unit_circle() const
|
||||
{
|
||||
return _unit_circle;
|
||||
}
|
||||
|
||||
Angle_2
|
||||
angle_2_object() const
|
||||
{ return Angle_2(); }
|
||||
|
||||
Compute_squared_distance_2
|
||||
compute_squared_distance_2_object() const
|
||||
{ return Compute_squared_distance_2(); }
|
||||
|
||||
class Construct_segment_2
|
||||
{
|
||||
typedef typename CGAL::Regular_triangulation_filtered_traits_2<R> Regular_geometric_traits_2;
|
||||
typedef typename Regular_geometric_traits_2::Construct_weighted_circumcenter_2 Construct_weighted_circumcenter_2;
|
||||
typedef typename Regular_geometric_traits_2::Weighted_point_2 Weighted_point_2;
|
||||
typedef typename Regular_geometric_traits_2::Bare_point Bare_point;
|
||||
|
||||
public:
|
||||
Construct_segment_2(const Circle_2& c) : _unit_circle(c)
|
||||
{
|
||||
}
|
||||
|
||||
Segment_2 operator()(const Point_2& p, const Point_2& q) const
|
||||
{
|
||||
typedef typename R::Collinear_2 Collinear_2;
|
||||
if(Collinear_2()(p, q, _unit_circle.center())){
|
||||
return Line_segment_2(p, q);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
Circle_2 circle( center, radius);
|
||||
assert(circle.has_on_boundary(p) && circle.has_on_boundary(q));
|
||||
|
||||
if(Orientation_2()(p, q, center) == LEFT_TURN) {
|
||||
return Arc_2(circle, p, q);
|
||||
}
|
||||
return Arc_2(circle, q, p);
|
||||
}
|
||||
|
||||
private:
|
||||
const Circle_2& _unit_circle;
|
||||
};
|
||||
|
||||
Construct_segment_2
|
||||
construct_segment_2_object() const
|
||||
{
|
||||
return Construct_segment_2(_unit_circle);
|
||||
}
|
||||
|
||||
class Construct_circumcenter_2
|
||||
{
|
||||
public:
|
||||
Construct_circumcenter_2(const Circle_2& c) : _unit_circle(c)
|
||||
{}
|
||||
|
||||
// TODO: improve this function
|
||||
Point_2 operator()(Point_2 p, Point_2 q, Point_2 r)
|
||||
{
|
||||
assert(_unit_circle.bounded_side(p) == ON_BOUNDED_SIDE);
|
||||
assert(_unit_circle.bounded_side(q) == ON_BOUNDED_SIDE);
|
||||
assert(_unit_circle.bounded_side(r) == ON_BOUNDED_SIDE);
|
||||
|
||||
Circle_2 circle(p, q, r);
|
||||
// circle must be inside the unit one
|
||||
assert(CGAL::do_intersect(_unit_circle, circle) == false);
|
||||
|
||||
if(circle.center() <= _unit_circle.center() && circle.center() >= _unit_circle.center()){
|
||||
return _unit_circle.center();
|
||||
}
|
||||
|
||||
FT x0 = circle.center().x(), y0 = circle.center().y();
|
||||
// a*alphaˆ2 + b*alpha + c = 0;
|
||||
FT a = x0*x0 + y0*y0;
|
||||
FT b = a - circle.squared_radius() + _unit_circle.squared_radius();
|
||||
FT c = _unit_circle.squared_radius();
|
||||
FT D = b*b - 4*a*c;
|
||||
|
||||
FT alpha = (b - CGAL::sqrt(to_double(D)))/(2*a);
|
||||
|
||||
Point_2 center(x0*alpha, y0*alpha);
|
||||
if(!circle.has_on_bounded_side(center))
|
||||
{ std::cout << "Center does not belong to the pencil of spheres!!!" << std::endl;} ;
|
||||
return center;
|
||||
}
|
||||
|
||||
private:
|
||||
const Circle_2 _unit_circle;
|
||||
};
|
||||
|
||||
Construct_circumcenter_2
|
||||
construct_circumcenter_2_object()
|
||||
{
|
||||
Construct_circumcenter_2(_unit_circle);
|
||||
}
|
||||
|
||||
Construct_midpoint_2
|
||||
construct_midpoint_2_object() const
|
||||
{ return Construct_midpoint_2(); }
|
||||
|
||||
//for natural_neighbor_coordinates_2
|
||||
typedef typename R::FT FT;
|
||||
typedef typename R::Equal_x_2 Equal_x_2;
|
||||
typedef typename R::Compute_area_2 Compute_area_2;
|
||||
Compute_area_2 compute_area_2_object () const
|
||||
{
|
||||
return Compute_area_2();
|
||||
}
|
||||
|
||||
// for compatibility with previous versions
|
||||
typedef Point_2 Point;
|
||||
typedef Segment_2 Segment;
|
||||
typedef Triangle_2 Triangle;
|
||||
typedef Ray_2 Ray;
|
||||
//typedef Line_2 Line;
|
||||
|
||||
Triangulation_hyperbolic_traits_2() :
|
||||
_unit_circle(Point_2(0, 0), 100*100)
|
||||
{}
|
||||
|
||||
Triangulation_hyperbolic_traits_2(FT r) :
|
||||
_unit_circle(Point_2(0, 0), r*r)
|
||||
{}
|
||||
|
||||
Triangulation_hyperbolic_traits_2(const Triangulation_hyperbolic_traits_2 & other) :
|
||||
_unit_circle(other._unit_circle)
|
||||
{}
|
||||
|
||||
Triangulation_hyperbolic_traits_2 &operator=
|
||||
(const Triangulation_hyperbolic_traits_2 &)
|
||||
{ return *this;}
|
||||
|
||||
Less_x_2
|
||||
less_x_2_object() const
|
||||
{ return Less_x_2();}
|
||||
|
||||
Less_y_2
|
||||
less_y_2_object() const
|
||||
{ return Less_y_2();}
|
||||
|
||||
Compare_x_2
|
||||
compare_x_2_object() const
|
||||
{ return Compare_x_2();}
|
||||
|
||||
Compare_y_2
|
||||
compare_y_2_object() const
|
||||
{ return Compare_y_2();}
|
||||
|
||||
Orientation_2
|
||||
orientation_2_object() const
|
||||
{ return Orientation_2();}
|
||||
|
||||
Side_of_oriented_circle_2
|
||||
side_of_oriented_circle_2_object() const
|
||||
{return Side_of_oriented_circle_2();}
|
||||
|
||||
Construct_circumcenter_2
|
||||
construct_circumcenter_2_object() const
|
||||
{return Construct_circumcenter_2(_unit_circle);}
|
||||
|
||||
class Construct_hyperbolic_bisector_2
|
||||
{
|
||||
public:
|
||||
Construct_hyperbolic_bisector_2(const Circle_2& unit_circle) :
|
||||
_unit_circle(unit_circle) {}
|
||||
|
||||
Segment_2 operator()(Point_2 p, Point_2 q) const
|
||||
{
|
||||
// If two points are almost of the same distance to the origin, then
|
||||
// the bisector is supported by the circle of huge radius etc.
|
||||
// This circle is computed inexactly.
|
||||
// At present time, in this case the bisector is supported by the line.
|
||||
|
||||
Compute_squared_distance_2 dist = Compute_squared_distance_2();
|
||||
Point origin = _unit_circle.center();
|
||||
FT dif = dist(origin, p) - dist(origin, q);
|
||||
FT eps = 0.0000000001;
|
||||
|
||||
// Bisector is straight in euclidean sense
|
||||
if(dif > -eps && dif < eps){
|
||||
|
||||
// ideally
|
||||
//if(Compare_distance_2()(_unit_circle.center(), p, q) == EQUAL){
|
||||
|
||||
// TODO: calling R::Construct_bisector
|
||||
Euclidean_line_2 l = Construct_bisector_2()(p, q);
|
||||
// compute the ending points
|
||||
std::pair<Point_2, Point_2> points = find_intersection(l);
|
||||
// TODO: improve
|
||||
Vector_2 v(points.first, points.second);
|
||||
if(v*l.to_vector() > 0){
|
||||
return Line_segment_2(points.first, points.second);
|
||||
}
|
||||
return Line_segment_2(points.second, points.first);
|
||||
}
|
||||
|
||||
Circle_2 c = construct_supporting_circle(p, q);
|
||||
// compute the ending points
|
||||
std::pair<Point_2, Point_2> points = find_intersection(c);
|
||||
|
||||
if(Orientation_2()(points.first, points.second, c.center()) == LEFT_TURN) {
|
||||
return Arc_2(c, points.first, points.second);
|
||||
}
|
||||
return Arc_2(c, points.second, points.first);
|
||||
}
|
||||
|
||||
private:
|
||||
// The cirle belongs to the pencil with limit points p and q
|
||||
Circle_2 construct_supporting_circle(Point_2 p, Point_2 q) const
|
||||
{
|
||||
// p, q are zero-circles
|
||||
// (x, y, xˆ2 + yˆ2 - rˆ2) = alpha*(xp, yp, xpˆ2 + ypˆ2) + (1-alpha)*(xq, yq, xqˆ2 + yqˆ2)
|
||||
// xˆ2 + yˆ2 - rˆ2 = Rˆ2, where R - is a radius of the given unit circle
|
||||
FT op = p.x()*p.x() + p.y()*p.y();
|
||||
FT oq = q.x()*q.x() + q.y()*q.y();
|
||||
FT alpha = (_unit_circle.squared_radius() - oq) / (op - oq);
|
||||
|
||||
FT x = alpha*p.x() + (1-alpha)*q.x();
|
||||
FT y = alpha*p.y() + (1-alpha)*q.y();
|
||||
FT radius = x*x + y*y - _unit_circle.squared_radius();
|
||||
|
||||
//improve
|
||||
typename R::Line_2 l = typename R::Construct_bisector_2()(p, q);
|
||||
Point_2 middle = Construct_midpoint_2()(p, q);
|
||||
Point_2 temp = middle + l.to_vector();
|
||||
if(Orientation_2()(middle, temp, Point_2(x, y)) == ON_POSITIVE_SIDE){
|
||||
return Circle_2(Point_2(x, y), radius, CLOCKWISE);
|
||||
}
|
||||
|
||||
return Circle_2(Point_2(x, y), radius, COUNTERCLOCKWISE);
|
||||
}
|
||||
|
||||
// Find intersection of an input circle orthogonal to the Poincaré disk
|
||||
// and the circle representing this disk
|
||||
|
||||
// TODO: sqrt(to_double()?)
|
||||
std::pair<Point_2, Point_2> find_intersection(Circle_2& circle) const
|
||||
{
|
||||
FT x = circle.center().x(), y = circle.center().y();
|
||||
|
||||
// axˆ2 + 2bˆx + c = 0;
|
||||
FT a = x*x + y*y;
|
||||
FT b = -_unit_circle.squared_radius() * x;
|
||||
FT c = _unit_circle.squared_radius()*_unit_circle.squared_radius() - _unit_circle.squared_radius()*y*y;
|
||||
assert(b*b - a*c > 0);
|
||||
FT D = CGAL::sqrt(to_double(b*b - a*c));
|
||||
|
||||
FT x1 = (-b - D)/a;
|
||||
FT x2 = (-b + D)/a;
|
||||
FT y1 = (_unit_circle.squared_radius() - x1*x)/y;
|
||||
FT y2 = (_unit_circle.squared_radius() - x2*x)/y;
|
||||
|
||||
return std::make_pair(Point_2(x1, y1), Point_2(x2, y2));
|
||||
}
|
||||
|
||||
// Find intersection of an input line orthogonal to the Poincaré disk
|
||||
// and the circle representing this disk
|
||||
|
||||
// TODO: sqrt(to_double()?)
|
||||
std::pair<Point_2, Point_2> find_intersection(Euclidean_line_2& l) const
|
||||
{
|
||||
typedef typename R::Vector_2 Vector_2;
|
||||
Vector_2 v = l.to_vector();
|
||||
|
||||
// normalize the vector
|
||||
FT squared_coeff = _unit_circle.squared_radius()/v.squared_length();
|
||||
FT coeff = CGAL::sqrt(to_double(squared_coeff));
|
||||
|
||||
Point_2 p1(coeff*v.x(), coeff*v.y());
|
||||
Point_2 p2(-p1.x(), -p1.y());
|
||||
return std::make_pair(p1, p2);
|
||||
}
|
||||
|
||||
private:
|
||||
const Circle_2 _unit_circle;
|
||||
};
|
||||
|
||||
Construct_hyperbolic_bisector_2
|
||||
construct_hyperbolic_bisector_2_object() const
|
||||
{ return Construct_hyperbolic_bisector_2(_unit_circle);}
|
||||
|
||||
Construct_bisector_2
|
||||
construct_bisector_2_object() const
|
||||
{return Construct_bisector_2();}
|
||||
|
||||
Compare_distance_2
|
||||
compare_distance_2_object() const
|
||||
{return Compare_distance_2();}
|
||||
|
||||
Construct_triangle_2 construct_triangle_2_object() const
|
||||
{return Construct_triangle_2();}
|
||||
|
||||
Construct_direction_2 construct_direction_2_object() const
|
||||
{return Construct_direction_2();}
|
||||
|
||||
class Construct_ray_2
|
||||
{
|
||||
public:
|
||||
Construct_ray_2(Circle_2 c) :
|
||||
_unit_circle(c) {}
|
||||
|
||||
Segment_2 operator()(Point_2 p, Segment_2 l) const
|
||||
{
|
||||
if(typename R::Segment_2* s = boost::get<typename R::Segment_2>(&l)){
|
||||
return operator()(p, *s);
|
||||
}
|
||||
if(Arc_2* arc = boost::get<Arc_2>(&l)){
|
||||
if(arc->get<0>().orientation() == CLOCKWISE){
|
||||
arc->get<1>() = p;
|
||||
return *arc;
|
||||
}
|
||||
arc->get<2>() = p;
|
||||
return *arc;
|
||||
}
|
||||
assert(false);
|
||||
return Segment_2();
|
||||
}
|
||||
|
||||
Segment_2 operator()(Point_2 p, typename R::Segment_2 s) const
|
||||
{
|
||||
return typename R::Segment_2(p, s.target());
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
const Circle_2 _unit_circle;
|
||||
};
|
||||
|
||||
Construct_ray_2 construct_ray_2_object() const
|
||||
{return Construct_ray_2(_unit_circle);}
|
||||
};
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
#endif // CGAL_TRIANGULATION_HYPERBOLIC_TRAITS_2_H
|
||||