diff --git a/.gitattributes b/.gitattributes index ec88acaa08f..744f7d42eb3 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1448,6 +1448,17 @@ GraphicsView/demo/Circular_kernel_2/arcs.arc -text GraphicsView/demo/Generator/Generator_2.qrc -text GraphicsView/demo/Generator/Generator_2.ui -text GraphicsView/demo/Generator/about_Generator_2.html svneol=native#text/html +GraphicsView/demo/L1_voronoi_diagram_2/CMakeLists.txt -text +GraphicsView/demo/L1_voronoi_diagram_2/L1_voronoi_diagram_2.cpp -text +GraphicsView/demo/L1_voronoi_diagram_2/L1_voronoi_diagram_2.qrc -text +GraphicsView/demo/L1_voronoi_diagram_2/L1_voronoi_diagram_2.ui -text +GraphicsView/demo/L1_voronoi_diagram_2/about_L1_voronoi_diagram_2.html -text +GraphicsView/demo/L1_voronoi_diagram_2/include/.scm-urls -text +GraphicsView/demo/L1_voronoi_diagram_2/include/CGAL/.scm-urls -text +GraphicsView/demo/L1_voronoi_diagram_2/include/CGAL/L1_voronoi_traits_2.h -text +GraphicsView/demo/L1_voronoi_diagram_2/include/CGAL/Qt/ArrangementGraphicsItem.h -text +GraphicsView/demo/L1_voronoi_diagram_2/include/CGAL/Qt/ArrangementPointInput.h -text +GraphicsView/demo/L1_voronoi_diagram_2/include/CGAL/Qt/SetGraphicsItem.h -text GraphicsView/demo/Largest_empty_rect_2/Largest_empty_rectangle_2.qrc -text GraphicsView/demo/Largest_empty_rect_2/Largest_empty_rectangle_2.ui -text GraphicsView/demo/Largest_empty_rect_2/about_Largest_empty_rectangle_2.html svneol=native#text/html diff --git a/GraphicsView/demo/L1_voronoi_diagram_2/CMakeLists.txt b/GraphicsView/demo/L1_voronoi_diagram_2/CMakeLists.txt new file mode 100644 index 00000000000..e8f0027c208 --- /dev/null +++ b/GraphicsView/demo/L1_voronoi_diagram_2/CMakeLists.txt @@ -0,0 +1,59 @@ +# Created by the script cgal_create_cmake_script +# This is the CMake script for compiling a CGAL application. + +project (L1_voronoi_diagram_2) + +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 ../../include) +include_directories (BEFORE ./include) + + +if ( CGAL_FOUND AND CGAL_Qt4_FOUND AND QT4_FOUND ) + +include(${QT_USE_FILE}) + +#-------------------------------- +# The "L1 Voronoi diagram" demo: L1_voronoi_diagram_2 +#-------------------------------- +# UI files (Qt Designer files) +qt4_wrap_ui( DT_UI_FILES L1_voronoi_diagram_2.ui ) + +# qrc files (resources files, that contain icons, at least) +qt4_add_resources ( DT_RESOURCE_FILES ./L1_voronoi_diagram_2.qrc ) + +# use the Qt MOC preprocessor on classes that derives from QObject +qt4_generate_moc( L1_voronoi_diagram_2.cpp L1_voronoi_diagram_2.moc ) + +# The executable itself. +add_executable ( L1_voronoi_diagram_2 L1_voronoi_diagram_2.cpp L1_voronoi_diagram_2.moc ${DT_UI_FILES} ${DT_RESOURCE_FILES} ) + +add_to_cached_list( CGAL_EXECUTABLE_TARGETS L1_voronoi_diagram_2 ) + +# Link with Qt libraries +target_link_libraries( L1_voronoi_diagram_2 ${QT_LIBRARIES} ) +# Link with CGAL +target_link_libraries( L1_voronoi_diagram_2 ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES}) + +else() + + message(STATUS "NOTICE: This demo requires CGAL and Qt4, and will not be compiled.") + +endif() diff --git a/GraphicsView/demo/L1_voronoi_diagram_2/L1_voronoi_diagram_2.cpp b/GraphicsView/demo/L1_voronoi_diagram_2/L1_voronoi_diagram_2.cpp new file mode 100644 index 00000000000..e1c424896cf --- /dev/null +++ b/GraphicsView/demo/L1_voronoi_diagram_2/L1_voronoi_diagram_2.cpp @@ -0,0 +1,379 @@ +// CGAL headers +#include +#include +#include +#include + +// Qt headers +#include +#include +#include +#include +#include + +#include + +// GraphicsView items and event filters (input classes) +#include +#include +#include + +// for viewportsBbox +#include + +// the two base classes +#include "ui_L1_voronoi_diagram_2.h" +#include + +typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel; +typedef Kernel::FT Number_type; +typedef Kernel::Iso_rectangle_2 Iso_rectangle_2; +typedef Kernel::Point_2 Point_2; +typedef std::vector Points; + +typedef CGAL::L1_voronoi_traits_2 Traits_3; +typedef Traits_3::Surface_3 Surface_3; +typedef CGAL::Envelope_diagram_2 Envelope_diagram_2; + +// Ask Efi how to get rid of this. I was not successful in defining a new +// << operator that does not output a string for Arr_linear_object +namespace CGAL { + template + Qt::PainterOstream& + operator<< (Qt::PainterOstream& os, + const Arr_linear_object_2 &obj) { + if (obj.is_segment()) + os << obj.segment(); + else if (obj.is_ray()) + os << obj.ray(); + else + os << obj.line(); + + return os; + } +} + +class MainWindow : + public CGAL::Qt::DemosMainWindow, + public Ui::L1_voronoi_diagram_2 +{ + Q_OBJECT + +private: + Points m_sites; + Envelope_diagram_2 *m_envelope_diagram; + QGraphicsScene m_scene; + + CGAL::Qt::ArrangementGraphicsItem *m_graphics_item; + CGAL::Qt::SetGraphicsItem * m_sites_graphics_item; + CGAL::Qt::ArrangementPointInput * m_pi; + + + void calculate_envelope(); + QRectF bounding_rect(); + +public: + MainWindow(); + +public slots: + + void processInput(CGAL::Object o); + + 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(); + + void on_actionShowVoronoi_toggled(bool checked); + + void open(const QString& fileName); + +signals: + void changed(); +}; + + +MainWindow::MainWindow() + : DemosMainWindow() +{ + setupUi(this); + + // Add a GraphicItem for the diagram + m_envelope_diagram = new Envelope_diagram_2(); + m_graphics_item = new CGAL::Qt::ArrangementGraphicsItem + (m_envelope_diagram); + + QObject::connect(this, SIGNAL(changed()), + m_graphics_item, SLOT(modelChanged())); + + m_graphics_item-> + setVerticesPen(QPen(Qt::red, + 3, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); + m_scene.addItem(m_graphics_item); + + // Add a GraphicItem for the sites + m_sites_graphics_item = new CGAL::Qt::SetGraphicsItem + (&m_sites); + + QObject::connect(this, SIGNAL(changed()), + m_sites_graphics_item, SLOT(modelChanged())); + + m_sites_graphics_item-> + setPen(QPen(Qt::blue, + 5, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); + m_scene.addItem(m_sites_graphics_item); + + + // 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 + // ophir + m_pi = new CGAL::Qt::ArrangementPointInput(this); + + QObject::connect(m_pi, SIGNAL(generate(CGAL::Object)), + this, SLOT(processInput(CGAL::Object))); + + // + // 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); + + // Check two actions + this->actionInsertPoint->setChecked(true); + + // + // Setup the scene and the view + // + m_scene.setItemIndexMethod(QGraphicsScene::NoIndex); + m_scene.setSceneRect(-100, -100, 100, 100); + this->graphicsView->setScene(&m_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_L1_voronoi_diagram_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)){ + m_sites.push_back(p); + calculate_envelope(); + } + 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__" + */ +void +MainWindow::on_actionInsertPoint_toggled(bool checked) +{ + if(checked){ + m_scene.installEventFilter(m_pi); + } else { + m_scene.removeEventFilter(m_pi); + } +} + +void +MainWindow::on_actionClear_triggered() +{ + m_sites.clear(); + calculate_envelope(); + emit(changed()); +} + + +void +MainWindow::on_actionInsertRandomPoints_triggered() +{ + QRectF rect = CGAL::Qt::viewportsBbox(&m_scene); + CGAL::Qt::Converter convert; + Iso_rectangle_2 isor = convert(rect); + CGAL::Random_points_in_iso_rectangle_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::max(), + 1, + &ok); + + if(!ok) { + return; + } + + // wait cursor + QApplication::setOverrideCursor(Qt::WaitCursor); + for(int i = 0; i < number_of_points; ++i){ + m_sites.push_back(*pg++); + } + calculate_envelope(); + // 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(const QString& fileName) +{ + // wait cursor + QApplication::setOverrideCursor(Qt::WaitCursor); + m_sites.clear(); + + std::ifstream ifs(qPrintable(fileName)); + + Kernel::Point_2 p; + while(ifs >> p) { + m_sites.push_back(p); + } + calculate_envelope(); + + // 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(Points::iterator it = m_sites.begin(); + it != m_sites.end(); ++it) + { + ofs << *it << std::endl; + } + } +} + + +void +MainWindow::on_actionRecenter_triggered() +{ + this->graphicsView->setSceneRect(bounding_rect()); + this->graphicsView->fitInView(bounding_rect(), Qt::KeepAspectRatio); +} + +void +MainWindow::on_actionShowVoronoi_toggled(bool checked) +{ + this->m_graphics_item->setVisible(checked); +} + + +void +MainWindow::calculate_envelope() { + if (m_envelope_diagram != NULL) { + m_graphics_item->setArrangement(NULL); + delete m_envelope_diagram; + m_envelope_diagram = NULL; + } + + m_envelope_diagram = new Envelope_diagram_2(); + m_graphics_item->setArrangement(m_envelope_diagram); + + CGAL::lower_envelope_3 (m_sites.begin(), m_sites.end(), *m_envelope_diagram); +} + +QRectF +MainWindow::bounding_rect() { + CGAL::Bbox_2 bbox(0, 0, 0, 0); + + if (m_envelope_diagram != NULL) { + for (Envelope_diagram_2::Vertex_iterator it = + m_envelope_diagram->vertices_begin(); + it != m_envelope_diagram->vertices_end(); ++it) { + double x = CGAL::to_double(it->point().x()); + double y = CGAL::to_double(it->point().y()); + CGAL::Bbox_2 temp(x, y, x, y); + bbox = bbox + temp; + } + } + + QRectF rect(bbox.xmin(), + bbox.ymin(), + bbox.xmax() - bbox.xmin(), + bbox.ymax() - bbox.ymin()); + + return rect; +} + + +#include "L1_voronoi_diagram_2.moc" + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + + app.setOrganizationDomain("geometryfactory.com"); + app.setOrganizationName("GeometryFactory"); + app.setApplicationName("L1 Voronoi diagram_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(); + return app.exec(); +} + diff --git a/GraphicsView/demo/L1_voronoi_diagram_2/L1_voronoi_diagram_2.qrc b/GraphicsView/demo/L1_voronoi_diagram_2/L1_voronoi_diagram_2.qrc new file mode 100644 index 00000000000..9566f96f4c2 --- /dev/null +++ b/GraphicsView/demo/L1_voronoi_diagram_2/L1_voronoi_diagram_2.qrc @@ -0,0 +1,6 @@ + + + ../resources/about_CGAL.html + about_L1_voronoi_diagram_2.html + + diff --git a/GraphicsView/demo/L1_voronoi_diagram_2/L1_voronoi_diagram_2.ui b/GraphicsView/demo/L1_voronoi_diagram_2/L1_voronoi_diagram_2.ui new file mode 100644 index 00000000000..baafa6ae1a0 --- /dev/null +++ b/GraphicsView/demo/L1_voronoi_diagram_2/L1_voronoi_diagram_2.ui @@ -0,0 +1,282 @@ + + + Ophir Setter + L1_voronoi_diagram_2 + + + + 0 + 0 + 800 + 600 + + + + CGAL L1 Voronoi diagram + + + + :/cgal/logos/cgal_icon:/cgal/logos/cgal_icon + + + + + + + Qt::StrongFocus + + + Qt::ScrollBarAlwaysOn + + + Qt::ScrollBarAlwaysOn + + + QGraphicsView::NoAnchor + + + + + + + + + File Tools + + + TopToolBarArea + + + false + + + + + + + + + 0 + 0 + 800 + 25 + + + + + &File + + + + + + + + + + + &Edit + + + + + + &Tools + + + + + + + + + + + + + + Visualization Tools + + + TopToolBarArea + + + false + + + + + + + + &About + + + + + About &CGAL + + + + + &Quit + + + Ctrl+Q + + + + + &Insert random points + + + Ctrl+I + + + + + true + + + + :/cgal/Actions/icons/moving_point.png:/cgal/Actions/icons/moving_point.png + + + &Simulate insertion + + + Simulate Insertion + + + Move mouse with left button pressed to see where point would be inserted + + + whats this + + + + + true + + + false + + + + :/cgal/Input/inputPoint.png:/cgal/Input/inputPoint.png + + + &Insert Point + + + Insert Point + + + Left: Insert vtx + + + + + + :/cgal/fileToolbar/fileNew.png:/cgal/fileToolbar/fileNew.png + + + &Clear + + + Ctrl+C + + + + + true + + + true + + + + :/cgal/Triangulation_2/Voronoi_diagram_2.png:/cgal/Triangulation_2/Voronoi_diagram_2.png + + + Show &Voronoi Diagram + + + Ctrl+V + + + + + true + + + + :/cgal/Actions/icons/triangulation.png:/cgal/Actions/icons/triangulation.png + + + Show &Delaunay Triangulation + + + Ctrl+D + + + + + + :/cgal/fileToolbar/fileOpen.png:/cgal/fileToolbar/fileOpen.png + + + &Load Points... + + + Ctrl+L + + + + + + :/cgal/fileToolbar/fileSave.png:/cgal/fileToolbar/fileSave.png + + + &Save Points... + + + Ctrl+S + + + + + true + + + + :/cgal/Actions/icons/circumcenter.png:/cgal/Actions/icons/circumcenter.png + + + &Circumcenter + + + Draw circumcenter + + + + + + :/cgal/Input/zoom-best-fit:/cgal/Input/zoom-best-fit + + + Re&center the viewport + + + Ctrl+R + + + + + + + + + + + diff --git a/GraphicsView/demo/L1_voronoi_diagram_2/about_L1_voronoi_diagram_2.html b/GraphicsView/demo/L1_voronoi_diagram_2/about_L1_voronoi_diagram_2.html new file mode 100644 index 00000000000..220cf094b7f --- /dev/null +++ b/GraphicsView/demo/L1_voronoi_diagram_2/about_L1_voronoi_diagram_2.html @@ -0,0 +1,9 @@ + + +

