Adding L1_voronoi_diagram_2 example for the Envelope_3 package

This commit is contained in:
Ophir Setter 2011-02-03 05:31:34 +00:00
parent 5b9190c6c3
commit a5d3cbc877
12 changed files with 1430 additions and 0 deletions

11
.gitattributes vendored
View File

@ -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

View File

@ -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()

View File

@ -0,0 +1,379 @@
// CGAL headers
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/envelope_3.h>
#include <CGAL/L1_voronoi_traits_2.h>
#include <CGAL/point_generators_2.h>
// Qt headers
#include <QtGui>
#include <QString>
#include <QActionGroup>
#include <QFileDialog>
#include <QInputDialog>
#include <fstream>
// GraphicsView items and event filters (input classes)
#include <CGAL/Qt/ArrangementGraphicsItem.h>
#include <CGAL/Qt/ArrangementPointInput.h>
#include <CGAL/Qt/SetGraphicsItem.h>
// for viewportsBbox
#include <CGAL/Qt/utility.h>
// the two base classes
#include "ui_L1_voronoi_diagram_2.h"
#include <CGAL/Qt/DemosMainWindow.h>
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<Point_2> Points;
typedef CGAL::L1_voronoi_traits_2<Kernel> Traits_3;
typedef Traits_3::Surface_3 Surface_3;
typedef CGAL::Envelope_diagram_2<Traits_3> 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 <typename Kernel, typename T>
Qt::PainterOstream<T>&
operator<< (Qt::PainterOstream<T>& os,
const Arr_linear_object_2<Kernel> &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<Envelope_diagram_2> *m_graphics_item;
CGAL::Qt::SetGraphicsItem<Points> * m_sites_graphics_item;
CGAL::Qt::ArrangementPointInput<Envelope_diagram_2> * 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<Envelope_diagram_2>
(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<Points>
(&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<Envelope_diagram_2>(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_<action_name>_<signal_name>"
*/
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<Kernel> 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);
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();
}

View File

@ -0,0 +1,6 @@
<RCC>
<qresource prefix="/cgal/help" lang="en" >
<file alias="about_CGAL.html" >../resources/about_CGAL.html</file>
<file>about_L1_voronoi_diagram_2.html</file>
</qresource>
</RCC>

View File

@ -0,0 +1,282 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<author>Ophir Setter</author>
<class>L1_voronoi_diagram_2</class>
<widget class="QMainWindow" name="L1_voronoi_diagram_2">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>CGAL L1 Voronoi diagram</string>
</property>
<property name="windowIcon">
<iconset resource="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="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>25</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
<property name="title">
<string>&amp;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>&amp;Edit</string>
</property>
<addaction name="actionInsertRandomPoints"/>
</widget>
<widget class="QMenu" name="menuTools">
<property name="title">
<string>&amp;Tools</string>
</property>
<addaction name="actionInsertPoint"/>
<addaction name="separator"/>
<addaction name="actionShowVoronoi"/>
<addaction name="separator"/>
<addaction name="actionRecenter"/>
</widget>
<addaction name="menuFile"/>
<addaction name="menuEdit"/>
<addaction name="menuTools"/>
</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="actionShowVoronoi"/>
<addaction name="actionRecenter"/>
</widget>
<action name="actionAbout">
<property name="text">
<string>&amp;About</string>
</property>
</action>
<action name="actionAboutCGAL">
<property name="text">
<string>About &amp;CGAL</string>
</property>
</action>
<action name="actionQuit">
<property name="text">
<string>&amp;Quit</string>
</property>
<property name="shortcut">
<string>Ctrl+Q</string>
</property>
</action>
<action name="actionInsertRandomPoints">
<property name="text">
<string>&amp;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="L1_voronoi_diagram_2.qrc">
<normaloff>:/cgal/Actions/icons/moving_point.png</normaloff>:/cgal/Actions/icons/moving_point.png</iconset>
</property>
<property name="text">
<string>&amp;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>
<normaloff>:/cgal/Input/inputPoint.png</normaloff>:/cgal/Input/inputPoint.png</iconset>
</property>
<property name="text">
<string>&amp;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>
<normaloff>:/cgal/fileToolbar/fileNew.png</normaloff>:/cgal/fileToolbar/fileNew.png</iconset>
</property>
<property name="text">
<string>&amp;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>true</bool>
</property>
<property name="icon">
<iconset>
<normaloff>:/cgal/Triangulation_2/Voronoi_diagram_2.png</normaloff>:/cgal/Triangulation_2/Voronoi_diagram_2.png</iconset>
</property>
<property name="text">
<string>Show &amp;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="L1_voronoi_diagram_2.qrc">
<normaloff>:/cgal/Actions/icons/triangulation.png</normaloff>:/cgal/Actions/icons/triangulation.png</iconset>
</property>
<property name="text">
<string>Show &amp;Delaunay Triangulation</string>
</property>
<property name="shortcut">
<string>Ctrl+D</string>
</property>
</action>
<action name="actionLoadPoints">
<property name="icon">
<iconset>
<normaloff>:/cgal/fileToolbar/fileOpen.png</normaloff>:/cgal/fileToolbar/fileOpen.png</iconset>
</property>
<property name="text">
<string>&amp;Load Points...</string>
</property>
<property name="shortcut">
<string>Ctrl+L</string>
</property>
</action>
<action name="actionSavePoints">
<property name="icon">
<iconset>
<normaloff>:/cgal/fileToolbar/fileSave.png</normaloff>:/cgal/fileToolbar/fileSave.png</iconset>
</property>
<property name="text">
<string>&amp;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="L1_voronoi_diagram_2.qrc">
<normaloff>:/cgal/Actions/icons/circumcenter.png</normaloff>:/cgal/Actions/icons/circumcenter.png</iconset>
</property>
<property name="text">
<string>&amp;Circumcenter</string>
</property>
<property name="toolTip">
<string>Draw circumcenter</string>
</property>
</action>
<action name="actionRecenter">
<property name="icon">
<iconset>
<normaloff>:/cgal/Input/zoom-best-fit</normaloff>:/cgal/Input/zoom-best-fit</iconset>
</property>
<property name="text">
<string>Re&amp;center the viewport</string>
</property>
<property name="shortcut">
<string>Ctrl+R</string>
</property>
</action>
</widget>
<resources>
<include location="L1_voronoi_diagram_2.qrc"/>
<include location="resources/CGAL.qrc"/>
<include location="../icons/Triangulation_2.qrc"/>
<include location="../icons/Input.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -0,0 +1,9 @@
<html>
<body>
<h2>L1 Voronoi diagram of points</h2>
<p>Copyright &copy; 2010 Ophir Setter</p>
<p>This application illustrates the 2D Voronoi diagram of points under
the L1 metric, by using <a href="http://www.cgal.org/">CGAL</a>
envelope algorithm.</p>
</body>
</html>

View File

@ -0,0 +1 @@
URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/trunk/GraphicsView/demo/Triangulation_2/include

View File

@ -0,0 +1 @@
URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/trunk/GraphicsView/demo/Triangulation_2/include/CGAL

View File

@ -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 <CGAL/basic.h>
#include <CGAL/tags.h>
#include <CGAL/representation_tags.h>
#include <CGAL/enum.h>
#include <CGAL/Arr_tags.h>
#include <CGAL/Arr_linear_traits_2.h>
#include <CGAL/number_utils.h>
#include <CGAL/Envelope_3/Envelope_base.h>
#include <CGAL/Envelope_3/Env_plane_traits_3_functions.h>
CGAL_BEGIN_NAMESPACE
template <class Kernel_>
class L1_voronoi_traits_2 : public Arr_linear_traits_2<Kernel_>
{
public:
typedef Kernel_ Kernel;
typedef typename Kernel::FT FT;
typedef Arr_linear_traits_2<Kernel> Base;
typedef L1_voronoi_traits_2<Kernel> 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<Curve_2, Multiplicity> 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 <class OutputIterator>
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 <class OutputIterator>
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 <class OutputIterator>
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

View File

@ -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 <ophirset@post.tau.ac.il>
//
#ifndef CGAL_QT_ARRANGEMENT_GRAPHICS_ITEM_H
#define CGAL_QT_ARRANGEMENT_GRAPHICS_ITEM_H
#include <CGAL/Qt/GraphicsItem.h>
#include <CGAL/Qt/PainterOstream.h>
#include <CGAL/Qt/utility.h>
#include <QGraphicsScene>
#include <QGraphicsSceneMouseEvent>
#include <QPainter>
#include <QStyleOption>
class QGraphicsSceneMouseEvent;
namespace CGAL {
namespace Qt {
template <typename Arr>
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 <typename Arr>
ArrangementGraphicsItem<Arr>::ArrangementGraphicsItem(const Arr *arr)
: m_arr(arr)
{
setZValue(3);
}
template <typename Arr>
void ArrangementGraphicsItem<Arr>::setArrangement(const Arr *arr) {
m_arr = arr;
}
template <typename Arr>
QRectF
ArrangementGraphicsItem<Arr>::boundingRect() const
{
QRectF rect = CGAL::Qt::viewportsBbox(scene());
return rect;
}
template <typename Arr>
void
ArrangementGraphicsItem<Arr>::paint(QPainter *painter,
const QStyleOptionGraphicsItem *option,
QWidget *w)
{
if (m_arr == NULL)
return;
QRectF rect = option->exposedRect;
PainterOstream<typename Arr::Geometry_traits_2> 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 <typename T>
void
ArrangementGraphicsItem<T>::modelChanged()
{
update();
}
} // namespace Qt
} // namespace CGAL
#endif // CGAL_QT_ARRANGEMENT_GRAPHICS_ITEM_H

View File

@ -0,0 +1,78 @@
#ifndef CGAL_QT_ARRANGEMENT_POINT_INPUT_H
#define CGAL_QT_ARRANGEMENT_POINT_INPUT_H
#include <CGAL/Qt/GraphicsViewInput.h>
#include <CGAL/Qt/Converter.h>
#include <QGraphicsSceneMouseEvent>
#include <QEvent>
#include <list>
namespace CGAL {
namespace Qt {
template <typename Arrangement>
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<Kernel> m_convert;
Point_2 m_p;
};
template <typename T>
ArrangementPointInput<T>::ArrangementPointInput(QObject* parent)
: GraphicsViewInput(parent)
{}
template <typename T>
void
ArrangementPointInput<T>::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
m_p = m_convert(event->scenePos());
}
template <typename T>
void
ArrangementPointInput<T>::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
emit (generate(CGAL::make_object(m_p)));
}
template <typename T>
bool
ArrangementPointInput<T>::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::GraphicsSceneMouseRelease) {
QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(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

View File

@ -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 <ophirset@post.tau.ac.il>
//
#ifndef CGAL_QT_SET_GRAPHICS_ITEM_H
#define CGAL_QT_SET_GRAPHICS_ITEM_H
#include <CGAL/Qt/GraphicsItem.h>
#include <CGAL/Qt/PainterOstream.h>
#include <CGAL/Qt/utility.h>
#include <QGraphicsScene>
#include <QGraphicsSceneMouseEvent>
#include <QPainter>
#include <QStyleOption>
class QGraphicsSceneMouseEvent;
namespace CGAL {
namespace Qt {
template <typename Set>
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 <typename Set>
SetGraphicsItem<Set>::SetGraphicsItem(const Set *set)
: m_set(set)
{
setZValue(3);
}
template <typename Set>
QRectF
SetGraphicsItem<Set>::boundingRect() const
{
QRectF rect = CGAL::Qt::viewportsBbox(scene());
return rect;
}
template <typename Set>
void
SetGraphicsItem<Set>::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<typename std::iterator_traits<typename Set::const_iterator>::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 <typename T>
void
SetGraphicsItem<T>::modelChanged()
{
update();
}
} // namespace Qt
} // namespace CGAL
#endif // CGAL_QT_SET_GRAPHICS_ITEM_H