L1 Voronoi diagram of points

+

Copyright © 2010 Ophir Setter

+

This application illustrates the 2D Voronoi diagram of points under + the L1 metric, by using CGAL + envelope algorithm.

+ + diff --git a/GraphicsView/demo/L1_voronoi_diagram_2/include/.scm-urls b/GraphicsView/demo/L1_voronoi_diagram_2/include/.scm-urls new file mode 100644 index 00000000000..e0c54c4fc04 --- /dev/null +++ b/GraphicsView/demo/L1_voronoi_diagram_2/include/.scm-urls @@ -0,0 +1 @@ +URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/trunk/GraphicsView/demo/Triangulation_2/include diff --git a/GraphicsView/demo/L1_voronoi_diagram_2/include/CGAL/.scm-urls b/GraphicsView/demo/L1_voronoi_diagram_2/include/CGAL/.scm-urls new file mode 100644 index 00000000000..bd0ac911866 --- /dev/null +++ b/GraphicsView/demo/L1_voronoi_diagram_2/include/CGAL/.scm-urls @@ -0,0 +1 @@ +URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/trunk/GraphicsView/demo/Triangulation_2/include/CGAL diff --git a/GraphicsView/demo/L1_voronoi_diagram_2/include/CGAL/L1_voronoi_traits_2.h b/GraphicsView/demo/L1_voronoi_diagram_2/include/CGAL/L1_voronoi_traits_2.h new file mode 100644 index 00000000000..380da559756 --- /dev/null +++ b/GraphicsView/demo/L1_voronoi_diagram_2/include/CGAL/L1_voronoi_traits_2.h @@ -0,0 +1,342 @@ +// Copyright (c) 2005 Tel-Aviv University (Israel). +// 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/Envelope_3/include/CGAL/Env_plane_traits_3.h $ +// $Id: Env_plane_traits_3.h 51989 2009-09-21 10:55:53Z efif $ +// +// Author(s) : Ophir Setter + +#ifndef CGAL_L1_VORONOI_DIAGRAM_TRAITS_2_H +#define CGAL_L1_VORONOI_DIAGRAM_TRAITS_2_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +CGAL_BEGIN_NAMESPACE + +template +class L1_voronoi_traits_2 : public Arr_linear_traits_2 +{ +public: + typedef Kernel_ Kernel; + typedef typename Kernel::FT FT; + typedef Arr_linear_traits_2 Base; + typedef L1_voronoi_traits_2 Self; + typedef std::size_t Multiplicity; + + typedef typename Base::Point_2 Point_2; + typedef typename Base::Curve_2 Curve_2; + typedef typename Base::X_monotone_curve_2 X_monotone_curve_2; + typedef typename Kernel::Segment_2 Segment_2; + typedef typename Kernel::Ray_2 Ray_2; + typedef typename Kernel::Line_2 Line_2; + typedef typename Kernel::Direction_2 Direction_2; + typedef std::pair Intersection_curve; + + typedef typename Base::Arr_left_side_category Arr_left_side_category; + typedef typename Base::Arr_bottom_side_category Arr_bottom_side_category; + typedef typename Base::Arr_top_side_category Arr_top_side_category; + typedef typename Base::Arr_right_side_category Arr_right_side_category; + + typedef Point_2 Xy_monotone_surface_3; + typedef Point_2 Surface_3; + + // Returns the distance between a two points in L1 metric. + static FT distance(const Point_2& p1, const Point_2& p2) { + FT dist = CGAL::abs(p1.x() - p2.x()) + CGAL::abs(p1.y() - p2.y()); + return dist; + } + + // Returns the midpoint (under the L1 metric) that is on the rectangle + // defined by the two points (the rectangle can be degenerate). + // As there are to enpoints, the index determines which is returned + static Point_2 midpoint(const Point_2& p1, const Point_2& p2, std::size_t index) { + const Point_2 *pp1; + const Point_2 *pp2; + + if (index % 2 == 0) { + pp1 = &p1; + pp2 = &p2; + } else { + pp1 = &p2; + pp2 = &p1; + } + + + FT delta_x = pp2->x() - pp1->x(); + FT delta_y = pp2->y() - pp1->y(); + + FT sign_x = CGAL::sign(delta_x); + FT sign_y = CGAL::sign(delta_y); + + FT abs_x = CGAL::abs(delta_x); + FT abs_y = CGAL::abs(delta_y); + + FT dist = (abs_x + abs_y) / 2; + FT mid_x = pp1->x(); + FT mid_y = pp1->y(); + + // Walk on the horizontal edge of the rectangle and then on the vertical. + + // There is a chance that the width of the rectangle is smaller then the mid-dist. + FT walk_x = CGAL::min(abs_x, dist); + mid_x += sign_x * walk_x; + dist -= walk_x; + + CGAL_assertion(abs_y > dist); + mid_y += sign_y * dist; + + return Point_2(mid_x, mid_y); + } + + static Comparison_result compare_z_at_xy (const X_monotone_curve_2& cv, + const Xy_monotone_surface_3& h1, + const Xy_monotone_surface_3& h2, + bool above) { + CGAL::Comparison_result side = (above == true) ? CGAL::LARGER : CGAL::SMALLER; + + Line_2 l; + if (cv.is_segment()) + l = cv.segment().supporting_line(); + else if (cv.is_ray()) + l = cv.ray().supporting_line(); + else + l = cv.line(); + + if (l.is_vertical()) { + // Could be a tie. + // To be "above" the curve, we acutually need to have smaller x coordinate, + // the order of the comparison function here is opposite to the none vertical + // case. + side = CGAL::opposite(side); + CGAL::Comparison_result res = CGAL::compare_x_at_y(h1, l); + if (res == side) + return CGAL::SMALLER; + + res = CGAL::compare_x_at_y(h2, l); + if (res == side) + return CGAL::LARGER; + + return CGAL::EQUAL; + } else { + // One of the points in indeed closer (tie can only happen on vertical lines). + CGAL::Comparison_result res = CGAL::compare_y_at_x(h1, l); + if (l.is_horizontal()) { + CGAL_assertion(CGAL::compare_y_at_x(h2, l) != res); + if (res == side) + return CGAL::SMALLER; + + res = CGAL::compare_y_at_x(h2, l); + if (res == side) + return CGAL::LARGER; + + return CGAL::EQUAL; + } + + CGAL_assertion(CGAL::compare_y_at_x(h2, l) == CGAL::opposite(res)); + if (res == side) + return CGAL::SMALLER; + else + return CGAL::LARGER; + } + } + class Make_xy_monotone_3 { + public: + template + OutputIterator operator()(const Surface_3& s, + bool /* is_lower */, + OutputIterator o) const { + *o++ = s; + return o; + } + }; + + Make_xy_monotone_3 make_xy_monotone_3_object() const { + return Make_xy_monotone_3(); + } + + class Compare_z_at_xy_3 { + public: + Comparison_result operator()(const Point_2& p, + const Xy_monotone_surface_3& h1, + const Xy_monotone_surface_3& h2) const { + return CGAL::compare(distance(p, h1), distance(p, h2)); + } + + Comparison_result operator()(const X_monotone_curve_2& cv, + const Xy_monotone_surface_3& h1, + const Xy_monotone_surface_3& h2) const { + Kernel k; + Point_2 p; + if(cv.is_segment()) + p = k.construct_midpoint_2_object()(cv.left(), cv.right()); + else + if(cv.is_ray()) + p = k.construct_point_on_2_object()(cv.ray(), 1); + else { + CGAL_assertion(cv.is_line()); + p = k.construct_point_on_2_object()(cv.line(), 1); + } + return this->operator()(p, h1, h2); + } + + Comparison_result operator()(const Xy_monotone_surface_3& h1, + const Xy_monotone_surface_3& h2) const { + // should happen only if the points are equal. + CGAL_assertion(h1 == h2); + return EQUAL; + } + }; + + Compare_z_at_xy_3 compare_z_at_xy_3_object() const + { + return Compare_z_at_xy_3(); + } + + class Compare_z_at_xy_above_3 + { + public: + Comparison_result operator()(const X_monotone_curve_2& cv, + const Xy_monotone_surface_3& h1, + const Xy_monotone_surface_3& h2) const { + return compare_z_at_xy (cv, h1, h2, true); + } + + }; + + Compare_z_at_xy_above_3 compare_z_at_xy_above_3_object() const + { + return Compare_z_at_xy_above_3(); + } + + class Compare_z_at_xy_below_3 + { + public: + Comparison_result operator()(const X_monotone_curve_2& cv, + const Xy_monotone_surface_3& h1, + const Xy_monotone_surface_3& h2) const { + return compare_z_at_xy (cv, h1, h2, false); + } + }; + + Compare_z_at_xy_below_3 compare_z_at_xy_below_3_object() const { + return Compare_z_at_xy_below_3(); + } + + class Construct_projected_boundary_2 { + public: + template + OutputIterator operator()(const Xy_monotone_surface_3& s, + OutputIterator o) const { + return o; + } + }; + + Construct_projected_boundary_2 + construct_projected_boundary_2_object() const + { + return Construct_projected_boundary_2(); + } + + + class Construct_projected_intersections_2 { + public: + template + OutputIterator operator()(const Xy_monotone_surface_3& s1, + const Xy_monotone_surface_3& s2, + OutputIterator o) const { + // The bisector construction is based on the description of the bisector + // from Handbook of Computational Geometry - the chapter on Voronoi diagrams + // by F. Aurenhammer and R. Klein. + + FT delta_x = s2.x() - s1.x(); + FT delta_y = s2.y() - s1.y(); + + CGAL::Sign s_x = CGAL::sign(delta_x); + CGAL::Sign s_y = CGAL::sign(delta_y); + + if (s_x == CGAL::ZERO && s_y == CGAL::ZERO) + return o; + + // The sites have the same x/y coordinate. + if (s_x == CGAL::ZERO || s_y == CGAL::ZERO) { + *o++ = CGAL::make_object(Intersection_curve(CGAL::bisector(s1, s2), 1)); + return o; + } + + Point_2 p1 = midpoint(s1, s2, 0); + Point_2 p2 = midpoint(s1, s2, 1); + CGAL_assertion(p1 != p2); + + Point_2 *top, *bottom, *left, *right; + if (CGAL::sign(p2.x() - p1.x()) == CGAL::POSITIVE) { + left = &p1; + right = &p2; + } + else { + CGAL_assertion(CGAL::sign(p2.x() - p1.x()) == CGAL::NEGATIVE); + left = &p2; + right = &p1; + } + + if (CGAL::sign(p2.y() - p1.y()) == CGAL::POSITIVE) { + bottom = &p1; + top = &p2; + } + else { + CGAL_assertion(CGAL::sign(p2.y() - p1.y()) == CGAL::NEGATIVE); + bottom = &p2; + top = &p1; + } + + // We construct the diagonal line either way. + *o++ = CGAL::make_object(Intersection_curve(Segment_2(p1, p2), 1)); + + // Now construct vertical rays. Two or four rays. If it is only two rays, + // then the multiplicity of all the curves is 1. + CGAL::Sign s_d = CGAL::sign(CGAL::abs(delta_y) - CGAL::abs(delta_x)); + std::size_t mult = (s_d == CGAL::ZERO) ? 0 : 1; + + if (s_d != CGAL::POSITIVE) { + // horizontal rectangle or square = vertical rays. + *o++ = CGAL::make_object(Intersection_curve(Ray_2(*top, Direction_2(0, 1)), mult)); + *o++ = CGAL::make_object(Intersection_curve(Ray_2(*bottom, Direction_2(0, -1)), mult)); + } + + if (s_d != CGAL::NEGATIVE) { + // vertical rectangle or square = horizontal rays. + *o++ = CGAL::make_object(Intersection_curve(Ray_2(*right, Direction_2(1, 0)), mult)); + *o++ = CGAL::make_object(Intersection_curve(Ray_2(*left, Direction_2(-1, 0)), mult)); + } + + return o; + } + }; + + Construct_projected_intersections_2 + construct_projected_intersections_2_object() const { + return Construct_projected_intersections_2(); + } + +}; + +CGAL_END_NAMESPACE + +#endif // CGAL_L1_VORONOI_DIAGRAM_TRAITS_2_H diff --git a/GraphicsView/demo/L1_voronoi_diagram_2/include/CGAL/Qt/ArrangementGraphicsItem.h b/GraphicsView/demo/L1_voronoi_diagram_2/include/CGAL/Qt/ArrangementGraphicsItem.h new file mode 100644 index 00000000000..36eefc21b45 --- /dev/null +++ b/GraphicsView/demo/L1_voronoi_diagram_2/include/CGAL/Qt/ArrangementGraphicsItem.h @@ -0,0 +1,143 @@ +// 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://ophirset@scm.gforge.inria.fr/svn/cgal/trunk/GraphicsView/include/CGAL/Qt/ArrangementGraphicsItem.h $ +// $Id: ArrangementGraphicsItem.h 45924 2008-10-01 09:19:53Z afabri $ +// +// +// Author(s) : Ophir Setter +// + +#ifndef CGAL_QT_ARRANGEMENT_GRAPHICS_ITEM_H +#define CGAL_QT_ARRANGEMENT_GRAPHICS_ITEM_H + + + +#include +#include +#include + +#include +#include +#include +#include + +class QGraphicsSceneMouseEvent; + + +namespace CGAL { +namespace Qt { + +template +class ArrangementGraphicsItem : public GraphicsItem +{ +public: + ArrangementGraphicsItem(const Arr *arr); + + void setArrangement(const Arr *arr); + + QRectF + boundingRect() const; + + void + paint(QPainter *painter, + const QStyleOptionGraphicsItem *option, + QWidget *widget); + + void + modelChanged(); + + const QPen& edgesPen() const + { + return m_edges_pen; + } + + const QPen& verticesPen() const + { + return m_vertices_pen; + } + + void setEdgesPen(const QPen& pen) + { + m_edges_pen = pen; + } + + void setVerticesPen(const QPen& pen) + { + m_vertices_pen = pen; + } + +private: + const Arr *m_arr; + QPen m_edges_pen; + QPen m_vertices_pen; +}; + +template +ArrangementGraphicsItem::ArrangementGraphicsItem(const Arr *arr) + : m_arr(arr) +{ + setZValue(3); +} + +template +void ArrangementGraphicsItem::setArrangement(const Arr *arr) { + m_arr = arr; +} + + +template +QRectF +ArrangementGraphicsItem::boundingRect() const +{ + QRectF rect = CGAL::Qt::viewportsBbox(scene()); + return rect; +} + +template +void +ArrangementGraphicsItem::paint(QPainter *painter, + const QStyleOptionGraphicsItem *option, + QWidget *w) +{ + if (m_arr == NULL) + return; + + QRectF rect = option->exposedRect; + PainterOstream pos(painter, rect); + + painter->setPen(edgesPen()); + for(typename Arr::Edge_const_iterator eit = m_arr->edges_begin(); + eit != m_arr->edges_end(); eit++) { + pos << eit->curve(); + } + + painter->setPen(verticesPen()); + for(typename Arr::Vertex_const_iterator vit = m_arr->vertices_begin(); + vit != m_arr->vertices_end(); vit++) { + pos << vit->point(); + } +} + + +template +void +ArrangementGraphicsItem::modelChanged() +{ + update(); +} + +} // namespace Qt +} // namespace CGAL + +#endif // CGAL_QT_ARRANGEMENT_GRAPHICS_ITEM_H diff --git a/GraphicsView/demo/L1_voronoi_diagram_2/include/CGAL/Qt/ArrangementPointInput.h b/GraphicsView/demo/L1_voronoi_diagram_2/include/CGAL/Qt/ArrangementPointInput.h new file mode 100644 index 00000000000..dda4d8adb6d --- /dev/null +++ b/GraphicsView/demo/L1_voronoi_diagram_2/include/CGAL/Qt/ArrangementPointInput.h @@ -0,0 +1,78 @@ + +#ifndef CGAL_QT_ARRANGEMENT_POINT_INPUT_H +#define CGAL_QT_ARRANGEMENT_POINT_INPUT_H + +#include +#include +#include +#include +#include + +namespace CGAL { +namespace Qt { + +template +class ArrangementPointInput : public GraphicsViewInput +{ +public: + typedef typename Arrangement::Geometry_traits_2::Kernel Kernel; + typedef typename Kernel::Point_2 Point_2; + + ArrangementPointInput(QObject* parent); + +protected: + void mousePressEvent(QGraphicsSceneMouseEvent *event); + void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + bool eventFilter(QObject *obj, QEvent *event); + + Converter m_convert; + Point_2 m_p; +}; + + +template +ArrangementPointInput::ArrangementPointInput(QObject* parent) + : GraphicsViewInput(parent) +{} + +template +void +ArrangementPointInput::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + m_p = m_convert(event->scenePos()); +} + + +template +void +ArrangementPointInput::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + emit (generate(CGAL::make_object(m_p))); +} + + + +template +bool +ArrangementPointInput::eventFilter(QObject *obj, QEvent *event) +{ + if (event->type() == QEvent::GraphicsSceneMousePress) { + QGraphicsSceneMouseEvent *mouseEvent = static_cast(event); + mousePressEvent(mouseEvent); + return true; + } else if (event->type() == QEvent::GraphicsSceneMouseRelease) { + QGraphicsSceneMouseEvent *mouseEvent = static_cast(event); + mouseReleaseEvent(mouseEvent); + return true; + } else{ + // standard event processing + return QObject::eventFilter(obj, event); + } +} + + +} // namespace Qt +} // namespace CGAL + +#endif // CGAL_QT_ARRANGEMENT_POINT_INPUT_H diff --git a/GraphicsView/demo/L1_voronoi_diagram_2/include/CGAL/Qt/SetGraphicsItem.h b/GraphicsView/demo/L1_voronoi_diagram_2/include/CGAL/Qt/SetGraphicsItem.h new file mode 100644 index 00000000000..a302d3fdbc7 --- /dev/null +++ b/GraphicsView/demo/L1_voronoi_diagram_2/include/CGAL/Qt/SetGraphicsItem.h @@ -0,0 +1,119 @@ +// 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://ophirset@scm.gforge.inria.fr/svn/cgal/trunk/GraphicsView/include/CGAL/Qt/ArrangementGraphicsItem.h $ +// $Id: ArrangementGraphicsItem.h 45924 2008-10-01 09:19:53Z afabri $ +// +// +// Author(s) : Ophir Setter +// + +#ifndef CGAL_QT_SET_GRAPHICS_ITEM_H +#define CGAL_QT_SET_GRAPHICS_ITEM_H + + + +#include +#include +#include + +#include +#include +#include +#include + +class QGraphicsSceneMouseEvent; + + +namespace CGAL { +namespace Qt { + +template +class SetGraphicsItem : public GraphicsItem +{ +public: + SetGraphicsItem(const Set *arr); + + QRectF + boundingRect() const; + + void + paint(QPainter *painter, + const QStyleOptionGraphicsItem *option, + QWidget *widget); + + void + modelChanged(); + + const QPen& pen() const { + return m_pen; + } + + void setPen(const QPen& pen) { + m_pen = pen; + } + +private: + const Set *m_set; + QPen m_pen; +}; + +template +SetGraphicsItem::SetGraphicsItem(const Set *set) + : m_set(set) +{ + setZValue(3); +} + +template +QRectF +SetGraphicsItem::boundingRect() const +{ + QRectF rect = CGAL::Qt::viewportsBbox(scene()); + return rect; +} + + +template +void +SetGraphicsItem::paint(QPainter *painter, + const QStyleOptionGraphicsItem *option, + QWidget *w) +{ + if (m_set == NULL) + return; + + QRectF rect = option->exposedRect; + // R is the kernel. Move it to a template parameter. + PainterOstream::value_type::R> + pos(painter, rect); + + painter->setPen(this->pen()); + for(typename Set::const_iterator it = m_set->begin(); + it != m_set->end(); it++) { + pos << *it; + } +} + + +template +void +SetGraphicsItem::modelChanged() +{ + update(); +} + +} // namespace Qt +} // namespace CGAL + +#endif // CGAL_QT_SET_GRAPHICS_ITEM_H