Merge remote-tracking branch 'cgal/master' into HEAD

This commit is contained in:
Sébastien Loriot 2023-06-15 10:47:07 +02:00
commit bbc4d08ee0
635 changed files with 43858 additions and 36571 deletions

View File

@ -75,7 +75,7 @@ jobs:
sudo apt-get update && sudo apt-get install -y graphviz ssh bibtex2html sudo apt-get update && sudo apt-get install -y graphviz ssh bibtex2html
sudo pip install lxml sudo pip install lxml
sudo pip install pyquery sudo pip install pyquery
wget --no-verbose -O doxygen_exe https://cgal.geometryfactory.com/~cgaltest/doxygen_1_8_13_patched/doxygen wget --no-verbose -O doxygen_exe https://cgal.geometryfactory.com/~cgaltest/doxygen_1_9_6_patched/doxygen
sudo mv doxygen_exe /usr/bin/doxygen sudo mv doxygen_exe /usr/bin/doxygen
sudo chmod +x /usr/bin/doxygen sudo chmod +x /usr/bin/doxygen
git config --global user.email "cgal@geometryfactory.com" git config --global user.email "cgal@geometryfactory.com"
@ -160,7 +160,7 @@ jobs:
script: | script: |
const error = process.env.ERRORMSG const error = process.env.ERRORMSG
const job_url = `${context.serverUrl}/CGAL/cgal/actions/runs/${context.runId}` const job_url = `${context.serverUrl}/CGAL/cgal/actions/runs/${context.runId}`
const msg = "There was an error while building the doc: \n"+error + "\n" + job_url const msg = "There was an error while building the doc: \n```\n"+error + "\n```\n" + job_url
github.rest.issues.createComment({ github.rest.issues.createComment({
owner: "CGAL", owner: "CGAL",
repo: "cgal", repo: "cgal",

1
.gitignore vendored
View File

@ -1212,3 +1212,4 @@ gmon.*
Polygonal_surface_reconstruction/examples/build* Polygonal_surface_reconstruction/examples/build*
Polygonal_surface_reconstruction/test/build* Polygonal_surface_reconstruction/test/build*
Solver_interface/examples/build* Solver_interface/examples/build*
/Mesh_3/examples/Mesh_3/indicator_0.inr.gz

View File

@ -24,7 +24,7 @@ include_directories(BEFORE ./ ./include)
find_package(CGAL REQUIRED OPTIONAL_COMPONENTS Qt5) find_package(CGAL REQUIRED OPTIONAL_COMPONENTS Qt5)
# Find Qt5 itself # Find Qt5 itself
find_package(Qt5 QUIET COMPONENTS Script OpenGL Gui Svg) find_package(Qt5 QUIET COMPONENTS Widgets OpenGL)
if(CGAL_Qt5_FOUND AND Qt5_FOUND) if(CGAL_Qt5_FOUND AND Qt5_FOUND)
@ -53,7 +53,7 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND)
#${CGAL_Qt5_MOC_FILES} #${CGAL_Qt5_MOC_FILES}
) )
# Link with Qt libraries # Link with Qt libraries
target_link_libraries(AABB_demo PRIVATE Qt5::OpenGL Qt5::Gui target_link_libraries(AABB_demo PRIVATE Qt5::Widgets Qt5::OpenGL
CGAL::CGAL CGAL::CGAL_Qt5) CGAL::CGAL CGAL::CGAL_Qt5)
add_to_cached_list(CGAL_EXECUTABLE_TARGETS AABB_demo) add_to_cached_list(CGAL_EXECUTABLE_TARGETS AABB_demo)

View File

@ -139,7 +139,7 @@ typedef unspecified_type Is_numerical_sensitive;
This type specifies the return type of the predicates provided This type specifies the return type of the predicates provided
by this traits. The type must be convertible to `bool` and by this traits. The type must be convertible to `bool` and
typically the type indeed maps to `bool`. However, there are also typically the type indeed maps to `bool`. However, there are also
cases such as interval arithmetic, in which it is `Uncertain<bool>` cases such as interval arithmetic, in which it is `CGAL::Uncertain<bool>`
or some similar type. or some similar type.
*/ */
@ -300,4 +300,3 @@ typedef unspecified_type Root_of;
/// @} /// @}
}; /* end AlgebraicStructureTraits */ }; /* end AlgebraicStructureTraits */

View File

@ -66,7 +66,7 @@ int descartes(Polynomial& p, const Field& low,const Field& high){
} }
/*! \ingroup \NiX_univariate_polynomial_utils /*! \ingroup \NiX_univariate_polynomial_utils
* \brief refine isolating interval for \c p w.r.t \c q * \brief refine isolating interval for \c p w.r.t. \c q
* *
* This function refines the interval ]<TT>low</TT>, <TT>high</TT>[ * This function refines the interval ]<TT>low</TT>, <TT>high</TT>[
* such that it does not contain any zero of \c q different from the * such that it does not contain any zero of \c q different from the

View File

@ -19,7 +19,7 @@ endif()
find_package(CGAL REQUIRED OPTIONAL_COMPONENTS Qt5) find_package(CGAL REQUIRED OPTIONAL_COMPONENTS Qt5)
find_package(Qt5 QUIET COMPONENTS Script OpenGL Svg) find_package(Qt5 QUIET COMPONENTS Widgets OpenGL)
if(CGAL_Qt5_FOUND AND Qt5_FOUND) if(CGAL_Qt5_FOUND AND Qt5_FOUND)
@ -40,7 +40,7 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND)
add_to_cached_list(CGAL_EXECUTABLE_TARGETS Alpha_shape_3) add_to_cached_list(CGAL_EXECUTABLE_TARGETS Alpha_shape_3)
target_link_libraries(Alpha_shape_3 PRIVATE CGAL::CGAL CGAL::CGAL_Qt5 target_link_libraries(Alpha_shape_3 PRIVATE CGAL::CGAL CGAL::CGAL_Qt5
Qt5::OpenGL Qt5::Gui) Qt5::Widgets Qt5::OpenGL)
include(${CGAL_MODULES_DIR}/CGAL_add_test.cmake) include(${CGAL_MODULES_DIR}/CGAL_add_test.cmake)
cgal_add_compilation_test(Alpha_shape_3) cgal_add_compilation_test(Alpha_shape_3)

View File

@ -25,8 +25,6 @@ using Mesh = CGAL::Surface_mesh<Point_3>;
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
std::cout.precision(17);
// Read the inputs // Read the inputs
const std::string ts_filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/armadillo.off"); // triangle soup const std::string ts_filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/armadillo.off"); // triangle soup
const std::string ss_filename = (argc > 2) ? argv[2] : CGAL::data_file_path("images/420.polylines.txt"); // segment soup const std::string ss_filename = (argc > 2) ? argv[2] : CGAL::data_file_path("images/420.polylines.txt"); // segment soup

View File

@ -8,8 +8,6 @@
#include <iostream> #include <iostream>
#include <string> #include <string>
namespace AW3 = CGAL::Alpha_wraps_3;
using K = CGAL::Exact_predicates_inexact_constructions_kernel; using K = CGAL::Exact_predicates_inexact_constructions_kernel;
using Point_3 = K::Point_3; using Point_3 = K::Point_3;
@ -18,8 +16,6 @@ using Mesh = CGAL::Surface_mesh<Point_3>;
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
std::cout.precision(17);
// Read the input // Read the input
const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("points_3/oni.pwn"); const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("points_3/oni.pwn");
std::cout << "Reading " << filename << "..." << std::endl; std::cout << "Reading " << filename << "..." << std::endl;

View File

@ -9,7 +9,6 @@
#include <iostream> #include <iostream>
#include <string> #include <string>
namespace AW3 = CGAL::Alpha_wraps_3;
namespace PMP = CGAL::Polygon_mesh_processing; namespace PMP = CGAL::Polygon_mesh_processing;
using K = CGAL::Exact_predicates_inexact_constructions_kernel; using K = CGAL::Exact_predicates_inexact_constructions_kernel;
@ -19,8 +18,6 @@ using Mesh = CGAL::Surface_mesh<Point_3>;
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
std::cout.precision(17);
// Read the input // Read the input
const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/armadillo.off"); const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/armadillo.off");
std::cout << "Reading " << filename << "..." << std::endl; std::cout << "Reading " << filename << "..." << std::endl;

View File

@ -8,7 +8,6 @@
#include <iostream> #include <iostream>
#include <string> #include <string>
namespace AW3 = CGAL::Alpha_wraps_3;
namespace PMP = CGAL::Polygon_mesh_processing; namespace PMP = CGAL::Polygon_mesh_processing;
using K = CGAL::Exact_predicates_inexact_constructions_kernel; using K = CGAL::Exact_predicates_inexact_constructions_kernel;
@ -18,8 +17,6 @@ using Mesh = CGAL::Surface_mesh<Point_3>;
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
std::cout.precision(17);
// Read the input // Read the input
const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/armadillo.off"); const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/armadillo.off");
std::cout << "Reading " << filename << "..." << std::endl; std::cout << "Reading " << filename << "..." << std::endl;

View File

@ -27,6 +27,7 @@ namespace Qt {
static constexpr int margin = 2; static constexpr int margin = 2;
//
ArrangementGraphicsItemBase::ArrangementGraphicsItemBase() : ArrangementGraphicsItemBase::ArrangementGraphicsItemBase() :
verticesPen(QPen(::Qt::blue, 3.)), edgesPen(QPen(::Qt::blue, 1.)) verticesPen(QPen(::Qt::blue, 3.)), edgesPen(QPen(::Qt::blue, 1.))
{ {
@ -38,13 +39,10 @@ ArrangementGraphicsItemBase::ArrangementGraphicsItemBase() :
} }
// msvc2015 doesn't play well with polymorphic lambdas // msvc2015 doesn't play well with polymorphic lambdas
namespace namespace {
{ struct ExplicitLambda {
struct ExplicitLambda
{
template <typename Arrangement> template <typename Arrangement>
void operator()(demo_types::TypeHolder<Arrangement>) void operator()(demo_types::TypeHolder<Arrangement>) {
{
Arrangement* arr = nullptr; Arrangement* arr = nullptr;
CGAL::assign(arr, arr_obj); CGAL::assign(arr, arr_obj);
agi = new ArrangementGraphicsItem<Arrangement>(arr); agi = new ArrangementGraphicsItem<Arrangement>(arr);
@ -53,10 +51,13 @@ struct ExplicitLambda
ArrangementGraphicsItemBase*& agi; ArrangementGraphicsItemBase*& agi;
CGAL::Object& arr_obj; CGAL::Object& arr_obj;
}; };
} // anonymous namespace } // anonymous namespace
ArrangementGraphicsItemBase* ArrangementGraphicsItemBase::create( //
demo_types::TraitsType tt, CGAL::Object arr_obj) ArrangementGraphicsItemBase*
ArrangementGraphicsItemBase::create(demo_types::TraitsType tt,
CGAL::Object arr_obj)
{ {
ArrangementGraphicsItemBase* agi; ArrangementGraphicsItemBase* agi;
ExplicitLambda explicit_lambda{agi, arr_obj}; ExplicitLambda explicit_lambda{agi, arr_obj};
@ -64,39 +65,35 @@ ArrangementGraphicsItemBase* ArrangementGraphicsItemBase::create(
return agi; return agi;
} }
//
const QPen& ArrangementGraphicsItemBase::getVerticesPen() const const QPen& ArrangementGraphicsItemBase::getVerticesPen() const
{ { return this->verticesPen; }
return this->verticesPen;
}
//
const QPen& ArrangementGraphicsItemBase::getEdgesPen() const const QPen& ArrangementGraphicsItemBase::getEdgesPen() const
{ { return this->edgesPen; }
return this->edgesPen;
}
//
void ArrangementGraphicsItemBase::setVerticesPen(const QPen& pen) void ArrangementGraphicsItemBase::setVerticesPen(const QPen& pen)
{ { this->verticesPen = pen; }
this->verticesPen = pen;
}
//
void ArrangementGraphicsItemBase::setEdgesPen(const QPen& pen) void ArrangementGraphicsItemBase::setEdgesPen(const QPen& pen)
{ { this->edgesPen = pen; }
this->edgesPen = pen;
}
//
template <typename Arr_> template <typename Arr_>
ArrangementGraphicsItem<Arr_>::ArrangementGraphicsItem(Arrangement* arr_) : ArrangementGraphicsItem<Arr_>::ArrangementGraphicsItem(Arrangement* arr_) :
arr(arr_), pointsGraphicsItem(new PointsGraphicsItem(this)) arr(arr_),
pointsGraphicsItem(new PointsGraphicsItem(this))
{ {
this->updatePointsItem(); this->updatePointsItem();
this->updateBoundingBox(); this->updateBoundingBox();
} }
//
template < typename Arr_ > template < typename Arr_ >
QRectF QRectF ArrangementGraphicsItem< Arr_ >::boundingRect() const {
ArrangementGraphicsItem< Arr_ >::
boundingRect( ) const
{
qreal xmin = -(std::numeric_limits<qreal>::max)() / 4; qreal xmin = -(std::numeric_limits<qreal>::max)() / 4;
qreal ymin = -(std::numeric_limits<qreal>::max)() / 4; qreal ymin = -(std::numeric_limits<qreal>::max)() / 4;
qreal xmax = (std::numeric_limits<qreal>::max)() / 4; qreal xmax = (std::numeric_limits<qreal>::max)() / 4;
@ -115,48 +112,47 @@ boundingRect( ) const
return {QPointF{xmin, ymin}, QPointF{xmax, ymax}}; return {QPointF{xmin, ymin}, QPointF{xmax, ymax}};
} }
//
template < typename Arr_ > template < typename Arr_ >
void void
ArrangementGraphicsItem< Arr_ >:: ArrangementGraphicsItem< Arr_ >::
paint(QPainter* painter, paint(QPainter* painter,
const QStyleOptionGraphicsItem* /* option */, const QStyleOptionGraphicsItem* /* option */,
QWidget* /*widget*/) QWidget* /*widget*/)
{ { this->paint(painter, *(arr->traits())); }
this->paint(painter, *(arr->traits()));
}
//
template <typename Arr_> template <typename Arr_>
template <typename TTraits> template <typename TTraits>
void ArrangementGraphicsItem<Arr_>::paint( void ArrangementGraphicsItem<Arr_>::paint(QPainter* painter,
QPainter* painter, const TTraits& traits) const TTraits& traits) {
{
this->paintFaces(painter); this->paintFaces(painter);
this->paintEdges(painter, traits); this->paintEdges(painter, traits);
} }
//
template <typename Arr_> template <typename Arr_>
template <typename Coefficient_> template <typename Coefficient_>
void ArrangementGraphicsItem<Arr_>::paint( void ArrangementGraphicsItem<Arr_>::
QPainter* painter, paint(QPainter* painter,
const CGAL::Arr_algebraic_segment_traits_2<Coefficient_>& traits) const CGAL::Arr_algebraic_segment_traits_2<Coefficient_>& traits) {
{
this->paintWithFloodFill(painter, traits); this->paintWithFloodFill(painter, traits);
} }
//
template <typename Arr_> template <typename Arr_>
template <typename AlgebraicKernel_d_1> template <typename AlgebraicKernel_d_1>
void ArrangementGraphicsItem<Arr_>::paint( void ArrangementGraphicsItem<Arr_>::
QPainter* painter, paint(QPainter* painter,
const CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>& traits) const CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>& traits) {
{
this->paintWithFloodFill(painter, traits); this->paintWithFloodFill(painter, traits);
} }
//
template <typename Arr_> template <typename Arr_>
template <typename TTraits> template <typename TTraits>
void ArrangementGraphicsItem<Arr_>::paintWithFloodFill( void ArrangementGraphicsItem<Arr_>::
QPainter* painter, const TTraits& traits) paintWithFloodFill(QPainter* painter, const TTraits& traits) {
{
auto windowRect = painter->window(); auto windowRect = painter->window();
auto width = windowRect.width(); auto width = windowRect.width();
auto height = windowRect.height(); auto height = windowRect.height();
@ -171,15 +167,12 @@ void ArrangementGraphicsItem<Arr_>::paintWithFloodFill(
// also useful with algebraic curves as sometimes pixels on the borders // also useful with algebraic curves as sometimes pixels on the borders
// aren't painted, and the flood algorithm 'leaks' // aren't painted, and the flood algorithm 'leaks'
static constexpr QRgb white = 0xFFFFFFFF; static constexpr QRgb white = 0xFFFFFFFF;
for (uint16_t i = 0; i < margin; i++) for (uint16_t i = 0; i < margin; i++) {
{ for (uint16_t j = 0; j < width; j++) {
for (uint16_t j = 0; j < width; j++)
{
st[i * width + j] = white; st[i * width + j] = white;
st[(height - 1 - i) * width + j] = white; st[(height - 1 - i) * width + j] = white;
} }
for (uint16_t j = 0; j < height; j++) for (uint16_t j = 0; j < height; j++) {
{
st[j * width + i] = white; st[j * width + i] = white;
st[j * width + (width - 1 - i)] = white; st[j * width + (width - 1 - i)] = white;
} }
@ -204,11 +197,11 @@ void ArrangementGraphicsItem<Arr_>::paintWithFloodFill(
painter->setTransform(painterTransform); painter->setTransform(painterTransform);
} }
//
template <typename Arr_> template <typename Arr_>
template <typename TTraits> template <typename TTraits>
void ArrangementGraphicsItem<Arr_>::paintEdges( void ArrangementGraphicsItem<Arr_>::paintEdges(QPainter* painter,
QPainter* painter, const TTraits&) const TTraits&) {
{
auto painterOstream = auto painterOstream =
ArrangementPainterOstream<TTraits>(painter, this->boundingRect()); ArrangementPainterOstream<TTraits>(painter, this->boundingRect());
@ -223,11 +216,12 @@ void ArrangementGraphicsItem<Arr_>::paintEdges(
} }
} }
//
template <typename Arr_> template <typename Arr_>
template <typename Coefficient_> template <typename Coefficient_>
void ArrangementGraphicsItem<Arr_>::paintEdges( void ArrangementGraphicsItem<Arr_>::
QPainter* painter, const CGAL::Arr_algebraic_segment_traits_2<Coefficient_>&) paintEdges(QPainter* painter,
{ const CGAL::Arr_algebraic_segment_traits_2<Coefficient_>&) {
using TTraits = CGAL::Arr_algebraic_segment_traits_2<Coefficient_>; using TTraits = CGAL::Arr_algebraic_segment_traits_2<Coefficient_>;
auto painterOstream = auto painterOstream =
@ -240,10 +234,10 @@ void ArrangementGraphicsItem<Arr_>::paintEdges(
painterOstream.paintEdges(arr->edges_begin(), arr->edges_end()); painterOstream.paintEdges(arr->edges_begin(), arr->edges_end());
} }
//
template <typename Arr_> template <typename Arr_>
void ArrangementGraphicsItem<Arr_>::paintFacesFloodFill( void ArrangementGraphicsItem<Arr_>::paintFacesFloodFill(QPainter* painter,
QPainter* painter, QImage& image) QImage& image) {
{
static constexpr QRgb invalid_rgb = 0; static constexpr QRgb invalid_rgb = 0;
QRgb* raw_img = reinterpret_cast<QRgb*>(image.bits()); QRgb* raw_img = reinterpret_cast<QRgb*>(image.bits());
@ -267,10 +261,8 @@ void ArrangementGraphicsItem<Arr_>::paintFacesFloodFill(
static constexpr int tot_margin = margin + 2; static constexpr int tot_margin = margin + 2;
auto cur_img_line = raw_img + tot_margin * width; auto cur_img_line = raw_img + tot_margin * width;
for (uint16_t y = tot_margin; y + 1 + tot_margin < height; y++) for (uint16_t y = tot_margin; y + 1 + tot_margin < height; y++) {
{ for (uint16_t x = tot_margin; x + 1 + tot_margin < width; x++) {
for (uint16_t x = tot_margin; x + 1 + tot_margin < width; x++)
{
// just to account for rendering errors // just to account for rendering errors
// make sure the pixel falls in the right face // make sure the pixel falls in the right face
if ( if (
@ -305,24 +297,24 @@ void ArrangementGraphicsItem<Arr_>::paintFacesFloodFill(
} }
} }
//
template <typename Arr_> template <typename Arr_>
void ArrangementGraphicsItem< Arr_ >::updateBoundingBox( ) void ArrangementGraphicsItem<Arr_>::updateBoundingBox() {
{
this->prepareGeometryChange(); this->prepareGeometryChange();
this->bb = {}; this->bb = {};
ConstructBoundingBox<Traits> construct_bounding_box; ConstructBoundingBox<Traits> ctr_bbox(*(this->arr->geometry_traits()));
for (auto it = this->arr->edges_begin(); it != this->arr->edges_end(); ++it) for (auto it = this->arr->edges_begin(); it != this->arr->edges_end(); ++it)
this->bb += construct_bounding_box(it->curve()); this->bb += ctr_bbox(it->curve());
for (auto it = this->arr->vertices_begin(); it != this->arr->vertices_end(); for (auto it = this->arr->vertices_begin(); it != this->arr->vertices_end();
++it) ++it)
this->bb += construct_bounding_box(it->point()); this->bb += ctr_bbox(it->point());
} }
//
template <typename Arr_> template <typename Arr_>
void ArrangementGraphicsItem<Arr_>::updatePointsItem() void ArrangementGraphicsItem<Arr_>::updatePointsItem() {
{
this->pointsGraphicsItem->clear(); this->pointsGraphicsItem->clear();
for (auto it = this->arr->vertices_begin(); it != this->arr->vertices_end(); for (auto it = this->arr->vertices_begin(); it != this->arr->vertices_end();
++it) ++it)
@ -332,9 +324,9 @@ void ArrangementGraphicsItem<Arr_>::updatePointsItem()
} }
} }
//
template <typename Arr_> template <typename Arr_>
void ArrangementGraphicsItem< Arr_ >::modelChanged( ) void ArrangementGraphicsItem<Arr_>::modelChanged() {
{
this->updatePointsItem(); this->updatePointsItem();
this->updateBoundingBox(); this->updateBoundingBox();
this->update(); this->update();
@ -342,21 +334,17 @@ void ArrangementGraphicsItem< Arr_ >::modelChanged( )
template < typename Arr_ > template < typename Arr_ >
void void
ArrangementGraphicsItem< Arr_ >:: ArrangementGraphicsItem<Arr_>::paintFace( Face_handle f, QPainter* painter) {
paintFace( Face_handle f, QPainter* painter )
{
if (f->visited()) return; if (f->visited()) return;
Hole_iterator hit; // holes iterator Hole_iterator hit; // holes iterator
this->paintFace(f, painter, *(arr->traits())); this->paintFace(f, painter, *(arr->traits()));
f->set_visited(true); f->set_visited(true);
for (hit = f->holes_begin(); hit != f->holes_end(); ++hit) for (hit = f->holes_begin(); hit != f->holes_end(); ++hit) {
{
// Traverse in clockwise order // Traverse in clockwise order
Ccb_halfedge_circulator cc = *hit; Ccb_halfedge_circulator cc = *hit;
do do {
{
Halfedge_handle he = cc; Halfedge_handle he = cc;
Halfedge_handle he2 = he->twin(); Halfedge_handle he2 = he->twin();
Face_handle inner_face = he2->face(); Face_handle inner_face = he2->face();
@ -367,13 +355,14 @@ paintFace( Face_handle f, QPainter* painter )
} }
} }
//
template <typename Arr_> template <typename Arr_>
template <typename Kernel_> template <typename Kernel_>
void ArrangementGraphicsItem<Arr_>::paintFace( void ArrangementGraphicsItem<Arr_>::
Face_handle f, QPainter* painter, const CGAL::Arr_segment_traits_2<Kernel_>&) paintFace(Face_handle f, QPainter* painter,
{ const CGAL::Arr_segment_traits_2<Kernel_>&) {
if (!f->is_unbounded()) // f is not the unbounded face if (!f->is_unbounded()) {
{ // f is not the unbounded face
QVector< QPointF > pts; // holds the points of the polygon QVector< QPointF > pts; // holds the points of the polygon
/* running with around the outer of the face and generate from it /* running with around the outer of the face and generate from it
@ -403,13 +392,13 @@ void ArrangementGraphicsItem<Arr_>::paintFace(
} }
} }
//
template <typename Arr_> template <typename Arr_>
template <typename Kernel_> template <typename Kernel_>
void ArrangementGraphicsItem<Arr_>::paintFace( void ArrangementGraphicsItem<Arr_>::
Face_handle f, QPainter* painter, const CGAL::Arr_polyline_traits_2<Kernel_>&) paintFace(Face_handle f, QPainter* painter,
{ const CGAL::Arr_polyline_traits_2<Kernel_>&) {
if (!f->is_unbounded()) if (!f->is_unbounded()) {
{
QVector< QPointF > pts; // holds the points of the polygon QVector< QPointF > pts; // holds the points of the polygon
CGAL::Qt::Converter<Kernel_> convert; CGAL::Qt::Converter<Kernel_> convert;
@ -433,8 +422,7 @@ void ArrangementGraphicsItem<Arr_>::paintFace(
auto first_subcurve = curve.subcurves_begin(); auto first_subcurve = curve.subcurves_begin();
QPointF src_first = convert(first_subcurve->source()); QPointF src_first = convert(first_subcurve->source());
if (src_first == src) if (src_first == src) {
{
for (auto it = curve.subcurves_begin(); it != curve.subcurves_end(); for (auto it = curve.subcurves_begin(); it != curve.subcurves_end();
++it) ++it)
{ {
@ -442,8 +430,7 @@ void ArrangementGraphicsItem<Arr_>::paintFace(
pts.push_back(convert(it->target())); pts.push_back(convert(it->target()));
} }
} }
else else {
{
QVector<QPointF> pts_tmp; QVector<QPointF> pts_tmp;
for (auto it = curve.subcurves_begin(); it != curve.subcurves_end(); for (auto it = curve.subcurves_begin(); it != curve.subcurves_end();
++it) ++it)
@ -461,18 +448,18 @@ void ArrangementGraphicsItem<Arr_>::paintFace(
painter->setBrush(f->color()); painter->setBrush(f->color());
painter->drawPolygon( pgn ); painter->drawPolygon( pgn );
} }
else else {
{
QRectF rect = this->viewportRect( ); QRectF rect = this->viewportRect( );
QColor color = f->color(); QColor color = f->color();
painter->fillRect(rect, color); painter->fillRect(rect, color);
} }
} }
//
template <typename Arr_> template <typename Arr_>
template <typename Coefficient_> template <typename Coefficient_>
void ArrangementGraphicsItem<Arr_>::paintFace( void ArrangementGraphicsItem<Arr_>::
Face_handle f, QPainter* painter, paintFace(Face_handle f, QPainter* painter,
const CGAL::Arr_algebraic_segment_traits_2<Coefficient_>& /* traits */) const CGAL::Arr_algebraic_segment_traits_2<Coefficient_>& /* traits */)
{ {
if (f->is_unbounded()) return; if (f->is_unbounded()) return;
@ -489,8 +476,7 @@ void ArrangementGraphicsItem<Arr_>::paintFace(
* polygon * polygon
*/ */
Ccb_halfedge_circulator cc = f->outer_ccb(); Ccb_halfedge_circulator cc = f->outer_ccb();
do do {
{
if (this->antenna(cc)) continue; if (this->antenna(cc)) continue;
auto points = painterOstream.getPointsList(cc->curve()); auto points = painterOstream.getPointsList(cc->curve());
@ -499,14 +485,12 @@ void ArrangementGraphicsItem<Arr_>::paintFace(
double src_x = CGAL::to_double(cc->source()->point().x()); double src_x = CGAL::to_double(cc->source()->point().x());
double tgt_x = CGAL::to_double(cc->target()->point().x()); double tgt_x = CGAL::to_double(cc->target()->point().x());
if (src_x < tgt_x) if (src_x < tgt_x) {
{
for (auto& vec : points) for (auto& vec : points)
for(auto& vit : vec) for(auto& vit : vec)
pts.push_back({vit.first, vit.second}); pts.push_back({vit.first, vit.second});
} }
else else {
{
for (auto vecit = points.rbegin(); vecit != points.rend(); ++vecit) for (auto vecit = points.rbegin(); vecit != points.rend(); ++vecit)
for (auto vit = vecit->rbegin(); vit != vecit->rend(); ++vit) for (auto vit = vecit->rbegin(); vit != vecit->rend(); ++vit)
pts.push_back({vit->first, vit->second}); pts.push_back({vit->first, vit->second});
@ -521,9 +505,9 @@ void ArrangementGraphicsItem<Arr_>::paintFace(
painter->restore(); painter->restore();
} }
//
template <typename Arr_> template <typename Arr_>
void ArrangementGraphicsItem<Arr_>::paintFaces(QPainter* painter) void ArrangementGraphicsItem<Arr_>::paintFaces(QPainter* painter) {
{
QPen pen = painter->pen(); QPen pen = painter->pen();
painter->setPen(this->facesPen); painter->setPen(this->facesPen);
@ -537,18 +521,16 @@ void ArrangementGraphicsItem<Arr_>::paintFaces(QPainter* painter)
painter->setPen(pen); painter->setPen(pen);
} }
//
template <typename Arr_> template <typename Arr_>
void ArrangementGraphicsItem<Arr_>::visit_ccb_faces( void ArrangementGraphicsItem<Arr_>::visit_ccb_faces(Face_handle& fh,
Face_handle& fh, QPainter* painter) QPainter* painter) {
{
this->paintFace(fh, painter); this->paintFace(fh, painter);
Ccb_halfedge_circulator cc = fh->outer_ccb(); Ccb_halfedge_circulator cc = fh->outer_ccb();
do do {
{
Halfedge he = *cc; Halfedge he = *cc;
if (!he.twin()->face()->visited()) if (!he.twin()->face()->visited()) {
{
Face_handle nei = he.twin()->face(); Face_handle nei = he.twin()->face();
this->visit_ccb_faces(nei, painter); this->visit_ccb_faces(nei, painter);
} }
@ -556,34 +538,34 @@ void ArrangementGraphicsItem<Arr_>::visit_ccb_faces(
} while (++cc != fh->outer_ccb()); } while (++cc != fh->outer_ccb());
} }
//
template <typename Arr_> template <typename Arr_>
bool ArrangementGraphicsItem<Arr_>::antenna(Halfedge_handle h) bool ArrangementGraphicsItem<Arr_>::antenna(Halfedge_handle h) {
{
Halfedge_handle twin = h->twin(); Halfedge_handle twin = h->twin();
return (twin->face() == h->face()); return (twin->face() == h->face());
} }
//
template <typename Arr_> template <typename Arr_>
template <typename ArrTraits> template <typename ArrTraits>
void ArrangementGraphicsItem<Arr_>::paintFace(Face_handle, QPainter*, ArrTraits) void ArrangementGraphicsItem<Arr_>::paintFace(Face_handle, QPainter*, ArrTraits)
{ {}
}
//
template <typename Arr_> template <typename Arr_>
template <typename RatKernel, typename AlgKernel, typename NtTraits> template <typename RatKernel, typename AlgKernel, typename NtTraits>
void ArrangementGraphicsItem<Arr_>::paintFace( void ArrangementGraphicsItem<Arr_>::
Face_handle f, QPainter* painter, paintFace(Face_handle f, QPainter* painter,
const CGAL::Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>&) const CGAL::Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>& traits)
{
if (!f->is_unbounded()) // f is not the unbounded face
{ {
if (!f->is_unbounded()) {
// f is not the unbounded face
QVector<QPointF> pts; // holds the points of the polygon QVector<QPointF> pts; // holds the points of the polygon
/* running with around the outer of the face and generate from it /* running with around the outer of the face and generate from it
* polygon * polygon
*/ */
Ccb_halfedge_circulator cc = f->outer_ccb(); Ccb_halfedge_circulator cc = f->outer_ccb();
do do {
{
if (this->antenna(cc)) { continue; } if (this->antenna(cc)) { continue; }
Halfedge_handle he = cc; Halfedge_handle he = cc;
@ -603,8 +585,7 @@ void ArrangementGraphicsItem<Arr_>::paintFace(
QPoint coord_target_viewport = this->fromScene(coord_target); QPoint coord_target_viewport = this->fromScene(coord_target);
if (c.orientation() == CGAL::COLLINEAR) { pts.push_back(coord_source); } if (c.orientation() == CGAL::COLLINEAR) { pts.push_back(coord_source); }
else else {
{
// If the curve is monotone, than its source and its target has the // If the curve is monotone, than its source and its target has the
// extreme x coordinates on this curve. // extreme x coordinates on this curve.
bool is_source_left = (sx < tx); bool is_source_left = (sx < tx);
@ -620,20 +601,17 @@ void ArrangementGraphicsItem<Arr_>::paintFace(
int start; int start;
int end; int end;
int step; int step;
if (is_source_left) if (is_source_left) {
{
start = x_min + DRAW_FACTOR; start = x_min + DRAW_FACTOR;
end = x_max; end = x_max;
step = DRAW_FACTOR; step = DRAW_FACTOR;
} }
else else {
{
start = x_max; start = x_max;
end = x_min; end = x_min;
step = -DRAW_FACTOR; step = -DRAW_FACTOR;
} }
for (int x = start; x < end; x += step) for (int x = start; x < end; x += step) {
{
double curr_x = this->toScene(QPoint{x, 0}).x(); double curr_x = this->toScene(QPoint{x, 0}).x();
AlgKernel ker; AlgKernel ker;
Point_2 curr_p(curr_x, 0); Point_2 curr_p(curr_x, 0);
@ -643,7 +621,7 @@ void ArrangementGraphicsItem<Arr_>::paintFace(
ker.compare_x_2_object()(curr_p, c.right()) != CGAL::LARGER)) ker.compare_x_2_object()(curr_p, c.right()) != CGAL::LARGER))
{ continue; } { continue; }
auto px = c.point_at_x(curr_p); auto px = traits.point_at_x(c, curr_p);
double curr_y = CGAL::to_double(px.y()); double curr_y = CGAL::to_double(px.y());
QPointF curr(curr_x, curr_y); QPointF curr(curr_x, curr_y);
pts.push_back(curr); pts.push_back(curr);
@ -656,33 +634,30 @@ void ArrangementGraphicsItem<Arr_>::paintFace(
painter->setBrush(f->color()); painter->setBrush(f->color());
painter->drawPolygon(pgn); painter->drawPolygon(pgn);
} }
else else {
{
QRectF rect = this->viewportRect(); QRectF rect = this->viewportRect();
QColor color = f->color(); QColor color = f->color();
painter->fillRect(rect, color); painter->fillRect(rect, color);
} }
} }
//
template <typename Arr_> template <typename Arr_>
template < template <typename RatKernel, typename AlgKernel, typename NtTraits,
typename RatKernel, typename AlgKernel, typename NtTraits,
typename BoundingTraits> typename BoundingTraits>
void ArrangementGraphicsItem<Arr_>::paintFace( void ArrangementGraphicsItem<Arr_>::
Face_handle f, QPainter* painter, paintFace(Face_handle f, QPainter* painter,
const CGAL::Arr_Bezier_curve_traits_2< const CGAL::Arr_Bezier_curve_traits_2
RatKernel, AlgKernel, NtTraits, BoundingTraits>&) <RatKernel, AlgKernel, NtTraits, BoundingTraits>&)
{
if (!f->is_unbounded())
{ {
if (!f->is_unbounded()) {
ArrangementPainterOstream<Traits> painterOstream{ ArrangementPainterOstream<Traits> painterOstream{
painter, this->boundingRect()}; painter, this->boundingRect()};
painterOstream.setScene(this->getScene()); painterOstream.setScene(this->getScene());
QVector<QPointF> pts; QVector<QPointF> pts;
Ccb_halfedge_circulator cc = f->outer_ccb(); Ccb_halfedge_circulator cc = f->outer_ccb();
do do {
{
if (this->antenna(cc)) continue; if (this->antenna(cc)) continue;
const X_monotone_curve_2& curve = cc->curve(); const X_monotone_curve_2& curve = cc->curve();
@ -702,31 +677,29 @@ void ArrangementGraphicsItem<Arr_>::paintFace(
painter->setBrush(color); painter->setBrush(color);
painter->drawPolygon(pgn); painter->drawPolygon(pgn);
} }
else else {
{
QRectF rect = this->viewportRect(); QRectF rect = this->viewportRect();
QColor color = f->color(); QColor color = f->color();
painter->fillRect(rect, color); painter->fillRect(rect, color);
} }
} }
//
template <typename Arr_> template <typename Arr_>
template <typename Kernel_> template <typename Kernel_>
void ArrangementGraphicsItem<Arr_>::paintFace( void ArrangementGraphicsItem<Arr_>::
Face_handle f, QPainter* painter, paintFace(Face_handle f, QPainter* painter,
const CGAL::Arr_linear_traits_2<Kernel_>& /* traits */) const CGAL::Arr_linear_traits_2<Kernel_>& /* traits */)
{ {
QVector<QPointF> pts; // holds the points of the polygon QVector<QPointF> pts; // holds the points of the polygon
QColor color = f->color(); QColor color = f->color();
painter->setBrush(color); painter->setBrush(color);
if (!f->is_unbounded()) if (!f->is_unbounded()) {
{
/* running with around the outer of the face and generate from it /* running with around the outer of the face and generate from it
* polygon * polygon
*/ */
Ccb_halfedge_circulator cc = f->outer_ccb(); Ccb_halfedge_circulator cc = f->outer_ccb();
do do {
{
Halfedge_handle hh = cc; Halfedge_handle hh = cc;
if (this->antenna(hh)) continue; if (this->antenna(hh)) continue;
@ -738,12 +711,10 @@ void ArrangementGraphicsItem<Arr_>::paintFace(
painter->drawPolygon(QPolygonF{pts}); painter->drawPolygon(QPolygonF{pts});
} }
else else {
{
std::vector<Halfedge_handle> halfedges; std::vector<Halfedge_handle> halfedges;
Ccb_halfedge_circulator cc = f->outer_ccb(); Ccb_halfedge_circulator cc = f->outer_ccb();
do do {
{
Halfedge_handle hh = cc; Halfedge_handle hh = cc;
if (cc->is_fictitious() || this->antenna(hh)) if (cc->is_fictitious() || this->antenna(hh))
continue; continue;
@ -753,8 +724,7 @@ void ArrangementGraphicsItem<Arr_>::paintFace(
QRectF rect = this->viewportRect(); QRectF rect = this->viewportRect();
switch (halfedges.size()) switch (halfedges.size()) {
{
// one unbounded face // one unbounded face
case 0: { case 0: {
painter->fillRect(rect, color); painter->fillRect(rect, color);
@ -766,39 +736,33 @@ void ArrangementGraphicsItem<Arr_>::paintFace(
auto&& line = curve.line(); auto&& line = curve.line();
// horizontal or mostly horizontal // horizontal or mostly horizontal
if (CGAL::abs(line.b()) > CGAL::abs(line.a())) if (CGAL::abs(line.b()) > CGAL::abs(line.a())) {
{
qreal left_y = CGAL::to_double(line.y_at_x(rect.left())); qreal left_y = CGAL::to_double(line.y_at_x(rect.left()));
qreal right_y = CGAL::to_double(line.y_at_x(rect.right())); qreal right_y = CGAL::to_double(line.y_at_x(rect.right()));
pts.push_back({rect.left(), left_y}); pts.push_back({rect.left(), left_y});
pts.push_back({rect.right(), right_y}); pts.push_back({rect.right(), right_y});
if (cc->direction() == ARR_LEFT_TO_RIGHT) if (cc->direction() == ARR_LEFT_TO_RIGHT) {
{
pts.push_back(rect.bottomRight()); pts.push_back(rect.bottomRight());
pts.push_back(rect.bottomLeft()); pts.push_back(rect.bottomLeft());
} }
else else {
{
pts.push_back(rect.topRight()); pts.push_back(rect.topRight());
pts.push_back(rect.topLeft()); pts.push_back(rect.topLeft());
} }
} }
// vertical or mostly vertical // vertical or mostly vertical
else else {
{
qreal top_x = CGAL::to_double(line.x_at_y(rect.top())); qreal top_x = CGAL::to_double(line.x_at_y(rect.top()));
qreal bottom_x = CGAL::to_double(line.x_at_y(rect.bottom())); qreal bottom_x = CGAL::to_double(line.x_at_y(rect.bottom()));
pts.push_back({top_x, rect.top()}); pts.push_back({top_x, rect.top()});
pts.push_back({bottom_x, rect.bottom()}); pts.push_back({bottom_x, rect.bottom()});
if (cc->direction() == ARR_LEFT_TO_RIGHT) if (cc->direction() == ARR_LEFT_TO_RIGHT) {
{
pts.push_back(rect.bottomLeft()); pts.push_back(rect.bottomLeft());
pts.push_back(rect.topLeft()); pts.push_back(rect.topLeft());
} }
else else {
{
pts.push_back(rect.bottomRight()); pts.push_back(rect.bottomRight());
pts.push_back(rect.topRight()); pts.push_back(rect.topRight());
} }
@ -817,16 +781,14 @@ void ArrangementGraphicsItem<Arr_>::paintFace(
typename Kernel_::RT dx, dy, c; typename Kernel_::RT dx, dy, c;
auto&& curve = halfedge->curve(); auto&& curve = halfedge->curve();
if (curve.is_segment()) if (curve.is_segment()) {
{
auto&& src = halfedge->source()->point(); auto&& src = halfedge->source()->point();
auto&& tgt = halfedge->target()->point(); auto&& tgt = halfedge->target()->point();
dy = tgt.y() - src.y(); dy = tgt.y() - src.y();
dx = tgt.x() - src.x(); dx = tgt.x() - src.x();
c = dx * src.y() - dy * src.x(); c = dx * src.y() - dy * src.x();
} }
else if(curve.is_ray()) else if(curve.is_ray()) {
{
auto&& ray = curve.ray(); auto&& ray = curve.ray();
auto&& dir = ray.direction(); auto&& dir = ray.direction();
auto&& src = ray.source(); auto&& src = ray.source();
@ -835,8 +797,7 @@ void ArrangementGraphicsItem<Arr_>::paintFace(
c = dx * src.y() - dy * src.x(); c = dx * src.y() - dy * src.x();
} }
// halfedge can be a line in case of a face between two parallel lines // halfedge can be a line in case of a face between two parallel lines
else else {
{
auto&& line = curve.line(); auto&& line = curve.line();
auto param_in_x = vertex->parameter_space_in_x(); auto param_in_x = vertex->parameter_space_in_x();
auto param_in_y = vertex->parameter_space_in_y(); auto param_in_y = vertex->parameter_space_in_y();
@ -844,8 +805,7 @@ void ArrangementGraphicsItem<Arr_>::paintFace(
dx = -line.b(); dx = -line.b();
c = line.c(); c = line.c();
if ( if ((param_in_x == LEFT_BOUNDARY && CGAL::is_positive(dx)) ||
(param_in_x == LEFT_BOUNDARY && CGAL::is_positive(dx)) ||
(param_in_x == RIGHT_BOUNDARY && CGAL::is_negative(dx)) || (param_in_x == RIGHT_BOUNDARY && CGAL::is_negative(dx)) ||
(param_in_y == BOTTOM_BOUNDARY && CGAL::is_positive(dy)) || (param_in_y == BOTTOM_BOUNDARY && CGAL::is_positive(dy)) ||
(param_in_y == TOP_BOUNDARY && CGAL::is_negative(dy))) (param_in_y == TOP_BOUNDARY && CGAL::is_negative(dy)))
@ -856,17 +816,14 @@ void ArrangementGraphicsItem<Arr_>::paintFace(
} }
} }
// horizontal or mostly horizontal // horizontal or mostly horizontal
if (CGAL::abs(dx) > CGAL::abs(dy)) if (CGAL::abs(dx) > CGAL::abs(dy)) {
{ qreal x = CGAL::is_positive(dx) ?
qreal x = CGAL::is_positive(dx) ? rect.right() + rect.width() rect.right() + rect.width() : rect.left() - rect.width();
: rect.left() - rect.width();
// in case vertex is a finite point // in case vertex is a finite point
if (!vertex->is_at_open_boundary()) if (!vertex->is_at_open_boundary()) {
{
auto p = vertex->point(); auto p = vertex->point();
// check not far away // check not far away
if ( if ((CGAL::is_positive(dx) && p.x() < x) ||
(CGAL::is_positive(dx) && p.x() < x) ||
(CGAL::is_negative(dx) && p.x() > x)) (CGAL::is_negative(dx) && p.x() > x))
{ {
pts.push_back({CGAL::to_double(p.x()), CGAL::to_double(p.y())}); pts.push_back({CGAL::to_double(p.x()), CGAL::to_double(p.y())});
@ -880,17 +837,14 @@ void ArrangementGraphicsItem<Arr_>::paintFace(
pts.push_back({x, y}); pts.push_back({x, y});
} }
// vertical or mostly vertical // vertical or mostly vertical
else else {
{ qreal y = CGAL::is_positive(dy) ?
qreal y = CGAL::is_positive(dy) ? rect.bottom() + rect.height() rect.bottom() + rect.height() : rect.top() - rect.height();
: rect.top() - rect.height();
// in case vertex is a finite point // in case vertex is a finite point
if (!vertex->is_at_open_boundary()) if (!vertex->is_at_open_boundary()) {
{
auto p = vertex->point(); auto p = vertex->point();
// check not far away // check not far away
if ( if ((CGAL::is_positive(dy) && p.y() < y) ||
(CGAL::is_positive(dy) && p.y() < y) ||
(CGAL::is_negative(dy) && p.y() > y)) (CGAL::is_negative(dy) && p.y() > y))
{ {
pts.push_back({CGAL::to_double(p.x()), CGAL::to_double(p.y())}); pts.push_back({CGAL::to_double(p.x()), CGAL::to_double(p.y())});
@ -905,8 +859,7 @@ void ArrangementGraphicsItem<Arr_>::paintFace(
} }
}; };
for (auto hh : halfedges) for (auto hh : halfedges) {
{
handle_vertex(hh, hh->source()); handle_vertex(hh, hh->source());
handle_vertex(hh, hh->target()); handle_vertex(hh, hh->target());
} }
@ -919,8 +872,9 @@ void ArrangementGraphicsItem<Arr_>::paintFace(
} }
// TODO: clean all this portion up (move it somewhere?), it's ugly! // TODO: clean all this portion up (move it somewhere?), it's ugly!
static CGAL::Bbox_2 reject_not_in_allowable_range( static CGAL::Bbox_2
const CGAL::Bbox_2& box, const CGAL::Bbox_2& allowable_range) reject_not_in_allowable_range(const CGAL::Bbox_2& box,
const CGAL::Bbox_2& allowable_range)
{ {
double xmin = std::numeric_limits<double>::infinity(); double xmin = std::numeric_limits<double>::infinity();
double ymin = std::numeric_limits<double>::infinity(); double ymin = std::numeric_limits<double>::infinity();
@ -934,25 +888,23 @@ static CGAL::Bbox_2 reject_not_in_allowable_range(
return {xmin, ymin, xmax, ymax}; return {xmin, ymin, xmax, ymax};
} }
static bool isFinite(const CGAL::Bbox_2& box) //
{ static bool isFinite(const CGAL::Bbox_2& box) {
return ! std::isinf(box.xmin()) && !std::isinf(box.xmax()) && return ! std::isinf(box.xmin()) && !std::isinf(box.xmax()) &&
! std::isinf(box.ymin()) && !std::isinf(box.ymax()); ! std::isinf(box.ymin()) && !std::isinf(box.ymax());
} }
static CGAL::Bbox_2 addMargins(const CGAL::Bbox_2& box) //
{ static CGAL::Bbox_2 addMargins(const CGAL::Bbox_2& box) {
// add margin to bounding box // add margin to bounding box
double x_margin; double x_margin;
double y_margin; double y_margin;
if (box.xmin() == box.xmax() || box.ymin() == box.ymax()) if (box.xmin() == box.xmax() || box.ymin() == box.ymax()) {
{
static constexpr float const_margin = 50; static constexpr float const_margin = 50;
x_margin = const_margin; x_margin = const_margin;
y_margin = const_margin; y_margin = const_margin;
} }
else else {
{
static constexpr double prop_margin = 0.10; static constexpr double prop_margin = 0.10;
x_margin = (box.xmax() - box.xmin()) * prop_margin; x_margin = (box.xmax() - box.xmin()) * prop_margin;
y_margin = (box.ymax() - box.ymin()) * prop_margin; y_margin = (box.ymax() - box.ymin()) * prop_margin;
@ -962,25 +914,23 @@ static CGAL::Bbox_2 addMargins(const CGAL::Bbox_2& box)
box.ymax() + y_margin}; box.ymax() + y_margin};
} }
//
template <class Arr_> template <class Arr_>
CGAL::Bbox_2 CGAL::Bbox_2
findOtherInterestingPoints(const Arr_*, const CGAL::Bbox_2&) findOtherInterestingPoints(const Arr_*, const CGAL::Bbox_2&) { return {}; }
{
return {};
}
#ifdef CGAL_USE_CORE #ifdef CGAL_USE_CORE
//
template <typename Coefficient_> template <typename Coefficient_>
static const auto& static const auto&
getXyCurves(const CGAL::Arr_algebraic_segment_traits_2<Coefficient_>* traits) getXyCurves(const CGAL::Arr_algebraic_segment_traits_2<Coefficient_>* traits) {
{
// the traits object is only needed the first time // the traits object is only needed the first time
// this assumes that X_monotone_curves created from the first traits object // this assumes that X_monotone_curves created from the first traits object
// will work with arrangements with a different object // will work with arrangements with a different object
using Traits = CGAL::Arr_algebraic_segment_traits_2<Coefficient_>; using Traits = CGAL::Arr_algebraic_segment_traits_2<Coefficient_>;
static std::vector<typename Traits::X_monotone_curve_2> xy_curves; static std::vector<typename Traits::X_monotone_curve_2> xy_curves;
if (xy_curves.empty()) if (xy_curves.empty()) {
{
typedef typename Traits::Polynomial_2 Polynomial_2; typedef typename Traits::Polynomial_2 Polynomial_2;
auto construct_curve = traits->construct_curve_2_object(); auto construct_curve = traits->construct_curve_2_object();
auto make_x_monotone = traits->make_x_monotone_2_object(); auto make_x_monotone = traits->make_x_monotone_2_object();
@ -1003,27 +953,25 @@ getXyCurves(const CGAL::Arr_algebraic_segment_traits_2<Coefficient_>* traits)
return xy_curves; return xy_curves;
} }
//
template <> template <>
CGAL::Bbox_2 findOtherInterestingPoints<demo_types::DemoTypes::Alg_seg_arr>( CGAL::Bbox_2
const demo_types::DemoTypes::Alg_seg_arr* arr, findOtherInterestingPoints<demo_types::DemoTypes::Alg_seg_arr>
const CGAL::Bbox_2& allowable_range) (const demo_types::DemoTypes::Alg_seg_arr* arr,
{ const CGAL::Bbox_2& allowable_range) {
using Traits = demo_types::DemoTypes::Alg_seg_traits; using Traits = demo_types::DemoTypes::Alg_seg_traits;
CGAL::Bbox_2 bb = {}; CGAL::Bbox_2 bb = {};
std::vector<CGAL::Object> intersections; std::vector<CGAL::Object> intersections;
for (auto it = arr->edges_begin(); it != arr->edges_end(); ++it) for (auto it = arr->edges_begin(); it != arr->edges_end(); ++it) {
{
for (auto& arc : getXyCurves(arr->traits())) for (auto& arc : getXyCurves(arr->traits()))
if (arc.is_vertical() != it->curve().is_vertical()) if (arc.is_vertical() != it->curve().is_vertical())
it->curve().intersections(arc, std::back_inserter(intersections)); it->curve().intersections(arc, std::back_inserter(intersections));
} }
for (auto it = intersections.begin(); it != intersections.end(); it++) for (auto it = intersections.begin(); it != intersections.end(); it++) {
{
std::pair<typename Traits::Point_2, unsigned int> point_multiplicity; std::pair<typename Traits::Point_2, unsigned int> point_multiplicity;
CGAL::assign(point_multiplicity, *it); CGAL::assign(point_multiplicity, *it);
auto& point = point_multiplicity.first; auto& point = point_multiplicity.first;
if (point.location() == CGAL::ARR_INTERIOR) if (point.location() == CGAL::ARR_INTERIOR) {
{
auto xy = point.to_double(); auto xy = point.to_double();
bb += reject_not_in_allowable_range( bb += reject_not_in_allowable_range(
{xy.first, xy.second, xy.first, xy.second}, allowable_range); {xy.first, xy.second, xy.first, xy.second}, allowable_range);
@ -1031,30 +979,28 @@ CGAL::Bbox_2 findOtherInterestingPoints<demo_types::DemoTypes::Alg_seg_arr>(
} }
return bb; return bb;
} }
#endif // CGAL_USE_CORE #endif // CGAL_USE_CORE
//
template <typename Arr_> template <typename Arr_>
QRectF ArrangementGraphicsItem<Arr_>::getInterestingViewport() const QRectF ArrangementGraphicsItem<Arr_>::getInterestingViewport() const {
{
QRectF scene_rect = this->getScene()->sceneRect(); QRectF scene_rect = this->getScene()->sceneRect();
CGAL::Bbox_2 scene_bbox = { CGAL::Bbox_2 scene_bbox = {
scene_rect.left(), scene_rect.top(), scene_rect.right(), scene_rect.left(), scene_rect.top(), scene_rect.right(),
scene_rect.bottom()}; scene_rect.bottom()};
ConstructBoundingBox<Traits> construct_bounding_box; ConstructBoundingBox<Traits> ctr_bbox(*(this->arr->geometry_traits()));
CGAL::Bbox_2 bounding_box = {}; CGAL::Bbox_2 bounding_box = {};
for (auto it = this->arr->edges_begin(); for (auto it = this->arr->edges_begin(); it != this->arr->edges_end(); ++it) {
it != this->arr->edges_end(); ++it)
{
bounding_box += reject_not_in_allowable_range( bounding_box += reject_not_in_allowable_range(
construct_bounding_box(it->curve()), scene_bbox); ctr_bbox(it->curve()), scene_bbox);
} }
for (auto it = this->arr->vertices_begin(); for (auto it = this->arr->vertices_begin();
it != this->arr->vertices_end(); ++it) it != this->arr->vertices_end(); ++it)
{ {
bounding_box += reject_not_in_allowable_range( bounding_box += reject_not_in_allowable_range(
construct_bounding_box(it->point()), scene_bbox); ctr_bbox(it->point()), scene_bbox);
} }
if (!isFinite(bounding_box)) if (!isFinite(bounding_box))
@ -1066,8 +1012,7 @@ QRectF ArrangementGraphicsItem<Arr_>::getInterestingViewport() const
bounding_box = addMargins(bounding_box); bounding_box = addMargins(bounding_box);
return QRectF( return QRectF(bounding_box.xmin(), bounding_box.ymin(),
bounding_box.xmin(), bounding_box.ymin(),
bounding_box.xmax() - bounding_box.xmin(), bounding_box.xmax() - bounding_box.xmin(),
bounding_box.ymax() - bounding_box.ymin()); bounding_box.ymax() - bounding_box.ymin());
} }

View File

@ -19,13 +19,10 @@
#include <CGAL/IO/Arr_with_history_iostream.h> #include <CGAL/IO/Arr_with_history_iostream.h>
#include <CGAL/IO/Arr_with_history_text_formatter.h> #include <CGAL/IO/Arr_with_history_text_formatter.h>
template < template <typename Arrangement,
typename Arrangement,
typename Traits = typename Arrangement::Geometry_traits_2> typename Traits = typename Arrangement::Geometry_traits_2>
struct ArrReader struct ArrReader {
{ Arrangement* operator()(std::ifstream& ifs) {
Arrangement* operator()(std::ifstream& ifs)
{
using Text_formatter = CGAL::Arr_text_formatter<Arrangement>; using Text_formatter = CGAL::Arr_text_formatter<Arrangement>;
using ArrFormatter = CGAL::Arr_with_history_text_formatter<Text_formatter>; using ArrFormatter = CGAL::Arr_with_history_text_formatter<Text_formatter>;
@ -37,33 +34,34 @@ struct ArrReader
}; };
#ifdef CGAL_USE_CORE #ifdef CGAL_USE_CORE
template <
typename Arrangement, typename Rat_kernel_, typename Alg_kernel_, // Specialization of `ArrReader` for the conic traits.
template <typename Arrangement, typename Rat_kernel_, typename Alg_kernel_,
typename Nt_traits_> typename Nt_traits_>
struct ArrReader< struct ArrReader<Arrangement,
Arrangement, CGAL::Arr_conic_traits_2<Rat_kernel_, Alg_kernel_, Nt_traits_>> CGAL::Arr_conic_traits_2<Rat_kernel_, Alg_kernel_, Nt_traits_>>
{ {
using Traits = typename Arrangement::Geometry_traits_2; using Traits = typename Arrangement::Geometry_traits_2;
using Curve_2 = typename Arrangement::Curve_2; using Curve_2 = typename Arrangement::Curve_2;
Arrangement* operator()(std::ifstream& ifs) Arrangement* operator()(std::ifstream& ifs) {
{ auto arr = new Arrangement();
Conic_reader<Traits> conicReader; const auto* traits = arr->geometry_traits();
Conic_reader<Traits> conicReader(*traits);;
std::vector<Curve_2> curve_list; std::vector<Curve_2> curve_list;
CGAL::Bbox_2 bbox; CGAL::Bbox_2 bbox;
conicReader.read_data(ifs, std::back_inserter(curve_list), bbox); conicReader.read_data(ifs, std::back_inserter(curve_list), bbox);
auto arr = new Arrangement();
CGAL::insert(*arr, curve_list.begin(), curve_list.end()); CGAL::insert(*arr, curve_list.begin(), curve_list.end());
return arr; return arr;
} }
}; };
template < // Specialization of `ArrReader` for the Bezier traits.
typename Arrangement, typename Rat_kernel_, typename Alg_kernel_, template <typename Arrangement, typename Rat_kernel_, typename Alg_kernel_,
typename Nt_traits_, typename Bounding_traits_> typename Nt_traits_, typename Bounding_traits_>
struct ArrReader< struct ArrReader<Arrangement,
Arrangement, CGAL::Arr_Bezier_curve_traits_2< CGAL::Arr_Bezier_curve_traits_2<Rat_kernel_, Alg_kernel_,
Rat_kernel_, Alg_kernel_, Nt_traits_, Bounding_traits_>> Nt_traits_, Bounding_traits_>>
{ {
Arrangement* operator()(std::ifstream&) { return nullptr; } Arrangement* operator()(std::ifstream&) { return nullptr; }
}; };
@ -77,8 +75,7 @@ struct ArrReader<
#endif #endif
std::pair<CGAL::Object, demo_types::TraitsType> std::pair<CGAL::Object, demo_types::TraitsType>
ArrangementIO::read(std::ifstream& ifs) ArrangementIO::read(std::ifstream& ifs) {
{
// read type info // read type info
while (ifs.peek() == '#' || std::isspace(ifs.peek())) ifs.get(); while (ifs.peek() == '#' || std::isspace(ifs.peek())) ifs.get();
@ -95,13 +92,10 @@ ArrangementIO::read(std::ifstream& ifs)
return res; return res;
} }
template < template <typename Arrangement,
typename Arrangement,
typename Traits = typename Arrangement::Geometry_traits_2> typename Traits = typename Arrangement::Geometry_traits_2>
struct ArrWriter struct ArrWriter {
{ void operator()(Arrangement* arr, std::ofstream& ofs) {
void operator()(Arrangement* arr, std::ofstream& ofs)
{
using TextFormatter = CGAL::Arr_text_formatter<Arrangement>; using TextFormatter = CGAL::Arr_text_formatter<Arrangement>;
using ArrFormatter = CGAL::Arr_with_history_text_formatter<TextFormatter>; using ArrFormatter = CGAL::Arr_with_history_text_formatter<TextFormatter>;
@ -111,19 +105,18 @@ struct ArrWriter
}; };
#ifdef CGAL_USE_CORE #ifdef CGAL_USE_CORE
template <
typename Arrangement, typename Rat_kernel_, typename Alg_kernel_, template <typename Arrangement, typename Rat_kernel_, typename Alg_kernel_,
typename Nt_traits_> typename Nt_traits_>
struct ArrWriter< struct ArrWriter<Arrangement, CGAL::Arr_conic_traits_2<Rat_kernel_, Alg_kernel_,
Arrangement, CGAL::Arr_conic_traits_2<Rat_kernel_, Alg_kernel_, Nt_traits_>> Nt_traits_>>
{ {
using Traits = typename Arrangement::Geometry_traits_2; using Traits = typename Arrangement::Geometry_traits_2;
using Curve_2 = typename Arrangement::Curve_2; using Curve_2 = typename Arrangement::Curve_2;
void operator()(Arrangement* arr, std::ofstream& ofs) void operator()(Arrangement* arr, std::ofstream& ofs) {
{ Conic_reader<Traits> conic_reader(*(arr->geometry_traits()));
Conic_reader<Traits> conicReader; conic_reader.write_data(ofs, arr->curves_begin(), arr->curves_end());
conicReader.write_data(ofs, arr->curves_begin(), arr->curves_end());
} }
}; };
@ -145,8 +138,8 @@ struct ArrWriter<
}; };
#endif #endif
bool ArrangementIO::write( bool ArrangementIO::write(const std::pair<CGAL::Object,
const std::pair<CGAL::Object, demo_types::TraitsType>& arr_pair, demo_types::TraitsType>& arr_pair,
std::ofstream& ofs) std::ofstream& ofs)
{ {
auto tt = arr_pair.second; auto tt = arr_pair.second;
@ -159,8 +152,7 @@ bool ArrangementIO::write(
demo_types::visitArrangementType(tt, [&](auto type_holder) { demo_types::visitArrangementType(tt, [&](auto type_holder) {
using Arrangement = typename decltype(type_holder)::type; using Arrangement = typename decltype(type_holder)::type;
Arrangement* arr; Arrangement* arr;
if (CGAL::assign(arr, arr_obj)) if (CGAL::assign(arr, arr_obj)) {
{
ArrWriter<Arrangement>{}(arr, ofs); ArrWriter<Arrangement>{}(arr, ofs);
result = true; result = true;
} }

View File

@ -15,55 +15,44 @@
#include <QGraphicsView> #include <QGraphicsView>
namespace CGAL namespace CGAL {
{ namespace Qt {
namespace Qt
{
// Instantiation of Arr_segment_traits_2 // Specialization of `ArrangementPainterOstream` for the segment traits.
template <typename Kernel_> template <typename Kernel_>
ArrangementPainterOstream<CGAL::Arr_segment_traits_2<Kernel_>>& ArrangementPainterOstream<CGAL::Arr_segment_traits_2<Kernel_>>&
ArrangementPainterOstream<CGAL::Arr_segment_traits_2<Kernel_>>::operator<<( ArrangementPainterOstream<CGAL::Arr_segment_traits_2<Kernel_>>::
const X_monotone_curve_2& curve) operator<<(const X_monotone_curve_2& curve) {
{
const Point_2& p1 = curve.source(); const Point_2& p1 = curve.source();
const Point_2& p2 = curve.target(); const Point_2& p2 = curve.target();
Segment_2 seg(p1, p2); Segment_2 seg(p1, p2);
// skip segments outside our view // skip segments outside our view
QRectF seg_bb = this->convert(seg.bbox()); QRectF seg_bb = this->convert(seg.bbox());
if ( if (this->clippingRect.isValid() &&
this->clippingRect.isValid() && !this->clippingRect.intersects(seg_bb) && ! this->clippingRect.intersects(seg_bb) &&
(!seg.is_horizontal() && !seg.is_vertical())) ! seg.is_horizontal() && ! seg.is_vertical())
{ return *this; } return *this;
this->painterOstream << seg; this->painterOstream << seg;
return *this; return *this;
} }
// Instantiation of Arr_polyline_traits_2 // Specialization of `ArrangementPainterOstream` for the polyline traits.
template <typename SegmentTraits> template <typename SegmentTraits>
ArrangementPainterOstream<CGAL::Arr_polyline_traits_2<SegmentTraits>>& ArrangementPainterOstream<CGAL::Arr_polyline_traits_2<SegmentTraits>>&
ArrangementPainterOstream<CGAL::Arr_polyline_traits_2<SegmentTraits>>:: ArrangementPainterOstream<CGAL::Arr_polyline_traits_2<SegmentTraits>>::
operator<<(const X_monotone_curve_2& curve) operator<<(const X_monotone_curve_2& curve) {
{ for (auto it = curve.subcurves_begin(); it != curve.subcurves_end(); ++it)
for (typename X_monotone_curve_2::Subcurve_const_iterator it =
curve.subcurves_begin();
it != curve.subcurves_end(); ++it)
{
this->painterOstream << *it; this->painterOstream << *it;
}
return *this; return *this;
} }
// Instantiation of Arr_conic_traits_2 // Specialization of `ArrangementPainterOstream` for the conic traits.
template <typename RatKernel, class AlgKernel, class NtTraits> template <typename RatKernel, typename AlgKernel, typename NtTraits>
auto ArrangementPainterOstream<CGAL::Arr_conic_traits_2< auto ArrangementPainterOstream
RatKernel, AlgKernel, NtTraits>>::visibleParts(X_monotone_curve_2 curve) <CGAL::Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>>::
-> std::vector<X_monotone_curve_2> visibleParts(X_monotone_curve_2 curve) -> std::vector<X_monotone_curve_2> {
{
// see if we intersect the bottom edge of the viewport // see if we intersect the bottom edge of the viewport
Point_2 bottomLeft = this->convert(this->clippingRect.bottomLeft()); Point_2 bottomLeft = this->convert(this->clippingRect.bottomLeft());
Point_2 bottomRight = this->convert(this->clippingRect.bottomRight()); Point_2 bottomRight = this->convert(this->clippingRect.bottomRight());
@ -99,18 +88,16 @@ auto ArrangementPainterOstream<CGAL::Arr_conic_traits_2<
Point_2 leftEndpt = curve.source(); Point_2 leftEndpt = curve.source();
Point_2 rightEndpt = curve.target(); Point_2 rightEndpt = curve.target();
if (leftEndpt.x() > rightEndpt.x()) { std::swap(leftEndpt, rightEndpt); } if (leftEndpt.x() > rightEndpt.x()) std::swap(leftEndpt, rightEndpt);
QPointF qendpt1 = this->convert(leftEndpt); QPointF qendpt1 = this->convert(leftEndpt);
QPointF qendpt2 = this->convert(rightEndpt); QPointF qendpt2 = this->convert(rightEndpt);
std::list<Point_2> pointList; std::list<Point_2> pointList;
for (unsigned int i = 0; i < intersections.size(); ++i) for (unsigned int i = 0; i < intersections.size(); ++i) {
{
CGAL::Object o = intersections[i]; CGAL::Object o = intersections[i];
std::pair<Intersection_point_2, Multiplicity> pair; std::pair<Intersection_point_2, Multiplicity> pair;
if (CGAL::assign(pair, o)) if (CGAL::assign(pair, o)) {
{
Point_2 pt = pair.first; Point_2 pt = pair.first;
pointList.push_back(pt); pointList.push_back(pt);
} }
@ -118,41 +105,36 @@ auto ArrangementPainterOstream<CGAL::Arr_conic_traits_2<
bool includeLeftEndpoint = this->clippingRect.contains(qendpt1); bool includeLeftEndpoint = this->clippingRect.contains(qendpt1);
bool includeRightEndpoint = this->clippingRect.contains(qendpt2); bool includeRightEndpoint = this->clippingRect.contains(qendpt2);
if (includeLeftEndpoint) { pointList.push_front(leftEndpt); } if (includeLeftEndpoint) pointList.push_front(leftEndpt);
if (includeRightEndpoint) { pointList.push_back(rightEndpt); } if (includeRightEndpoint) pointList.push_back(rightEndpt);
// TODO: make ArrangementPainterOstream take traits object // TODO: make ArrangementPainterOstream take traits object
Traits traits; auto trim = traits.trim_2_object();
Construct_x_monotone_subcurve_2<Traits> construct_x_monotone_subcurve_2{
&traits};
std::vector<X_monotone_curve_2> clippings; std::vector<X_monotone_curve_2> clippings;
typename std::list<Point_2>::iterator pointListItr = pointList.begin(); auto it = pointList.begin();
for (unsigned int i = 0; i < pointList.size(); i += 2) for (unsigned int i = 0; i < pointList.size(); i += 2) {
{ typename Traits::Point_2 p1 = *it++;
typename Traits::Point_2 p1 = *pointListItr++; typename Traits::Point_2 p2 = *it++;
typename Traits::Point_2 p2 = *pointListItr++; auto xcv = trim(curve, p1, p2);
X_monotone_curve_2 subcurve = clippings.push_back(xcv);
construct_x_monotone_subcurve_2(curve, p1, p2);
clippings.push_back(subcurve);
} }
return clippings; return clippings;
} }
template <typename RatKernel, class AlgKernel, class NtTraits> //
void ArrangementPainterOstream< template <typename RatKernel, typename AlgKernel, typename NtTraits>
CGAL::Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>>:: void ArrangementPainterOstream
filterIntersectionPoints(std::vector<CGAL::Object>& res) <CGAL::Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>>::
{ filterIntersectionPoints(std::vector<CGAL::Object>& res) {
std::vector<std::pair<Intersection_point_2, Multiplicity>> tmp; std::vector<std::pair<Intersection_point_2, Multiplicity>> tmp;
// filter out the non-intersection point results // filter out the non-intersection point results
for (unsigned int i = 0; i < res.size(); ++i) for (unsigned int i = 0; i < res.size(); ++i) {
{
CGAL::Object obj = res[i]; CGAL::Object obj = res[i];
std::pair<Intersection_point_2, Multiplicity> pair; std::pair<Intersection_point_2, Multiplicity> pair;
if (CGAL::assign(pair, obj)) { tmp.push_back(pair); } if (CGAL::assign(pair, obj)) tmp.push_back(pair);
} }
res.clear(); res.clear();
@ -161,80 +143,76 @@ void ArrangementPainterOstream<
std::sort(tmp.begin(), tmp.end(), compare_intersection_point_result); std::sort(tmp.begin(), tmp.end(), compare_intersection_point_result);
// box up the sorted elements // box up the sorted elements
for (unsigned int i = 0; i < tmp.size(); ++i) for (unsigned int i = 0; i < tmp.size(); ++i) {
{
std::pair<Intersection_point_2, Multiplicity> pair = tmp[i]; std::pair<Intersection_point_2, Multiplicity> pair = tmp[i];
CGAL::Object o = CGAL::make_object(pair); CGAL::Object o = CGAL::make_object(pair);
res.push_back(o); res.push_back(o);
} }
} }
template <typename RatKernel, class AlgKernel, class NtTraits> //
ArrangementPainterOstream< template <typename RatKernel, typename AlgKernel, typename NtTraits>
CGAL::Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>>& ArrangementPainterOstream
ArrangementPainterOstream<CGAL::Arr_conic_traits_2< <CGAL::Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>>&
RatKernel, AlgKernel, NtTraits>>::operator<<(const X_monotone_curve_2& curve) ArrangementPainterOstream
{ <CGAL::Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>>::
CGAL::Bbox_2 bb = curve.bbox(); operator<<(const X_monotone_curve_2& curve) {
CGAL::Bbox_2 bb = traits.construct_bbox_2_object()(curve);
QRectF qbb = this->convert(bb); QRectF qbb = this->convert(bb);
// quick cull // quick cull
if (this->clippingRect.isValid() && ! this->clippingRect.intersects(qbb)) if (this->clippingRect.isValid() && ! this->clippingRect.intersects(qbb))
{ return *this; } return *this;
// get number of segments // get number of segments
QGraphicsView* view = this->scene->views().first(); QGraphicsView* view = this->scene->views().first();
int xmin = view->mapFromScene(bb.xmin(), bb.ymin()).x(); auto pmin = view->mapFromScene(bb.xmin(), bb.ymin());
int xmax = view->mapFromScene(bb.xmax(), bb.ymin()).x(); auto pmax = view->mapFromScene(bb.xmax(), bb.ymax());
// can be negative due to rotation transformation double world_xdiff = std::abs(bb.xmax() - bb.xmin());
size_t n = static_cast<size_t>(std::abs(xmax - xmin)); double screen_xdiff = std::abs(pmax.x() - pmin.x());
if (n == 0) { return *this; } double error = world_xdiff / screen_xdiff;
auto paintCurve = [&](auto&& curve_) { auto paint_curve = [&](auto&& curve_) {
std::vector<std::pair<double, double>> app_pts; using Approximate_point_2 = typename Traits::Approximate_point_2;
app_pts.reserve(n + 1); std::vector<Approximate_point_2> points;
curve_.polyline_approximation(n, std::back_inserter(app_pts)); auto aprox = traits.approximate_2_object();
aprox(curve_, error, std::back_inserter(points));
auto p_curr = app_pts.begin(); auto p_curr = points.begin();
auto end_pts = app_pts.end(); auto end_pts = points.end();
auto p_next = p_curr + 1; auto p_next = p_curr + 1;
do do {
{ QPointF p1(p_curr->x(), p_curr->y());
QPointF p1(p_curr->first, p_curr->second); QPointF p2(p_next->x(), p_next->y());
QPointF p2(p_next->first, p_next->second);
this->qp->drawLine(p1, p2); this->qp->drawLine(p1, p2);
p_curr++; ++p_curr;
p_next++; ++p_next;
} while (p_next != end_pts); } while (p_next != end_pts);
}; };
if (this->clippingRect.isValid()) if (this->clippingRect.isValid()) {
{ if (this->clippingRect.contains(qbb)) {
std::vector<X_monotone_curve_2> visibleParts; paint_curve(curve);
if (this->clippingRect.contains(qbb)) return *this;
visibleParts.push_back(curve);
else
visibleParts = this->visibleParts(curve);
for (auto& visiblePart : visibleParts) paintCurve(visiblePart);
} }
else std::vector<X_monotone_curve_2> parts;
{ // draw the whole curve parts = this->visibleParts(curve);
paintCurve(curve); for (auto& part : parts) paint_curve(part);
return *this;
} }
// draw the whole curve
paint_curve(curve);
return *this; return *this;
} }
// Instantiation of Arr_Bezier_traits_2 // Specialization of `ArrangementPainterOstream` for the Bezier traits.
template < template <typename RatKernel, typename AlgKernel, typename NtTraits,
typename RatKernel, typename AlgKernel, typename NtTraits,
typename BoundingTraits> typename BoundingTraits>
std::vector<std::pair<double, double>> std::vector<std::pair<double, double>>
ArrangementPainterOstream<CGAL::Arr_Bezier_curve_traits_2< ArrangementPainterOstream
RatKernel, AlgKernel, NtTraits, <CGAL::Arr_Bezier_curve_traits_2<RatKernel, AlgKernel, NtTraits,
BoundingTraits>>::getPoints(const X_monotone_curve_2& curve) BoundingTraits>>::
{ getPoints(const X_monotone_curve_2& curve) {
std::pair<double, double> param_range = curve.parameter_range(); std::pair<double, double> param_range = curve.parameter_range();
auto&& supporting_curve = curve.supporting_curve(); auto&& supporting_curve = curve.supporting_curve();
@ -250,12 +228,13 @@ ArrangementPainterOstream<CGAL::Arr_Bezier_curve_traits_2<
return sampled_points; return sampled_points;
} }
template < //
typename RatKernel, typename AlgKernel, typename NtTraits, template <typename RatKernel, typename AlgKernel, typename NtTraits,
typename BoundingTraits> typename BoundingTraits>
auto ArrangementPainterOstream<CGAL::Arr_Bezier_curve_traits_2< auto ArrangementPainterOstream
RatKernel, AlgKernel, NtTraits, <CGAL::Arr_Bezier_curve_traits_2<RatKernel, AlgKernel, NtTraits,
BoundingTraits>>::operator<<(const X_monotone_curve_2& curve) BoundingTraits>>::
operator<<(const X_monotone_curve_2& curve)
-> ArrangementPainterOstream<Traits>& -> ArrangementPainterOstream<Traits>&
{ {
auto sampled_points = this->getPoints(curve); auto sampled_points = this->getPoints(curve);
@ -270,57 +249,45 @@ auto ArrangementPainterOstream<CGAL::Arr_Bezier_curve_traits_2<
return *this; return *this;
} }
// Instantiation of Arr_linear_traits_2 // Specialization of `ArrangementPainterOstream` for the linear traits.
template <typename Kernel_> template <typename Kernel_>
ArrangementPainterOstream<CGAL::Arr_linear_traits_2<Kernel_>>& ArrangementPainterOstream<CGAL::Arr_linear_traits_2<Kernel_>>&
ArrangementPainterOstream<CGAL::Arr_linear_traits_2<Kernel_>>::operator<<( ArrangementPainterOstream<CGAL::Arr_linear_traits_2<Kernel_>>::
const X_monotone_curve_2& curve) operator<<(const X_monotone_curve_2& curve) {
{ if (curve.is_segment()) {
if (curve.is_segment())
{
Segment_2 seg = curve.segment(); Segment_2 seg = curve.segment();
// skip segments outside our view // skip segments outside our view
QRectF seg_bb = this->convert(seg.bbox()); QRectF seg_bb = this->convert(seg.bbox());
if ( if (this->clippingRect.isValid() &&
this->clippingRect.isValid() &&
! this->clippingRect.intersects(seg_bb) && ! this->clippingRect.intersects(seg_bb) &&
(!seg.is_horizontal() && !seg.is_vertical())) (!seg.is_horizontal() && !seg.is_vertical()))
{ return *this; } return *this;
this->painterOstream << seg; this->painterOstream << seg;
} }
else if (curve.is_ray()) else if (curve.is_ray()) {
{
Ray_2 ray = curve.ray(); Ray_2 ray = curve.ray();
QLineF qseg = this->convert(ray); QLineF qseg = this->convert(ray);
if (qseg.isNull()) if (qseg.isNull()) return *this; // it's out of view
{ // it's out of view
return *this;
}
Segment_2 seg = this->convert(qseg); Segment_2 seg = this->convert(qseg);
this->painterOstream << seg; this->painterOstream << seg;
} }
else // curve.is_line( ) else {
{ // curve.is_line( )
Line_2 line = curve.line(); Line_2 line = curve.line();
QLineF qseg = this->convert(line); QLineF qseg = this->convert(line);
if (qseg.isNull()) if (qseg.isNull()) return *this; // it's out of view
{ // it's out of view
return *this;
}
Segment_2 seg = this->convert(qseg); Segment_2 seg = this->convert(qseg);
this->painterOstream << seg; this->painterOstream << seg;
} }
return *this; return *this;
} }
// Instantiation of Arr_algebraic_segment_traits_2 // Specialization of `ArrangementPainterOstream` for the algebraic traits.
template <typename Traits> template <typename Traits>
static bool lies_on_border( static bool lies_on_border(const ArrangementPainterOstream<Traits>* apo,
const ArrangementPainterOstream<Traits>* apo, const QPointF& point) const QPointF& point) {
{
QGraphicsView* view = apo->getScene()->views().first(); QGraphicsView* view = apo->getScene()->views().first();
qreal width = view->width(); qreal width = view->width();
qreal height = view->height(); qreal height = view->height();
@ -329,26 +296,27 @@ static bool lies_on_border(
std::abs(point.y() - height) < tol || point.y() < tol; std::abs(point.y() - height) < tol || point.y() < tol;
} }
//
template <typename Coefficient_> template <typename Coefficient_>
void ArrangementPainterOstream< void
CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>::remapFacadePainter() ArrangementPainterOstream<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>::
{ remapFacadePainter()
this->qp->setTransform(this->getPointsListMapping()); { this->qp->setTransform(this->getPointsListMapping()); }
}
//
template <typename Coefficient_> template <typename Coefficient_>
QTransform ArrangementPainterOstream< QTransform
CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>::getPointsListMapping() ArrangementPainterOstream<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>::
{ getPointsListMapping() {
auto worldTransform = this->qp->transform(); auto worldTransform = this->qp->transform();
return this->getPointsListMapping(worldTransform); return this->getPointsListMapping(worldTransform);
} }
//
template <typename Coefficient_> template <typename Coefficient_>
QTransform QTransform
ArrangementPainterOstream<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>:: ArrangementPainterOstream<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>::
getPointsListMapping(const QTransform& worldTransform) getPointsListMapping(const QTransform& worldTransform) {
{
auto view = this->getView(); auto view = this->getView();
QRectF viewport = this->viewportRect(); QRectF viewport = this->viewportRect();
@ -371,11 +339,11 @@ ArrangementPainterOstream<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>::
return QTransform{m11, m12, m21, m22, dx, dy}; return QTransform{m11, m12, m21, m22, dx, dy};
} }
//
template <typename Coefficient_> template <typename Coefficient_>
auto ArrangementPainterOstream<CGAL::Arr_algebraic_segment_traits_2< auto ArrangementPainterOstream
Coefficient_>>::getPointsList(const X_monotone_curve_2& curve) <CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>::
-> std::vector<Coord_vec_2> getPointsList(const X_monotone_curve_2& curve) -> std::vector<Coord_vec_2> {
{
typedef Curve_renderer_facade<CKvA_2> Facade; typedef Curve_renderer_facade<CKvA_2> Facade;
typedef std::pair<double, double> Coord_2; typedef std::pair<double, double> Coord_2;
typedef std::vector<Coord_2> Coord_vec_2; typedef std::vector<Coord_2> Coord_vec_2;
@ -385,11 +353,11 @@ auto ArrangementPainterOstream<CGAL::Arr_algebraic_segment_traits_2<
return points; return points;
} }
//
template <typename Coefficient_> template <typename Coefficient_>
ArrangementPainterOstream<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>& ArrangementPainterOstream<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>&
ArrangementPainterOstream<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>:: ArrangementPainterOstream<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>::
operator<<(const X_monotone_curve_2& curve) operator<<(const X_monotone_curve_2& curve) {
{
this->qp->save(); this->qp->save();
this->remapFacadePainter(); this->remapFacadePainter();
this->paintCurve(curve); this->paintCurve(curve);
@ -397,20 +365,19 @@ operator<<(const X_monotone_curve_2& curve)
return *this; return *this;
} }
//
template <typename Coefficient_> template <typename Coefficient_>
void ArrangementPainterOstream<CGAL::Arr_algebraic_segment_traits_2< void ArrangementPainterOstream
Coefficient_>>::paintCurve(const X_monotone_curve_2& curve) <CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>::
{ paintCurve(const X_monotone_curve_2& curve) {
std::vector<Coord_vec_2> points = this->getPointsList(curve); std::vector<Coord_vec_2> points = this->getPointsList(curve);
for (auto& vec : points) for (auto& vec : points) {
{
auto vit = vec.begin(); auto vit = vec.begin();
QPainterPath path; QPainterPath path;
QPointF qpt(vit->first, vit->second); QPointF qpt(vit->first, vit->second);
path.moveTo(qpt); path.moveTo(qpt);
for (auto& vit : vec) for (auto& vit : vec) {
{
QPointF qpt_new = QPointF(vit.first, vit.second); QPointF qpt_new = QPointF(vit.first, vit.second);
if (lies_on_border(this, qpt) && lies_on_border(this, qpt_new)) if (lies_on_border(this, qpt) && lies_on_border(this, qpt_new))
path.moveTo(qpt_new); path.moveTo(qpt_new);
@ -422,10 +389,10 @@ void ArrangementPainterOstream<CGAL::Arr_algebraic_segment_traits_2<
} }
} }
//
template <typename Coefficient_> template <typename Coefficient_>
void ArrangementPainterOstream< void ArrangementPainterOstream
CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>::setupFacade() <CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>::setupFacade() {
{
typedef Curve_renderer_facade<CKvA_2> Facade; typedef Curve_renderer_facade<CKvA_2> Facade;
QGraphicsView* view = this->getView(); QGraphicsView* view = this->getView();
QRectF viewport = this->viewportRect(); QRectF viewport = this->viewportRect();
@ -433,18 +400,16 @@ void ArrangementPainterOstream<
Facade::setup(bbox, view->width(), view->height()); Facade::setup(bbox, view->width(), view->height());
} }
// Instantiation of Arr_rational_function_traits_2 // Specialization of `ArrangementPainterOstream` for Arr_rational_function_traits_2
template <typename T>
template <class T>
constexpr const T& clamp(const T& v, const T& lo, const T& hi) constexpr const T& clamp(const T& v, const T& lo, const T& hi)
{ { return (v < lo) ? lo : (hi < v) ? hi : v; }
return (v < lo) ? lo : (hi < v) ? hi : v;
}
//
template <typename AlgebraicKernel_d_1_> template <typename AlgebraicKernel_d_1_>
auto ArrangementPainterOstream<CGAL::Arr_rational_function_traits_2< auto ArrangementPainterOstream
AlgebraicKernel_d_1_>>::operator<<(const X_monotone_curve_2& curve) -> Self& <CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1_>>::
{ operator<<(const X_monotone_curve_2& curve) -> Self& {
QPainterPath painterPath; QPainterPath painterPath;
const QRectF viewport = this->viewportRect(); const QRectF viewport = this->viewportRect();
// overshoot so that the slope would be more accurate // overshoot so that the slope would be more accurate
@ -458,8 +423,7 @@ auto ArrangementPainterOstream<CGAL::Arr_rational_function_traits_2<
// TODO: this is ugly! clean up these conditions // TODO: this is ugly! clean up these conditions
auto path_filler = [&](double x, double y) { auto path_filler = [&](double x, double y) {
if (y > max_y || y < min_y) if (y > max_y || y < min_y) {
{
double x_ = x; double x_ = x;
double y_ = clamp(y, min_y, max_y); double y_ = clamp(y, min_y, max_y);
@ -467,8 +431,8 @@ auto ArrangementPainterOstream<CGAL::Arr_rational_function_traits_2<
if (!disconnected) { painterPath.lineTo(x_, y_); } if (!disconnected) { painterPath.lineTo(x_, y_); }
// connect between two out of range points when they cross different // connect between two out of range points when they cross different
// boundaries // boundaries
else if ( else if ((last_y == min_y && y_ == max_y) ||
(last_y == min_y && y_ == max_y) || (last_y == max_y && y_ == min_y)) (last_y == max_y && y_ == min_y))
{ {
painterPath.moveTo(last_x, last_y); painterPath.moveTo(last_x, last_y);
painterPath.lineTo(x_, y_); painterPath.lineTo(x_, y_);
@ -478,15 +442,12 @@ auto ArrangementPainterOstream<CGAL::Arr_rational_function_traits_2<
disconnected = true; disconnected = true;
} }
else if (first_point) else if (first_point) {
{
painterPath.moveTo(x, y); painterPath.moveTo(x, y);
disconnected = false; disconnected = false;
} }
else else {
{ if (disconnected) {
if (disconnected)
{
painterPath.moveTo(last_x, last_y); painterPath.moveTo(last_x, last_y);
disconnected = false; disconnected = false;
} }
@ -501,11 +462,11 @@ auto ArrangementPainterOstream<CGAL::Arr_rational_function_traits_2<
return *this; return *this;
} }
//
template <typename AlgebraicKernel_d_1_> template <typename AlgebraicKernel_d_1_>
auto ArrangementPainterOstream<CGAL::Arr_rational_function_traits_2< auto ArrangementPainterOstream
AlgebraicKernel_d_1_>>::getPointsList(const X_monotone_curve_2& curve) <CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1_>>::
-> std::vector<Coord_vec_2> getPointsList(const X_monotone_curve_2& curve) -> std::vector<Coord_vec_2> {
{
std::vector<Coord_vec_2> points_list; std::vector<Coord_vec_2> points_list;
Coord_vec_2* cur_list = nullptr; Coord_vec_2* cur_list = nullptr;
@ -521,15 +482,13 @@ auto ArrangementPainterOstream<CGAL::Arr_rational_function_traits_2<
// TODO: this is ugly! clean up these conditions // TODO: this is ugly! clean up these conditions
auto path_filler = [&](double x, double y) { auto path_filler = [&](double x, double y) {
if (y > max_y || y < min_y) if (y > max_y || y < min_y) {
{
double x_ = x; double x_ = x;
double y_ = clamp(y, min_y, max_y); double y_ = clamp(y, min_y, max_y);
if (!disconnected) if (!disconnected) cur_list->push_back({x_, y_});
cur_list->push_back({x_, y_}); else if ((last_y == min_y && y_ == max_y) ||
else if ( (last_y == max_y && y_ == min_y))
(last_y == min_y && y_ == max_y) || (last_y == max_y && y_ == min_y))
{ {
cur_list->push_back({last_x, last_y}); cur_list->push_back({last_x, last_y});
cur_list->push_back({x_, y_}); cur_list->push_back({x_, y_});
@ -539,10 +498,8 @@ auto ArrangementPainterOstream<CGAL::Arr_rational_function_traits_2<
disconnected = true; disconnected = true;
} }
else else {
{ if (disconnected) {
if (disconnected)
{
points_list.emplace_back(); points_list.emplace_back();
cur_list = &points_list.back(); cur_list = &points_list.back();
if (!first_point) cur_list->push_back({last_x, last_y}); if (!first_point) cur_list->push_back({last_x, last_y});
@ -557,12 +514,12 @@ auto ArrangementPainterOstream<CGAL::Arr_rational_function_traits_2<
return points_list; return points_list;
} }
//
template <typename AlgebraicKernel_d_1_> template <typename AlgebraicKernel_d_1_>
template <typename Lambda> template <typename Lambda>
void ArrangementPainterOstream< void ArrangementPainterOstream
CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1_>>:: <CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1_>>::
sample_points(const X_monotone_curve_2& curve, Lambda&& lambda) sample_points(const X_monotone_curve_2& curve, Lambda&& lambda) {
{
// TODO: cache maximum and minimal points for each curve, and include them // TODO: cache maximum and minimal points for each curve, and include them
// in the sampled points // in the sampled points
const QRectF viewport = this->viewportRect(); const QRectF viewport = this->viewportRect();
@ -572,17 +529,14 @@ void ArrangementPainterOstream<
auto&& numer = curve._f.numer(); auto&& numer = curve._f.numer();
auto&& denom = curve._f.denom(); auto&& denom = curve._f.denom();
auto eval_at = [&](auto&& x) { auto eval_at = [&](auto&& x) { return numer.evaluate(x) / denom.evaluate(x); };
return numer.evaluate(x) / denom.evaluate(x);
};
if ( // be conservative and prefer this branch to avoid zero division // be conservative and prefer this branch to avoid zero division
curve.left_parameter_space_in_x() == ARR_INTERIOR && if (curve.left_parameter_space_in_x() == ARR_INTERIOR &&
curve.left_x().to_interval().second >= min_x) curve.left_x().to_interval().second >= min_x)
{ {
min_x = curve.left_x().to_interval().second; min_x = curve.left_x().to_interval().second;
switch (curve.left_parameter_space_in_y()) switch (curve.left_parameter_space_in_y()) {
{
case ARR_INTERIOR: { case ARR_INTERIOR: {
auto left_pt = curve.left().to_double(); auto left_pt = curve.left().to_double();
lambda(min_x, left_pt.second); lambda(min_x, left_pt.second);
@ -601,26 +555,19 @@ void ArrangementPainterOstream<
} }
} }
} }
else if ( else if (curve.right_parameter_space_in_x() != ARR_INTERIOR ||
curve.right_parameter_space_in_x() != ARR_INTERIOR ||
min_x < curve.right_x().to_interval().first) min_x < curve.right_x().to_interval().first)
{
lambda(min_x, CGAL::to_double(eval_at(Rational{min_x}))); lambda(min_x, CGAL::to_double(eval_at(Rational{min_x})));
} else return; // outside of viewport
else // outside of viewport
{
return;
}
std::pair<double, double> last_pt; std::pair<double, double> last_pt;
if ( // be conservative and prefer this branch to avoid zero division // be conservative and prefer this branch to avoid zero division
curve.right_parameter_space_in_x() == ARR_INTERIOR && if (curve.right_parameter_space_in_x() == ARR_INTERIOR &&
curve.right_x().to_interval().first <= max_x) curve.right_x().to_interval().first <= max_x)
{ {
max_x = curve.right_x().to_interval().first; max_x = curve.right_x().to_interval().first;
switch (curve.right_parameter_space_in_y()) switch (curve.right_parameter_space_in_y()) {
{
case ARR_INTERIOR: { case ARR_INTERIOR: {
last_pt = {max_x, curve.right().to_double().second}; last_pt = {max_x, curve.right().to_double().second};
break; break;
@ -633,19 +580,12 @@ void ArrangementPainterOstream<
last_pt = {max_x, -std::numeric_limits<double>::infinity()}; last_pt = {max_x, -std::numeric_limits<double>::infinity()};
break; break;
} }
default: { default: { CGAL_error(); }
CGAL_error();
}
} }
} }
else if (max_x > min_x) else if (max_x > min_x)
{
last_pt = {max_x, CGAL::to_double(eval_at(Rational{max_x}))}; last_pt = {max_x, CGAL::to_double(eval_at(Rational{max_x}))};
} else return; // outside of viewport
else // outside of viewport
{
return;
}
static constexpr int dx_pixel = 1; static constexpr int dx_pixel = 1;
static constexpr int min_num_points = 20; static constexpr int min_num_points = 20;

View File

@ -101,10 +101,8 @@ static constexpr TraitsType enumFromArrType()
} }
template <class Lambda, class Types = DemoTypes> template <class Lambda, class Types = DemoTypes>
static void visitArrangementType(TraitsType tt, Lambda&& lambda) static void visitArrangementType(TraitsType tt, Lambda&& lambda) {
{ switch (tt) {
switch (tt)
{
case TraitsType::SEGMENT_TRAITS: case TraitsType::SEGMENT_TRAITS:
lambda(TypeHolder<typename Types::Seg_arr>{}); lambda(TypeHolder<typename Types::Seg_arr>{});
break; break;

View File

@ -13,7 +13,7 @@ if(POLICY CMP0071)
endif() endif()
find_package(CGAL REQUIRED OPTIONAL_COMPONENTS Core Qt5) find_package(CGAL REQUIRED OPTIONAL_COMPONENTS Core Qt5)
find_package(Qt5 QUIET COMPONENTS Gui Widgets) find_package(Qt5 QUIET COMPONENTS Widgets)
if (CGAL_Qt5_FOUND AND Qt5_FOUND) if (CGAL_Qt5_FOUND AND Qt5_FOUND)
include(${CGAL_USE_FILE}) include(${CGAL_USE_FILE})
@ -110,7 +110,7 @@ if (CGAL_Qt5_FOUND AND Qt5_FOUND)
${CGAL_Qt5_RESOURCE_FILES} ${CGAL_Qt5_RESOURCE_FILES}
${CGAL_Qt5_MOC_FILES}) ${CGAL_Qt5_MOC_FILES})
target_link_libraries(arrangement_2 PRIVATE Qt5::Core Qt5::Gui Qt5::Widgets) target_link_libraries(arrangement_2 PRIVATE Qt5::Widgets)
target_link_libraries(arrangement_2 PRIVATE CGAL::CGAL CGAL::CGAL_Qt5) target_link_libraries(arrangement_2 PRIVATE CGAL::CGAL CGAL::CGAL_Qt5)
if(CGAL_Core_FOUND) if(CGAL_Core_FOUND)
target_link_libraries(arrangement_2 PRIVATE CGAL::CGAL_Core) target_link_libraries(arrangement_2 PRIVATE CGAL::CGAL_Core)

View File

@ -18,8 +18,10 @@
#include <string> #include <string>
template <typename Traits> template <typename Traits>
class Conic_reader class Conic_reader {
{ private:
const Traits& m_traits;
public: public:
typedef typename Traits::Curve_2 Curve_2; typedef typename Traits::Curve_2 Curve_2;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2; typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
@ -31,6 +33,10 @@ public:
typedef typename Traits::Rat_segment_2 Rat_segment_2; typedef typename Traits::Rat_segment_2 Rat_segment_2;
typedef typename Traits::Rat_circle_2 Rat_circle_2; typedef typename Traits::Rat_circle_2 Rat_circle_2;
// Cnstruct from traits.
Conic_reader(const Traits& traits) : m_traits(traits) {}
//
template <class OutputIterator> template <class OutputIterator>
int read_data(std::ifstream& inp, OutputIterator curves_out, int read_data(std::ifstream& inp, OutputIterator curves_out,
CGAL::Bbox_2& bbox) CGAL::Bbox_2& bbox)
@ -49,7 +55,7 @@ public:
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
if (read_curve(inp, cv)) { if (read_curve(inp, cv)) {
++curves_out = cv; ++curves_out = cv;
CGAL::Bbox_2 curve_bbox = cv.bbox(); CGAL::Bbox_2 curve_bbox = m_traits.construct_bbox_2_object()(cv);
if (i == 0) bbox = curve_bbox; if (i == 0) bbox = curve_bbox;
else bbox = bbox + curve_bbox; else bbox = bbox + curve_bbox;
} }
@ -58,8 +64,9 @@ public:
} }
/*! */ /*! */
bool read_curve(std::ifstream & is, Curve_2 & cv) bool read_curve(std::ifstream& is, Curve_2& cv) {
{ auto ctr_cv = m_traits.construct_curve_2_object();
// Read a line from the input file. // Read a line from the input file.
char one_line[128]; char one_line[128];
@ -71,8 +78,7 @@ public:
str_line >> type; str_line >> type;
if (type == 's' || type == 'S') if (type == 's' || type == 'S') {
{
// Construct a line segment. The line should have the format: // Construct a line segment. The line should have the format:
// s <x1> <y1> <x2> <y2> // s <x1> <y1> <x2> <y2>
// where (x1, y1), (x2, y2) are the endpoints of a segment. // where (x1, y1), (x2, y2) are the endpoints of a segment.
@ -92,10 +98,9 @@ public:
Rat_point_2 p1(x1, y1), p2(x2, y2); Rat_point_2 p1(x1, y1), p2(x2, y2);
Rat_segment_2 seg(p1, p2); Rat_segment_2 seg(p1, p2);
cv = Curve_2 (seg); cv = ctr_cv(seg);
} }
else if (type == 'c' || type == 'C') else if (type == 'c' || type == 'C') {
{
// Construct a full circle. The line should have the format: // Construct a full circle. The line should have the format:
// c <x0> <y0> <R_sq> // c <x0> <y0> <R_sq>
// where (x0, y0) is the center of the circle and R_sq is its squared // where (x0, y0) is the center of the circle and R_sq is its squared
@ -107,10 +112,9 @@ public:
Rat_point_2 p0(x0, y0); Rat_point_2 p0(x0, y0);
Rat_circle_2 circ(p0, R_sq); Rat_circle_2 circ(p0, R_sq);
cv = Curve_2 (circ); cv = ctr_cv(circ);
} }
else if (type == 't' || type == 'T') else if (type == 't' || type == 'T') {
{
// Construct a circular arc. The line should have the format: // Construct a circular arc. The line should have the format:
// t <x1> <y1> <x2> <y2> <x3> <y3> // t <x1> <y1> <x2> <y2> <x3> <y3>
// where (x1, y1), (x2, y2) and (x3, y3) define the arc. // where (x1, y1), (x2, y2) and (x3, y3) define the arc.
@ -120,10 +124,9 @@ public:
Rat_point_2 p1(x1, y1), p2(x2, y2), p3(x3, y3); Rat_point_2 p1(x1, y1), p2(x2, y2), p3(x3, y3);
cv = Curve_2 (p1, p2, p3); cv = ctr_cv(p1, p2, p3);
} }
else if (type == 'f' || type == 'F') else if (type == 'f' || type == 'F') {
{
// Construct a full conic curve. The line should have the format: // Construct a full conic curve. The line should have the format:
// c <r> <s> <t> <u> <v> <w> // c <r> <s> <t> <u> <v> <w>
// where r, s, t, u, v, w define the conic equation. // where r, s, t, u, v, w define the conic equation.
@ -131,10 +134,9 @@ public:
str_line >> r >> s >> t >> u >> v >> w; str_line >> r >> s >> t >> u >> v >> w;
cv = Curve_2 (r, s, t, u, v, w); cv = ctr_cv(r, s, t, u, v, w);
} }
else if (type == 'a' || type == 'A') else if (type == 'a' || type == 'A') {
{
// Construct a conic arc. The line should have the format: // Construct a conic arc. The line should have the format:
// c <r> <s> <t> <u> <v> <w> <orient> <x1> <y1> <x2> <y2> // c <r> <s> <t> <u> <v> <w> <orient> <x1> <y1> <x2> <y2>
// where r, s, t, u, v, w define the conic equation, while (x1, y1) // where r, s, t, u, v, w define the conic equation, while (x1, y1)
@ -148,12 +150,9 @@ public:
CGAL::Orientation orient; CGAL::Orientation orient;
str_line >> i_orient; str_line >> i_orient;
if (i_orient > 0) if (i_orient > 0) orient = CGAL::COUNTERCLOCKWISE;
orient = CGAL::COUNTERCLOCKWISE; else if (i_orient < 0) orient = CGAL::CLOCKWISE;
else if (i_orient < 0) else orient = CGAL::COLLINEAR;
orient = CGAL::CLOCKWISE;
else
orient = CGAL::COLLINEAR;
// Read the end points of the arc and create it. // Read the end points of the arc and create it.
// Notice we read the coordinates as strings, then we convert them to // Notice we read the coordinates as strings, then we convert them to
@ -175,10 +174,9 @@ public:
Point_2 ps (x1, y1); Point_2 ps (x1, y1);
Point_2 pt (x2, y2); Point_2 pt (x2, y2);
cv = Curve_2 (r, s, t, u, v, w, orient, ps ,pt); cv = ctr_cv(r, s, t, u, v, w, orient, ps ,pt);
} }
else if (type == 'q' || type == 'Q') else if (type == 'q' || type == 'Q') {
{
// Construct a circular arc. The line should have the format: // Construct a circular arc. The line should have the format:
// t <x1> <y1> <x2> <y2> <x3> <y3> <x4> <y4> <x5> <y5> // t <x1> <y1> <x2> <y2> <x3> <y3> <x4> <y4> <x5> <y5>
// where (x1, y1), (x2, y2), (x3, y3), (x4, y4) and (x5, y5) define the // where (x1, y1), (x2, y2), (x3, y3), (x4, y4) and (x5, y5) define the
@ -189,10 +187,9 @@ public:
Rat_point_2 p1(x1, y1), p2(x2, y2), p3(x3, y3), p4(x4, y4), p5(x5, y5); Rat_point_2 p1(x1, y1), p2(x2, y2), p3(x3, y3), p4(x4, y4), p5(x5, y5);
cv = Curve_2 (p1, p2, p3, p4, p5); cv = ctr_cv(p1, p2, p3, p4, p5);
} }
else if(type == 'e' || type == 'E') else if(type == 'e' || type == 'E') {
{
// Construct a full ellipse. The line should have the format: // Construct a full ellipse. The line should have the format:
// e <r1_1> <r2_1> <x0_1> <y0_1> // raddi and center of ellipse // e <r1_1> <r2_1> <x0_1> <y0_1> // raddi and center of ellipse
@ -211,10 +208,9 @@ public:
V = -2 * sqr_r1 * y0; V = -2 * sqr_r1 * y0;
W = sqr_r2*x0*x0 + sqr_r1*y0*y0 - sqr_r1*sqr_r2; W = sqr_r2*x0*x0 + sqr_r1*y0*y0 - sqr_r1*sqr_r2;
cv = Curve_2 (R, S, T, U, V, W); cv = ctr_cv(R, S, T, U, V, W);
} }
else else {
{
std::cerr << "Illegal conic type specification: " << type << "." std::cerr << "Illegal conic type specification: " << type << "."
<< std::endl; << std::endl;
return false; return false;
@ -224,8 +220,7 @@ public:
} }
/*! */ /*! */
void skip_comments( std::ifstream& is, char* one_line ) void skip_comments(std::ifstream& is, char* one_line) {
{
while (!is.eof()) { while (!is.eof()) {
is.getline(one_line, 128); is.getline(one_line, 128);
if (one_line[0] != '#') break; if (one_line[0] != '#') break;
@ -234,13 +229,10 @@ public:
// should probably change class name since it reads and writes // should probably change class name since it reads and writes
template <typename InputIterator> template <typename InputIterator>
int write_data(std::ofstream & ofs, InputIterator begin_, InputIterator end_) int write_data(std::ofstream& ofs, InputIterator begin_, InputIterator end_) {
{
ofs << std::distance(begin_, end_) << std::endl; ofs << std::distance(begin_, end_) << std::endl;
for (auto it = begin_; it != end_; ++it) for (auto it = begin_; it != end_; ++it) {
{ if (it->is_full_conic()) {
if (it->is_full_conic())
{
ofs << "F "; ofs << "F ";
ofs << it->r() << " "; ofs << it->r() << " ";
ofs << it->s() << " "; ofs << it->s() << " ";
@ -250,15 +242,13 @@ public:
ofs << it->w() << " "; ofs << it->w() << " ";
ofs << std::endl; ofs << std::endl;
} }
else if (it->orientation() == CGAL::COLLINEAR) else if (it->orientation() == CGAL::COLLINEAR) {
{
ofs << "S "; ofs << "S ";
ofs << it->source() << " "; ofs << it->source() << " ";
ofs << it->target() << " "; ofs << it->target() << " ";
ofs << std::endl; ofs << std::endl;
} }
else else {
{
ofs << "A "; ofs << "A ";
ofs << it->r() << " "; ofs << it->r() << " ";
ofs << it->s() << " "; ofs << it->s() << " ";
@ -266,12 +256,9 @@ public:
ofs << it->u() << " "; ofs << it->u() << " ";
ofs << it->v() << " "; ofs << it->v() << " ";
ofs << it->w() << " "; ofs << it->w() << " ";
if (it->orientation() == CGAL::COUNTERCLOCKWISE) if (it->orientation() == CGAL::COUNTERCLOCKWISE) ofs << "1 ";
ofs << "1 "; else if (it->orientation() == CGAL::CLOCKWISE) ofs << "-1 ";
else if (it->orientation() == CGAL::CLOCKWISE) else ofs << "0 ";
ofs << "-1 ";
else
ofs << "0 ";
ofs << it->source() << " "; ofs << it->source() << " ";
ofs << it->target() << " "; ofs << it->target() << " ";
ofs << std::endl; ofs << std::endl;

View File

@ -18,25 +18,29 @@
#include <limits> #include <limits>
namespace CGAL namespace CGAL {
{ namespace Qt {
namespace Qt
{
template <class ArrTraits> //
CurveGraphicsItem<ArrTraits>::CurveGraphicsItem() : template <typename GeometryTraits>
bb(), m_edgeColor(::Qt::red), m_edgeWidth(2), CurveGraphicsItem<GeometryTraits>::CurveGraphicsItem(const Traits& traits) :
m_vertexColor(::Qt::red), m_vertexRadius(1) m_traits(traits),
bb(),
m_edgeColor(::Qt::red),
m_edgeWidth(2),
m_vertexColor(::Qt::red),
m_vertexRadius(1)
{ {
this->setZValue(4); this->setZValue(4);
this->pointsGraphicsItem.setParentItem(this); this->pointsGraphicsItem.setParentItem(this);
} }
template <class ArrTraits> //
void CurveGraphicsItem<ArrTraits>::paint( template <typename GeometryTraits>
QPainter* painter, const QStyleOptionGraphicsItem* /* option */, void CurveGraphicsItem<GeometryTraits>::
QWidget* /* widget */) paint(QPainter* painter,
{ const QStyleOptionGraphicsItem* /* option */,
QWidget* /* widget */) {
// draw the curves // draw the curves
QPen edgesPen(this->m_edgeColor, this->m_edgeWidth); QPen edgesPen(this->m_edgeColor, this->m_edgeWidth);
edgesPen.setCosmetic(true); edgesPen.setCosmetic(true);
@ -48,9 +52,9 @@ void CurveGraphicsItem<ArrTraits>::paint(
for (auto& curve : this->curves) { painterOstream << curve; } for (auto& curve : this->curves) { painterOstream << curve; }
} }
template <class ArrTraits> //
QRectF CurveGraphicsItem<ArrTraits>::boundingRect() const template <typename GeometryTraits>
{ QRectF CurveGraphicsItem<GeometryTraits>::boundingRect() const {
auto viewport = this->viewportRect(); auto viewport = this->viewportRect();
qreal xmin = viewport.left(); qreal xmin = viewport.left();
qreal ymin = viewport.top(); qreal ymin = viewport.top();
@ -60,8 +64,7 @@ QRectF CurveGraphicsItem<ArrTraits>::boundingRect() const
if (this->bb.ymin() > ymin) ymin = this->bb.ymin(); if (this->bb.ymin() > ymin) ymin = this->bb.ymin();
if (this->bb.xmax() < xmax) xmax = this->bb.xmax(); if (this->bb.xmax() < xmax) xmax = this->bb.xmax();
if (this->bb.ymax() < ymax) ymax = this->bb.ymax(); if (this->bb.ymax() < ymax) ymax = this->bb.ymax();
if (xmin > xmax || ymin > ymax) if (xmin > xmax || ymin > ymax) {
{
xmin = 0; xmin = 0;
xmax = 0; xmax = 0;
ymin = 0; ymin = 0;
@ -70,93 +73,92 @@ QRectF CurveGraphicsItem<ArrTraits>::boundingRect() const
return {QPointF{xmin, ymin}, QPointF{xmax, ymax}}; return {QPointF{xmin, ymin}, QPointF{xmax, ymax}};
} }
template <class ArrTraits> //
void CurveGraphicsItem<ArrTraits>::insert(const X_monotone_curve_2& curve) template <typename GeometryTraits>
{ void CurveGraphicsItem<GeometryTraits>::insert(const X_monotone_curve_2& curve) {
this->curves.push_back(curve); this->curves.push_back(curve);
this->updateBoundingBox(); this->updateBoundingBox();
} }
template <class ArrTraits> //
void CurveGraphicsItem<ArrTraits>::insert(const Point_2& point) template <typename GeometryTraits>
{ void CurveGraphicsItem<GeometryTraits>::insert(const Point_2& point) {
this->pointsGraphicsItem.insert(point); this->pointsGraphicsItem.insert(point);
this->updateBoundingBox(); this->updateBoundingBox();
} }
template <class ArrTraits> //
void CurveGraphicsItem<ArrTraits>::clear() template <typename GeometryTraits>
{ void CurveGraphicsItem<GeometryTraits>::clear() {
this->curves.clear(); this->curves.clear();
this->pointsGraphicsItem.clear(); this->pointsGraphicsItem.clear();
this->updateBoundingBox(); this->updateBoundingBox();
} }
template <class ArrTraits> //
void CurveGraphicsItem<ArrTraits>::modelChanged() template <typename GeometryTraits>
{ void CurveGraphicsItem<GeometryTraits>::modelChanged() {
this->updateBoundingBox(); this->updateBoundingBox();
this->update(); this->update();
} }
template <class ArrTraits> //
const QColor& CurveGraphicsItem<ArrTraits>::edgeColor() const template <typename GeometryTraits>
{ const QColor& CurveGraphicsItem<GeometryTraits>::edgeColor() const {
return this->m_edgeColor; return this->m_edgeColor;
} }
template <class ArrTraits> //
void CurveGraphicsItem<ArrTraits>::setEdgeColor(const QColor& color) template <typename GeometryTraits>
{ void CurveGraphicsItem<GeometryTraits>::setEdgeColor(const QColor& color) {
this->m_edgeColor = color; this->m_edgeColor = color;
} }
template <class ArrTraits> //
int CurveGraphicsItem<ArrTraits>::edgeWidth() const template <typename GeometryTraits>
{ int CurveGraphicsItem<GeometryTraits>::edgeWidth() const {
return this->m_edgeWidth; return this->m_edgeWidth;
} }
template <class ArrTraits> //
void CurveGraphicsItem<ArrTraits>::setEdgeWidth(int width) template <typename GeometryTraits>
{ void CurveGraphicsItem<GeometryTraits>::setEdgeWidth(int width) {
this->m_edgeWidth = width; this->m_edgeWidth = width;
} }
template <class ArrTraits> //
const QColor& CurveGraphicsItem<ArrTraits>::vertexColor() const template <typename GeometryTraits>
{ const QColor& CurveGraphicsItem<GeometryTraits>::vertexColor() const {
return this->m_vertexColor; return this->m_vertexColor;
} }
template <class ArrTraits> //
void CurveGraphicsItem<ArrTraits>::setVertexColor(const QColor& color) template <typename GeometryTraits>
{ void CurveGraphicsItem<GeometryTraits>::setVertexColor(const QColor& color) {
this->m_vertexColor = color; this->m_vertexColor = color;
} }
template <class ArrTraits> //
int CurveGraphicsItem<ArrTraits>::vertexRadius() const template <typename GeometryTraits>
{ int CurveGraphicsItem<GeometryTraits>::vertexRadius() const {
return this->m_vertexRadius; return this->m_vertexRadius;
} }
template <class ArrTraits> //
void CurveGraphicsItem<ArrTraits>::setVertexRadius(int radius) template <typename GeometryTraits>
{ void CurveGraphicsItem<GeometryTraits>::setVertexRadius(int radius) {
this->m_vertexRadius = radius; this->m_vertexRadius = radius;
} }
template <class ArrTraits> //
void CurveGraphicsItem<ArrTraits>::updateBoundingBox() template <typename GeometryTraits>
{ void CurveGraphicsItem<GeometryTraits>::updateBoundingBox() {
this->prepareGeometryChange(); this->prepareGeometryChange();
this->bb = {}; this->bb = {};
ConstructBoundingBox<Traits> construct_bounding_box; ConstructBoundingBox<Traits> ctr_bbox(m_traits);
for (auto& curve : curves) for (auto& curve : curves) this->bb += ctr_bbox(curve);
this->bb += construct_bounding_box(curve);
} }
ARRANGEMENT_DEMO_SPECIALIZE_TRAITS(CurveGraphicsItem) ARRANGEMENT_DEMO_SPECIALIZE_TRAITS(CurveGraphicsItem)

View File

@ -23,26 +23,24 @@
namespace CGAL { namespace CGAL {
namespace Qt { namespace Qt {
/** /* Draws selected curves and vertices of an arrangement.
Draws selected curves and vertices of an arrangement.
*/ */
// TODO: ArrangementGraphicsItem should probably use this class // TODO: ArrangementGraphicsItem should probably use this class
template < class ArrTraits > template <typename GeometryTraits>
class CurveGraphicsItem : public GraphicsItem, public GraphicsSceneMixin class CurveGraphicsItem : public GraphicsItem, public GraphicsSceneMixin {
{
public: public:
// known curve types // known curve types
typedef ArrTraits Traits; typedef GeometryTraits Traits;
typedef typename Traits::Curve_2 Curve_2; typedef typename Traits::Curve_2 Curve_2;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2; typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Traits::Point_2 Point_2; typedef typename Traits::Point_2 Point_2;
public: // ctors public:
CurveGraphicsItem( ); // Construct from traits.
CurveGraphicsItem(const Traits& traits);
public: // methods public: // methods
void paint( void paint(QPainter* painter, const QStyleOptionGraphicsItem* /* option */,
QPainter* painter, const QStyleOptionGraphicsItem* /* option */,
QWidget* /* widget */) override; QWidget* /* widget */) override;
QRectF boundingRect() const override; QRectF boundingRect() const override;
void insert(const X_monotone_curve_2& curve); void insert(const X_monotone_curve_2& curve);
@ -64,6 +62,7 @@ protected: // methods
void updateBoundingBox( ); void updateBoundingBox( );
protected: // fields protected: // fields
const Traits& m_traits;
std::vector<X_monotone_curve_2> curves; std::vector<X_monotone_curve_2> curves;
PointsGraphicsItem pointsGraphicsItem; PointsGraphicsItem pointsGraphicsItem;
CGAL::Bbox_2 bb; CGAL::Bbox_2 bb;

View File

@ -20,8 +20,7 @@
#include "Utils/Utils.h" #include "Utils/Utils.h"
template <typename Arr_> template <typename Arr_>
class DeleteCurveCallback : public DeleteCurveCallbackBase class DeleteCurveCallback : public DeleteCurveCallbackBase {
{
public: public:
typedef Arr_ Arrangement; typedef Arr_ Arrangement;
typedef typename Arrangement::Halfedge_handle Halfedge_handle; typedef typename Arrangement::Halfedge_handle Halfedge_handle;
@ -62,11 +61,12 @@ struct ExplicitLambda
CGAL::Object& arr_obj; CGAL::Object& arr_obj;
QObject* parent; QObject* parent;
}; };
} // anonymous namespace } // anonymous namespace
//
DeleteCurveCallbackBase* DeleteCurveCallbackBase::create( DeleteCurveCallbackBase* DeleteCurveCallbackBase::create(
demo_types::TraitsType tt, CGAL::Object arr_obj, QObject* parent) demo_types::TraitsType tt, CGAL::Object arr_obj, QObject* parent) {
{
DeleteCurveCallbackBase* res; DeleteCurveCallbackBase* res;
ExplicitLambda explicit_lambda{res, arr_obj, parent}; ExplicitLambda explicit_lambda{res, arr_obj, parent};
demo_types::visitArrangementType(tt, explicit_lambda); demo_types::visitArrangementType(tt, explicit_lambda);
@ -75,13 +75,14 @@ DeleteCurveCallbackBase* DeleteCurveCallbackBase::create(
/*! Constructor */ /*! Constructor */
template <typename Arr_> template <typename Arr_>
DeleteCurveCallback<Arr_>::DeleteCurveCallback( DeleteCurveCallback<Arr_>::DeleteCurveCallback(Arrangement* arr_,
Arrangement* arr_, QObject* parent_) : QObject* parent_) :
DeleteCurveCallbackBase(parent_), DeleteCurveCallbackBase(parent_),
highlightedCurve(new CGAL::Qt::CurveGraphicsItem<Traits>()), arr(arr_) highlightedCurve(new CGAL::Qt::CurveGraphicsItem<Traits>(*(arr_->geometry_traits()))),
arr(arr_)
{ {
QObject::connect( QObject::connect(this, SIGNAL(modelChanged()),
this, SIGNAL(modelChanged()), this->highlightedCurve, SLOT(modelChanged())); this->highlightedCurve, SLOT(modelChanged()));
this->setDeleteMode(DeleteMode::DeleteOriginatingCuve); this->setDeleteMode(DeleteMode::DeleteOriginatingCuve);
} }
@ -91,13 +92,13 @@ DeleteCurveCallback<Arr_>::DeleteCurveCallback(
sets the current scene of the viewport sets the current scene of the viewport
*/ */
template <typename Arr_> template <typename Arr_>
void DeleteCurveCallback<Arr_>::setScene(QGraphicsScene* scene_) void DeleteCurveCallback<Arr_>::setScene(QGraphicsScene* scene_) {
{
CGAL::Qt::Callback::setScene(scene_); CGAL::Qt::Callback::setScene(scene_);
this->highlightedCurve->setScene(scene_); this->highlightedCurve->setScene(scene_);
if (this->scene) { this->scene->addItem(this->highlightedCurve); } if (this->scene) { this->scene->addItem(this->highlightedCurve); }
} }
//
template <typename Arr_> template <typename Arr_>
void DeleteCurveCallback<Arr_>::reset() void DeleteCurveCallback<Arr_>::reset()
{ {
@ -105,28 +106,25 @@ void DeleteCurveCallback<Arr_>::reset()
this->removableHalfedge = Halfedge_handle(); this->removableHalfedge = Halfedge_handle();
} }
//
template <typename Arr_> template <typename Arr_>
void DeleteCurveCallback<Arr_>::mousePressEvent( void DeleteCurveCallback<Arr_>::
QGraphicsSceneMouseEvent* /* event */) mousePressEvent(QGraphicsSceneMouseEvent* /* event */) {
{
if (this->removableHalfedge == Halfedge_handle()) { return; } if (this->removableHalfedge == Halfedge_handle()) { return; }
if (this->deleteMode == DeleteMode::DeleteOriginatingCuve) if (this->deleteMode == DeleteMode::DeleteOriginatingCuve) {
{
Originating_curve_iterator it = Originating_curve_iterator it =
this->arr->originating_curves_begin(this->removableHalfedge); this->arr->originating_curves_begin(this->removableHalfedge);
Originating_curve_iterator it_end = Originating_curve_iterator it_end =
this->arr->originating_curves_end(this->removableHalfedge); this->arr->originating_curves_end(this->removableHalfedge);
while (it != it_end) while (it != it_end) {
{
Originating_curve_iterator temp = it; Originating_curve_iterator temp = it;
++temp; ++temp;
CGAL::remove_curve(*(this->arr), it); CGAL::remove_curve(*(this->arr), it);
it = temp; it = temp;
} }
} }
else else {
{
// CGAL::remove_edge( *(this->arr), this->removableHalfedge->curve( ) ); // CGAL::remove_edge( *(this->arr), this->removableHalfedge->curve( ) );
this->arr->remove_edge(this->removableHalfedge); this->arr->remove_edge(this->removableHalfedge);
} }
@ -134,16 +132,15 @@ void DeleteCurveCallback<Arr_>::mousePressEvent(
Q_EMIT modelChanged(); Q_EMIT modelChanged();
} }
//
template <typename Arr_> template <typename Arr_>
void DeleteCurveCallback<Arr_>::mouseMoveEvent(QGraphicsSceneMouseEvent* event) void DeleteCurveCallback<Arr_>::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
{ { this->highlightNearestCurve(event); }
this->highlightNearestCurve(event);
}
//
template <typename Arr_> template <typename Arr_>
void DeleteCurveCallback<Arr_>::highlightNearestCurve( void DeleteCurveCallback<Arr_>::
QGraphicsSceneMouseEvent* event) highlightNearestCurve(QGraphicsSceneMouseEvent* event) {
{
typedef typename ArrTraitsAdaptor<Traits>::Kernel Kernel; typedef typename ArrTraitsAdaptor<Traits>::Kernel Kernel;
typedef typename Kernel::Point_2 Point; typedef typename Kernel::Point_2 Point;
@ -164,12 +161,11 @@ void DeleteCurveCallback<Arr_>::highlightNearestCurve(
// create a curve graphics item and add it to the scene // create a curve graphics item and add it to the scene
this->highlightedCurve->clear(); this->highlightedCurve->clear();
if (this->deleteMode == DeleteMode::DeleteOriginatingCuve) if (this->deleteMode == DeleteMode::DeleteOriginatingCuve) {
{ // highlight the originating curve // highlight the originating curve
Originating_curve_iterator ocit, temp; Originating_curve_iterator ocit, temp;
ocit = this->arr->originating_curves_begin(this->removableHalfedge); ocit = this->arr->originating_curves_begin(this->removableHalfedge);
while (ocit != this->arr->originating_curves_end(this->removableHalfedge)) while (ocit != this->arr->originating_curves_end(this->removableHalfedge)) {
{
temp = ocit; temp = ocit;
++temp; ++temp;
@ -184,8 +180,8 @@ void DeleteCurveCallback<Arr_>::highlightNearestCurve(
ocit = temp; ocit = temp;
} }
} }
else else {
{ // highlight just the edge // highlight just the edge
this->highlightedCurve->insert(this->removableHalfedge->curve()); this->highlightedCurve->insert(this->removableHalfedge->curve());
} }

View File

@ -84,10 +84,13 @@ struct ExplicitLambda
CGAL::Object& arr_obj; CGAL::Object& arr_obj;
QObject* parent; QObject* parent;
}; };
} // anonymous namespace } // anonymous namespace
EnvelopeCallbackBase* EnvelopeCallbackBase::create( //
demo_types::TraitsType tt, CGAL::Object arr_obj, QObject* parent) EnvelopeCallbackBase*
EnvelopeCallbackBase::create(demo_types::TraitsType tt, CGAL::Object arr_obj,
QObject* parent)
{ {
EnvelopeCallbackBase* res; EnvelopeCallbackBase* res;
ExplicitLambda explicit_lambda{res, arr_obj, parent}; ExplicitLambda explicit_lambda{res, arr_obj, parent};
@ -95,11 +98,12 @@ EnvelopeCallbackBase* EnvelopeCallbackBase::create(
return res; return res;
} }
//
template <typename Arr_> template <typename Arr_>
EnvelopeCallback<Arr_>::EnvelopeCallback(Arrangement* arr_, QObject* parent) : EnvelopeCallback<Arr_>::EnvelopeCallback(Arrangement* arr_, QObject* parent) :
EnvelopeCallbackBase(parent), arr(arr_), EnvelopeCallbackBase(parent), arr(arr_),
lowerEnvelope(new CGAL::Qt::CurveGraphicsItem<Traits>()), lowerEnvelope(new CGAL::Qt::CurveGraphicsItem<Traits>(*(arr_->geometry_traits()))),
upperEnvelope(new CGAL::Qt::CurveGraphicsItem<Traits>()), showLower(false), upperEnvelope(new CGAL::Qt::CurveGraphicsItem<Traits>(*(arr_->geometry_traits()))), showLower(false),
showUpper(false) showUpper(false)
{ {
this->lowerEnvelope->hide(); this->lowerEnvelope->hide();

View File

@ -24,11 +24,10 @@
#include <QEvent> #include <QEvent>
#include <QKeyEvent> #include <QKeyEvent>
//
template <std::size_t I = 0, typename FuncT, typename... Tp> template <std::size_t I = 0, typename FuncT, typename... Tp>
inline std::enable_if_t<I == sizeof...(Tp), void> inline typename std::enable_if<I == sizeof...(Tp), void>::type
for_each(std::tuple<Tp...>&, FuncT) for_each(std::tuple<Tp...>&, FuncT) {}
{
}
template <std::size_t I = 0, typename FuncT, typename... Tp> template <std::size_t I = 0, typename FuncT, typename... Tp>
inline std::enable_if_t < inline std::enable_if_t <
@ -38,51 +37,46 @@ template <std::size_t I = 0, typename FuncT, typename... Tp>
for_each<I + 1, FuncT, Tp...>(t, f); for_each<I + 1, FuncT, Tp...>(t, f);
} }
namespace CGAL namespace CGAL {
{ namespace Qt {
namespace Qt
{
GraphicsViewCurveInputBase::GraphicsViewCurveInputBase( //
QObject* parent, QGraphicsScene* scene) : GraphicsViewCurveInputBase::
GraphicsViewCurveInputBase(QObject* parent, QGraphicsScene* scene) :
Callback(parent, scene), Callback(parent, scene),
inputMethod(nullptr) inputMethod(nullptr)
{ {}
}
//
void GraphicsViewCurveInputBase::setInputMethod(CurveInputMethod* inputMethod_) void GraphicsViewCurveInputBase::setInputMethod(CurveInputMethod* inputMethod_)
{ { this->inputMethod = inputMethod_; }
this->inputMethod = inputMethod_;
}
void GraphicsViewCurveInputBase::reset() //
{ void GraphicsViewCurveInputBase::reset() {
if (this->inputMethod) if (this->inputMethod) {
{
this->inputMethod->reset(); this->inputMethod->reset();
this->inputMethod = nullptr; this->inputMethod = nullptr;
} }
} }
//
bool GraphicsViewCurveInputBase::eventFilter(QObject* obj, QEvent* event) bool GraphicsViewCurveInputBase::eventFilter(QObject* obj, QEvent* event)
{ { return this->inputMethod->eventFilter(obj, event); }
return this->inputMethod->eventFilter(obj, event);
}
//
void GraphicsViewCurveInputBase::setColor(QColor c) void GraphicsViewCurveInputBase::setColor(QColor c)
{ { this->inputMethod->setColor(c); }
this->inputMethod->setColor(c);
}
//
template <typename Arr_> template <typename Arr_>
GraphicsViewCurveInput<Arr_>::GraphicsViewCurveInput( GraphicsViewCurveInput<Arr_>::
Arrangement* arrangement_, QObject* parent, QGraphicsScene* scene) : GraphicsViewCurveInput(Arrangement* arrangement_, QObject* parent,
QGraphicsScene* scene) :
GraphicsViewCurveInputBase(parent, scene), GraphicsViewCurveInputBase(parent, scene),
arrangement(arrangement_) arrangement(arrangement_)
{ {
this->setDefaultInputMethod( this->setDefaultInputMethod(std::integral_constant<bool,
std::integral_constant< std::tuple_size<InputMethodTuple>::value != 0>{});
bool, std::tuple_size<InputMethodTuple>::value != 0>{});
for_each(inputMethods, [&](auto&& it) { for_each(inputMethods, [&](auto&& it) {
it.setScene(scene); it.setScene(scene);
it.setCallback(this); it.setCallback(this);
@ -90,51 +84,48 @@ GraphicsViewCurveInput<Arr_>::GraphicsViewCurveInput(
curveGenerator.setTraits(this->arrangement->traits()); curveGenerator.setTraits(this->arrangement->traits());
} }
//
template <typename Arr_> template <typename Arr_>
void GraphicsViewCurveInput<Arr_>::setCurveType(CurveType type) void GraphicsViewCurveInput<Arr_>::setCurveType(CurveType type) {
{
this->reset(); this->reset();
for_each(inputMethods, [&](auto&& it) { for_each(inputMethods,
[&](auto&& it) {
if (it.curveType() == type) if (it.curveType() == type)
this->setInputMethod(static_cast<CurveInputMethod*>(&it)); this->setInputMethod(static_cast<CurveInputMethod*>(&it));
}); });
} }
//
template <typename Arr_> template <typename Arr_>
void GraphicsViewCurveInput<Arr_>::setPointSnapper(PointSnapperBase* snapper_) void GraphicsViewCurveInput<Arr_>::setPointSnapper(PointSnapperBase* snapper_)
{ { for_each(inputMethods, [&](auto&& it) { it.setPointSnapper(snapper_); }); }
for_each(inputMethods, [&](auto&& it) { it.setPointSnapper(snapper_); });
}
//
template <typename Arr_> template <typename Arr_>
template <typename> template <typename>
void GraphicsViewCurveInput<Arr_>::setDefaultInputMethod(std::true_type) void GraphicsViewCurveInput<Arr_>::setDefaultInputMethod(std::true_type)
{ { this->setInputMethod(&std::get<0>(inputMethods)); }
this->setInputMethod(&std::get<0>(inputMethods));
}
//
template <typename Arr_> template <typename Arr_>
void GraphicsViewCurveInput<Arr_>::setDefaultInputMethod(std::false_type) void GraphicsViewCurveInput<Arr_>::setDefaultInputMethod(std::false_type)
{ {}
}
//
template <typename Arr_> template <typename Arr_>
void GraphicsViewCurveInput<Arr_>::generate(CGAL::Object o) void GraphicsViewCurveInput<Arr_>::generate(CGAL::Object o) {
{ insertCurve(demo_types::enumFromArrType<Arrangement>(),
insertCurve(
demo_types::enumFromArrType<Arrangement>(),
CGAL::make_object(this->arrangement), o); CGAL::make_object(this->arrangement), o);
Q_EMIT CGAL::Qt::GraphicsViewCurveInputBase::modelChanged(); Q_EMIT CGAL::Qt::GraphicsViewCurveInputBase::modelChanged();
} }
//
template <typename Arr_> template <typename Arr_>
void GraphicsViewCurveInput<Arr_>::curveInputDoneEvent( void GraphicsViewCurveInput<Arr_>::
const std::vector<Point_2>& clickedPoints, CurveType type) curveInputDoneEvent(const std::vector<Point_2>& clickedPoints, CurveType type) {
{
boost::optional<Curve_2> cv = boost::optional<Curve_2> cv =
this->curveGenerator.generate(clickedPoints, type); this->curveGenerator.generate(clickedPoints, type);
if (cv) if (cv) {
{
Insert_curve<Arrangement>{}(this->arrangement, *cv); Insert_curve<Arrangement>{}(this->arrangement, *cv);
Q_EMIT this->modelChanged(); Q_EMIT this->modelChanged();
} }
@ -142,13 +133,12 @@ void GraphicsViewCurveInput<Arr_>::curveInputDoneEvent(
// CurveGeneratorBase // CurveGeneratorBase
template <typename ArrTraits_> template <typename ArrTraits_>
auto CurveGeneratorBase<ArrTraits_>::generate( auto CurveGeneratorBase<ArrTraits_>::
const std::vector<Point_2>& clickedPoints, CurveType type) generate(const std::vector<Point_2>& clickedPoints, CurveType type)
-> boost::optional<Curve_2> -> boost::optional<Curve_2>
{ {
boost::optional<Curve_2> res; boost::optional<Curve_2> res;
switch (type) switch (type) {
{
case CurveType::Segment: case CurveType::Segment:
res = generateSegment(clickedPoints); res = generateSegment(clickedPoints);
break; break;
@ -181,16 +171,16 @@ auto CurveGeneratorBase<ArrTraits_>::generate(
return res; return res;
} }
//
template <typename ArrTraits_> template <typename ArrTraits_>
void CurveGeneratorBase<ArrTraits_>::setTraits(const ArrTraits* traits_) void CurveGeneratorBase<ArrTraits_>::setTraits(const ArrTraits* traits_)
{ { this->traits = traits_; }
this->traits = traits_;
}
// Curve Generator Segment Traits // Curve Generator Segment Traits
template <typename Kernel_> template <typename Kernel_>
auto CurveGenerator<CGAL::Arr_segment_traits_2<Kernel_>>::generateSegment( auto CurveGenerator<CGAL::Arr_segment_traits_2<Kernel_>>::
const std::vector<Point_2>& clickedPoints) -> boost::optional<Curve_2> generateSegment(const std::vector<Point_2>& clickedPoints)
-> boost::optional<Curve_2>
{ {
Curve_2 res{clickedPoints[0], clickedPoints[1]}; Curve_2 res{clickedPoints[0], clickedPoints[1]};
return res; return res;
@ -211,25 +201,25 @@ auto CurveGenerator<CGAL::Arr_polyline_traits_2<SegmentTraits>>::
// Curve Generator Linear Traits // Curve Generator Linear Traits
template <typename Kernel_> template <typename Kernel_>
auto CurveGenerator<CGAL::Arr_linear_traits_2<Kernel_>>::generateSegment( auto CurveGenerator<CGAL::Arr_linear_traits_2<Kernel_>>::
const std::vector<Point_2>& points) -> boost::optional<Curve_2> generateSegment(const std::vector<Point_2>& points) -> boost::optional<Curve_2>
{ {
Curve_2 res = Curve_2(Segment_2(points[0], points[1])); Curve_2 res = Curve_2(Segment_2(points[0], points[1]));
return res; return res;
} }
//
template <typename Kernel_> template <typename Kernel_>
auto CurveGenerator<CGAL::Arr_linear_traits_2<Kernel_>>::generateRay( auto CurveGenerator<CGAL::Arr_linear_traits_2<Kernel_>>::
const std::vector<Point_2>& points) -> boost::optional<Curve_2> generateRay(const std::vector<Point_2>& points) -> boost::optional<Curve_2> {
{
Curve_2 res = Curve_2(Ray_2(points[0], points[1])); Curve_2 res = Curve_2(Ray_2(points[0], points[1]));
return res; return res;
} }
//
template <typename Kernel_> template <typename Kernel_>
auto CurveGenerator<CGAL::Arr_linear_traits_2<Kernel_>>::generateLine( auto CurveGenerator<CGAL::Arr_linear_traits_2<Kernel_>>::
const std::vector<Point_2>& points) -> boost::optional<Curve_2> generateLine(const std::vector<Point_2>& points) -> boost::optional<Curve_2> {
{
Curve_2 res = Curve_2(Line_2(points[0], points[1])); Curve_2 res = Curve_2(Line_2(points[0], points[1]));
return res; return res;
} }
@ -240,21 +230,24 @@ auto CurveGenerator<Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>>::
generateSegment(const std::vector<Point_2>& points) generateSegment(const std::vector<Point_2>& points)
-> boost::optional<Curve_2> -> boost::optional<Curve_2>
{ {
Curve_2 res = Curve_2(Rat_segment_2(points[0], points[1])); auto ctr_cv = this->traits->construct_curve_2_object();
Curve_2 res = ctr_cv(Rat_segment_2(points[0], points[1]));
return res; return res;
} }
//
template <typename RatKernel, typename AlgKernel, typename NtTraits> template <typename RatKernel, typename AlgKernel, typename NtTraits>
auto CurveGenerator<Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>>:: auto CurveGenerator<Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>>::
generateCircle(const std::vector<Point_2>& points) -> boost::optional<Curve_2> generateCircle(const std::vector<Point_2>& points) -> boost::optional<Curve_2> {
{
auto sq_rad = auto sq_rad =
(points[0].x() - points[1].x()) * (points[0].x() - points[1].x()) + (points[0].x() - points[1].x()) * (points[0].x() - points[1].x()) +
(points[0].y() - points[1].y()) * (points[0].y() - points[1].y()); (points[0].y() - points[1].y()) * (points[0].y() - points[1].y());
Curve_2 res = Curve_2(Rat_circle_2(points[0], sq_rad)); auto ctr_cv = this->traits->construct_curve_2_object();
Curve_2 res = ctr_cv(Rat_circle_2(points[0], sq_rad));
return res; return res;
} }
//
template <typename RatKernel, typename AlgKernel, typename NtTraits> template <typename RatKernel, typename AlgKernel, typename NtTraits>
auto CurveGenerator<Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>>:: auto CurveGenerator<Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>>::
generateEllipse(const std::vector<Point_2>& points) generateEllipse(const std::vector<Point_2>& points)
@ -279,10 +272,12 @@ auto CurveGenerator<Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>>::
Rat_FT v = -2 * y0 * a_sq; Rat_FT v = -2 * y0 * a_sq;
Rat_FT ww = x0 * x0 * b_sq + y0 * y0 * a_sq - a_sq * b_sq; Rat_FT ww = x0 * x0 * b_sq + y0 * y0 * a_sq - a_sq * b_sq;
Curve_2 res = Curve_2(r, s, t, u, v, ww); auto ctr_cv = this->traits->construct_curve_2_object();
Curve_2 res = ctr_cv(r, s, t, u, v, ww);
return res; return res;
} }
//
template <typename RatKernel, typename AlgKernel, typename NtTraits> template <typename RatKernel, typename AlgKernel, typename NtTraits>
auto CurveGenerator<Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>>:: auto CurveGenerator<Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>>::
generateThreePointCircularArc(const std::vector<Point_2>& points) generateThreePointCircularArc(const std::vector<Point_2>& points)
@ -295,18 +290,18 @@ auto CurveGenerator<Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>>::
Rat_point_2 p2 = Rat_point_2(qp2.x(), qp2.y()); Rat_point_2 p2 = Rat_point_2(qp2.x(), qp2.y());
Rat_point_2 p3 = Rat_point_2(qp3.x(), qp3.y()); Rat_point_2 p3 = Rat_point_2(qp3.x(), qp3.y());
RatKernel ker; RatKernel ker;
if (!ker.collinear_2_object()(p1, p2, p3)) if (! ker.collinear_2_object()(p1, p2, p3)) {
{ auto ctr_cv = this->traits->construct_curve_2_object();
Curve_2 res(p1, p2, p3); Curve_2 res = ctr_cv(p1, p2, p3);
return res; return res;
} }
else else {
{
std::cout << "Points don't specify a valid conic." << std::endl; std::cout << "Points don't specify a valid conic." << std::endl;
return {}; return {};
} }
} }
//
template <typename RatKernel, typename AlgKernel, typename NtTraits> template <typename RatKernel, typename AlgKernel, typename NtTraits>
auto CurveGenerator<Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>>:: auto CurveGenerator<Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>>::
generateFivePointConicArc(const std::vector<Point_2>& points) generateFivePointConicArc(const std::vector<Point_2>& points)
@ -322,17 +317,14 @@ auto CurveGenerator<Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>>::
Rat_point_2 p2 = Rat_point_2(qp2.x(), qp2.y()); Rat_point_2 p2 = Rat_point_2(qp2.x(), qp2.y());
Rat_point_2 p3 = Rat_point_2(qp3.x(), qp3.y()); Rat_point_2 p3 = Rat_point_2(qp3.x(), qp3.y());
Rat_point_2 p4 = Rat_point_2(qp4.x(), qp4.y()); Rat_point_2 p4 = Rat_point_2(qp4.x(), qp4.y());
try try {
{ auto ctr_cv = this->traits->construct_curve_2_object();
Curve_2 res(p0, p1, p2, p3, p4); Curve_2 res = ctr_cv(p0, p1, p2, p3, p4);
if (res.is_valid()) if (res.is_valid()) return res;
return res; else std::cout << "Points don't specify a valid conic. Try again!"
else
std::cout << "Points don't specify a valid conic. Try again!"
<< std::endl; << std::endl;
} }
catch (...) catch (...) {
{
std::cout << "Points don't specify a valid conic. Try again!" << std::endl; std::cout << "Points don't specify a valid conic. Try again!" << std::endl;
} }
return {}; return {};
@ -341,8 +333,7 @@ auto CurveGenerator<Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>>::
// CurveGenerator Algebraic Traits // CurveGenerator Algebraic Traits
template <typename Coefficient_> template <typename Coefficient_>
auto CurveGenerator<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>:: auto CurveGenerator<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>::
generateLine(const std::vector<Point_2>& points) -> boost::optional<Curve_2> generateLine(const std::vector<Point_2>& points) -> boost::optional<Curve_2> {
{
RationalTraits ratTraits; RationalTraits ratTraits;
Rational dx = points[1].x() - points[0].x(); Rational dx = points[1].x() - points[0].x();
@ -351,8 +342,7 @@ auto CurveGenerator<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>::
Polynomial_2 y = CGAL::shift(Polynomial_2(1), 1, 1); Polynomial_2 y = CGAL::shift(Polynomial_2(1), 1, 1);
Polynomial_2 poly; Polynomial_2 poly;
if (dx != 0) if (dx != 0) {
{
Rational mRat = dy / dx; Rational mRat = dy / dx;
Rational cRat = points[0].y() - mRat * points[0].x(); Rational cRat = points[0].y() - mRat * points[0].x();
// y = (a/b) x + (e/f) // y = (a/b) x + (e/f)
@ -364,8 +354,7 @@ auto CurveGenerator<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>::
poly = b * f * y - f * a * x - b * e; poly = b * f * y - f * a * x - b * e;
} }
// vertical line // vertical line
else else {
{
Rational xP = points[0].x(); Rational xP = points[0].x();
auto a = ratTraits.numerator(xP); auto a = ratTraits.numerator(xP);
auto b = ratTraits.denominator(xP); auto b = ratTraits.denominator(xP);
@ -377,10 +366,10 @@ auto CurveGenerator<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>::
return res; return res;
} }
//
template <typename Coefficient_> template <typename Coefficient_>
auto CurveGenerator<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>:: auto CurveGenerator<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>::
generateCircle(const std::vector<Point_2>& points) -> boost::optional<Curve_2> generateCircle(const std::vector<Point_2>& points) -> boost::optional<Curve_2> {
{
auto sq_rad = auto sq_rad =
(points[0].x() - points[1].x()) * (points[0].x() - points[1].x()) + (points[0].x() - points[1].x()) * (points[0].x() - points[1].x()) +
(points[0].y() - points[1].y()) * (points[0].y() - points[1].y()); (points[0].y() - points[1].y()) * (points[0].y() - points[1].y());
@ -401,6 +390,7 @@ auto CurveGenerator<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>::
return this->generateEllipse_(center, rx, ry); return this->generateEllipse_(center, rx, ry);
} }
//
template <typename Coefficient_> template <typename Coefficient_>
auto CurveGenerator<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>:: auto CurveGenerator<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>::
generateEllipse_(const Point_2& center, Rational rxRat, Rational ryRat) generateEllipse_(const Point_2& center, Rational rxRat, Rational ryRat)
@ -432,11 +422,11 @@ auto CurveGenerator<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>::
return res; return res;
} }
template < //
typename RatKernel, typename AlgKernel, typename NtTraits, template <typename RatKernel, typename AlgKernel, typename NtTraits,
typename BoundingTraits> typename BoundingTraits>
auto CurveGenerator< auto CurveGenerator
Arr_Bezier_curve_traits_2<RatKernel, AlgKernel, NtTraits, BoundingTraits>>:: <Arr_Bezier_curve_traits_2<RatKernel, AlgKernel, NtTraits, BoundingTraits>>::
generateBezier(const std::vector<Point_2>& clickedPoints) generateBezier(const std::vector<Point_2>& clickedPoints)
-> boost::optional<Curve_2> -> boost::optional<Curve_2>
{ {
@ -445,13 +435,10 @@ auto CurveGenerator<
} }
// msvc2015 doesn't play well with polymorphic lambdas // msvc2015 doesn't play well with polymorphic lambdas
namespace namespace {
{ struct ExplicitLambda {
struct ExplicitLambda
{
template <typename Arrangement> template <typename Arrangement>
void operator()(demo_types::TypeHolder<Arrangement>) void operator()(demo_types::TypeHolder<Arrangement>) {
{
Arrangement* arr = nullptr; Arrangement* arr = nullptr;
CGAL::assign(arr, arr_obj); CGAL::assign(arr, arr_obj);
res = new GraphicsViewCurveInput<Arrangement>(arr, parent, scene); res = new GraphicsViewCurveInput<Arrangement>(arr, parent, scene);
@ -464,6 +451,7 @@ struct ExplicitLambda
}; };
} // anonymous namespace } // anonymous namespace
//
GraphicsViewCurveInputBase* GraphicsViewCurveInputBase::create( GraphicsViewCurveInputBase* GraphicsViewCurveInputBase::create(
demo_types::TraitsType tt, CGAL::Object arr_obj, QObject* parent, demo_types::TraitsType tt, CGAL::Object arr_obj, QObject* parent,
QGraphicsScene* scene) QGraphicsScene* scene)
@ -478,8 +466,11 @@ GraphicsViewCurveInputBase* GraphicsViewCurveInputBase::create(
} // namespace CGAL } // namespace CGAL
#ifdef CGAL_USE_CORE #ifdef CGAL_USE_CORE
CGAL::Object algebraicCurveFromExpression(
const CGAL::Object& arr_obj, const std::string& exp, bool& is_first_curve) //
CGAL::Object algebraicCurveFromExpression(const CGAL::Object& arr_obj,
const std::string& exp,
bool& is_first_curve)
{ {
using Polynomial_2 = demo_types::DemoTypes::Alg_seg_traits::Polynomial_2; using Polynomial_2 = demo_types::DemoTypes::Alg_seg_traits::Polynomial_2;
using Alg_seg_arr = demo_types::DemoTypes::Alg_seg_arr; using Alg_seg_arr = demo_types::DemoTypes::Alg_seg_arr;
@ -498,9 +489,11 @@ CGAL::Object algebraicCurveFromExpression(
return CGAL::make_object(cv); return CGAL::make_object(cv);
} }
CGAL::Object rationalCurveFromExpression( //
const CGAL::Object& arr_obj, const std::string& numerator, CGAL::Object rationalCurveFromExpression(const CGAL::Object& arr_obj,
const std::string& denominator, bool& is_first_curve) const std::string& numerator,
const std::string& denominator,
bool& is_first_curve)
{ {
using Polynomial_1 = demo_types::DemoTypes::Rational_traits::Polynomial_1; using Polynomial_1 = demo_types::DemoTypes::Rational_traits::Polynomial_1;
using Rational_arr = demo_types::DemoTypes::Rational_arr; using Rational_arr = demo_types::DemoTypes::Rational_arr;
@ -521,4 +514,5 @@ CGAL::Object rationalCurveFromExpression(
return CGAL::make_object(cv); return CGAL::make_object(cv);
} }
#endif #endif

View File

@ -30,14 +30,11 @@ namespace demo_types
enum class TraitsType : int; enum class TraitsType : int;
} }
namespace CGAL namespace CGAL {
{ namespace Qt {
namespace Qt
{
template <typename ArrTraits_> template <typename ArrTraits_>
class CurveGeneratorBase class CurveGeneratorBase {
{
public: public:
using ArrTraits = ArrTraits_; using ArrTraits = ArrTraits_;
using Curve_2 = typename ArrTraits::Curve_2; using Curve_2 = typename ArrTraits::Curve_2;
@ -50,31 +47,40 @@ public:
virtual boost::optional<Curve_2> virtual boost::optional<Curve_2>
generateSegment(const std::vector<Point_2>&) { return {}; } generateSegment(const std::vector<Point_2>&) { return {}; }
virtual boost::optional<Curve_2> virtual boost::optional<Curve_2>
generateRay(const std::vector<Point_2>&) { return {}; } generateRay(const std::vector<Point_2>&) { return {}; }
virtual boost::optional<Curve_2> virtual boost::optional<Curve_2>
generateLine(const std::vector<Point_2>&) { return {}; } generateLine(const std::vector<Point_2>&) { return {}; }
virtual boost::optional<Curve_2> virtual boost::optional<Curve_2>
generatePolyline(const std::vector<Point_2>&) { return {}; } generatePolyline(const std::vector<Point_2>&) { return {}; }
virtual boost::optional<Curve_2> virtual boost::optional<Curve_2>
generateCircle(const std::vector<Point_2>&) { return {}; } generateCircle(const std::vector<Point_2>&) { return {}; }
virtual boost::optional<Curve_2> virtual boost::optional<Curve_2>
generateEllipse(const std::vector<Point_2>&) { return {}; } generateEllipse(const std::vector<Point_2>&) { return {}; }
virtual boost::optional<Curve_2> virtual boost::optional<Curve_2>
generateThreePointCircularArc(const std::vector<Point_2>&) { return {}; } generateThreePointCircularArc(const std::vector<Point_2>&) { return {}; }
virtual boost::optional<Curve_2> virtual boost::optional<Curve_2>
generateFivePointConicArc(const std::vector<Point_2>&) { return {}; } generateFivePointConicArc(const std::vector<Point_2>&) { return {}; }
virtual boost::optional<Curve_2> virtual boost::optional<Curve_2>
generateBezier(const std::vector<Point_2>&) { return {}; } generateBezier(const std::vector<Point_2>&) { return {}; }
const ArrTraits* traits; const ArrTraits* traits;
}; };
// Generic implementation.
template <typename ArrTraits_> template <typename ArrTraits_>
struct CurveGenerator : public CurveGeneratorBase<ArrTraits_> struct CurveGenerator : public CurveGeneratorBase<ArrTraits_>
{ {};
};
// Specialization for the segment traits.
template <typename Kernel_> template <typename Kernel_>
struct CurveGenerator<CGAL::Arr_segment_traits_2<Kernel_>> : struct CurveGenerator<CGAL::Arr_segment_traits_2<Kernel_>> :
public CurveGeneratorBase<CGAL::Arr_segment_traits_2<Kernel_>> public CurveGeneratorBase<CGAL::Arr_segment_traits_2<Kernel_>>
@ -89,6 +95,7 @@ struct CurveGenerator<CGAL::Arr_segment_traits_2<Kernel_>> :
generateSegment(const std::vector<Point_2>&) override; generateSegment(const std::vector<Point_2>&) override;
}; };
// Specialization for the polyline traits.
template <typename SegmentTraits> template <typename SegmentTraits>
struct CurveGenerator<CGAL::Arr_polyline_traits_2<SegmentTraits>> : struct CurveGenerator<CGAL::Arr_polyline_traits_2<SegmentTraits>> :
public CurveGeneratorBase<CGAL::Arr_polyline_traits_2<SegmentTraits>> public CurveGeneratorBase<CGAL::Arr_polyline_traits_2<SegmentTraits>>
@ -102,10 +109,10 @@ struct CurveGenerator<CGAL::Arr_polyline_traits_2<SegmentTraits>> :
generatePolyline(const std::vector<Point_2>&) override; generatePolyline(const std::vector<Point_2>&) override;
}; };
// Specialization for the conic traits.
template <typename RatKernel, typename AlgKernel, typename NtTraits> template <typename RatKernel, typename AlgKernel, typename NtTraits>
struct CurveGenerator<Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>> : struct CurveGenerator<Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>> :
public CurveGeneratorBase< public CurveGeneratorBase<Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>>
Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>>
{ {
using ArrTraits = Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>; using ArrTraits = Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>;
using Curve_2 = typename ArrTraits::Curve_2; using Curve_2 = typename ArrTraits::Curve_2;
@ -120,11 +127,15 @@ struct CurveGenerator<Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>> :
boost::optional<Curve_2> boost::optional<Curve_2>
generateSegment(const std::vector<Point_2>&) override; generateSegment(const std::vector<Point_2>&) override;
boost::optional<Curve_2> generateCircle(const std::vector<Point_2>&) override; boost::optional<Curve_2> generateCircle(const std::vector<Point_2>&) override;
boost::optional<Curve_2> boost::optional<Curve_2>
generateEllipse(const std::vector<Point_2>&) override; generateEllipse(const std::vector<Point_2>&) override;
boost::optional<Curve_2> boost::optional<Curve_2>
generateThreePointCircularArc(const std::vector<Point_2>&) override; generateThreePointCircularArc(const std::vector<Point_2>&) override;
boost::optional<Curve_2> boost::optional<Curve_2>
generateFivePointConicArc(const std::vector<Point_2>&) override; generateFivePointConicArc(const std::vector<Point_2>&) override;
}; };

View File

@ -21,8 +21,7 @@
#include <QGraphicsSceneMouseEvent> #include <QGraphicsSceneMouseEvent>
template <typename Arr_> template <typename Arr_>
class MergeEdgeCallback : public MergeEdgeCallbackBase class MergeEdgeCallback : public MergeEdgeCallbackBase {
{
public: public:
typedef Arr_ Arrangement; typedef Arr_ Arrangement;
typedef typename Arrangement::Halfedge_handle Halfedge_handle; typedef typename Arrangement::Halfedge_handle Halfedge_handle;
@ -51,14 +50,12 @@ protected:
}; // class MergeEdgeCallback }; // class MergeEdgeCallback
// msvc2015 doesn't play well with polymorphic lambdas // msvc2015 doesn't play well with polymorphic lambdas
namespace namespace {
{
struct ExplicitLambda struct ExplicitLambda {
{
template <typename Arrangement> template <typename Arrangement>
void operator()(demo_types::TypeHolder<Arrangement>) void operator()(demo_types::TypeHolder<Arrangement>) {
{ Arrangement* arr(nullptr);
Arrangement* arr = nullptr;
CGAL::assign(arr, arr_obj); CGAL::assign(arr, arr_obj);
res = new MergeEdgeCallback<Arrangement>(arr, parent); res = new MergeEdgeCallback<Arrangement>(arr, parent);
} }
@ -67,11 +64,13 @@ struct ExplicitLambda
CGAL::Object& arr_obj; CGAL::Object& arr_obj;
QObject* parent; QObject* parent;
}; };
} // anonymous namespace } // anonymous namespace
MergeEdgeCallbackBase* MergeEdgeCallbackBase::create( //
demo_types::TraitsType tt, CGAL::Object arr_obj, QObject* parent) MergeEdgeCallbackBase*
{ MergeEdgeCallbackBase::create(demo_types::TraitsType tt, CGAL::Object arr_obj,
QObject* parent) {
MergeEdgeCallbackBase* res; MergeEdgeCallbackBase* res;
ExplicitLambda explicit_lambda{res, arr_obj, parent}; ExplicitLambda explicit_lambda{res, arr_obj, parent};
demo_types::visitArrangementType(tt, explicit_lambda); demo_types::visitArrangementType(tt, explicit_lambda);
@ -80,55 +79,52 @@ MergeEdgeCallbackBase* MergeEdgeCallbackBase::create(
/*! Constructor */ /*! Constructor */
template <typename Arr_> template <typename Arr_>
MergeEdgeCallback<Arr_>::MergeEdgeCallback( MergeEdgeCallback<Arr_>::MergeEdgeCallback(Arrangement* arr_,
Arrangement* arr_, QObject* parent_) : QObject* parent_) :
MergeEdgeCallbackBase(parent_), MergeEdgeCallbackBase(parent_),
highlightedCurve(new CGAL::Qt::CurveGraphicsItem<Traits>()), highlightedCurve(new CGAL::Qt::CurveGraphicsItem<Traits>(*(arr_->geometry_traits()))),
highlightedCurve2(new CGAL::Qt::CurveGraphicsItem<Traits>()), arr(arr_), highlightedCurve2(new CGAL::Qt::CurveGraphicsItem<Traits>(*(arr_->geometry_traits()))), arr(arr_),
isFirst(true) isFirst(true)
{ {
QObject::connect( QObject::connect(this, SIGNAL(modelChanged()), this->highlightedCurve,
this, SIGNAL(modelChanged()), this->highlightedCurve, SLOT(modelChanged())); SLOT(modelChanged()));
QObject::connect( QObject::connect(this, SIGNAL(modelChanged()), this->highlightedCurve2,
this, SIGNAL(modelChanged()), this->highlightedCurve2,
SLOT(modelChanged())); SLOT(modelChanged()));
} }
//
template <typename Arr_> template <typename Arr_>
void MergeEdgeCallback<Arr_>::setScene(QGraphicsScene* scene_) void MergeEdgeCallback<Arr_>::setScene(QGraphicsScene* scene_) {
{
Callback::setScene(scene_); Callback::setScene(scene_);
this->highlightedCurve->setScene(scene_); this->highlightedCurve->setScene(scene_);
this->highlightedCurve2->setScene(scene_); this->highlightedCurve2->setScene(scene_);
if (scene_) if (scene_) {
{
this->scene->addItem(this->highlightedCurve); this->scene->addItem(this->highlightedCurve);
this->scene->addItem(this->highlightedCurve2); this->scene->addItem(this->highlightedCurve2);
} }
} }
//
template <typename Arr_> template <typename Arr_>
void MergeEdgeCallback<Arr_>::reset() void MergeEdgeCallback<Arr_>::reset() {
{
this->isFirst = true; this->isFirst = true;
this->highlightedCurve->clear(); this->highlightedCurve->clear();
this->highlightedCurve2->clear(); this->highlightedCurve2->clear();
this->mergeableHalfedge = Halfedge_handle(); this->mergeableHalfedge = Halfedge_handle();
} }
//
template <typename Arr_> template <typename Arr_>
void MergeEdgeCallback<Arr_>::mousePressEvent(QGraphicsSceneMouseEvent* event) void MergeEdgeCallback<Arr_>::mousePressEvent(QGraphicsSceneMouseEvent* event) {
{ if (this->isFirst) {
if (this->isFirst) // save the first edge if mergeable
{ // save the first edge if mergeable
Halfedge_handle halfedge = this->getNearestMergeableCurve(event); Halfedge_handle halfedge = this->getNearestMergeableCurve(event);
if (halfedge == Halfedge_handle()) { return; } if (halfedge == Halfedge_handle()) return;
this->isFirst = false; this->isFirst = false;
this->mergeableHalfedge = halfedge; this->mergeableHalfedge = halfedge;
} }
else else {
{
Halfedge_handle nextHalfedge = Halfedge_handle nextHalfedge =
this->getNearestMergeableCurve(this->mergeableHalfedge, event); this->getNearestMergeableCurve(this->mergeableHalfedge, event);
this->mergeEdge.mergeEdge(this->arr, this->mergeableHalfedge, nextHalfedge); this->mergeEdge.mergeEdge(this->arr, this->mergeableHalfedge, nextHalfedge);
@ -138,24 +134,21 @@ void MergeEdgeCallback<Arr_>::mousePressEvent(QGraphicsSceneMouseEvent* event)
Q_EMIT modelChanged(); Q_EMIT modelChanged();
} }
//
template <typename Arr_> template <typename Arr_>
void MergeEdgeCallback<Arr_>::mouseMoveEvent(QGraphicsSceneMouseEvent* event) void MergeEdgeCallback<Arr_>::mouseMoveEvent(QGraphicsSceneMouseEvent* event) {
{ if (this->isFirst) {
if (this->isFirst)
{
Halfedge_handle halfedge = this->getNearestMergeableCurve(event); Halfedge_handle halfedge = this->getNearestMergeableCurve(event);
if (halfedge == Halfedge_handle()) { return; } if (halfedge == Halfedge_handle()) { return; }
this->highlightedCurve->clear(); this->highlightedCurve->clear();
this->highlightedCurve->insert(halfedge->curve()); this->highlightedCurve->insert(halfedge->curve());
Q_EMIT modelChanged(); Q_EMIT modelChanged();
} }
else else {
{
Halfedge_handle nextHalfedge = Halfedge_handle nextHalfedge =
this->getNearestMergeableCurve(this->mergeableHalfedge, event); this->getNearestMergeableCurve(this->mergeableHalfedge, event);
if (nextHalfedge != Halfedge_handle()) if (nextHalfedge != Halfedge_handle()) {
{
this->highlightedCurve2->clear(); this->highlightedCurve2->clear();
this->highlightedCurve2->insert(nextHalfedge->curve()); this->highlightedCurve2->insert(nextHalfedge->curve());
Q_EMIT modelChanged(); Q_EMIT modelChanged();
@ -163,65 +156,60 @@ void MergeEdgeCallback<Arr_>::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
} }
} }
//
template <typename Arr_> template <typename Arr_>
typename MergeEdgeCallback<Arr_>::Halfedge_handle typename MergeEdgeCallback<Arr_>::Halfedge_handle
MergeEdgeCallback<Arr_>::getNearestMergeableCurve( MergeEdgeCallback<Arr_>::
QGraphicsSceneMouseEvent* event) getNearestMergeableCurve(QGraphicsSceneMouseEvent* event) {
{
// find the nearest curve to the cursor that is adjacent to a curve that // find the nearest curve to the cursor that is adjacent to a curve that
// can be merged with it // can be merged with it
typedef typename ArrTraitsAdaptor<Traits>::Kernel Kernel; using Kernel = typename ArrTraitsAdaptor<Traits>::Kernel;
typedef typename Kernel::Point_2 Kernel_point_2; using Kernel_point_2 = typename Kernel::Point_2;
Kernel_point_2 p = CGAL::Qt::Converter<Kernel>{}(event->scenePos()); Kernel_point_2 p = CGAL::Qt::Converter<Kernel>{}(event->scenePos());
double minDist = (std::numeric_limits<double>::max)(); double min_dist = (std::numeric_limits<double>::max)();
Halfedge_iterator nearestHei; Halfedge_iterator nearestHei;
bool found = false; bool found = false;
for (Halfedge_iterator hei = this->arr->halfedges_begin(); for (auto hei = this->arr->halfedges_begin();
hei != this->arr->halfedges_end(); ++hei) hei != this->arr->halfedges_end(); ++hei)
{ {
Vertex_iterator source = hei->source(); Vertex_iterator source = hei->source();
Vertex_iterator target = hei->target(); Vertex_iterator target = hei->target();
if (source->degree() != 2 && target->degree() != 2) // then this halfedge has no mergeable neighbors
{ // then this halfedge has no mergeable neighbors if (source->degree() != 2 && target->degree() != 2) continue;
continue;
}
Halfedge_handle h1 = hei->prev(); Halfedge_handle h1 = hei->prev();
Halfedge_handle h2 = hei->next(); Halfedge_handle h2 = hei->next();
if ( if ((!this->mergeEdge.areMergeable(this->arr, hei, h1)) &&
(!this->mergeEdge.areMergeable(this->arr, hei, h1)) &&
(!this->mergeEdge.areMergeable(this->arr, hei, h2))) (!this->mergeEdge.areMergeable(this->arr, hei, h2)))
{ continue; } { continue; }
X_monotone_curve_2 curve = hei->curve(); X_monotone_curve_2 curve = hei->curve();
Compute_squared_distance_2<Traits> squaredDistance; Compute_squared_distance_2<Traits>
squaredDistance.setScene(this->getScene()); squared_distance(*(arr->geometry_traits()));
double dist = CGAL::to_double(squaredDistance(p, curve)); squared_distance.setScene(this->getScene());
if (!found || dist < minDist) double dist = CGAL::to_double(squared_distance(p, curve));
{ if (! found || dist < min_dist) {
found = true; found = true;
minDist = dist; min_dist = dist;
nearestHei = hei; nearestHei = hei;
} }
} }
if (!found) // then we did not find a mergeable halfedge
{ // then we did not find a mergeable halfedge if (! found) return Halfedge_handle();
return Halfedge_handle();
}
return nearestHei; return nearestHei;
} }
//
template <typename Arr_> template <typename Arr_>
typename MergeEdgeCallback<Arr_>::Halfedge_handle typename MergeEdgeCallback<Arr_>::Halfedge_handle
MergeEdgeCallback<Arr_>::getNearestMergeableCurve( MergeEdgeCallback<Arr_>::
Halfedge_handle h, QGraphicsSceneMouseEvent* event) getNearestMergeableCurve(Halfedge_handle h, QGraphicsSceneMouseEvent* event) {
{
// find the nearest curve to the cursor that is adjacent to a curve that // find the nearest curve to the cursor that is adjacent to a curve that
// can be merged with it // can be merged with it
typedef typename ArrTraitsAdaptor<Traits>::Kernel Kernel; using Kernel = typename ArrTraitsAdaptor<Traits>::Kernel;
typedef typename Kernel::Point_2 Kernel_point_2; using Kernel_point_2 = typename Kernel::Point_2 ;
Kernel_point_2 p = CGAL::Qt::Converter<Kernel>{}(event->scenePos()); Kernel_point_2 p = CGAL::Qt::Converter<Kernel>{}(event->scenePos());
Halfedge_handle h1 = h->prev(); Halfedge_handle h1 = h->prev();
@ -229,29 +217,23 @@ MergeEdgeCallback<Arr_>::getNearestMergeableCurve(
Vertex_iterator source = h->source(); Vertex_iterator source = h->source();
Vertex_iterator target = h->target(); Vertex_iterator target = h->target();
if (source->degree() != 2 && target->degree() != 2) if (source->degree() != 2 && target->degree() != 2) return Halfedge_handle();
return Halfedge_handle(); else if (source->degree() != 2) return h2;
else if (source->degree() != 2) else if (target->degree() != 2) return h1;
return h2; else if (this->mergeEdge.areMergeable(arr, h, h1) &&
else if (target->degree() != 2)
return h1;
else if (
this->mergeEdge.areMergeable(arr, h, h1) &&
this->mergeEdge.areMergeable(arr, h, h2)) this->mergeEdge.areMergeable(arr, h, h2))
{ {
X_monotone_curve_2 c1 = h1->curve(); X_monotone_curve_2 c1 = h1->curve();
X_monotone_curve_2 c2 = h2->curve(); X_monotone_curve_2 c2 = h2->curve();
Compute_squared_distance_2<Traits> squaredDistance; Compute_squared_distance_2<Traits>
squaredDistance.setScene(this->getScene()); squared_distance(*(arr->geometry_traits()));
double d1 = CGAL::to_double(squaredDistance(p, c1)); squared_distance.setScene(this->getScene());
double d2 = CGAL::to_double(squaredDistance(p, c2)); double d1 = CGAL::to_double(squared_distance(p, c1));
double d2 = CGAL::to_double(squared_distance(p, c2));
return (d1 < d2) ? h1 : h2; return (d1 < d2) ? h1 : h2;
} }
else if (this->mergeEdge.areMergeable(arr, h, h2)) else if (this->mergeEdge.areMergeable(arr, h, h2)) return h2;
return h2; else if (this->mergeEdge.areMergeable(arr, h, h1)) return h1;
else if (this->mergeEdge.areMergeable(arr, h, h1)) else return Halfedge_handle();
return h1;
else
return Halfedge_handle();
} }

View File

@ -96,54 +96,55 @@ PointLocationCallbackBase* PointLocationCallbackBase::create(
/*! Constructor */ /*! Constructor */
template <typename Arr_> template <typename Arr_>
PointLocationCallback<Arr_>::PointLocationCallback( PointLocationCallback<Arr_>::PointLocationCallback(Arrangement* arr_,
Arrangement* arr_, QObject* parent_) : QObject* parent_) :
PointLocationCallbackBase(parent_), PointLocationCallbackBase(parent_),
arr(arr_), highlightedCurves(new CGAL::Qt::CurveGraphicsItem<Traits>()) arr(arr_),
highlightedCurves(new CGAL::Qt::CurveGraphicsItem<Traits>(*(arr_->geometry_traits())))
{ {
QObject::connect( QObject::connect(this, SIGNAL(modelChanged()), this->highlightedCurves,
this, SIGNAL(modelChanged()), this->highlightedCurves,
SLOT(modelChanged())); SLOT(modelChanged()));
} }
//
template <typename Arr_> template <typename Arr_>
void PointLocationCallback<Arr_>::setScene(QGraphicsScene* scene_) void PointLocationCallback<Arr_>::setScene(QGraphicsScene* scene_) {
{
this->scene = scene_; this->scene = scene_;
this->highlightedCurves->setScene(scene_); this->highlightedCurves->setScene(scene_);
if (this->scene) { this->scene->addItem(this->highlightedCurves); } if (this->scene) { this->scene->addItem(this->highlightedCurves); }
} }
//
template <typename Arr_> template <typename Arr_>
void PointLocationCallback<Arr_>::reset() void PointLocationCallback<Arr_>::reset() {
{
this->highlightedCurves->clear(); this->highlightedCurves->clear();
Q_EMIT modelChanged(); Q_EMIT modelChanged();
} }
//
template <typename Arr_> template <typename Arr_>
void PointLocationCallback<Arr_>::mousePressEvent( void PointLocationCallback<Arr_>::
QGraphicsSceneMouseEvent* event) mousePressEvent(QGraphicsSceneMouseEvent* event) {
{
this->highlightPointLocation(event); this->highlightPointLocation(event);
} }
//
template <typename Arr_> template <typename Arr_>
void PointLocationCallback<Arr_>::mouseMoveEvent( void PointLocationCallback<Arr_>::
QGraphicsSceneMouseEvent* /* event */) mouseMoveEvent(QGraphicsSceneMouseEvent* /* event */) {
{
} }
//
template <typename Arr_> template <typename Arr_>
void PointLocationCallback<Arr_>::highlightPointLocation( void PointLocationCallback<Arr_>::
QGraphicsSceneMouseEvent* event) highlightPointLocation(QGraphicsSceneMouseEvent* event) {
{
typename Traits::Left_side_category category; typename Traits::Left_side_category category;
this->highlightPointLocation(event, category); this->highlightPointLocation(event, category);
Q_EMIT modelChanged(); Q_EMIT modelChanged();
} }
//
template <typename Arr_> template <typename Arr_>
void PointLocationCallback<Arr_>::highlightPointLocation( void PointLocationCallback<Arr_>::highlightPointLocation(
QGraphicsSceneMouseEvent* event, CGAL::Arr_oblivious_side_tag) QGraphicsSceneMouseEvent* event, CGAL::Arr_oblivious_side_tag)
@ -152,22 +153,19 @@ void PointLocationCallback<Arr_>::highlightPointLocation(
PointLocationFunctions<Arrangement>{}.getFace(this->arr, event->scenePos()); PointLocationFunctions<Arrangement>{}.getFace(this->arr, event->scenePos());
this->highlightedCurves->clear(); this->highlightedCurves->clear();
if (!face->is_unbounded()) if (!face->is_unbounded()) { // it is an interior face; highlight its border
{ // it is an interior face; highlight its border
Ccb_halfedge_const_circulator cc = face->outer_ccb(); Ccb_halfedge_const_circulator cc = face->outer_ccb();
do do {
{
X_monotone_curve_2 curve = cc->curve(); X_monotone_curve_2 curve = cc->curve();
this->highlightedCurves->insert(curve); this->highlightedCurves->insert(curve);
} while (++cc != face->outer_ccb()); } while (++cc != face->outer_ccb());
} }
Hole_const_iterator hit; Hole_const_iterator hit;
Hole_const_iterator eit = face->holes_end(); Hole_const_iterator eit = face->holes_end();
for (hit = face->holes_begin(); hit != eit; ++hit) for (hit = face->holes_begin(); hit != eit; ++hit) {
{ // highlight any holes inside this face // highlight any holes inside this face
Ccb_halfedge_const_circulator cc = *hit; Ccb_halfedge_const_circulator cc = *hit;
do do {
{
X_monotone_curve_2 curve = cc->curve(); X_monotone_curve_2 curve = cc->curve();
this->highlightedCurves->insert(curve); this->highlightedCurves->insert(curve);
cc++; cc++;
@ -175,30 +173,28 @@ void PointLocationCallback<Arr_>::highlightPointLocation(
} }
} }
//
template <typename Arr_> template <typename Arr_>
void PointLocationCallback<Arr_>::highlightPointLocation( void PointLocationCallback<Arr_>::
QGraphicsSceneMouseEvent* event, CGAL::Arr_open_side_tag) highlightPointLocation(QGraphicsSceneMouseEvent* event, CGAL::Arr_open_side_tag)
{ {
Face_const_handle face = Face_const_handle face =
PointLocationFunctions<Arrangement>{}.getFace(this->arr, event->scenePos()); PointLocationFunctions<Arrangement>{}.getFace(this->arr, event->scenePos());
this->highlightedCurves->clear(); this->highlightedCurves->clear();
Ccb_halfedge_const_circulator cc = face->outer_ccb(); Ccb_halfedge_const_circulator cc = face->outer_ccb();
do do {
{ if (!cc->is_fictitious()) {
if (!cc->is_fictitious())
{
X_monotone_curve_2 curve = cc->curve(); X_monotone_curve_2 curve = cc->curve();
this->highlightedCurves->insert(curve); this->highlightedCurves->insert(curve);
} }
} while (++cc != face->outer_ccb()); } while (++cc != face->outer_ccb());
Hole_const_iterator hit; Hole_const_iterator hit;
Hole_const_iterator eit = face->holes_end(); Hole_const_iterator eit = face->holes_end();
for (hit = face->holes_begin(); hit != eit; ++hit) for (hit = face->holes_begin(); hit != eit; ++hit) {
{ // highlight any holes inside this face // highlight any holes inside this face
Ccb_halfedge_const_circulator cc = *hit; Ccb_halfedge_const_circulator cc = *hit;
do do {
{
X_monotone_curve_2 curve = cc->curve(); X_monotone_curve_2 curve = cc->curve();
this->highlightedCurves->insert(curve); this->highlightedCurves->insert(curve);
cc++; cc++;

View File

@ -16,6 +16,7 @@
#include <CGAL/number_utils.h> #include <CGAL/number_utils.h>
#include <limits> #include <limits>
//
static const CGAL::Bbox_2 inf_bbox = { static const CGAL::Bbox_2 inf_bbox = {
-std::numeric_limits<double>::infinity(), -std::numeric_limits<double>::infinity(),
-std::numeric_limits<double>::infinity(), -std::numeric_limits<double>::infinity(),
@ -24,25 +25,27 @@ static const CGAL::Bbox_2 inf_bbox = {
static constexpr double inf_double = std::numeric_limits<double>::infinity(); static constexpr double inf_double = std::numeric_limits<double>::infinity();
template <typename Traits_> //
struct ConstructBoundingBox_impl template <typename GeometryTraits>
{ class ConstructBoundingBox_impl {
using Traits = Traits_; using Traits = GeometryTraits;
using X_monotone_curve_2 = typename Traits::X_monotone_curve_2; using X_monotone_curve_2 = typename Traits::X_monotone_curve_2;
using Curve_2 = typename Traits::Curve_2; using Curve_2 = typename Traits::Curve_2;
using Point_2 = typename Traits::Point_2; using Point_2 = typename Traits::Point_2;
CGAL::Bbox_2 public:
operator()(const X_monotone_curve_2& curve) // Construct from traits;
{ ConstructBoundingBox_impl(const Traits& traits) : m_traits(traits) {}
//
CGAL::Bbox_2 operator()(const X_monotone_curve_2& curve) {
#ifdef CGAL_USE_CORE #ifdef CGAL_USE_CORE
using Zero_resultant_exception = CGAL::internal::Zero_resultant_exception< using Zero_resultant_exception = CGAL::internal::Zero_resultant_exception<
typename demo_types::DemoTypes::Alg_seg_traits::Polynomial_2>; typename demo_types::DemoTypes::Alg_seg_traits::Polynomial_2>;
#endif #endif
CGAL::Bbox_2 bbox; CGAL::Bbox_2 bbox;
try try {
{
bbox = curve.bbox(); bbox = curve.bbox();
} }
// algebraic traits sometimes crash when calling bbox // algebraic traits sometimes crash when calling bbox
@ -70,13 +73,15 @@ struct ConstructBoundingBox_impl
return bbox; return bbox;
} }
CGAL::Bbox_2 //
operator()(const Point_2& point) CGAL::Bbox_2 operator()(const Point_2& point) {
{
double x = CGAL::to_double(point.x()); double x = CGAL::to_double(point.x());
double y = CGAL::to_double(point.y()); double y = CGAL::to_double(point.y());
return {x, y, x, y}; return {x, y, x, y};
} }
private:
const Traits& m_traits;
}; };
// We currently avoid using bbox function in Arr_sgegment_2 because it creates // We currently avoid using bbox function in Arr_sgegment_2 because it creates
@ -84,21 +89,22 @@ struct ConstructBoundingBox_impl
// TODO: remove this class and the polyline one once it's fixed // TODO: remove this class and the polyline one once it's fixed
// and use bbox directly // and use bbox directly
template <typename Kernel_> template <typename Kernel_>
struct ConstructBoundingBox_impl<CGAL::Arr_segment_traits_2<Kernel_>> class ConstructBoundingBox_impl<CGAL::Arr_segment_traits_2<Kernel_>> {
{
using Traits = CGAL::Arr_segment_traits_2<Kernel_>; using Traits = CGAL::Arr_segment_traits_2<Kernel_>;
using X_monotone_curve_2 = typename Traits::X_monotone_curve_2; using X_monotone_curve_2 = typename Traits::X_monotone_curve_2;
using Curve_2 = typename Traits::Curve_2; using Curve_2 = typename Traits::Curve_2;
using Point_2 = typename Traits::Point_2; using Point_2 = typename Traits::Point_2;
CGAL::Bbox_2 public:
operator()(const X_monotone_curve_2& curve) // Construct from traits;
{ ConstructBoundingBox_impl(const Traits& traits) : m_traits(traits) {}
return this->operator()(curve.source(), curve.target());
}
CGAL::Bbox_2 operator()(const Point_2& p1, const Point_2& p2) //
{ CGAL::Bbox_2 operator()(const X_monotone_curve_2& curve)
{ return this->operator()(curve.source(), curve.target()); }
//
CGAL::Bbox_2 operator()(const Point_2& p1, const Point_2& p2) {
CGAL::Bbox_2 bbox; CGAL::Bbox_2 bbox;
double x1 = CGAL::to_double(p1.x()); double x1 = CGAL::to_double(p1.x());
double y1 = CGAL::to_double(p1.y()); double y1 = CGAL::to_double(p1.y());
@ -106,40 +112,39 @@ struct ConstructBoundingBox_impl<CGAL::Arr_segment_traits_2<Kernel_>>
double y2 = CGAL::to_double(p2.y()); double y2 = CGAL::to_double(p2.y());
double min_x, max_x, min_y, max_y; double min_x, max_x, min_y, max_y;
if (x1 < x2) if (x1 < x2) {
{
min_x = x1; min_x = x1;
max_x = x2; max_x = x2;
} }
else else {
{
min_x = x2; min_x = x2;
max_x = x1; max_x = x1;
} }
if (y1 < y2) if (y1 < y2) {
{
min_y = y1; min_y = y1;
max_y = y2; max_y = y2;
} }
else else {
{
min_y = y2; min_y = y2;
max_y = y1; max_y = y1;
} }
return {min_x, min_y, max_x, max_y}; return {min_x, min_y, max_x, max_y};
} }
CGAL::Bbox_2 //
operator()(const Point_2& point) CGAL::Bbox_2 operator()(const Point_2& point) {
{
double x = CGAL::to_double(point.x()); double x = CGAL::to_double(point.x());
double y = CGAL::to_double(point.y()); double y = CGAL::to_double(point.y());
return {x, y, x, y}; return {x, y, x, y};
} }
private:
const Traits& m_traits;
}; };
//
template <typename SegmentTraits_2_> template <typename SegmentTraits_2_>
struct ConstructBoundingBox_impl<CGAL::Arr_polyline_traits_2<SegmentTraits_2_>> class ConstructBoundingBox_impl<CGAL::Arr_polyline_traits_2<SegmentTraits_2_>>
{ {
using Traits = CGAL::Arr_polyline_traits_2<SegmentTraits_2_>; using Traits = CGAL::Arr_polyline_traits_2<SegmentTraits_2_>;
using SegmentTraits_2 = SegmentTraits_2_; using SegmentTraits_2 = SegmentTraits_2_;
@ -147,21 +152,22 @@ struct ConstructBoundingBox_impl<CGAL::Arr_polyline_traits_2<SegmentTraits_2_>>
using Curve_2 = typename Traits::Curve_2; using Curve_2 = typename Traits::Curve_2;
using Point_2 = typename Traits::Point_2; using Point_2 = typename Traits::Point_2;
CGAL::Bbox_2 public:
operator()(const X_monotone_curve_2& curve) // Construct from traits;
{ ConstructBoundingBox_impl(const Traits& traits) : m_traits(traits) {}
ConstructBoundingBox_impl<SegmentTraits_2> construct_bounding_box;
//
CGAL::Bbox_2 operator()(const X_monotone_curve_2& curve) {
const auto* sub_traits = m_traits.subcurve_traits_2();
ConstructBoundingBox_impl<SegmentTraits_2> ctr_bbox(*sub_traits);
auto n = curve.number_of_subcurves(); auto n = curve.number_of_subcurves();
CGAL::Bbox_2 bbox; CGAL::Bbox_2 bbox;
for (std::size_t i = 0; i < n; ++i) for (std::size_t i = 0; i < n; ++i) bbox += ctr_bbox(curve[i]);
bbox += construct_bounding_box(curve[i]);
return bbox; return bbox;
} }
CGAL::Bbox_2 operator()(const Point_2& p1, const Point_2& p2) //
{ CGAL::Bbox_2 operator()(const Point_2& p1, const Point_2& p2) {
CGAL::Bbox_2 bbox; CGAL::Bbox_2 bbox;
double x1 = CGAL::to_double(p1.x()); double x1 = CGAL::to_double(p1.x());
double y1 = CGAL::to_double(p1.y()); double y1 = CGAL::to_double(p1.y());
@ -169,61 +175,57 @@ struct ConstructBoundingBox_impl<CGAL::Arr_polyline_traits_2<SegmentTraits_2_>>
double y2 = CGAL::to_double(p2.y()); double y2 = CGAL::to_double(p2.y());
double min_x, max_x, min_y, max_y; double min_x, max_x, min_y, max_y;
if (x1 < x2) if (x1 < x2) {
{
min_x = x1; min_x = x1;
max_x = x2; max_x = x2;
} }
else else {
{
min_x = x2; min_x = x2;
max_x = x1; max_x = x1;
} }
if (y1 < y2) if (y1 < y2) {
{
min_y = y1; min_y = y1;
max_y = y2; max_y = y2;
} }
else else {
{
min_y = y2; min_y = y2;
max_y = y1; max_y = y1;
} }
return {min_x, min_y, max_x, max_y}; return {min_x, min_y, max_x, max_y};
} }
CGAL::Bbox_2 //
operator()(const Point_2& point) CGAL::Bbox_2 operator()(const Point_2& point) {
{
double x = CGAL::to_double(point.x()); double x = CGAL::to_double(point.x());
double y = CGAL::to_double(point.y()); double y = CGAL::to_double(point.y());
return {x, y, x, y}; return {x, y, x, y};
} }
private:
const Traits& m_traits;
}; };
//
template <typename Kernel_> template <typename Kernel_>
struct ConstructBoundingBox_impl<CGAL::Arr_linear_traits_2<Kernel_>> class ConstructBoundingBox_impl<CGAL::Arr_linear_traits_2<Kernel_>> {
{
using Traits = CGAL::Arr_linear_traits_2<Kernel_>; using Traits = CGAL::Arr_linear_traits_2<Kernel_>;
using X_monotone_curve_2 = typename Traits::X_monotone_curve_2; using X_monotone_curve_2 = typename Traits::X_monotone_curve_2;
using Curve_2 = typename Traits::Curve_2; using Curve_2 = typename Traits::Curve_2;
using Point_2 = typename Traits::Point_2; using Point_2 = typename Traits::Point_2;
CGAL::Bbox_2 public:
operator()(const X_monotone_curve_2& curve) // Construct from traits;
{ ConstructBoundingBox_impl(const Traits& traits) : m_traits(traits) {}
if (curve.is_segment())
{ //
return ConstructBoundingBox_impl<CGAL::Arr_segment_traits_2<Kernel_>>{}( CGAL::Bbox_2 operator()(const X_monotone_curve_2& curve) {
curve.source(), curve.target()); if (curve.is_segment()) {
} auto&& seg = curve.segment();
else if (curve.is_line()) return operator()(seg.source()) + operator()(seg.target());
{
return inf_bbox;
} }
else if (curve.is_line()) return inf_bbox;
// ray // ray
else else {
{
auto&& ray = curve.ray(); auto&& ray = curve.ray();
auto&& src = ray.source(); auto&& src = ray.source();
double src_x = CGAL::to_double(src.x()); double src_x = CGAL::to_double(src.x());
@ -232,65 +234,101 @@ struct ConstructBoundingBox_impl<CGAL::Arr_linear_traits_2<Kernel_>>
bool dx = CGAL::is_positive(dir.dx()); bool dx = CGAL::is_positive(dir.dx());
bool dy = CGAL::is_positive(dir.dy()); bool dy = CGAL::is_positive(dir.dy());
if (dx && dy) if (dx && dy) return {src_x, src_y, inf_double, inf_double};
return {src_x, src_y, inf_double, inf_double}; else if (!dx && dy) return {-inf_double, src_y, src_x, inf_double};
else if (!dx && dy) else if (!dx && !dy) return {-inf_double, -inf_double, src_x, src_y};
return {-inf_double, src_y, src_x, inf_double};
else if (!dx && !dy)
return {-inf_double, -inf_double, src_x, src_y};
else // if (dx && !dy) else // if (dx && !dy)
return {src_x, -inf_double, inf_double, src_y}; return {src_x, -inf_double, inf_double, src_y};
} }
} }
CGAL::Bbox_2 operator()(const Point_2& point) //
{ CGAL::Bbox_2 operator()(const Point_2& point) {
double x = CGAL::to_double(point.x()); double x = CGAL::to_double(point.x());
double y = CGAL::to_double(point.y()); double y = CGAL::to_double(point.y());
return {x, y, x, y}; return {x, y, x, y};
} }
private:
const Traits& m_traits;
}; };
// Specialization of `ConstructBoundingBox_impl` for the conic traits.
template <typename RatKernel, typename AlgKernel, typename NtTraits>
class ConstructBoundingBox_impl
<CGAL::Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>> {
using Traits = CGAL::Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>;
using Point_2 = typename Traits::Point_2;
using X_monotone_curve_2 = typename Traits::X_monotone_curve_2;
template < public:
typename RatKernel_, typename AlgKernel_, typename NtTraits_, // Construct from traits;
ConstructBoundingBox_impl(const Traits& traits) : m_traits(traits) {}
// Obtain the bounding box for an x-monotone conic curve.
CGAL::Bbox_2 operator()(const X_monotone_curve_2& xcv)
{ return m_traits.construct_bbox_2_object()(xcv); }
// Obtain the bounding box for an conic point.
CGAL::Bbox_2 operator()(const Point_2& point) {
double x = CGAL::to_double(point.x());
double y = CGAL::to_double(point.y());
return {x, y, x, y};
}
private:
const Traits& m_traits;
};
// Specialization of `ConstructBoundingBox_impl` for the Bezier traits.
template <typename RatKernel_, typename AlgKernel_, typename NtTraits_,
typename BoundingTraits_> typename BoundingTraits_>
struct ConstructBoundingBox_impl<CGAL::Arr_Bezier_curve_traits_2< class ConstructBoundingBox_impl<CGAL::Arr_Bezier_curve_traits_2
RatKernel_, AlgKernel_, NtTraits_, BoundingTraits_>> <RatKernel_, AlgKernel_, NtTraits_,
BoundingTraits_>>
{ {
using Traits = typename CGAL::Arr_Bezier_curve_traits_2< using Traits = typename CGAL::Arr_Bezier_curve_traits_2
RatKernel_, AlgKernel_, NtTraits_, BoundingTraits_>; <RatKernel_, AlgKernel_, NtTraits_, BoundingTraits_>;
using X_monotone_curve_2 = typename Traits::X_monotone_curve_2; using X_monotone_curve_2 = typename Traits::X_monotone_curve_2;
using Curve_2 = typename Traits::Curve_2; using Curve_2 = typename Traits::Curve_2;
using Point_2 = typename Traits::Point_2; using Point_2 = typename Traits::Point_2;
CGAL::Bbox_2 public:
operator()(const X_monotone_curve_2& curve) // Construct from traits;
{ ConstructBoundingBox_impl(const Traits& traits) : m_traits(traits) {}
//
CGAL::Bbox_2 operator()(const X_monotone_curve_2& curve) {
// TODO: find a way to find the bounding box of a bezier X_monotone_curve // TODO: find a way to find the bounding box of a bezier X_monotone_curve
return curve.supporting_curve().bbox(); return curve.supporting_curve().bbox();
} }
CGAL::Bbox_2 //
operator()(const Point_2& point) CGAL::Bbox_2 operator()(const Point_2& point) {
{
std::pair<double, double> p = point.approximate(); std::pair<double, double> p = point.approximate();
return {p.first, p.second, p.first, p.second}; return {p.first, p.second, p.first, p.second};
} }
private:
const Traits& m_traits;
}; };
// Specialization of `ConstructBoundingBox_impl` for the rational-function
// traits.
template <typename AlgebraicKernel_d_1> template <typename AlgebraicKernel_d_1>
struct ConstructBoundingBox_impl< class ConstructBoundingBox_impl<CGAL::Arr_rational_function_traits_2
CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>> <AlgebraicKernel_d_1>> {
{
using Traits = CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>; using Traits = CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>;
using X_monotone_curve_2 = typename Traits::X_monotone_curve_2; using X_monotone_curve_2 = typename Traits::X_monotone_curve_2;
using Curve_2 = typename Traits::Curve_2; using Curve_2 = typename Traits::Curve_2;
using Point_2 = typename Traits::Point_2; using Point_2 = typename Traits::Point_2;
CGAL::Bbox_2 public:
operator()(const X_monotone_curve_2& curve) // Construct from traits;
{ ConstructBoundingBox_impl(const Traits& traits) : m_traits(traits) {}
//
CGAL::Bbox_2 operator()(const X_monotone_curve_2& curve) {
double min_x, max_x, min_y, max_y; double min_x, max_x, min_y, max_y;
if (curve.left_parameter_space_in_x() == CGAL::ARR_INTERIOR) if (curve.left_parameter_space_in_x() == CGAL::ARR_INTERIOR)
min_x = CGAL::to_double(curve.left_x()); min_x = CGAL::to_double(curve.left_x());
@ -313,25 +351,26 @@ struct ConstructBoundingBox_impl<
return {min_x, min_y, max_x, max_y}; return {min_x, min_y, max_x, max_y};
} }
CGAL::Bbox_2 //
operator()(const Point_2& point) CGAL::Bbox_2 operator()(const Point_2& point) {
{
double x = CGAL::to_double(point.x()); double x = CGAL::to_double(point.x());
double y = CGAL::to_double(point.y()); double y = CGAL::to_double(point.y());
return {x, y, x, y}; return {x, y, x, y};
} }
private:
const Traits& m_traits;
}; };
//
template <typename Arr_> template <typename Arr_>
CGAL::Bbox_2 CGAL::Bbox_2
ConstructBoundingBox<Arr_>::operator()(const X_monotone_curve_2& curve) ConstructBoundingBox<Arr_>::operator()(const X_monotone_curve_2& curve)
{ { return ConstructBoundingBox_impl<Traits>(m_traits)(curve); }
return ConstructBoundingBox_impl<Traits>{}(curve);
} //
template <typename Arr_> template <typename Arr_>
CGAL::Bbox_2 ConstructBoundingBox<Arr_>::operator()(const Point_2& point) CGAL::Bbox_2 ConstructBoundingBox<Arr_>::operator()(const Point_2& point)
{ { return ConstructBoundingBox_impl<Traits>(m_traits)(point); }
return ConstructBoundingBox_impl<Traits>{}(point);
}
ARRANGEMENT_DEMO_SPECIALIZE_TRAITS(ConstructBoundingBox) ARRANGEMENT_DEMO_SPECIALIZE_TRAITS(ConstructBoundingBox)

View File

@ -17,15 +17,23 @@
// bounding box utility for arrangements // bounding box utility for arrangements
// doesn't have to be exact, only good enough for rendering // doesn't have to be exact, only good enough for rendering
template <typename Traits_> template <typename Traits_>
class ConstructBoundingBox class ConstructBoundingBox {
{
public: public:
using Traits = Traits_; using Traits = Traits_;
using X_monotone_curve_2 = typename Traits::X_monotone_curve_2; using X_monotone_curve_2 = typename Traits::X_monotone_curve_2;
using Point_2 = typename Traits::Point_2; using Point_2 = typename Traits::Point_2;
// Construct from traits.
ConstructBoundingBox(const Traits& traits) : m_traits(traits) {}
//
CGAL::Bbox_2 operator()(const X_monotone_curve_2& curve); CGAL::Bbox_2 operator()(const X_monotone_curve_2& curve);
//
CGAL::Bbox_2 operator()(const Point_2& point); CGAL::Bbox_2 operator()(const Point_2& point);
private:
const Traits& m_traits;
}; };
#endif #endif

View File

@ -23,11 +23,11 @@
#include <CGAL/Arr_default_overlay_traits.h> #include <CGAL/Arr_default_overlay_traits.h>
#include <CGAL/Arr_overlay_2.h> #include <CGAL/Arr_overlay_2.h>
//
template <typename Kernel_> template <typename Kernel_>
double double
Compute_squared_distance_2<CGAL::Arr_segment_traits_2<Kernel_>>::operator()( Compute_squared_distance_2<CGAL::Arr_segment_traits_2<Kernel_>>::
const Point_2& p, const X_monotone_curve_2& c) const operator()(const Point_2& p, const X_monotone_curve_2& c) const {
{
Point_2 p1 = c.source(); Point_2 p1 = c.source();
Point_2 p2 = c.target(); Point_2 p2 = c.target();
Segment_2 seg(p1, p2); Segment_2 seg(p1, p2);
@ -35,33 +35,31 @@ Compute_squared_distance_2<CGAL::Arr_segment_traits_2<Kernel_>>::operator()(
return CGAL::to_double(CGAL::squared_distance(p, seg)); return CGAL::to_double(CGAL::squared_distance(p, seg));
} }
//
template <typename Kernel_> template <typename Kernel_>
double double
Compute_squared_distance_2<CGAL::Arr_linear_traits_2<Kernel_>>::operator()( Compute_squared_distance_2<CGAL::Arr_linear_traits_2<Kernel_>>::
const Point_2& p, const X_monotone_curve_2& c) const operator()(const Point_2& p, const X_monotone_curve_2& c) const {
{
Segment_2 seg; Segment_2 seg;
Ray_2 ray; Ray_2 ray;
Line_2 line; Line_2 line;
FT res; FT res;
if (c.is_segment()) if (c.is_segment()) {
{
seg = c.segment(); seg = c.segment();
res = CGAL::squared_distance(p, seg); res = CGAL::squared_distance(p, seg);
} }
else if (c.is_ray()) else if (c.is_ray()) {
{
ray = c.ray(); ray = c.ray();
res = CGAL::squared_distance(p, ray); res = CGAL::squared_distance(p, ray);
} }
else // ( c.is_line( ) ) else {// ( c.is_line( ) )
{
line = c.line(); line = c.line();
res = CGAL::squared_distance(p, line); res = CGAL::squared_distance(p, line);
} }
return CGAL::to_double(res); return CGAL::to_double(res);
} }
//
template <typename Kernel_> template <typename Kernel_>
double double
Compute_squared_distance_2<CGAL::Arr_polyline_traits_2<Kernel_>>::operator()( Compute_squared_distance_2<CGAL::Arr_polyline_traits_2<Kernel_>>::operator()(
@ -72,13 +70,11 @@ Compute_squared_distance_2<CGAL::Arr_polyline_traits_2<Kernel_>>::operator()(
bool first = true; bool first = true;
FT min_dist = 0; FT min_dist = 0;
while (seg_it_s != c.subcurves_end()) while (seg_it_s != c.subcurves_end()) {
{
Segment_2 seg = *seg_it_s; Segment_2 seg = *seg_it_s;
FT dist = CGAL::squared_distance(p, seg); FT dist = CGAL::squared_distance(p, seg);
if (first || dist < min_dist) if (first || dist < min_dist) {
{
first = false; first = false;
min_dist = dist; min_dist = dist;
} }
@ -88,19 +84,18 @@ Compute_squared_distance_2<CGAL::Arr_polyline_traits_2<Kernel_>>::operator()(
return CGAL::to_double(min_dist); return CGAL::to_double(min_dist);
} }
//
template <typename RatKernel, typename AlgKernel, typename NtTraits> template <typename RatKernel, typename AlgKernel, typename NtTraits>
double Compute_squared_distance_2< double Compute_squared_distance_2
CGAL::Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>>:: <CGAL::Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>>::
operator()(const Point_2& p, const X_monotone_curve_2& c) const operator()(const Point_2& p, const X_monotone_curve_2& c) const {
{ // Get the coordinates of the curve source and target.
// Get the coordinates of the curve's source and target.
// double sx = CGAL::to_double( c.source( ).x( ) ); // double sx = CGAL::to_double( c.source( ).x( ) );
// double sy = CGAL::to_double( c.source( ).y( ) ); // double sy = CGAL::to_double( c.source( ).y( ) );
// double tx = CGAL::to_double( c.target( ).x( ) ); // double tx = CGAL::to_double( c.target( ).x( ) );
// double ty = CGAL::to_double( c.target( ).y( ) ); // double ty = CGAL::to_double( c.target( ).y( ) );
if (c.orientation() == CGAL::COLLINEAR) if (c.orientation() == CGAL::COLLINEAR) {
{
Point_2 ps = c.source(); Point_2 ps = c.source();
Point_2 pt = c.target(); Point_2 pt = c.target();
Segment_2 seg(ps, pt); Segment_2 seg(ps, pt);
@ -108,8 +103,7 @@ operator()(const Point_2& p, const X_monotone_curve_2& c) const
FT res = CGAL::squared_distance(p, seg); FT res = CGAL::squared_distance(p, seg);
return CGAL::to_double(res); return CGAL::to_double(res);
} }
else else {
{
// If the curve is monotone, than its source and its target has the // If the curve is monotone, than its source and its target has the
// extreme x coordinates on this curve. // extreme x coordinates on this curve.
// bool is_source_left = (sx < tx); // bool is_source_left = (sx < tx);
@ -126,10 +120,11 @@ operator()(const Point_2& p, const X_monotone_curve_2& c) const
// AlgKernel ker; // AlgKernel ker;
int n = 100; int n = 100;
if (this->scene != nullptr && this->scene->views().size() != 0) if (this->scene != nullptr && this->scene->views().size() != 0) {
{ // use the scene to approximate the resolution of the curve // use the scene to approximate the resolution of the curve
QGraphicsView* view = this->scene->views().first(); QGraphicsView* view = this->scene->views().first();
CGAL::Bbox_2 bb = c.bbox(); // assumes bounded curve // assumes bounded curve
CGAL::Bbox_2 bb = this->m_traits.construct_bbox_2_object()(c);
int xmin = view->mapFromScene(bb.xmin(), bb.ymin()).x(); int xmin = view->mapFromScene(bb.xmin(), bb.ymin()).x();
int xmax = view->mapFromScene(bb.xmax(), bb.ymin()).x(); int xmax = view->mapFromScene(bb.xmax(), bb.ymin()).x();
n = xmax - xmin; n = xmax - xmin;
@ -142,34 +137,32 @@ operator()(const Point_2& p, const X_monotone_curve_2& c) const
auto end_pts = app_pts.end(); auto end_pts = app_pts.end();
auto p_curr = app_pts.begin(); auto p_curr = app_pts.begin();
auto p_next = p_curr + 1; auto p_next = p_curr + 1;
do do {
{
Point_2 p1(p_curr->first, p_curr->second); Point_2 p1(p_curr->first, p_curr->second);
Point_2 p2(p_next->first, p_next->second); Point_2 p2(p_next->first, p_next->second);
Segment_2 seg(p1, p2); Segment_2 seg(p1, p2);
FT dist = CGAL::squared_distance(p, seg); FT dist = CGAL::squared_distance(p, seg);
if (first || dist < min_dist) if (first || dist < min_dist) {
{
first = false; first = false;
min_dist = dist; min_dist = dist;
} }
p_curr++; ++p_curr;
p_next++; ++p_next;
} while (p_next != end_pts); } while (p_next != end_pts);
return CGAL::to_double(min_dist); return CGAL::to_double(min_dist);
} }
} }
template < //
typename RatKernel, typename AlgKernel, typename NtTraits, template <typename RatKernel, typename AlgKernel, typename NtTraits,
typename BoundingTraits> typename BoundingTraits>
double Compute_squared_distance_2<CGAL::Arr_Bezier_curve_traits_2< double Compute_squared_distance_2<CGAL::Arr_Bezier_curve_traits_2
RatKernel, AlgKernel, NtTraits, BoundingTraits>>:: <RatKernel, AlgKernel, NtTraits,
operator()(const Point_2& p, const X_monotone_curve_2& curve) const BoundingTraits>>::
{ operator()(const Point_2& p, const X_monotone_curve_2& curve) const {
// TODO: this should probably be cached! // TODO: this should probably be cached!
CGAL::Qt::ArrangementPainterOstream<Traits> painterOstream{nullptr}; CGAL::Qt::ArrangementPainterOstream<Traits> painterOstream{nullptr};
painterOstream.setScene(this->getScene()); painterOstream.setScene(this->getScene());
@ -177,23 +170,22 @@ operator()(const Point_2& p, const X_monotone_curve_2& curve) const
std::pair<double, double> p_pair = { std::pair<double, double> p_pair = {
CGAL::to_double(p.x()), CGAL::to_double(p.y())}; CGAL::to_double(p.x()), CGAL::to_double(p.y())};
double minDist = (std::numeric_limits<double>::max)(); double min_dist = (std::numeric_limits<double>::max)();
auto points = painterOstream.getPoints(curve); auto points = painterOstream.getPoints(curve);
for (auto& vit : points) for (auto& vit : points) {
{
QPointF coord(vit.first, vit.second); QPointF coord(vit.first, vit.second);
float curDist = (vit.first - p_pair.first) * (vit.first - p_pair.first) + float cur_dist = (vit.first - p_pair.first) * (vit.first - p_pair.first) +
(vit.second - p_pair.second) * (vit.second - p_pair.second); (vit.second - p_pair.second) * (vit.second - p_pair.second);
minDist = curDist < minDist ? curDist : minDist; min_dist = cur_dist < min_dist ? cur_dist : min_dist;
} }
return minDist; return min_dist;
} }
//
template <typename Coefficient_> template <typename Coefficient_>
double double
Compute_squared_distance_2<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>:: Compute_squared_distance_2<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>::
operator()(const Point_2& p, const X_monotone_curve_2& curve) const operator()(const Point_2& p, const X_monotone_curve_2& curve) const {
{
// TODO: this should probably be cached! // TODO: this should probably be cached!
CGAL::Qt::ArrangementPainterOstream<Traits> painterOstream{nullptr}; CGAL::Qt::ArrangementPainterOstream<Traits> painterOstream{nullptr};
painterOstream.setScene(this->getScene()); painterOstream.setScene(this->getScene());
@ -212,77 +204,73 @@ operator()(const Point_2& p, const X_monotone_curve_2& curve) const
QPoint p_viewport = QPoint p_viewport =
view->mapFromScene(QPointF{p.x().doubleValue(), p.y().doubleValue()}); view->mapFromScene(QPointF{p.x().doubleValue(), p.y().doubleValue()});
double minDist = (std::numeric_limits<double>::max)(); double min_dist = (std::numeric_limits<double>::max)();
for (auto& vec : points) for (auto& vec : points) {
{ for (auto vit = vec.begin(); vit != vec.end(); ++vit) {
for (auto vit = vec.begin(); vit != vec.end(); ++vit)
{
QPoint coord(vit->first, vit->second); QPoint coord(vit->first, vit->second);
float curDist = QLineF{facadeToViewport.map(coord), p_viewport}.length(); float cur_dist = QLineF{facadeToViewport.map(coord), p_viewport}.length();
minDist = curDist < minDist ? curDist : minDist; min_dist = cur_dist < min_dist ? cur_dist : min_dist;
} }
} }
return minDist; return min_dist;
} }
//
template <typename AlgebraicKernel_d_1> template <typename AlgebraicKernel_d_1>
double Compute_squared_distance_2< double Compute_squared_distance_2<
CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>>:: CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>>::
operator()(const Point_2& p, const X_monotone_curve_2& curve) const operator()(const Point_2& p, const X_monotone_curve_2& curve) const {
{
// TODO: this should probably be cached! // TODO: this should probably be cached!
CGAL::Qt::ArrangementPainterOstream<Traits> painterOstream{nullptr}; CGAL::Qt::ArrangementPainterOstream<Traits> painter_ostream{nullptr};
painterOstream.setScene(this->getScene()); painter_ostream.setScene(this->getScene());
std::pair<double, double> p_pair = { std::pair<double, double> p_pair = {
CGAL::to_double(p.x()), CGAL::to_double(p.y())}; CGAL::to_double(p.x()), CGAL::to_double(p.y())
};
double minDist = (std::numeric_limits<double>::max)(); double min_dist = (std::numeric_limits<double>::max)();
auto points_list = painterOstream.getPointsList(curve); auto points_list = painter_ostream.getPointsList(curve);
for (auto& points : points_list) for (auto& points : points_list) {
{ for (auto& vit : points) {
for (auto& vit : points)
{
QPointF coord(vit.first, vit.second); QPointF coord(vit.first, vit.second);
float curDist = float cur_dist =
(vit.first - p_pair.first) * (vit.first - p_pair.first) + (vit.first - p_pair.first) * (vit.first - p_pair.first) +
(vit.second - p_pair.second) * (vit.second - p_pair.second); (vit.second - p_pair.second) * (vit.second - p_pair.second);
minDist = curDist < minDist ? curDist : minDist; min_dist = cur_dist < min_dist ? cur_dist : min_dist;
} }
} }
return minDist; return min_dist;
} }
//
template <typename ArrTraits> template <typename ArrTraits>
auto Arr_construct_point_2<ArrTraits>::operator()(const Kernel_point_2& pt) auto Arr_construct_point_2<ArrTraits>::
-> Point_2 operator()(const Kernel_point_2& pt) -> Point_2
{ { return (*this)(FT{pt.x()}, FT{pt.y()}, traits); }
return (*this)(FT{pt.x()}, FT{pt.y()}, traits);
}
//
template <typename ArrTraits> template <typename ArrTraits>
auto Arr_construct_point_2<ArrTraits>::operator()(const FT& x, const FT& y) auto Arr_construct_point_2<ArrTraits>::
-> Point_2 operator()(const FT& x, const FT& y) -> Point_2
{ { return (*this)(x, y, traits); }
return (*this)(x, y, traits);
}
//
template <typename ArrTraits> template <typename ArrTraits>
template <typename TTraits> template <typename TTraits>
auto Arr_construct_point_2<ArrTraits>::operator()( auto Arr_construct_point_2<ArrTraits>::
const FT& x, const FT& y, const TTraits*) -> Point_2 operator()(const FT& x, const FT& y, const TTraits*) -> Point_2 {
{
CoordinateType xx(x); CoordinateType xx(x);
CoordinateType yy(y); CoordinateType yy(y);
Point_2 res(xx, yy); Point_2 res(xx, yy);
return res; return res;
} }
//
template <typename ArrTraits> template <typename ArrTraits>
template <typename AlgebraicKernel_d_1> template <typename AlgebraicKernel_d_1>
auto Arr_construct_point_2<ArrTraits>::operator()( auto Arr_construct_point_2<ArrTraits>::
const FT& x, const FT& y, operator()(const FT& x, const FT& y,
const CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>*) const CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>*)
-> Point_2 -> Point_2
{ {
@ -304,46 +292,44 @@ auto Arr_construct_point_2<ArrTraits>::operator()(
return res; return res;
} }
//
template <typename Arr_> template <typename Arr_>
auto Find_nearest_edge<Arr_>::operator()(const Point_2& queryPt) auto Find_nearest_edge<Arr_>::operator()(const Point_2& query_pt)
-> Halfedge_const_handle -> Halfedge_const_handle
{ {
Face_const_handle face = Face_const_handle face =
PointLocationFunctions<Arrangement>{}.getFace(arr, queryPt); PointLocationFunctions<Arrangement>{}.getFace(arr, query_pt);
bool first = 1; bool first = 1;
X_monotone_curve_2 closestCurve; X_monotone_curve_2 closestCurve;
Halfedge_const_handle closestEdge; Halfedge_const_handle closestEdge;
double minDist(0); double min_dist(0);
if (!face->is_unbounded()) const auto& traits = arr->geometry_traits();
{ // it is an interior face so it has a ccb Point_curve_distance point_curve_distance(*traits);
if (! face->is_unbounded()) {
// it is an interior face so it has a ccb
Ccb_halfedge_const_circulator cc = face->outer_ccb(); Ccb_halfedge_const_circulator cc = face->outer_ccb();
do do {
{
X_monotone_curve_2 curve = cc->curve(); X_monotone_curve_2 curve = cc->curve();
double dist = this->pointCurveDistance(queryPt, curve); double dist = point_curve_distance(query_pt, curve);
if (first || dist < minDist) if (first || dist < min_dist) {
{
first = 0; first = 0;
minDist = dist; min_dist = dist;
closestEdge = cc; closestEdge = cc;
} }
} while (++cc != face->outer_ccb()); } while (++cc != face->outer_ccb());
} }
else if (face->has_outer_ccb()) else if (face->has_outer_ccb()) {
{
Ccb_halfedge_const_circulator cc = face->outer_ccb(); Ccb_halfedge_const_circulator cc = face->outer_ccb();
do do {
{ if (cc->is_fictitious()) continue;
if (cc->is_fictitious()) { continue; }
X_monotone_curve_2 curve = cc->curve(); X_monotone_curve_2 curve = cc->curve();
double dist = this->pointCurveDistance(queryPt, curve); double dist = point_curve_distance(query_pt, curve);
if (first || dist < minDist) if (first || dist < min_dist) {
{
first = 0; first = 0;
minDist = dist; min_dist = dist;
closestEdge = cc; closestEdge = cc;
} }
} while (++cc != face->outer_ccb()); } while (++cc != face->outer_ccb());
@ -351,17 +337,15 @@ auto Find_nearest_edge<Arr_>::operator()(const Point_2& queryPt)
Hole_const_iterator hit; Hole_const_iterator hit;
Hole_const_iterator eit = face->holes_end(); Hole_const_iterator eit = face->holes_end();
// int counter = 0; // int counter = 0;
for (hit = face->holes_begin(); hit != eit; ++hit) for (hit = face->holes_begin(); hit != eit; ++hit) {
{ // check any holes inside this face // check any holes inside this face
Ccb_halfedge_const_circulator cc = *hit; Ccb_halfedge_const_circulator cc = *hit;
do do {
{
X_monotone_curve_2 curve = cc->curve(); X_monotone_curve_2 curve = cc->curve();
double dist = this->pointCurveDistance(queryPt, curve); double dist = point_curve_distance(query_pt, curve);
if (first || dist < minDist) if (first || dist < min_dist) {
{
first = 0; first = 0;
minDist = dist; min_dist = dist;
closestEdge = cc; closestEdge = cc;
} }
cc++; cc++;
@ -371,6 +355,7 @@ auto Find_nearest_edge<Arr_>::operator()(const Point_2& queryPt)
return closestEdge; return closestEdge;
} }
//
template <typename Arr_> template <typename Arr_>
auto Find_nearest_edge<Arr_>::getFace(const CGAL::Object& obj) auto Find_nearest_edge<Arr_>::getFace(const CGAL::Object& obj)
-> Face_const_handle -> Face_const_handle
@ -389,6 +374,7 @@ auto Find_nearest_edge<Arr_>::getFace(const CGAL::Object& obj)
return (eit->face()); return (eit->face());
} }
//
template <typename ArrTraits> template <typename ArrTraits>
Construct_x_monotone_subcurve_2<ArrTraits>::Construct_x_monotone_subcurve_2( Construct_x_monotone_subcurve_2<ArrTraits>::Construct_x_monotone_subcurve_2(
const ArrTraits* traits_) : const ArrTraits* traits_) :
@ -402,6 +388,7 @@ Construct_x_monotone_subcurve_2<ArrTraits>::Construct_x_monotone_subcurve_2(
{ {
} }
//
template <typename ArrTraits> template <typename ArrTraits>
auto Construct_x_monotone_subcurve_2<ArrTraits>::operator()( auto Construct_x_monotone_subcurve_2<ArrTraits>::operator()(
const X_monotone_curve_2& curve, const boost::optional<Point_2>& pLeft, const X_monotone_curve_2& curve, const boost::optional<Point_2>& pLeft,
@ -424,47 +411,45 @@ auto Construct_x_monotone_subcurve_2<ArrTraits>::operator()(
X_monotone_curve_2 subcurve; X_monotone_curve_2 subcurve;
X_monotone_curve_2 unusedTrimmings; X_monotone_curve_2 unusedTrimmings;
X_monotone_curve_2 finalSubcurve; X_monotone_curve_2 finalSubcurve;
if ( if (pLeft &&
pLeft && (unbounded_min || this->compare_x_2(*pLeft, pMin) == CGAL::LARGER)) (unbounded_min || this->compare_x_2(*pLeft, pMin) == CGAL::LARGER))
{ {
auto y1 = this->compute_y_at_x(curve, pLeft->x()); auto y1 = this->compute_y_at_x(curve, pLeft->x());
Point_2 splitPoint = {pLeft->x(), y1}; Point_2 splitPoint = {pLeft->x(), y1};
this->split_2(curve, splitPoint, unusedTrimmings, subcurve); this->split_2(curve, splitPoint, unusedTrimmings, subcurve);
} }
else else {
{
subcurve = curve; subcurve = curve;
} }
if ( if (pRight &&
pRight &&
(unbounded_max || this->compare_x_2(*pRight, pMax) == CGAL::SMALLER)) (unbounded_max || this->compare_x_2(*pRight, pMax) == CGAL::SMALLER))
{ {
auto y2 = this->compute_y_at_x(subcurve, pRight->x()); auto y2 = this->compute_y_at_x(subcurve, pRight->x());
Point_2 splitPoint = {pRight->x(), y2}; Point_2 splitPoint = {pRight->x(), y2};
this->split_2(subcurve, splitPoint, finalSubcurve, unusedTrimmings); this->split_2(subcurve, splitPoint, finalSubcurve, unusedTrimmings);
} }
else else {
{
finalSubcurve = subcurve; finalSubcurve = subcurve;
} }
return finalSubcurve; return finalSubcurve;
} }
//
template <typename RatKernel, typename AlgKernel, typename NtTraits> template <typename RatKernel, typename AlgKernel, typename NtTraits>
auto Construct_x_monotone_subcurve_2< auto Construct_x_monotone_subcurve_2
CGAL::Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>>:: <CGAL::Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>>::
operator()( operator()(const X_monotone_curve_2& curve,
const X_monotone_curve_2& curve, const boost::optional<Point_2>& pLeft, const boost::optional<Point_2>& pLeft,
const boost::optional<Point_2>& pRight) -> X_monotone_curve_2 const boost::optional<Point_2>& pRight) -> X_monotone_curve_2
{ {
// TODO: handle when pLeft or pRight is null // TODO: handle when pLeft or pRight is null
// find the points on the curve // find the points on the curve
Point_2 left = curve.point_at_x(*pLeft); Point_2 left = m_traits.point_at_x(curve, *pLeft);
Point_2 right = curve.point_at_x(*pRight); Point_2 right = m_traits.point_at_x(curve, *pRight);
// make sure the points are oriented in the direction that the curve is // make sure the points are oriented in the direction that the curve is
// going // going
@ -475,16 +460,17 @@ operator()(
ker.compare_xy_2_object()(left, right) == CGAL::LARGER))) ker.compare_xy_2_object()(left, right) == CGAL::LARGER)))
{ std::swap(left, right); } { std::swap(left, right); }
X_monotone_curve_2 res = curve.trim(left, right); X_monotone_curve_2 res = m_traits.trim_2_object()(curve, left, right);
return res; return res;
} }
template < //
typename RatKernel, typename AlgKernel, typename NtTraits, template <typename RatKernel, typename AlgKernel, typename NtTraits,
typename BoundingTraits> typename BoundingTraits>
Construct_x_monotone_subcurve_2<CGAL::Arr_Bezier_curve_traits_2< Construct_x_monotone_subcurve_2<CGAL::Arr_Bezier_curve_traits_2
RatKernel, AlgKernel, NtTraits, <RatKernel, AlgKernel, NtTraits,
BoundingTraits>>::Construct_x_monotone_subcurve_2(const ArrTraits* traits_) : BoundingTraits>>::
Construct_x_monotone_subcurve_2(const ArrTraits* traits_) :
traits(traits_), traits(traits_),
split_2(this->traits->split_2_object()), split_2(this->traits->split_2_object()),
compare_x_2(this->traits->compare_x_2_object()), compare_x_2(this->traits->compare_x_2_object()),
@ -494,8 +480,8 @@ Construct_x_monotone_subcurve_2<CGAL::Arr_Bezier_curve_traits_2<
{ {
} }
template < //
typename RatKernel, typename AlgKernel, typename NtTraits, template <typename RatKernel, typename AlgKernel, typename NtTraits,
typename BoundingTraits> typename BoundingTraits>
auto Construct_x_monotone_subcurve_2<CGAL::Arr_Bezier_curve_traits_2< auto Construct_x_monotone_subcurve_2<CGAL::Arr_Bezier_curve_traits_2<
RatKernel, AlgKernel, NtTraits, BoundingTraits>>:: RatKernel, AlgKernel, NtTraits, BoundingTraits>>::
@ -516,40 +502,35 @@ operator()(
// at algebraic "x", so we need to make it rational // at algebraic "x", so we need to make it rational
auto local_get_t = [&](auto&& point) { auto local_get_t = [&](auto&& point) {
if (point.is_rational()) if (point.is_rational())
return this->compute_y_at_x.get_t( return this->compute_y_at_x.get_t(curve, ((typename Point_2::Rat_point_2)point).x());
curve, ((typename Point_2::Rat_point_2)point).x());
else else
return this->compute_y_at_x.get_t(curve, point.approximate().first); return this->compute_y_at_x.get_t(curve, point.approximate().first);
}; };
if (pLeft && this->compare_x_2(*pLeft, pMin) == CGAL::LARGER) if (pLeft && this->compare_x_2(*pLeft, pMin) == CGAL::LARGER) {
{
auto t = local_get_t(*pLeft); auto t = local_get_t(*pLeft);
Point_2 splitPoint(curve.supporting_curve(), t); Point_2 splitPoint(curve.supporting_curve(), t);
this->split_2(curve, splitPoint, unusedTrimmings, subcurve); this->split_2(curve, splitPoint, unusedTrimmings, subcurve);
} }
else else {
{
subcurve = curve; subcurve = curve;
} }
if (pRight && this->compare_x_2(*pRight, pMax) == CGAL::SMALLER) if (pRight && this->compare_x_2(*pRight, pMax) == CGAL::SMALLER) {
{
auto t = local_get_t(*pRight); auto t = local_get_t(*pRight);
Point_2 splitPoint(curve.supporting_curve(), t); Point_2 splitPoint(curve.supporting_curve(), t);
this->split_2(subcurve, splitPoint, finalSubcurve, unusedTrimmings); this->split_2(subcurve, splitPoint, finalSubcurve, unusedTrimmings);
} }
else else {
{
finalSubcurve = subcurve; finalSubcurve = subcurve;
} }
return finalSubcurve; return finalSubcurve;
} }
//
template <typename AlgebraicKernel_d_1> template <typename AlgebraicKernel_d_1>
Construct_x_monotone_subcurve_2<CGAL::Arr_rational_function_traits_2< Construct_x_monotone_subcurve_2<CGAL::Arr_rational_function_traits_2<
AlgebraicKernel_d_1>>::Construct_x_monotone_subcurve_2(const Traits* AlgebraicKernel_d_1>>::Construct_x_monotone_subcurve_2(const Traits* traits_) :
traits_) :
traits(traits_), traits(traits_),
split_2(this->traits->split_2_object()), split_2(this->traits->split_2_object()),
compare_x_2(this->traits->compare_x_2_object()), compare_x_2(this->traits->compare_x_2_object()),
@ -559,6 +540,7 @@ Construct_x_monotone_subcurve_2<CGAL::Arr_rational_function_traits_2<
{ {
} }
//
template <typename AlgebraicKernel_d_1> template <typename AlgebraicKernel_d_1>
auto Construct_x_monotone_subcurve_2< auto Construct_x_monotone_subcurve_2<
CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>>:: CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>>::
@ -577,33 +559,31 @@ operator()(
X_monotone_curve_2 subcurve; X_monotone_curve_2 subcurve;
X_monotone_curve_2 unusedTrimmings; X_monotone_curve_2 unusedTrimmings;
X_monotone_curve_2 finalSubcurve; X_monotone_curve_2 finalSubcurve;
if ( if (pLeft &&
pLeft && (unbounded_min || this->compare_x_2(*pLeft, pMin) == CGAL::LARGER)) (unbounded_min || this->compare_x_2(*pLeft, pMin) == CGAL::LARGER))
{ {
Point_2 splitPoint{curve._f, pLeft->x()}; Point_2 splitPoint{curve._f, pLeft->x()};
this->split_2(curve, splitPoint, unusedTrimmings, subcurve); this->split_2(curve, splitPoint, unusedTrimmings, subcurve);
} }
else else {
{
subcurve = curve; subcurve = curve;
} }
if ( if (pRight &&
pRight &&
(unbounded_max || this->compare_x_2(*pRight, pMax) == CGAL::SMALLER)) (unbounded_max || this->compare_x_2(*pRight, pMax) == CGAL::SMALLER))
{ {
auto y2 = this->compute_y_at_x(subcurve, pRight->x()); auto y2 = this->compute_y_at_x(subcurve, pRight->x());
Point_2 splitPoint{curve._f, pRight->x()}; Point_2 splitPoint{curve._f, pRight->x()};
this->split_2(subcurve, splitPoint, finalSubcurve, unusedTrimmings); this->split_2(subcurve, splitPoint, finalSubcurve, unusedTrimmings);
} }
else else {
{
finalSubcurve = subcurve; finalSubcurve = subcurve;
} }
return finalSubcurve; return finalSubcurve;
} }
//
template <typename ArrTraits> template <typename ArrTraits>
Arr_compute_y_at_x_2<ArrTraits>::Arr_compute_y_at_x_2(const Traits* traits_) : Arr_compute_y_at_x_2<ArrTraits>::Arr_compute_y_at_x_2(const Traits* traits_) :
traits(traits_), traits(traits_),
@ -611,61 +591,61 @@ Arr_compute_y_at_x_2<ArrTraits>::Arr_compute_y_at_x_2(const Traits* traits_) :
{ {
} }
//
template <typename ArrTraits> template <typename ArrTraits>
auto Arr_compute_y_at_x_2<ArrTraits>::operator()( auto Arr_compute_y_at_x_2<ArrTraits>::
const X_monotone_curve_2& curve, const CoordinateType& x) -> CoordinateType operator()(const X_monotone_curve_2& curve, const CoordinateType& x)
-> CoordinateType
{ {
typename Traits::Left_side_category category; typename Traits::Left_side_category category;
return this->operator()(curve, x, this->traits, category); return this->operator()(curve, x, this->traits, category);
} }
//
template <typename ArrTraits> template <typename ArrTraits>
double Arr_compute_y_at_x_2<ArrTraits>::approx( double Arr_compute_y_at_x_2<ArrTraits>::
const X_monotone_curve_2& curve, const CoordinateType& x) approx(const X_monotone_curve_2& curve, const CoordinateType& x)
{ {
return CGAL::to_double((*this)(curve, x)); return CGAL::to_double((*this)(curve, x));
} }
//
template <typename ArrTraits> template <typename ArrTraits>
template <typename TTraits> template <typename TTraits>
auto Arr_compute_y_at_x_2<ArrTraits>::operator()( auto Arr_compute_y_at_x_2<ArrTraits>::
const X_monotone_curve_2& curve, const CoordinateType& x, operator()(const X_monotone_curve_2& curve, const CoordinateType& x,
const TTraits* traits_, CGAL::Arr_oblivious_side_tag) -> CoordinateType const TTraits* traits_, CGAL::Arr_oblivious_side_tag)
-> CoordinateType
{ {
typedef auto ctr_xcv = traits_->construct_x_monotone_curve_2_object();
typename TTraits::Construct_x_monotone_curve_2 Construct_x_monotone_curve_2;
Construct_x_monotone_curve_2 construct_x_monotone_curve_2 =
traits_->construct_x_monotone_curve_2_object();
CoordinateType res(0); CoordinateType res(0);
CGAL::Bbox_2 clipRect = curve.bbox(); CGAL::Bbox_2 clipRect = curve.bbox();
Point_2 p1c1(x, CoordinateType(clipRect.ymin() - 1)); // clicked point Point_2 p1c1(x, CoordinateType(clipRect.ymin() - 1)); // clicked point
// upper bounding box // upper bounding box
Point_2 p2c1(x, CoordinateType(clipRect.ymax() + 1)); Point_2 p2c1(x, CoordinateType(clipRect.ymax() + 1));
const X_monotone_curve_2 verticalLine = const X_monotone_curve_2 verticalLine = ctr_xcv(p1c1, p2c1);
construct_x_monotone_curve_2(p1c1, p2c1);
CGAL::Object o; CGAL::Object o;
CGAL::Oneset_iterator<CGAL::Object> oi(o); CGAL::Oneset_iterator<CGAL::Object> oi(o);
this->intersectCurves(curve, verticalLine, oi); this->intersectCurves(curve, verticalLine, oi);
IntersectionResult pair; IntersectionResult pair;
if (CGAL::assign(pair, o)) if (CGAL::assign(pair, o)) {
{
Point_2 pt = pair.first; Point_2 pt = pair.first;
res = pt.y(); res = pt.y();
} }
return res; return res;
} }
//
template <typename ArrTraits> template <typename ArrTraits>
template <typename TTraits> template <typename TTraits>
auto Arr_compute_y_at_x_2<ArrTraits>::operator()( auto Arr_compute_y_at_x_2<ArrTraits>::
const X_monotone_curve_2& curve, const CoordinateType& x, operator()(const X_monotone_curve_2& curve, const CoordinateType& x,
const TTraits* traits_, CGAL::Arr_open_side_tag) -> CoordinateType const TTraits* traits_, CGAL::Arr_open_side_tag) -> CoordinateType
{ {
typename TTraits::Construct_x_monotone_curve_2 construct_x_monotone_curve_2 = auto ctr_xcv = traits_->construct_x_monotone_curve_2_object();
traits_->construct_x_monotone_curve_2_object();
CoordinateType res(0); CoordinateType res(0);
// QRectF clipRect = this->viewportRect( ); // QRectF clipRect = this->viewportRect( );
Line_2 line = curve.supporting_line(); Line_2 line = curve.supporting_line();
@ -673,22 +653,56 @@ auto Arr_compute_y_at_x_2<ArrTraits>::operator()(
Point_2 p1c1(x, CoordinateType(-10000000)); // clicked point Point_2 p1c1(x, CoordinateType(-10000000)); // clicked point
Point_2 p2c1(x, CoordinateType(10000000)); // upper bounding box Point_2 p2c1(x, CoordinateType(10000000)); // upper bounding box
const X_monotone_curve_2 verticalLine = const X_monotone_curve_2 verticalLine = ctr_xcv(p1c1, p2c1);
construct_x_monotone_curve_2(p1c1, p2c1);
CGAL::Object o; CGAL::Object o;
CGAL::Oneset_iterator<CGAL::Object> oi(o); CGAL::Oneset_iterator<CGAL::Object> oi(o);
this->intersectCurves(curve, verticalLine, oi); this->intersectCurves(curve, verticalLine, oi);
IntersectionResult pair; IntersectionResult pair;
if (CGAL::assign(pair, o)) if (CGAL::assign(pair, o)) {
{
Point_2 pt = pair.first; Point_2 pt = pair.first;
res = pt.y(); res = pt.y();
} }
return res; return res;
} }
// Specialization for the conic traits.
template <typename RatKernel, typename AlgKernel, typename NtTraits>
auto
Arr_compute_y_at_x_2<CGAL::Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>>::
operator()(const X_monotone_curve_2& curve, const Coordinate_type& x)
-> Coordinate_type
{
auto ctr_xcv = m_traits.construct_x_monotone_curve_2_object();
CGAL::Bbox_2 clip_rect = m_traits.construct_bbox_2_object()(curve);
Point_2 p1c1(x, Coordinate_type(clip_rect.ymin() - 1)); // clicked point
// upper bounding box
Point_2 p2c1(x, Coordinate_type(clip_rect.ymax() + 1));
const X_monotone_curve_2 vertical_line = ctr_xcv(p1c1, p2c1);
CGAL::Object o;
CGAL::Oneset_iterator<CGAL::Object> oi(o);
this->intersect_curves(curve, vertical_line, oi);
Coordinate_type res(0);
IntersectionResult pair;
if (CGAL::assign(pair, o)) {
Point_2 pt = pair.first;
res = pt.y();
}
return res;
}
// Specialization for the conic traits.
template <typename RatKernel, typename AlgKernel, typename NtTraits>
double
Arr_compute_y_at_x_2<CGAL::Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>>::
approx(const X_monotone_curve_2& curve, const Coordinate_type& x)
{ return CGAL::to_double((*this)(curve, x)); }
// Specialization for the algebraic traits.
template <typename Coefficient_> template <typename Coefficient_>
auto Arr_compute_y_at_x_2<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>:: auto Arr_compute_y_at_x_2<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>::
operator()(const X_monotone_curve_2& curve, const CoordinateType& x) operator()(const X_monotone_curve_2& curve, const CoordinateType& x)
@ -700,19 +714,19 @@ operator()(const X_monotone_curve_2& curve, const CoordinateType& x)
X_monotone_curve_2 c2 = this->makeVerticalLine(x); X_monotone_curve_2 c2 = this->makeVerticalLine(x);
intersect(curve, c2, oi); intersect(curve, c2, oi);
std::pair<Point_2, Multiplicity> res; std::pair<Point_2, Multiplicity> res;
if (CGAL::assign(res, o)) // TODO: handle failure case if (CGAL::assign(res, o)) {
{ // TODO: handle failure case
const Point_2& p = res.first; const Point_2& p = res.first;
CoordinateType coord = p.y(); CoordinateType coord = p.y();
return coord; return coord;
} }
else else {
{
std::cout << "Warning: vertical projection failed" << std::endl; std::cout << "Warning: vertical projection failed" << std::endl;
return CoordinateType(0); return CoordinateType(0);
} }
} }
// Specialization for the algebraic traits.
template <typename Coefficient_> template <typename Coefficient_>
double double
Arr_compute_y_at_x_2<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>:: Arr_compute_y_at_x_2<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>::
@ -721,6 +735,7 @@ Arr_compute_y_at_x_2<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>::
return CGAL::to_double(this->operator()(curve, x)); return CGAL::to_double(this->operator()(curve, x));
} }
// Specialization for the algebraic traits.
template <typename Coefficient_> template <typename Coefficient_>
auto Arr_compute_y_at_x_2<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>:: auto Arr_compute_y_at_x_2<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>::
makeVerticalLine(const CoordinateType& x) -> X_monotone_curve_2 makeVerticalLine(const CoordinateType& x) -> X_monotone_curve_2
@ -739,6 +754,7 @@ auto Arr_compute_y_at_x_2<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>::
return curves[0]; // by construction, there is one curve in curves return curves[0]; // by construction, there is one curve in curves
} }
//
template <typename Bezier_x_monotone_2> template <typename Bezier_x_monotone_2>
static inline auto get_t_range(const Bezier_x_monotone_2& curve) static inline auto get_t_range(const Bezier_x_monotone_2& curve)
{ {
@ -754,8 +770,8 @@ static inline auto get_t_range(const Bezier_x_monotone_2& curve)
(pt_org->point_bound().t_min + pt_org->point_bound().t_max) / 2); (pt_org->point_bound().t_min + pt_org->point_bound().t_max) / 2);
} }
template < //
typename RatKernel, typename AlgKernel, typename NtTraits, template <typename RatKernel, typename AlgKernel, typename NtTraits,
typename BoundingTraits> typename BoundingTraits>
auto Arr_compute_y_at_x_2<CGAL::Arr_Bezier_curve_traits_2< auto Arr_compute_y_at_x_2<CGAL::Arr_Bezier_curve_traits_2<
RatKernel, AlgKernel, NtTraits, BoundingTraits>>:: RatKernel, AlgKernel, NtTraits, BoundingTraits>>::
@ -768,8 +784,8 @@ operator()(const X_monotone_curve_2& curve, const Rational& x) -> Algebraic
nt_traits.convert(supp_curve.y_norm()); nt_traits.convert(supp_curve.y_norm());
} }
template < //
typename RatKernel, typename AlgKernel, typename NtTraits, template <typename RatKernel, typename AlgKernel, typename NtTraits,
typename BoundingTraits> typename BoundingTraits>
auto Arr_compute_y_at_x_2<CGAL::Arr_Bezier_curve_traits_2< auto Arr_compute_y_at_x_2<CGAL::Arr_Bezier_curve_traits_2<
RatKernel, AlgKernel, NtTraits, BoundingTraits>>:: RatKernel, AlgKernel, NtTraits, BoundingTraits>>::
@ -782,8 +798,7 @@ auto Arr_compute_y_at_x_2<CGAL::Arr_Bezier_curve_traits_2<
const Algebraic& t_src{t_range.first}; const Algebraic& t_src{t_range.first};
const Algebraic& t_trg{t_range.second}; const Algebraic& t_trg{t_range.second};
for (auto t_iter = t_vals.begin(); t_iter != t_vals.end(); ++t_iter) for (auto t_iter = t_vals.begin(); t_iter != t_vals.end(); ++t_iter) {
{
auto res1 = CGAL::compare(*t_iter, t_src); auto res1 = CGAL::compare(*t_iter, t_src);
if (res1 == CGAL::EQUAL) return (curve.source().y()); if (res1 == CGAL::EQUAL) return (curve.source().y());
auto res2 = CGAL::compare(*t_iter, t_trg); auto res2 = CGAL::compare(*t_iter, t_trg);
@ -795,16 +810,17 @@ auto Arr_compute_y_at_x_2<CGAL::Arr_Bezier_curve_traits_2<
return 0; return 0;
} }
template < //
typename RatKernel, typename AlgKernel, typename NtTraits, template <typename RatKernel, typename AlgKernel, typename NtTraits,
typename BoundingTraits> typename BoundingTraits>
double Arr_compute_y_at_x_2<CGAL::Arr_Bezier_curve_traits_2< double Arr_compute_y_at_x_2<CGAL::Arr_Bezier_curve_traits_2
RatKernel, AlgKernel, NtTraits, <RatKernel, AlgKernel, NtTraits,
BoundingTraits>>::approx(const X_monotone_curve_2& curve, const Rational& x) BoundingTraits>>::
{ approx(const X_monotone_curve_2& curve, const Rational& x) {
return CGAL::to_double((*this)(curve, x)); return CGAL::to_double((*this)(curve, x));
} }
//
template <typename AlgebraicKernel_d_1> template <typename AlgebraicKernel_d_1>
auto Arr_compute_y_at_x_2< auto Arr_compute_y_at_x_2<
CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>>:: CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>>::
@ -814,6 +830,7 @@ operator()(const X_monotone_curve_2& curve, const Algebraic_real_1& x)
return Point_2{curve._f, x}.y(); return Point_2{curve._f, x}.y();
} }
//
template <typename AlgebraicKernel_d_1> template <typename AlgebraicKernel_d_1>
auto Arr_compute_y_at_x_2< auto Arr_compute_y_at_x_2<
CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>>:: CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>>::
@ -822,6 +839,7 @@ operator()(const X_monotone_curve_2& curve, const Rational& x) -> Rational
return curve._f.numer().evaluate(x) / curve._f.denom().evaluate(x); return curve._f.numer().evaluate(x) / curve._f.denom().evaluate(x);
} }
//
template <typename AlgebraicKernel_d_1> template <typename AlgebraicKernel_d_1>
auto Arr_compute_y_at_x_2< auto Arr_compute_y_at_x_2<
CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>>:: CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>>::
@ -830,6 +848,7 @@ approx(const X_monotone_curve_2& curve, const Rational& x) -> double
return CGAL::to_double((*this)(curve, x)); return CGAL::to_double((*this)(curve, x));
} }
//
CGAL::Object createArrangement(demo_types::TraitsType tt) CGAL::Object createArrangement(demo_types::TraitsType tt)
{ {
CGAL::Object res; CGAL::Object res;
@ -858,18 +877,16 @@ void deleteArrangement(demo_types::TraitsType tt, const CGAL::Object& arr_obj)
}); });
} }
CGAL::Object makeOverlayArrangement(const std::vector<CGAL::Object>& arrs) //
{ CGAL::Object makeOverlayArrangement(const std::vector<CGAL::Object>& arrs) {
CGAL::Object arr_obj; CGAL::Object arr_obj;
if (arrs.size() == 2) if (arrs.size() == 2) {
{
demo_types::forEachArrangementType([&](auto type_holder) { demo_types::forEachArrangementType([&](auto type_holder) {
using Arrangement = typename decltype(type_holder)::type; using Arrangement = typename decltype(type_holder)::type;
Arrangement* arr1; Arrangement* arr1;
Arrangement* arr2; Arrangement* arr2;
if (CGAL::assign(arr1, arrs[0]) && CGAL::assign(arr2, arrs[1])) if (CGAL::assign(arr1, arrs[0]) && CGAL::assign(arr2, arrs[1])) {
{
auto overlay_arr = new Arrangement(); auto overlay_arr = new Arrangement();
CGAL::Arr_default_overlay_traits<Arrangement> overlay_traits; CGAL::Arr_default_overlay_traits<Arrangement> overlay_traits;
@ -881,8 +898,8 @@ CGAL::Object makeOverlayArrangement(const std::vector<CGAL::Object>& arrs)
return arr_obj; return arr_obj;
} }
void insertCurve( //
demo_types::TraitsType tt, const CGAL::Object& arr_obj, void insertCurve(demo_types::TraitsType tt, const CGAL::Object& arr_obj,
const CGAL::Object& curve_obj) const CGAL::Object& curve_obj)
{ {
demo_types::visitArrangementType(tt, [&](auto type_holder) { demo_types::visitArrangementType(tt, [&](auto type_holder) {

View File

@ -21,11 +21,11 @@
class QGraphicsScene; class QGraphicsScene;
template <typename ArrTraits > // Genereic `Arr_compute_y_at_x_2`
class Arr_compute_y_at_x_2 : public GraphicsSceneMixin template <typename Traits_>
{ class Arr_compute_y_at_x_2 : public GraphicsSceneMixin {
public: public:
typedef ArrTraits Traits; typedef Traits_ Traits;
typedef typename ArrTraitsAdaptor<Traits>::Kernel Kernel; typedef typename ArrTraitsAdaptor<Traits>::Kernel Kernel;
typedef typename ArrTraitsAdaptor<Traits>::CoordinateType CoordinateType; typedef typename ArrTraitsAdaptor<Traits>::CoordinateType CoordinateType;
// typedef typename Kernel::FT FT; // typedef typename Kernel::FT FT;
@ -38,32 +38,72 @@ public:
IntersectionResult; IntersectionResult;
/*! Constructor */ /*! Constructor */
Arr_compute_y_at_x_2( const Traits* ); Arr_compute_y_at_x_2(const Traits* traits);
//
CoordinateType CoordinateType
operator()(const X_monotone_curve_2& curve, const CoordinateType& x); operator()(const X_monotone_curve_2& curve, const CoordinateType& x);
//
double approx(const X_monotone_curve_2& curve, const CoordinateType& x); double approx(const X_monotone_curve_2& curve, const CoordinateType& x);
protected: protected:
//
template <typename TTraits> template <typename TTraits>
CoordinateType operator()( CoordinateType operator()(const X_monotone_curve_2& curve,
const X_monotone_curve_2& curve, const CoordinateType& x, const CoordinateType& x, const TTraits* traits_,
const TTraits* traits_, CGAL::Arr_oblivious_side_tag); CGAL::Arr_oblivious_side_tag);
//
template <typename TTraits> template <typename TTraits>
CoordinateType operator()( CoordinateType operator()(const X_monotone_curve_2& curve,
const X_monotone_curve_2& curve, const CoordinateType& x, const CoordinateType& x, const TTraits* traits_,
const TTraits* traits_, CGAL::Arr_open_side_tag); CGAL::Arr_open_side_tag);
protected: protected:
const Traits* traits; const Traits* traits;
Intersect_2 intersectCurves; Intersect_2 intersectCurves;
}; };
// Specialization of `Arr_compute_y_at_x_2` for the conic traits.
template <typename RatKernel, typename AlgKernel, typename NtTraits>
class Arr_compute_y_at_x_2
<CGAL::Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>> :
public GraphicsSceneMixin
{
public:
typedef CGAL::Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>
Traits;
typedef typename Traits::Point_2 Point_2;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
typedef typename ArrTraitsAdaptor<Traits>::CoordinateType Coordinate_type;
typedef typename Traits::Intersect_2 Intersect_2;
typedef typename Traits::Multiplicity Multiplicity;
typedef std::pair<Point_2, Multiplicity> IntersectionResult;
// Construct from traits.
Arr_compute_y_at_x_2(const Traits* traits) :
m_traits(*traits),
intersect_curves(m_traits.intersect_2_object())
{}
// Compute the y-coordinate at of the curve at a give x-coordinate.
Coordinate_type
operator()(const X_monotone_curve_2& curve, const Coordinate_type& x);
// Compute an approximation of the y-coordinate at of the curve at a give
// x-coordinate.
double approx(const X_monotone_curve_2& curve, const Coordinate_type& x);
private:
const Traits& m_traits;
Intersect_2 intersect_curves;
};
// Specialization of `Arr_compute_y_at_x_2` for the algebraic traits.
template <typename Coefficient_> template <typename Coefficient_>
class Arr_compute_y_at_x_2< CGAL::Arr_algebraic_segment_traits_2< class Arr_compute_y_at_x_2<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>> :
Coefficient_ > > : public GraphicsSceneMixin public GraphicsSceneMixin
{ {
public: public:
typedef Coefficient_ Coefficient; typedef Coefficient_ Coefficient;
@ -74,20 +114,25 @@ public:
typedef typename Traits::Multiplicity Multiplicity; typedef typename Traits::Multiplicity Multiplicity;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2; typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
//
Arr_compute_y_at_x_2(const Traits* traits_) : traits(traits_) { } Arr_compute_y_at_x_2(const Traits* traits_) : traits(traits_) { }
//
CoordinateType CoordinateType
operator()(const X_monotone_curve_2& curve, const CoordinateType& x); operator()(const X_monotone_curve_2& curve, const CoordinateType& x);
//
double approx(const X_monotone_curve_2& curve, const CoordinateType& x); double approx(const X_monotone_curve_2& curve, const CoordinateType& x);
protected: protected:
//
X_monotone_curve_2 makeVerticalLine(const CoordinateType& x); X_monotone_curve_2 makeVerticalLine(const CoordinateType& x);
const Traits* traits; const Traits* traits;
}; };
template < // Specialization of `Arr_compute_y_at_x_2` for the Bezier traits.
typename RatKernel, typename AlgKernel, typename NtTraits, template <typename RatKernel, typename AlgKernel, typename NtTraits,
typename BoundingTraits> typename BoundingTraits>
class Arr_compute_y_at_x_2<CGAL::Arr_Bezier_curve_traits_2< class Arr_compute_y_at_x_2<CGAL::Arr_Bezier_curve_traits_2<
RatKernel, AlgKernel, NtTraits, BoundingTraits>> : public GraphicsSceneMixin RatKernel, AlgKernel, NtTraits, BoundingTraits>> : public GraphicsSceneMixin
@ -100,16 +145,23 @@ public:
typedef typename Traits::Algebraic Algebraic; typedef typename Traits::Algebraic Algebraic;
typedef typename Traits::Point_2 Point_2; typedef typename Traits::Point_2 Point_2;
//
Arr_compute_y_at_x_2(const Traits*) { } Arr_compute_y_at_x_2(const Traits*) { }
//
Algebraic operator()(const X_monotone_curve_2& curve, const Rational& x); Algebraic operator()(const X_monotone_curve_2& curve, const Rational& x);
//
double approx(const X_monotone_curve_2& curve, const Rational& x); double approx(const X_monotone_curve_2& curve, const Rational& x);
//
Algebraic get_t(const X_monotone_curve_2& curve, const Rational& x); Algebraic get_t(const X_monotone_curve_2& curve, const Rational& x);
}; };
// Specialization of `Arr_compute_y_at_x_2` for the rational-function traits.
template <typename AlgebraicKernel_d_1> template <typename AlgebraicKernel_d_1>
class Arr_compute_y_at_x_2< class Arr_compute_y_at_x_2<CGAL::Arr_rational_function_traits_2
CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>> : <AlgebraicKernel_d_1>> :
public GraphicsSceneMixin public GraphicsSceneMixin
{ {
public: public:
@ -119,25 +171,48 @@ public:
typedef typename Traits::Point_2 Point_2; typedef typename Traits::Point_2 Point_2;
typedef typename Traits::Rational Rational; typedef typename Traits::Rational Rational;
//
Arr_compute_y_at_x_2(const Traits*) {} Arr_compute_y_at_x_2(const Traits*) {}
//
Algebraic_real_1 Algebraic_real_1
operator()(const X_monotone_curve_2& curve, const Algebraic_real_1& x); operator()(const X_monotone_curve_2& curve, const Algebraic_real_1& x);
//
Rational Rational
operator()(const X_monotone_curve_2& curve, const Rational& x); operator()(const X_monotone_curve_2& curve, const Rational& x);
//
double approx(const X_monotone_curve_2& curve, const Rational& x); double approx(const X_monotone_curve_2& curve, const Rational& x);
}; };
template <typename ArrTraits> // Common base class for all `Compute_squared_distance_2`
class Compute_squared_distance_2_base : public GraphicsSceneMixin template <typename Traits_>
{ class Compute_squared_distance_2_base : public GraphicsSceneMixin {
using Traits = Traits_;
public:
// Construct from traits.
Compute_squared_distance_2_base(const Traits& traits) : m_traits(traits) {}
protected:
const Traits& m_traits;
}; };
template <typename ArrTraits > // Generic `Compute_squared_distance_2`
template <typename Traits_>
class Compute_squared_distance_2 : class Compute_squared_distance_2 :
public Compute_squared_distance_2_base< ArrTraits > public Compute_squared_distance_2_base<Traits_>
{ }; {
using Traits = Traits_;
using Base = Compute_squared_distance_2_base<Traits>;
public:
// Construct from traits.
Compute_squared_distance_2(const Traits& traits) : Base(traits) {}
};
// Specialization of `Compute_squared_distance_2` for the segment traits.
template <typename Kernel_> template <typename Kernel_>
class Compute_squared_distance_2<CGAL::Arr_segment_traits_2<Kernel_>> : class Compute_squared_distance_2<CGAL::Arr_segment_traits_2<Kernel_>> :
public Compute_squared_distance_2_base<CGAL::Arr_segment_traits_2<Kernel_>> public Compute_squared_distance_2_base<CGAL::Arr_segment_traits_2<Kernel_>>
@ -151,9 +226,16 @@ public:
typedef typename Kernel::Segment_2 Segment_2; typedef typename Kernel::Segment_2 Segment_2;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2; typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
using Base = Compute_squared_distance_2_base<Traits>;
// Construct from traits.
Compute_squared_distance_2(const Traits& traits) : Base(traits) {}
//
double operator() ( const Point_2& p, const X_monotone_curve_2& c) const; double operator() ( const Point_2& p, const X_monotone_curve_2& c) const;
}; };
// Specialization of `Compute_squared_distance_2` for the linear traits.
template <typename Kernel_> template <typename Kernel_>
class Compute_squared_distance_2< CGAL::Arr_linear_traits_2< Kernel_>> : class Compute_squared_distance_2< CGAL::Arr_linear_traits_2< Kernel_>> :
public Compute_squared_distance_2_base<CGAL::Arr_linear_traits_2<Kernel_>> public Compute_squared_distance_2_base<CGAL::Arr_linear_traits_2<Kernel_>>
@ -169,9 +251,16 @@ public:
typedef typename Kernel::Line_2 Line_2; typedef typename Kernel::Line_2 Line_2;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2; typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
using Base = Compute_squared_distance_2_base<Traits>;
// Construct from traits.
Compute_squared_distance_2(const Traits& traits) : Base(traits) {}
//
double operator()(const Point_2& p, const X_monotone_curve_2& c) const; double operator()(const Point_2& p, const X_monotone_curve_2& c) const;
}; };
// Specialization of `Compute_squared_distance_2` for the polyline traits.
template <typename Kernel_> template <typename Kernel_>
class Compute_squared_distance_2< CGAL::Arr_polyline_traits_2< Kernel_>> : class Compute_squared_distance_2< CGAL::Arr_polyline_traits_2< Kernel_>> :
public Compute_squared_distance_2_base<CGAL::Arr_polyline_traits_2<Kernel_>> public Compute_squared_distance_2_base<CGAL::Arr_polyline_traits_2<Kernel_>>
@ -187,9 +276,16 @@ public:
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2; typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Curve_2::Subcurve_const_iterator Seg_const_it; typedef typename Curve_2::Subcurve_const_iterator Seg_const_it;
using Base = Compute_squared_distance_2_base<Traits>;
// Construct from traits.
Compute_squared_distance_2(const Traits& traits) : Base(traits) {}
//
double operator()(const Point_2& p, const X_monotone_curve_2& c) const; double operator()(const Point_2& p, const X_monotone_curve_2& c) const;
}; };
// Specialization of `Compute_squared_distance_2` for the conic traits.
template <typename RatKernel, typename AlgKernel, typename NtTraits> template <typename RatKernel, typename AlgKernel, typename NtTraits>
class Compute_squared_distance_2<CGAL::Arr_conic_traits_2<RatKernel, class Compute_squared_distance_2<CGAL::Arr_conic_traits_2<RatKernel,
AlgKernel, AlgKernel,
@ -210,35 +306,48 @@ public:
typedef typename Traits::Curve_2 Curve_2; typedef typename Traits::Curve_2 Curve_2;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2; typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
public: // methods using Base = Compute_squared_distance_2_base<Traits>;
// Construct from traits.
Compute_squared_distance_2(const Traits& traits) : Base(traits) {}
//
double operator()(const Point_2& p, const X_monotone_curve_2& c) const; double operator()(const Point_2& p, const X_monotone_curve_2& c) const;
}; };
template < // Specialization of `Compute_squared_distance_2` for the Bezier traits.
typename RatKernel, typename AlgKernel, typename NtTraits, template <typename RatKernel, typename AlgKernel, typename NtTraits,
typename BoundingTraits> typename BoundingTraits>
class Compute_squared_distance_2<CGAL::Arr_Bezier_curve_traits_2< class Compute_squared_distance_2
RatKernel, AlgKernel, NtTraits, BoundingTraits>> : <CGAL::Arr_Bezier_curve_traits_2<RatKernel, AlgKernel, NtTraits,
public Compute_squared_distance_2_base<CGAL::Arr_Bezier_curve_traits_2< BoundingTraits>> :
RatKernel, AlgKernel, NtTraits, BoundingTraits>> public Compute_squared_distance_2_base
<CGAL::Arr_Bezier_curve_traits_2
<RatKernel, AlgKernel, NtTraits,BoundingTraits>>
{ {
public: public:
typedef CGAL::Arr_Bezier_curve_traits_2< typedef CGAL::Arr_Bezier_curve_traits_2<RatKernel, AlgKernel, NtTraits,
RatKernel, AlgKernel, NtTraits, BoundingTraits> BoundingTraits> Traits;
Traits;
typedef typename ArrTraitsAdaptor<Traits>::Kernel Kernel; typedef typename ArrTraitsAdaptor<Traits>::Kernel Kernel;
typedef typename Kernel::Point_2 Point_2; typedef typename Kernel::Point_2 Point_2;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2; typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
public: // methods using Base = Compute_squared_distance_2_base<Traits>;
// Construct from traits.
Compute_squared_distance_2(const Traits& traits) : Base(traits) {}
//
double operator()(const Point_2& p, const X_monotone_curve_2& c) const; double operator()(const Point_2& p, const X_monotone_curve_2& c) const;
}; };
// Specialization of `Compute_squared_distance_2` for the rational-function
// traits.
template <typename AlgebraicKernel_d_1> template <typename AlgebraicKernel_d_1>
class Compute_squared_distance_2< class Compute_squared_distance_2
CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>> : <CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>> :
public Compute_squared_distance_2_base< public Compute_squared_distance_2_base
CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>> <CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>>
{ {
public: public:
typedef CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1> Traits; typedef CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1> Traits;
@ -246,15 +355,21 @@ public:
typedef typename Kernel::Point_2 Point_2; typedef typename Kernel::Point_2 Point_2;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2; typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
public: using Base = Compute_squared_distance_2_base<Traits>;
// Construct from traits.
Compute_squared_distance_2(const Traits& traits) : Base(traits) {}
//
double operator()(const Point_2& p, const X_monotone_curve_2& c) const; double operator()(const Point_2& p, const X_monotone_curve_2& c) const;
}; };
// Specialization of `Compute_squared_distance_2` for the algebraic traits.
template <typename Coefficient_> template <typename Coefficient_>
class Compute_squared_distance_2< CGAL::Arr_algebraic_segment_traits_2< class Compute_squared_distance_2
Coefficient_ > > : <CGAL::Arr_algebraic_segment_traits_2<Coefficient_>> :
public Compute_squared_distance_2_base< CGAL::Arr_algebraic_segment_traits_2< public Compute_squared_distance_2_base
Coefficient_ > > <CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>
{ {
public: public:
typedef Coefficient_ Coefficient; typedef Coefficient_ Coefficient;
@ -277,7 +392,12 @@ public:
Construct_innermost_coefficient_const_iterator_range Construct_innermost_coefficient_const_iterator_range
ConstructInnerCoeffIter; ConstructInnerCoeffIter;
public: using Base = Compute_squared_distance_2_base<Traits>;
// Construct from traits.
Compute_squared_distance_2(const Traits& traits) : Base(traits) {}
//
double operator()(const Point_2& p, const X_monotone_curve_2& c) const; double operator()(const Point_2& p, const X_monotone_curve_2& c) const;
}; };
@ -297,49 +417,50 @@ struct IsOpenBoundaryArrangement :
std::is_convertible< std::is_convertible<
typename ArrTraits::Right_side_category, typename ArrTraits::Right_side_category,
CGAL::Arr_open_side_tag>::value> CGAL::Arr_open_side_tag>::value>
{ {};
};
//
template <typename ArrTraits, typename=void> template <typename ArrTraits, typename=void>
class Param_space_in_x_2 class Param_space_in_x_2 {
{
public: public:
typedef typename ArrTraits::X_monotone_curve_2 X_monotone_curve_2; typedef typename ArrTraits::X_monotone_curve_2 X_monotone_curve_2;
//
Param_space_in_x_2(const ArrTraits*) {} Param_space_in_x_2(const ArrTraits*) {}
//
CGAL::Arr_parameter_space CGAL::Arr_parameter_space
operator()(const X_monotone_curve_2&, CGAL::Arr_curve_end) operator()(const X_monotone_curve_2&, CGAL::Arr_curve_end)
{ { return CGAL::INTERIOR; }
return CGAL::INTERIOR;
}
}; };
//
template <typename ArrTraits> template <typename ArrTraits>
class Param_space_in_x_2< class Param_space_in_x_2<ArrTraits,
ArrTraits, std::enable_if_t<IsOpenBoundaryArrangement<ArrTraits>::value>> std::enable_if_t<IsOpenBoundaryArrangement<ArrTraits>::
value>>
{ {
public: public:
typedef typename ArrTraits::X_monotone_curve_2 X_monotone_curve_2; typedef typename ArrTraits::X_monotone_curve_2 X_monotone_curve_2;
typedef typename ArrTraits::Parameter_space_in_x_2 Parameter_space_in_x_2; typedef typename ArrTraits::Parameter_space_in_x_2 Parameter_space_in_x_2;
//
Param_space_in_x_2(const ArrTraits* traits) : Param_space_in_x_2(const ArrTraits* traits) :
parameter_space_in_x_2(traits->parameter_space_in_x_2_object()) parameter_space_in_x_2(traits->parameter_space_in_x_2_object())
{ {}
}
//
CGAL::Arr_parameter_space CGAL::Arr_parameter_space
operator()(const X_monotone_curve_2& curve, CGAL::Arr_curve_end curve_end) operator()(const X_monotone_curve_2& curve, CGAL::Arr_curve_end curve_end)
{ { return this->parameter_space_in_x_2(curve, curve_end); }
return this->parameter_space_in_x_2(curve, curve_end);
}
private: private:
Parameter_space_in_x_2 parameter_space_in_x_2; Parameter_space_in_x_2 parameter_space_in_x_2;
}; };
//
template <typename ArrTraits> template <typename ArrTraits>
class Construct_x_monotone_subcurve_2 class Construct_x_monotone_subcurve_2 {
{
public: public:
typedef typename ArrTraits::X_monotone_curve_2 X_monotone_curve_2; typedef typename ArrTraits::X_monotone_curve_2 X_monotone_curve_2;
typedef typename ArrTraits::Split_2 Split_2; typedef typename ArrTraits::Split_2 Split_2;
@ -349,13 +470,13 @@ public:
typedef Param_space_in_x_2<ArrTraits> Parameter_space_in_x_2; typedef Param_space_in_x_2<ArrTraits> Parameter_space_in_x_2;
typedef typename ArrTraits::Point_2 Point_2; typedef typename ArrTraits::Point_2 Point_2;
//
Construct_x_monotone_subcurve_2(const ArrTraits* traits_); Construct_x_monotone_subcurve_2(const ArrTraits* traits_);
/* /* Return the subcurve of curve bracketed by pLeft and pRight.
Return the subcurve of curve bracketed by pLeft and pRight. *
* We assume pLeft and pRight don't lie on the curve and always do a vertical
We assume pLeft and pRight don't lie on the curve and always do a vertical * projection.
projection.
*/ */
X_monotone_curve_2 operator()(const X_monotone_curve_2& curve, X_monotone_curve_2 operator()(const X_monotone_curve_2& curve,
const boost::optional<Point_2>& pLeft, const boost::optional<Point_2>& pLeft,
@ -372,8 +493,7 @@ protected:
}; // class Construct_x_monotone_subcurve_2 }; // class Construct_x_monotone_subcurve_2
/* /* This specialization for conic traits makes use of X_monotone_curve_2::trim,
* This specialization for conic traits makes use of X_monotone_curve_2::trim,
* which is not necessarily available. * which is not necessarily available.
*/ */
template <typename RatKernel, typename AlgKernel, typename NtTraits> template <typename RatKernel, typename AlgKernel, typename NtTraits>
@ -383,8 +503,45 @@ class Construct_x_monotone_subcurve_2< CGAL::Arr_conic_traits_2< RatKernel,
{ {
public: public:
typedef CGAL::Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits> typedef CGAL::Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>
Traits;
typedef typename ArrTraitsAdaptor<Traits>::Kernel Kernel;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Traits::Split_2 Split_2;
typedef typename Traits::Intersect_2 Intersect_2;
typedef typename Traits::Multiplicity Multiplicity;
typedef typename Traits::Construct_min_vertex_2 Construct_min_vertex_2;
typedef typename Traits::Construct_max_vertex_2 Construct_max_vertex_2;
typedef typename Traits::Compare_x_2 Compare_x_2;
typedef typename Kernel::FT FT;
typedef typename ArrTraitsAdaptor<Traits>::CoordinateType
CoordinateType;
typedef typename Traits::Point_2 Point_2;
typedef typename Kernel::Point_2 Kernel_point_2;
// Construct from traits.
Construct_x_monotone_subcurve_2(const Traits* traits) : m_traits(*traits) {}
/* Return the subcurve of curve bracketed by pLeft and pRight.
*/
X_monotone_curve_2 operator()(const X_monotone_curve_2& curve,
const boost::optional<Point_2>& pLeft,
const boost::optional<Point_2>& pRight );
private:
const Traits& m_traits;
};
//
template <typename RatKernel, typename AlgKernel, typename NtTraits,
typename BoundingTraits>
class Construct_x_monotone_subcurve_2
<CGAL::Arr_Bezier_curve_traits_2
<RatKernel, AlgKernel, NtTraits, BoundingTraits>>
{
public:
typedef CGAL::Arr_Bezier_curve_traits_2<RatKernel, AlgKernel, NtTraits,
BoundingTraits>
ArrTraits; ArrTraits;
typedef typename ArrTraitsAdaptor<ArrTraits>::Kernel Kernel;
typedef typename ArrTraits::X_monotone_curve_2 X_monotone_curve_2; typedef typename ArrTraits::X_monotone_curve_2 X_monotone_curve_2;
typedef typename ArrTraits::Split_2 Split_2; typedef typename ArrTraits::Split_2 Split_2;
typedef typename ArrTraits::Intersect_2 Intersect_2; typedef typename ArrTraits::Intersect_2 Intersect_2;
@ -392,15 +549,10 @@ public:
typedef typename ArrTraits::Construct_min_vertex_2 Construct_min_vertex_2; typedef typename ArrTraits::Construct_min_vertex_2 Construct_min_vertex_2;
typedef typename ArrTraits::Construct_max_vertex_2 Construct_max_vertex_2; typedef typename ArrTraits::Construct_max_vertex_2 Construct_max_vertex_2;
typedef typename ArrTraits::Compare_x_2 Compare_x_2; typedef typename ArrTraits::Compare_x_2 Compare_x_2;
typedef typename Kernel::FT FT;
typedef typename ArrTraitsAdaptor< ArrTraits >::CoordinateType
CoordinateType;
typedef typename ArrTraits::Point_2 Point_2; typedef typename ArrTraits::Point_2 Point_2;
typedef typename Kernel::Point_2 Kernel_point_2;
Construct_x_monotone_subcurve_2( const ArrTraits* ) //
{ Construct_x_monotone_subcurve_2(const ArrTraits* traits_);
}
/* /*
Return the subcurve of curve bracketed by pLeft and pRight. Return the subcurve of curve bracketed by pLeft and pRight.
@ -409,36 +561,6 @@ public:
const boost::optional<Point_2>& pLeft, const boost::optional<Point_2>& pLeft,
const boost::optional<Point_2>& pRight); const boost::optional<Point_2>& pRight);
}; // class Construct_x_monotone_subcurve_2 for Arr_conic_traits_2
template <
typename RatKernel, typename AlgKernel, typename NtTraits,
typename BoundingTraits>
class Construct_x_monotone_subcurve_2<CGAL::Arr_Bezier_curve_traits_2<
RatKernel, AlgKernel, NtTraits, BoundingTraits>>
{
public:
typedef CGAL::Arr_Bezier_curve_traits_2<
RatKernel, AlgKernel, NtTraits, BoundingTraits>
ArrTraits;
typedef typename ArrTraits::X_monotone_curve_2 X_monotone_curve_2;
typedef typename ArrTraits::Split_2 Split_2;
typedef typename ArrTraits::Intersect_2 Intersect_2;
typedef typename ArrTraits::Multiplicity Multiplicity;
typedef typename ArrTraits::Construct_min_vertex_2 Construct_min_vertex_2;
typedef typename ArrTraits::Construct_max_vertex_2 Construct_max_vertex_2;
typedef typename ArrTraits::Compare_x_2 Compare_x_2;
typedef typename ArrTraits::Point_2 Point_2;
Construct_x_monotone_subcurve_2(const ArrTraits* traits_);
/*
Return the subcurve of curve bracketed by pLeft and pRight.
*/
X_monotone_curve_2 operator()(
const X_monotone_curve_2& curve, const boost::optional<Point_2>& pLeft,
const boost::optional<Point_2>& pRight);
protected: protected:
const ArrTraits* traits; const ArrTraits* traits;
Split_2 split_2; Split_2 split_2;
@ -446,8 +568,9 @@ protected:
Arr_compute_y_at_x_2< ArrTraits > compute_y_at_x; Arr_compute_y_at_x_2< ArrTraits > compute_y_at_x;
Construct_min_vertex_2 construct_min_vertex_2; Construct_min_vertex_2 construct_min_vertex_2;
Construct_max_vertex_2 construct_max_vertex_2; Construct_max_vertex_2 construct_max_vertex_2;
}; // class Construct_x_monotone_subcurve_2 for Arr_conic_traits_2 };
//
template <typename AlgebraicKernel_d_1> template <typename AlgebraicKernel_d_1>
class Construct_x_monotone_subcurve_2< class Construct_x_monotone_subcurve_2<
CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>> CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>>
@ -471,11 +594,10 @@ public:
Construct_x_monotone_subcurve_2( const Traits* traits_ ); Construct_x_monotone_subcurve_2( const Traits* traits_ );
/* /* Return the subcurve of curve bracketed by pLeft and pRight.
Return the subcurve of curve bracketed by pLeft and pRight. *
* We assume pLeft and pRight don't lie on the curve and always do a vertical
We assume pLeft and pRight don't lie on the curve and always do a vertical * projection.
projection.
*/ */
X_monotone_curve_2 operator()(const X_monotone_curve_2& curve, X_monotone_curve_2 operator()(const X_monotone_curve_2& curve,
const boost::optional<Point_2>& pLeft, const boost::optional<Point_2>& pLeft,
@ -490,14 +612,12 @@ protected:
Construct_max_vertex_2 construct_max_vertex_2; Construct_max_vertex_2 construct_max_vertex_2;
}; // class Construct_x_monotone_subcurve_2 }; // class Construct_x_monotone_subcurve_2
/** /* Converts between Kernel points and Arrangement points.
Converts between Kernel points and Arrangement points. *
* The conversion is not necessarily exact.
The conversion is not necessarily exact.
*/ */
template <typename ArrTraits> template <typename ArrTraits>
class Arr_construct_point_2 class Arr_construct_point_2 {
{
typedef ArrTraits Traits; typedef ArrTraits Traits;
typedef typename ArrTraits::Point_2 Point_2; typedef typename ArrTraits::Point_2 Point_2;
typedef typename ArrTraitsAdaptor< ArrTraits >::CoordinateType CoordinateType; typedef typename ArrTraitsAdaptor< ArrTraits >::CoordinateType CoordinateType;
@ -506,46 +626,49 @@ class Arr_construct_point_2
typedef typename Kernel::FT FT; typedef typename Kernel::FT FT;
public: public:
//
Arr_construct_point_2(const Traits* traits_) : traits(traits_) { } Arr_construct_point_2(const Traits* traits_) : traits(traits_) { }
//
template <typename P> template <typename P>
Point_2 operator()(const P& p) Point_2 operator()(const P& p) { return this->operator()(p.x(), p.y()); }
{
return this->operator()(p.x(), p.y());
}
//
template <typename T, typename U> template <typename T, typename U>
Point_2 operator()(const T& x, const U& y) Point_2 operator()(const T& x, const U& y)
{ { return this->operator()(FT{x}, FT{y}); }
return this->operator()(FT{x}, FT{y});
}
//
Point_2 operator()(const Kernel_point_2& pt); Point_2 operator()(const Kernel_point_2& pt);
//
Point_2 operator()(const FT& x, const FT& y); Point_2 operator()(const FT& x, const FT& y);
protected: protected:
//
template <typename TTraits > template <typename TTraits >
Point_2 operator()(const FT& x, const FT& y, const TTraits*); Point_2 operator()(const FT& x, const FT& y, const TTraits*);
//
template <typename AlgebraicKernel_d_1> template <typename AlgebraicKernel_d_1>
Point_2 operator()( Point_2
const FT& x, const FT& y, operator()(const FT& x, const FT& y,
const CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>*); const CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>*);
const Traits* traits; const Traits* traits;
}; };
class Find_nearest_edge_base : public GraphicsSceneMixin //
{ class Find_nearest_edge_base : public GraphicsSceneMixin {
public: public:
/*! Destructor (virtual) */ /*! Destructor */
virtual ~Find_nearest_edge_base() {} virtual ~Find_nearest_edge_base() {}
}; };
//
template <typename Arr_> template <typename Arr_>
class Find_nearest_edge : public Find_nearest_edge_base class Find_nearest_edge : public Find_nearest_edge_base {
{ public:
public: // typedefs
typedef Arr_ Arrangement; typedef Arr_ Arrangement;
typedef typename Arrangement::Geometry_traits_2 ArrTraits; typedef typename Arrangement::Geometry_traits_2 ArrTraits;
typedef Compute_squared_distance_2<ArrTraits> Point_curve_distance; typedef Compute_squared_distance_2<ArrTraits> Point_curve_distance;
@ -570,40 +693,44 @@ public:
virtual ~Find_nearest_edge() {} virtual ~Find_nearest_edge() {}
public: // member methods public: // member methods
//
Halfedge_const_handle operator()(const Point_2& queryPt); Halfedge_const_handle operator()(const Point_2& queryPt);
virtual void setScene( QGraphicsScene* scene_ ) //
{ virtual void setScene(QGraphicsScene* scene_) {
this->pointCurveDistance.setScene( scene_ ); // this->pointCurveDistance.setScene(scene_);
Find_nearest_edge_base::setScene(scene_); Find_nearest_edge_base::setScene(scene_);
} }
protected: // member methods protected:
//
Face_const_handle getFace(const CGAL::Object& obj); Face_const_handle getFace(const CGAL::Object& obj);
protected: // member fields protected:
Arrangement* arr; Arrangement* arr;
Point_curve_distance pointCurveDistance; };
}; // class Find_nearest_edge
//
template <typename Arr_> template <typename Arr_>
class Insert_curve class Insert_curve {
{
public: public:
typedef Arr_ Arrangement; typedef Arr_ Arrangement;
typedef typename Arrangement::Geometry_traits_2 ArrTraits; typedef typename Arrangement::Geometry_traits_2 ArrTraits;
typedef typename ArrTraits::Curve_2 Curve_2; typedef typename ArrTraits::Curve_2 Curve_2;
//
void operator()(Arrangement*, const Curve_2&); void operator()(Arrangement*, const Curve_2&);
}; };
// free functions gathered here to speed up compilation of other files // free functions gathered here to speed up compilation of other files
// specializing once in one file is better than in multiple files // specializing once in one file is better than in multiple files
CGAL::Object createArrangement(demo_types::TraitsType); CGAL::Object createArrangement(demo_types::TraitsType);
void deleteArrangement(demo_types::TraitsType, const CGAL::Object&); void deleteArrangement(demo_types::TraitsType, const CGAL::Object&);
CGAL::Object makeOverlayArrangement(const std::vector<CGAL::Object>&); CGAL::Object makeOverlayArrangement(const std::vector<CGAL::Object>&);
void insertCurve(
demo_types::TraitsType, const CGAL::Object& arr, const CGAL::Object& curve); void insertCurve(demo_types::TraitsType, const CGAL::Object& arr,
const CGAL::Object& curve);
#endif // CGAL_ARRANGEMENTS_DEMO_UTILS_H #endif // CGAL_ARRANGEMENTS_DEMO_UTILS_H

View File

@ -22,8 +22,7 @@
#include <QGraphicsSceneMouseEvent> #include <QGraphicsSceneMouseEvent>
template <typename Arr_> template <typename Arr_>
class VerticalRayShootCallback : public VerticalRayShootCallbackBase class VerticalRayShootCallback : public VerticalRayShootCallbackBase {
{
public: public:
typedef VerticalRayShootCallbackBase Superclass; typedef VerticalRayShootCallbackBase Superclass;
typedef Arr_ Arrangement; typedef Arr_ Arrangement;
@ -57,13 +56,12 @@ VerticalRayShootCallbackBase::VerticalRayShootCallbackBase(QObject* parent_) :
} }
// msvc2015 doesn't play well with polymorphic lambdas // msvc2015 doesn't play well with polymorphic lambdas
namespace namespace {
{
struct ExplicitLambda //
{ struct ExplicitLambda {
template <typename Arrangement> template <typename Arrangement>
void operator()(demo_types::TypeHolder<Arrangement>) void operator()(demo_types::TypeHolder<Arrangement>) {
{
Arrangement* arr = nullptr; Arrangement* arr = nullptr;
CGAL::assign(arr, arr_obj); CGAL::assign(arr, arr_obj);
res = new VerticalRayShootCallback<Arrangement>(arr, parent); res = new VerticalRayShootCallback<Arrangement>(arr, parent);
@ -73,28 +71,30 @@ struct ExplicitLambda
CGAL::Object& arr_obj; CGAL::Object& arr_obj;
QObject* parent; QObject* parent;
}; };
} // anonymous namespace } // anonymous namespace
VerticalRayShootCallbackBase* VerticalRayShootCallbackBase::create( //
demo_types::TraitsType tt, CGAL::Object arr_obj, QObject* parent) VerticalRayShootCallbackBase*
{ VerticalRayShootCallbackBase::create(demo_types::TraitsType tt,
CGAL::Object arr_obj, QObject* parent) {
VerticalRayShootCallbackBase* res; VerticalRayShootCallbackBase* res;
ExplicitLambda explicit_lambda{res, arr_obj, parent}; ExplicitLambda explicit_lambda{res, arr_obj, parent};
demo_types::visitArrangementType(tt, explicit_lambda); demo_types::visitArrangementType(tt, explicit_lambda);
return res; return res;
} }
//
void VerticalRayShootCallbackBase::setShootingUp(bool isShootingUp) void VerticalRayShootCallbackBase::setShootingUp(bool isShootingUp)
{ { this->shootingUp = isShootingUp; }
this->shootingUp = isShootingUp;
}
//
template <typename Arr_> template <typename Arr_>
VerticalRayShootCallback<Arr_>::VerticalRayShootCallback( VerticalRayShootCallback<Arr_>::
Arrangement* arr_, QObject* parent_) : VerticalRayShootCallback(Arrangement* arr_, QObject* parent_) :
VerticalRayShootCallbackBase(parent_), VerticalRayShootCallbackBase(parent_),
arr(arr_), arr(arr_),
highlightedCurves(new CGAL::Qt::CurveGraphicsItem<Traits>()) highlightedCurves(new CGAL::Qt::CurveGraphicsItem<Traits>(*(arr->geometry_traits())))
{ {
this->rayGraphicsItem.setZValue(100); this->rayGraphicsItem.setZValue(100);
@ -102,81 +102,75 @@ VerticalRayShootCallback<Arr_>::VerticalRayShootCallback(
this->highlightedCurves->setVertexColor(this->rayGraphicsItem.color()); this->highlightedCurves->setVertexColor(this->rayGraphicsItem.color());
this->highlightedCurves->setZValue(100); this->highlightedCurves->setZValue(100);
QObject::connect( QObject::connect(this, SIGNAL(modelChanged()), this->highlightedCurves,
this, SIGNAL(modelChanged()), this->highlightedCurves,
SLOT(modelChanged())); SLOT(modelChanged()));
QObject::connect( QObject::connect(this, SIGNAL(modelChanged()), this, SLOT(slotModelChanged()));
this, SIGNAL(modelChanged()), this, SLOT(slotModelChanged()));
} }
//
template <typename Arr_> template <typename Arr_>
void VerticalRayShootCallback<Arr_>::setEdgeWidth( int width ) void VerticalRayShootCallback<Arr_>::setEdgeWidth(int width) {
{
this->highlightedCurves->setEdgeWidth(width); this->highlightedCurves->setEdgeWidth(width);
this->rayGraphicsItem.setWidth(width); this->rayGraphicsItem.setWidth(width);
} }
//
template <typename Arr_> template <typename Arr_>
void VerticalRayShootCallback<Arr_>::setEdgeColor( const QColor& color ) void VerticalRayShootCallback<Arr_>::setEdgeColor(const QColor& color) {
{
this->highlightedCurves->setEdgeColor(color); this->highlightedCurves->setEdgeColor(color);
this->rayGraphicsItem.setColor(color); this->rayGraphicsItem.setColor(color);
} }
//
template <typename Arr_> template <typename Arr_>
const QColor& VerticalRayShootCallback<Arr_>::edgeColor() const const QColor& VerticalRayShootCallback<Arr_>::edgeColor() const
{ { return this->highlightedCurves->edgeColor(); }
return this->highlightedCurves->edgeColor( );
}
//
template <typename Arr_> template <typename Arr_>
int VerticalRayShootCallback<Arr_>::edgeWidth() const int VerticalRayShootCallback<Arr_>::edgeWidth() const
{ { return this->highlightedCurves->edgeWidth(); }
return this->highlightedCurves->edgeWidth( );
}
//
template <typename Arr_> template <typename Arr_>
void VerticalRayShootCallback<Arr_>::setScene(QGraphicsScene* scene_) void VerticalRayShootCallback<Arr_>::setScene(QGraphicsScene* scene_) {
{
CGAL::Qt::Callback::setScene(scene_); CGAL::Qt::Callback::setScene(scene_);
this->highlightedCurves->setScene(scene_); this->highlightedCurves->setScene(scene_);
if (scene_) if (scene_) {
{
this->scene->addItem(this->highlightedCurves); this->scene->addItem(this->highlightedCurves);
this->scene->addItem(&this->rayGraphicsItem); this->scene->addItem(&this->rayGraphicsItem);
} }
} }
//
template <typename Arr_> template <typename Arr_>
void VerticalRayShootCallback<Arr_>::slotModelChanged() void VerticalRayShootCallback<Arr_>::slotModelChanged()
{ {
} }
//
template <typename Arr_> template <typename Arr_>
void VerticalRayShootCallback<Arr_>::reset() void VerticalRayShootCallback<Arr_>::reset() {
{
this->rayGraphicsItem.reset(); this->rayGraphicsItem.reset();
this->highlightedCurves->clear(); this->highlightedCurves->clear();
Q_EMIT modelChanged(); Q_EMIT modelChanged();
} }
//
template <typename Arr_> template <typename Arr_>
void VerticalRayShootCallback<Arr_>::mousePressEvent( void VerticalRayShootCallback<Arr_>::
QGraphicsSceneMouseEvent* event) mousePressEvent(QGraphicsSceneMouseEvent* event)
{ { this->highlightPointLocation(event); }
this->highlightPointLocation(event);
}
//
template <typename Arr_> template <typename Arr_>
void VerticalRayShootCallback<Arr_>::mouseMoveEvent( void VerticalRayShootCallback<Arr_>::
QGraphicsSceneMouseEvent* /* event */) mouseMoveEvent(QGraphicsSceneMouseEvent* /* event */) {}
{
}
//
template <typename Arr_> template <typename Arr_>
void VerticalRayShootCallback<Arr_>::highlightPointLocation( void VerticalRayShootCallback<Arr_>::
QGraphicsSceneMouseEvent* event) highlightPointLocation(QGraphicsSceneMouseEvent* event) {
{
this->highlightedCurves->clear(); this->highlightedCurves->clear();
QPointF queryQPt = event->scenePos(); QPointF queryQPt = event->scenePos();
@ -192,25 +186,21 @@ void VerticalRayShootCallback<Arr_>::highlightPointLocation(
QRectF viewportRect = this->viewportRect(); QRectF viewportRect = this->viewportRect();
qreal y2; qreal y2;
if (this->shootingUp) if (this->shootingUp) { // +y in Qt is towards the bottom
{ // +y in Qt is towards the bottom
y2 = viewportRect.bottom(); y2 = viewportRect.bottom();
} }
else else {
{
y2 = viewportRect.top(); y2 = viewportRect.top();
} }
Face_const_handle unboundedFace; Face_const_handle unboundedFace;
Halfedge_const_handle halfedge; Halfedge_const_handle halfedge;
Vertex_const_handle vertex; Vertex_const_handle vertex;
if (CGAL::assign(unboundedFace, pointLocationResult)) if (CGAL::assign(unboundedFace, pointLocationResult)) {
{
this->rayGraphicsItem.setSource(queryQPt); this->rayGraphicsItem.setSource(queryQPt);
this->rayGraphicsItem.setTargetY(y2); this->rayGraphicsItem.setTargetY(y2);
this->rayGraphicsItem.setIsInfinite(true); this->rayGraphicsItem.setIsInfinite(true);
} }
else if (CGAL::assign(halfedge, pointLocationResult)) else if (CGAL::assign(halfedge, pointLocationResult)) {
{
this->highlightedCurves->insert(halfedge->curve()); this->highlightedCurves->insert(halfedge->curve());
// draw a ray from the clicked point to the hit curve // draw a ray from the clicked point to the hit curve
@ -221,10 +211,8 @@ void VerticalRayShootCallback<Arr_>::highlightPointLocation(
this->rayGraphicsItem.setTargetY(yApprox); this->rayGraphicsItem.setTargetY(yApprox);
this->rayGraphicsItem.setIsInfinite(false); this->rayGraphicsItem.setIsInfinite(false);
} }
else if (CGAL::assign(vertex, pointLocationResult)) else if (CGAL::assign(vertex, pointLocationResult)) {
{ if (!vertex->is_at_open_boundary()) {
if (!vertex->is_at_open_boundary())
{
auto pt = vertex->point(); auto pt = vertex->point();
this->highlightedCurves->insert(pt); this->highlightedCurves->insert(pt);
} }

View File

@ -4819,21 +4819,19 @@ defined in the header file `arr_conics.h`.
#include <CGAL/Arr_conic_traits_2.h> #include <CGAL/Arr_conic_traits_2.h>
#include <CGAL/Arrangement_2.h> #include <CGAL/Arrangement_2.h>
typedef CGAL::CORE_algebraic_number_traits Nt_traits; using Nt_traits = CGAL::CORE_algebraic_number_traits;
typedef Nt_traits::Rational Rational; using Rational = Nt_traits::Rational;
typedef CGAL::Cartesian<Rational> Rat_kernel; using Rat_kernel = CGAL::Cartesian<Rational>;
typedef Rat_kernel::Point_2 Rat_point; using Rat_point = Rat_kernel::Point_2;
typedef Rat_kernel::Segment_2 Rat_segment; using Rat_segment = Rat_kernel::Segment_2;
typedef Rat_kernel::Circle_2 Rat_circle; using Rat_circle = Rat_kernel::Circle_2;
typedef Nt_traits::Algebraic Algebraic; using Algebraic = Nt_traits::Algebraic;
typedef CGAL::Cartesian<Algebraic> Alg_kernel; using Alg_kernel = CGAL::Cartesian<Algebraic>;
using Traits = CGAL::Arr_conic_traits_2<Rat_kernel, Alg_kernel, Nt_traits>;
typedef CGAL::Arr_conic_traits_2<Rat_kernel, Alg_kernel, Nt_traits> using Point = Traits::Point_2;
Traits; using Conic_arc = Traits::Curve_2;
typedef Traits::Point_2 Point; using X_monotone_conic_arc = Traits::X_monotone_curve_2;
typedef Traits::Curve_2 Conic_arc; using Arrangement = CGAL::Arrangement_2<Traits>;
typedef Traits::X_monotone_curve_2 X_monotone_conic_arc;
typedef CGAL::Arrangement_2<Traits> Arrangement;
\endcode \endcode
<!-- ------------------------------------------------------------------------- --> <!-- ------------------------------------------------------------------------- -->
@ -6599,7 +6597,7 @@ member functions when operating on an arrangement-with-history object.
\cgalExample{Arrangement_on_surface_2/edge_manipulation_curve_history.cpp} \cgalExample{Arrangement_on_surface_2/edge_manipulation_curve_history.cpp}
<!-- ========================================================================= --> <!-- ========================================================================= -->
\section aos_sec-io Input/Output Streams \section aos_sec-io Input/Output Streams and Visualization
<!-- ========================================================================= --> <!-- ========================================================================= -->
In some cases, one would like to save an arrangement object In some cases, one would like to save an arrangement object
@ -6744,6 +6742,24 @@ arrangement formatter class (see Section \ref arr_ssecarr_io_aux_data)
and defines a simple textual input/output format. and defines a simple textual input/output format.
\cgalAdvancedEnd \cgalAdvancedEnd
<!-- ------------------------------------------------------------------------- -->
\subsection arr_ssecarr_io_vis Drawing an Arrangement
<!-- ------------------------------------------------------------------------- -->
An arrangement data structure can be visualized by calling the \link PkgArrangementOnSurface2Draw CGAL::draw<arr>() \endlink function as shown in the following example. This function opens a new window showing the given arrangement. A call to this function is blocking; that is, the program continues execution only after the user closes the window.
\cgalExample{Arrangement_on_surface_2/draw_arr.cpp}
This function requires `CGAL_Qt5`, and is only available if the macro `CGAL_USE_BASIC_VIEWER` is defined.
Linking with the cmake target `CGAL::CGAL_Basic_viewer` will link with `CGAL_Qt5` and add the definition `CGAL_USE_BASIC_VIEWER`.
\cgalFigureBegin{aos_fig-draw_arr,draw_arr.png}
A snapshot of the window created by the program
\ref Arrangement_on_surface_2/draw_arr.cpp. The constructed arrangement consists
of 14 vertices, 15 edges, and 3 faces. Notice that the colors are generated at random.
\cgalFigureEnd
<!-- ========================================================================= --> <!-- ========================================================================= -->
\section aos_sec-bgl Adapting to Boost Graphs \section aos_sec-bgl Adapting to Boost Graphs
<!-- ========================================================================= --> <!-- ========================================================================= -->

View File

@ -34,37 +34,37 @@ namespace CGAL {
* p_t\f$ (the source and target points, respectively). The orientation \f$ o\f$ * p_t\f$ (the source and target points, respectively). The orientation \f$ o\f$
* indicates whether we proceed from \f$ p_s\f$ to \f$ p_t\f$ in a clockwise or * indicates whether we proceed from \f$ p_s\f$ to \f$ p_t\f$ in a clockwise or
* in a counterclockwise direction. Note that \f$ C\f$ may also correspond to a * in a counterclockwise direction. Note that \f$ C\f$ may also correspond to a
* line or to pair of lines - in this case \f$ o\f$ may specify a `COLLINEAR` * line or to pair of lines---in this case \f$ o\f$ may specify a `COLLINEAR`
* orientation. * orientation.
* *
* </UL> * </UL>
* *
* A very useful subset of the set of conic arcs are line segments and circular * A very useful subset of the set of conic arcs are line segments and circular
* arcs, as arrangements of circular arcs and line segments have some * arcs, as arrangements of circular arcs and line segments have some
* interesting applications (e.g. offsetting polygons, motion planning for a * interesting applications (e.g., offsetting polygons and motion planning for a
* disc robot, etc.). Circular arcs and line segment are simpler objects and can * disc robot). Circular arcs and line segment are simpler objects and can be
* be dealt with more efficiently than arbitrary arcs. For these reasons, it is * dealt with more efficiently than arbitrary arcs. Indeed, it is possible to
* possible to construct conic arcs from segments and from circles. Using these * construct conic arcs from segments and from circles. Using these constructors
* constructors is highly recommended: It is more straightforward and also * is highly recommended: It is more straightforward and also expedites the
* speeds up the arrangement construction. However, in case the set of input * arrangement construction. However, in case the set of input curves contain
* curves contain only circular arcs and line segments, it is recommended to use * only circular arcs and line segments, it is recommended using the
* the `Arr_circle_segment_2` class to achieve faster running times. * `Arr_circle_segment_2` class to achieve better running times.
* *
* In our representation, all conic coefficients (namely \f$ r, s, t, u, v, * In our representation, all conic coefficients (namely \f$r, s, t, u, v, w\f$)
* w\f$) must be rational numbers. This guarantees that the coordinates of all * must be rational numbers. This guarantees that the coordinates of all
* arrangement vertices (in particular, those representing intersection points) * arrangement vertices (in particular, those representing intersection points)
* are algebraic numbers of degree \f$4\f$ (a real number \f$\alpha\f$ is an * are algebraic numbers of degree \f$4\f$ (a real number \f$\alpha\f$ is an
* algebraic number of degree \f$d\f$ if there exist a polynomial \f$ p\f$ with * algebraic number of degree \f$d\f$ if there exist a polynomial \f$ p\f$ with
* <I>integer</I> coefficient of degree \f$ d\f$ such that \f$ p(\alpha) = * <I>integer</I> coefficient of degree \f$d\f$ such that \f$p(\alpha) = 0\f$).
* 0\f$). We therefore require separate representations of the curve * We therefore require separate representations of the curve
* coefficients and the point coordinates. The `NtTraits` should be instantiated * coefficients and the point coordinates. The `NtTraits` should be instantiated
* with a class that defines nested `Integer`, `Rational` and `Algebraic` number * with a class that defines nested `Integer`, `Rational`, and `Algebraic` number
* types and supports various operations on them, yielding certified computation * types and supports various operations on them, yielding certified computation
* results (for example, it can convert rational numbers to algebraic numbers * results (for example, it can convert rational numbers to algebraic numbers
* and can compute roots of polynomials with integer coefficients). The other * and can compute roots of polynomials with integer coefficients). The other
* template parameters, `RatKernel` and `AlgKernel` should be geometric kernels * template parameters, `RatKernel` and `AlgKernel` should be geometric kernels
* templated with the `NtTraits::Rational` and `NtTraits::Algebraic` number * instantiated with the `NtTraits::Rational` and `NtTraits::Algebraic` number
* types, respectively. It is recommended to instantiate the * types, respectively. It is recommended instantiating the
* `CORE_algebraic_number_traits` class as the `NtTraits` parameter, with * `CORE_algebraic_number_traits` class as the `NtTraits` parameter, with
* `Cartesian<NtTraits::Rational>` and `Cartesian<NtTraits::Algebraic>` * `Cartesian<NtTraits::Rational>` and `Cartesian<NtTraits::Algebraic>`
* instantiating the two kernel types, respectively. The number types in this * instantiating the two kernel types, respectively. The number types in this
@ -115,110 +115,9 @@ public:
/// \name Creation /// \name Creation
/// @{ /// @{
/*! constructs an arc corresponding to the line segment `seg`. /*! constructs an empty (invalid) arc.
*/ */
Curve_2(const typename RatKernel::Segment_2& seg); Curve_2();
/*! constructs an arc corresponding to the full circle `circ`
* (note that this circle has a center point with rational coordinates
* and rational squared radius).
*/
Curve_2(const typename RatKernel::Circle_2& circ);
/*! constructs a circular arc supported by the circle `circ`, going
* in the given orientation `o` from the source point `ps` to its target
* point `pt`.
*
* \pre `ps` and `pt` both lie on the circle `circ`.
*
* \pre `o` is not `COLLINEAR`.
*/
Curve_2(const typename RatKernel::Circle_2& circ, Orientation o,
const Point_2& ps, const Point_2& pt);
/*! constructs a circular arc going from `p1` (its source point)
* through `p2` to `p3` (its target point). Note that all three points have
* rational coordinates. The orientation of the arc is determined
* automatically.
*
* \pre The three points are not collinear.
*/
Curve_2(const typename RatKernel::Point_2& p1,
const typename RatKernel::Point_2& p2,
const typename RatKernel::Point_2& p3);
/*! constructs a conic arc that corresponds to the full conic curve
* \f$ r x^2 + s y^2 + t x y + u x + v y + w = 0\f$.
*
* \pre As a conic arc must be bounded, the given curve must be an ellipse,
* that is \f$ 4 r s - t^2 > 0\f$.
*/
Curve_2(const Rational& r, const Rational& s,
const Rational& t, const Rational& u,
const Rational& v, const Rational& w);
/*! constructs a conic arc supported by the conic curve
* \f$ r x^2 + s y^2 + t x y + u x + v y + w = 0\f$, going in the given
* orientation `o` from the source point `ps` to its target point `pt`. * *
*
* \pre `ps` and `pt` both satisfy the equation of the supporting conic
* curve and define a bounded segment of this curve (e.g. in case of a
* hyperbolic arc, both point should be located on the same branch of the
* hyperbola).
*
* \pre `o` is not `COLLINEAR` if the supporting conic is curves, and must
* be `COLLINEAR` if it is not curved (a line or a line-pair).
*/
Curve_2(const Rational& r, const Rational& s,
const Rational& t, const Rational& u,
const Rational& v, const Rational& w,
Orientation o,
const Point_2& ps, const Point_2& pt);
/*! constructs a conic arc going from `p1` (its source point)
* through `p2`, `p3` and `p4` (in this order) to `p5` (its target
* point). Note that all five points have rational coordinates. The
* orientation of the arc is determined automatically.
*
* \pre No three points of the five are not collinear.
*
* \pre The five points define a valid arc, in their given order.
*/
Curve_2(const typename RatKernel::Point_2& p1,
const typename RatKernel::Point_2& p2,
const typename RatKernel::Point_2& p3,
const typename RatKernel::Point_2& p4,
const typename RatKernel::Point_2& p5);
/*! constructs a conic arc supported by the conic curve
* \f$ r x^2 + s y^2 + t x y + u x + v y + w = 0\f$, going in the given
* orientation `o` from its source point to its target Point. In this case
* only some approximations of the endpoints (`app_ps` and `app_pt`,
* respectively) is available, and their exact locations are given
* implicitly, specified by the intersections of the supporting conic curve
* with \f$ r_1 x^2 + s_1 y^2 + t_1 x y + u_1 x + v_1 y + w_1 = 0\f$ and \f$
* r_2 x^2 + s_2 y^2 + t_2 x y + u_2 x + v_2 y + w_2 = 0\f$, respectively.
*
* \pre The two auxiliary curves specifying the endpoints really intersect
* with the supporting conic curve, such that the arc endpoints define a
* bounded segment of the supporting curve (e.g. in case of a hyperbolic
* arc, both point should be located on the same branch of the hyperbola).
*
* \pre `o` is not `COLLINEAR` if the supporting conic is curves, and must
* be `COLLINEAR` if it is not curved (a line or a line-pair).
*/
Curve_2(const Rational& r, const Rational& s,
const Rational& t, const Rational& u,
const Rational& v, const Rational& w,
Orientation o,
const Point_2& app_ps,
const Rational& r1, const Rational& s1,
const Rational& t1, const Rational& u1,
const Rational& v1, const Rational& w1,
const Point_2& app_pt,
const Rational& r2, const Rational& s2,
const Rational& t2, const Rational& u2,
const Rational& v2, const Rational& w2);
/// @} /// @}
@ -230,8 +129,7 @@ public:
* violation does not cause the program to abort. Instead, the constructed * violation does not cause the program to abort. Instead, the constructed
* arc is invalid (a defaultly constructed arc is also invalid). It is * arc is invalid (a defaultly constructed arc is also invalid). It is
* however recommended to check that a constructed arc is valid before * however recommended to check that a constructed arc is valid before
* inserting it to an arrangement, as this operation <I>will</I> cause the * inserting it to an arrangement.
* program to abort.
*/ */
bool is_valid() const; bool is_valid() const;
@ -299,10 +197,6 @@ public:
*/ */
Orientation orientation() const; Orientation orientation() const;
/*! return a bounding box of the arc `a`.
*/
Bbox_2 bbox() const;
/// @} /// @}
/// \name Operations /// \name Operations
@ -322,13 +216,14 @@ public:
}; /* end Arr_conic_traits_2::Curve_2 */ }; /* end Arr_conic_traits_2::Curve_2 */
/*! The `X_monotone_curve_2` class nested within the conic-arc traits is /*! \class X_monotone_curve_2
* The `X_monotone_curve_2` class nested within the conic-arc traits is
* used to represent \f$x\f$-monotone conic arcs. It inherits from the * used to represent \f$x\f$-monotone conic arcs. It inherits from the
* `Curve_2` type, therefore supports the access methods and the operations * `Curve_2` type, therefore supports the access methods and the operations
* listed above. * listed above.
* *
* For efficiency reasons, we recommend users not to construct \f$ * For efficiency reasons, we recommend users not to construct
* x\f$-monotone conic arc directly, but rather use the `Make_x_monotone_2` * \f$x\f$-monotone conic arc directly, but rather use the `Make_x_monotone_2`
* functor supplied by the conic-arc traits class to convert conic curves to * functor supplied by the conic-arc traits class to convert conic curves to
* \f$x\f$-monotone curves. * \f$x\f$-monotone curves.
*/ */
@ -338,10 +233,9 @@ public:
/// \name Creation /// \name Creation
/// @{ /// @{
/*! converts the given arc to an \f$ x\f$-monotone arc. /*! constructs an empty (invalid) arc.
* \pre `arc` is \f$ x\f$-monotone.
*/ */
X_monotone_curve_2(const Curve_2& arc); X_monotone_curve_2();
/// @} /// @}
@ -387,21 +281,251 @@ public:
/// @} /// @}
}; };
/*! \class Construct_curve_2
* A functor that constructs a conic arc.
*/
class Construct_curve_2 {
public:
/*! constructs an arc corresponding to the line segment `seg`.
*/
Curve_2 operator()(const typename RatKernel::Segment_2& seg) const;
/*! constructs an arc corresponding to the full circle `circ`
* (note that this circle has a center point with rational coordinates
* and rational squared radius).
*/
Curve_2 operator()(const typename RatKernel::Circle_2& circ) const;
/*! constructs a circular arc supported by the circle `circ`, going
* in the given orientation `o` from the source point `ps` to its target
* point `pt`.
*
* \pre `ps` and `pt` both lie on the circle `circ`.
*
* \pre `o` is not `COLLINEAR`.
*/
Curve_2 operator()(const typename RatKernel::Circle_2& circ, Orientation o,
const Point_2& ps, const Point_2& pt) const;
/*! constructs a circular arc going from `p1` (its source point)
* through `p2` to `p3` (its target point). Note that all three points have
* rational coordinates. The orientation of the arc is determined
* automatically.
*
* \pre The three points are not collinear.
*/
Curve_2 operator()(const typename RatKernel::Point_2& p1,
const typename RatKernel::Point_2& p2,
const typename RatKernel::Point_2& p3) const;
/*! constructs a conic arc that corresponds to the full conic curve
* \f$r x^2 + s y^2 + t x y + u x + v y + w = 0\f$.
*
* \pre As a conic arc must be bounded, the given curve must be an ellipse,
* that is \f$4 r s - t^2 > 0\f$.
*/
Curve_2 operator()(const Rational& r, const Rational& s,
const Rational& t, const Rational& u,
const Rational& v, const Rational& w) const;
/*! constructs a conic arc supported by the conic curve
* \f$r x^2 + s y^2 + t x y + u x + v y + w = 0\f$, going in the given
* orientation `o` from the source point `ps` to its target point `pt`.
*
* \pre `ps` and `pt` both satisfy the equation of the supporting conic
* curve and define a bounded segment of this curve (e.g. in case of a
* hyperbolic arc, both point should be located on the same branch of the
* hyperbola).
*
* \pre `o` is not `COLLINEAR` if the supporting conic is curves, and must
* be `COLLINEAR` if it is not curved (a line or a line-pair).
*/
Curve_2 operator()(const Rational& r, const Rational& s,
const Rational& t, const Rational& u,
const Rational& v, const Rational& w,
Orientation o,
const Point_2& ps, const Point_2& pt) const;
/*! constructs a conic arc going from `p1` (its source point)
* through `p2`, `p3` and `p4` (in this order) to `p5` (its target
* point). Note that all five points have rational coordinates. The
* orientation of the arc is determined automatically.
*
* \pre No three points of the five are not collinear.
*
* \pre The five points define a valid arc, in their given order.
*/
Curve_2 operator()(const typename RatKernel::Point_2& p1,
const typename RatKernel::Point_2& p2,
const typename RatKernel::Point_2& p3,
const typename RatKernel::Point_2& p4,
const typename RatKernel::Point_2& p5) const;
/*! constructs a conic arc supported by the conic curve
* \f$r x^2 + s y^2 + t x y + u x + v y + w = 0\f$, going in the given
* orientation `o` from its source point to its target Point. In this case
* only some approximations of the endpoints (`app_ps` and `app_pt`,
* respectively) is available, and their exact locations are given
* implicitly, specified by the intersections of the supporting conic curve
* with \f$r_1 x^2 + s_1 y^2 + t_1 x y + u_1 x + v_1 y + w_1 = 0\f$ and
* \f$r_2 x^2 + s_2 y^2 + t_2 x y + u_2 x + v_2 y + w_2 = 0\f$, respectively.
*
* \pre The two auxiliary curves specifying the endpoints really intersect
* with the supporting conic curve, such that the arc endpoints define a
* bounded segment of the supporting curve (e.g. in case of a hyperbolic
* arc, both point should be located on the same branch of the hyperbola).
*
* \pre `o` is not `COLLINEAR` if the supporting conic is curves, and must
* be `COLLINEAR` if it is not curved (a line or a line-pair).
*/
Curve_2 operator()(const Rational& r, const Rational& s,
const Rational& t, const Rational& u,
const Rational& v, const Rational& w,
Orientation o,
const Point_2& app_ps,
const Rational& r1, const Rational& s1,
const Rational& t1, const Rational& u1,
const Rational& v1, const Rational& w1,
const Point_2& app_pt,
const Rational& r2, const Rational& s2,
const Rational& t2, const Rational& u2,
const Rational& v2, const Rational& w2) const;
};
/*! \class Construct_x_monotone_curve_2
* A functor that constructs an \f$x\f$-monotone conic arc.
*/
class Construct_x_monotone_curve_2 {
public:
/*! converts a given arc to an \f$x\f$-monotone arc.
* \param cv The input arc.
* \pre `cv` is \f$x\f$-monotone.
*/
X_monotone_curve_2 operator()(const Curve_2& cv) const;
/*! Constructs an \f$x\f$-monotone curve connecting the two given endpoints.
* \param source The first point.
* \param target The second point.
* \pre `source` and `target` must not be the same.
* \return A segment connecting `source` and `target`.
*/
X_monotone_curve_2 operator()(const Point_2& source, const Point_2& target) const;
/*! Constructs a special segment of a given line connecting to given
* endpoints.
* \param a, b, c The coefficients of the supporting line (\f$ax + by + c = 0\f$).
* \param source The source point.
* \param target The target point.
* \pre `source` and `target` must not be the same.
* \return A segment connecting `source` and `target`.
*/
X_monotone_curve_2 operator()(const Algebraic& a, const Algebraic& b,
const Algebraic& c,
const Point_2& source, const Point_2& target) const;
};
/*! \class Construct_bbox_2
* A functor that constructs a bounding box of a conic arc.
*/
class Construct_bbox_2 {
public:
/*! Obtain a bounding box for a conic arc.
* \param cv The conic arc.
* \return The bounding box.
*/
Bbox_2 operator()(const Curve_2& cv) const { return bbox(cv); }
/*! Obtain a bounding box for an \f$x\f$-monotone conic arc.
* \param xcv The \f$x\f$-monotone conic arc.
* \return The bounding box.
*/
Bbox_2 operator()(const X_monotone_curve_2& xcv) const { return bbox(xcv); }
};
/*! \name Auxiliary Functor definitions, used gor, e.g., the landmarks
* point-location strategy and the drawing function.
*/
//@{
typedef double Approximate_number_type;
typedef CGAL::Cartesian<Approximate_number_type> Approximate_kernel;
typedef Approximate_kernel::Point_2 Approximate_point_2;
/*! \class Approximate_2
* A functor that approximates a point and an \f$x\f$-monotone curve.
*/
class Approximate_2 {
public:
/*! Obtain an approximation of a point coordinate.
* \param p The exact point.
* \param i The coordinate index (either 0 or 1).
* \pre `i` is either 0 or 1.
* \return An approximation of p's \f$x\f$-coordinate (if `i` == 0), or an
* approximation of p's \f$y\f$-coordinate (if `i` == 1).
*/
Approximate_number_type operator()(const Point_2& p, int i) const;
/*! Obtain an approximation of a point.
* \param p The exact point.
*/
Approximate_point_2 operator()(const Point_2& p) const;
/*! Obtain a polyline that approximates an \f$x\f$-monotone curve. The
* polyline is defined by a range of approximate points beginning at
* `oi`. The type `OutputIterator` must dereference the type
* `Approximate_point_2`. The first and last points in the range are always
* the endpoints of the given arc `xcv`. The operator returns a
* past-the-end iterator of the destination range.
* \param oi An output iterator for the resulting polyline.
* \param error The error bound of the polyline approximation. This is
* the Hausdorff distance between the arc and the polyline
* that approximates the arc.
* \param xcv The exact \f$x\f$-monotone arc.
* \param l2r A Boolean flag that indicates whether the arc direction is
* left to right.
* \return The past-the-end iterator of the output iterator.
*/
template <typename OutputIterator>
OutputIterator operator()(OutputIterator oi, double error,
const X_monotone_curve_2& xcv,
bool l2r = true) const;
};
/*! \class Trim_2
* A functor that trims a conic arc.
*/
class Trim_2 { class Trim_2 {
public: public:
/// \name Creation /*! Trims the given \f$x\f$-monotone arc to new endpoints.
* \param xcv The \f$x\f$-monotone arc
* \param source The new source point.
* \param target The new target point.
* \pre `source` and `target` lies on the arc.
*/
X_monotone_curve_2 operator()(const X_monotone_curve_2& xcv,
const Point_2& source,
const Point_2& target) const;
};
/// \name Accessing Functor Objects
/// @{ /// @{
/*! Trims the given x-monotone curve to an from src to tgt. /*! Obtain a `Construct_curve_2` functor. */
* \ pre `src` and `tgt` lies on the curve Construct_curve_2 construct_curve_2_object() const;
*/
X_monotone_curve_2(const X_monotone_curve_2& xcv, /*! Obtain a `Construct_x_monotone_curve_2` functor. */
const Point_2& src, Construct_x_monotone_curve_2 construct_x_monotone_curve_2_object() const;
const Point_2& tgt) const;
/*! Obtain a `Bbox_2` functor. */
Construct_bbox_2 construct_bbox_2_object() const;
/*! Obtain a `Trim_2` functor. */
Trim_2 trim_2_object() const;
/*! Obtain an `Approximate_2` functor. */
Trim_2 approximate_2_object() const;
/// @} /// @}
}/* end Arr_conic_traits_2::Trim_2 */
}; /* end Arr_conic_traits_2 */ }; /* end Arr_conic_traits_2 */
} /* end namespace CGAL */ } /* end namespace CGAL */

View File

@ -52,6 +52,10 @@ namespace CGAL {
* \sa `PkgArrangementOnSurface2Read` * \sa `PkgArrangementOnSurface2Read`
* \sa `PkgArrangementOnSurface2Write` * \sa `PkgArrangementOnSurface2Write`
*
* Drawing function
*
* \sa `PkgArrangementOnSurface2Draw`
*/ */
template <typename GeometryTraits, typename TopologyTraits> template <typename GeometryTraits, typename TopologyTraits>
class Arrangement_on_surface_2 { class Arrangement_on_surface_2 {

View File

@ -0,0 +1,55 @@
// Copyright (c) 2012
// Utrecht University (The Netherlands),
// ETH Zurich (Switzerland),
// INRIA Sophia-Antipolis (France),
// Max-Planck-Institute Saarbruecken (Germany),
// and Tel-Aviv University (Israel). All rights reserved.
//
// This file is part of CGAL (www.cgal.org)
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Efi Fogel <efifogel@gmail.com>
#ifndef CGAL_DRAW_ARRANGEMENT_2_H
#define CGAL_DRAW_ARRANGEMENT_2_H
#include <CGAL/Qt/Basic_viewer_qt.h>
#ifdef DOXYGEN_RUNNING
namespace CGAL {
/*! \ingroup PkgArrangementOnSurface2Draw
*
* opens a new window and draws `arr`, an instance of the `CGAL::Arrangement_2`
* class template. A call to this function is blocking; that is, the program
* continues only after the user closes the window. This function requires
* `CGAL_Qt5`, and is only available if the macro `CGAL_USE_BASIC_VIEWER` is
* defined. Linking with the cmake target `CGAL::CGAL_Basic_viewer` will link
* with `CGAL_Qt5` and add the definition `CGAL_USE_BASIC_VIEWER`.
*
* \tparam GeometryTraits_2 a geometry traits type, a model of a 2D arrangement
* traits concept. At this point it must be an instance of either
* `CGAL::Arr_segment_traits_2` or `CGAL::Arr_conic_traits_2`.
*
* \tparam Dcel the \dcel type, a model of the `ArrangementDcel` concept.
*
* \param arr the 2D arrangement to draw.
* \param title the window title.
*
* \sa `ArrangementDcel`
* \sa `ArrangementTraits_2`
*/
template <typename GeometryTraits_2, typename Dcel>
void draw(const Arrangement_2<GeometryTraits_2, Dcel>& arr,
const char* title = "2D Arrangement Basic Viewer");
} /* namespace CGAL */
#endif
#endif

View File

@ -46,6 +46,14 @@ namespace ArrTraits {}
/// \defgroup PkgArrangementOnSurface2Funcs Free Functions /// \defgroup PkgArrangementOnSurface2Funcs Free Functions
/// \ingroup PkgArrangementOnSurface2Ref /// \ingroup PkgArrangementOnSurface2Ref
/*!
\code
#include <CGAL/draw_arrangement_2.h>
\endcode
*/
/// \defgroup PkgArrangementOnSurface2Draw Drawing
/// \ingroup PkgArrangementOnSurface2Ref
/// \defgroup PkgArrangementOnSurface2Insert CGAL::insert() /// \defgroup PkgArrangementOnSurface2Insert CGAL::insert()
/// \ingroup PkgArrangementOnSurface2Funcs /// \ingroup PkgArrangementOnSurface2Funcs
@ -252,4 +260,7 @@ implemented as peripheral classes or as free (global) functions.
- \link PkgArrangementOnSurface2op_left_shift `CGAL::operator<<` \endlink - \link PkgArrangementOnSurface2op_left_shift `CGAL::operator<<` \endlink
- \link PkgArrangementOnSurface2op_right_shift `CGAL::operator<<` \endlink - \link PkgArrangementOnSurface2op_right_shift `CGAL::operator<<` \endlink
\cgalCRPSection{Draw an `Arrangemen_2` object}
- \link PkgArrangementOnSurface2Draw CGAL::draw<>() \endlink
*/ */

View File

@ -43,4 +43,9 @@
\example Arrangement_on_surface_2/unbounded_non_intersecting.cpp \example Arrangement_on_surface_2/unbounded_non_intersecting.cpp
\example Arrangement_on_surface_2/unbounded_rational_functions.cpp \example Arrangement_on_surface_2/unbounded_rational_functions.cpp
\example Arrangement_on_surface_2/vertical_ray_shooting.cpp \example Arrangement_on_surface_2/vertical_ray_shooting.cpp
\example Arrangement_on_surface_2/draw_arr.cpp
\example Arrangement_on_surface_2/linear_conics.cpp
\example Arrangement_on_surface_2/parabolas.cpp
\example Arrangement_on_surface_2/ellipses.cpp
\example Arrangement_on_surface_2/hyperbolas.cpp
*/ */

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -4,7 +4,7 @@
cmake_minimum_required(VERSION 3.1...3.23) cmake_minimum_required(VERSION 3.1...3.23)
project(Arrangement_on_surface_2_Examples) project(Arrangement_on_surface_2_Examples)
find_package(CGAL REQUIRED COMPONENTS Core) find_package(CGAL REQUIRED COMPONENTS Core OPTIONAL_COMPONENTS Qt5)
# create a target per cppfile # create a target per cppfile
file( file(
@ -14,3 +14,19 @@ file(
foreach(cppfile ${cppfiles}) foreach(cppfile ${cppfiles})
create_single_source_cgal_program("${cppfile}") create_single_source_cgal_program("${cppfile}")
endforeach() endforeach()
if(CGAL_Qt5_FOUND)
target_link_libraries(draw_arr PUBLIC CGAL::CGAL_Basic_viewer)
target_link_libraries(linear_conics PUBLIC CGAL::CGAL_Basic_viewer)
target_link_libraries(parabolas PUBLIC CGAL::CGAL_Basic_viewer)
target_link_libraries(ellipses PUBLIC CGAL::CGAL_Basic_viewer)
target_link_libraries(hyperbolas PUBLIC CGAL::CGAL_Basic_viewer)
target_link_libraries(polylines PUBLIC CGAL::CGAL_Basic_viewer)
target_link_libraries(circles PUBLIC CGAL::CGAL_Basic_viewer)
target_link_libraries(circular_arcs PUBLIC CGAL::CGAL_Basic_viewer)
else()
message(
STATUS
"NOTICE: Several examples require Qt and will not be compiled."
)
endif()

View File

@ -6,20 +6,18 @@
#include <CGAL/Arr_conic_traits_2.h> #include <CGAL/Arr_conic_traits_2.h>
#include <CGAL/Arrangement_2.h> #include <CGAL/Arrangement_2.h>
typedef CGAL::CORE_algebraic_number_traits Nt_traits; using Nt_traits = CGAL::CORE_algebraic_number_traits;
typedef Nt_traits::Rational Rational; using Rational = Nt_traits::Rational;
typedef CGAL::Cartesian<Rational> Rat_kernel; using Rat_kernel = CGAL::Cartesian<Rational>;
typedef Rat_kernel::Point_2 Rat_point; using Rat_point = Rat_kernel::Point_2;
typedef Rat_kernel::Segment_2 Rat_segment; using Rat_segment = Rat_kernel::Segment_2;
typedef Rat_kernel::Circle_2 Rat_circle; using Rat_circle = Rat_kernel::Circle_2;
typedef Nt_traits::Algebraic Algebraic; using Algebraic = Nt_traits::Algebraic;
typedef CGAL::Cartesian<Algebraic> Alg_kernel; using Alg_kernel = CGAL::Cartesian<Algebraic>;
using Traits = CGAL::Arr_conic_traits_2<Rat_kernel, Alg_kernel, Nt_traits>;
typedef CGAL::Arr_conic_traits_2<Rat_kernel, Alg_kernel, Nt_traits> using Point = Traits::Point_2;
Traits; using Conic_arc = Traits::Curve_2;
typedef Traits::Point_2 Point; using X_monotone_conic_arc = Traits::X_monotone_curve_2;
typedef Traits::Curve_2 Conic_arc; using Arrangement = CGAL::Arrangement_2<Traits>;
typedef Traits::X_monotone_curve_2 X_monotone_conic_arc;
typedef CGAL::Arrangement_2<Traits> Arrangement;
#endif #endif

View File

@ -1,6 +1,8 @@
//! \file examples/Arrangement_on_surface_2/circles.cpp //! \file examples/Arrangement_on_surface_2/circles.cpp
// Constructing an arrangement of circles using the circle-segment traits. // Constructing an arrangement of circles using the circle-segment traits.
#include <CGAL/draw_arrangement_2.h>
#include "arr_circular.h" #include "arr_circular.h"
int main() { int main() {
@ -27,5 +29,6 @@ int main() {
std::cout << "The vertex with maximal degree in the arrangement is: " std::cout << "The vertex with maximal degree in the arrangement is: "
<< "v_max = (" << v_max->point() << ") " << "v_max = (" << v_max->point() << ") "
<< "with degree " << v_max->degree() << "." << std::endl; << "with degree " << v_max->degree() << "." << std::endl;
CGAL::draw(arr);
return 0; return 0;
} }

View File

@ -1,6 +1,8 @@
//! \file examples/Arrangement_on_surface_2/circular_arc.cpp //! \file examples/Arrangement_on_surface_2/circular_arc.cpp
// Constructing an arrangement of various circular arcs and line segments. // Constructing an arrangement of various circular arcs and line segments.
#include <CGAL/draw_arrangement_2.h>
#include "arr_circular.h" #include "arr_circular.h"
#include "arr_print.h" #include "arr_print.h"
@ -56,5 +58,6 @@ int main() {
Arrangement arr; Arrangement arr;
insert(arr, curves.begin(), curves.end()); insert(arr, curves.begin(), curves.end());
print_arrangement_size(arr); print_arrangement_size(arr);
CGAL::draw(arr);
return 0; return 0;
} }

View File

@ -14,7 +14,10 @@
typedef CGAL::Arr_naive_point_location<Arrangement> Naive_pl; typedef CGAL::Arr_naive_point_location<Arrangement> Naive_pl;
int main() { int main() {
Arrangement arr; Traits traits;
auto ctr_cv = traits.construct_curve_2_object();
Arrangement arr(&traits);
Naive_pl pl(arr); Naive_pl pl(arr);
// Insert a hyperbolic arc, supported by the hyperbola y = x^2/(1-x) // Insert a hyperbolic arc, supported by the hyperbola y = x^2/(1-x)
@ -22,16 +25,18 @@ int main() {
// Note that the arc is counterclockwise oriented. // Note that the arc is counterclockwise oriented.
Point ps1(-1, Rational(1,2)); Point ps1(-1, Rational(1,2));
Point pt1(Rational(1,2), Rational(1,2)); Point pt1(Rational(1,2), Rational(1,2));
Conic_arc cv1(1, 0, 1, 0, -1, 0, CGAL::COUNTERCLOCKWISE, ps1, pt1); Conic_arc cv1 = ctr_cv(1, 0, 1, 0, -1, 0, CGAL::COUNTERCLOCKWISE, ps1, pt1);
insert(arr, cv1, pl); // insert(arr, cv1, pl);
#if 0
// Insert the bottom half of the circle centered at (0, 1/2) whose radius // Insert the bottom half of the circle centered at (0, 1/2) whose radius
// is 1/2 (therefore its squared radius is 1/4). // is 1/2 (therefore its squared radius is 1/4).
Rat_circle circ2(Rat_point(0, Rational(1,2)), Rational(1,4)); Rat_circle circ2(Rat_point(0, Rational(1,2)), Rational(1,4));
Point ps2(-Rational(1,2), Rational(1,2)); Point ps2(-Rational(1,2), Rational(1,2));
Point pt2(Rational(1,2), Rational(1,2)); Point pt2(Rational(1,2), Rational(1,2));
Conic_arc cv2(circ2, CGAL::COUNTERCLOCKWISE, ps2, pt2); Conic_arc cv2 = ctr_cv(circ2, CGAL::COUNTERCLOCKWISE, ps2, pt2);
insert(arr, cv2, pl); insert(arr, cv2, pl);
#endif
print_arrangement(arr); print_arrangement(arr);
return 0; return 0;

View File

@ -9,31 +9,31 @@
#include "arr_print.h" #include "arr_print.h"
int main() { int main() {
Arrangement arr; Traits traits;
Arrangement arr(&traits);
auto ctr_cv = traits.construct_curve_2_object();
// Insert a hyperbolic arc (C1), supported by the hyperbola y = 1/x // Insert a hyperbolic arc (C1), supported by the hyperbola y = 1/x
// (or: xy - 1 = 0) with the endpoints (1/4, 4) and (2, 1/2). // (or: xy - 1 = 0) with the endpoints (1/4, 4) and (2, 1/2).
// The arc is counterclockwise oriented. // The arc is counterclockwise oriented.
insert(arr, Conic_arc(0, 0, 1, 0, 0, -1, CGAL::COUNTERCLOCKWISE, insert(arr, ctr_cv(0, 0, 1, 0, 0, -1, CGAL::COUNTERCLOCKWISE,
Point(Rational(1,4), 4), Point(2, Rational(1,2)))); Point(Rational(1,4), 4), Point(2, Rational(1,2))));
// Insert a full ellipse (C2), which is (x/4)^2 + (y/2)^2 = 0 rotated by // Insert a full ellipse (C2), which is (x/4)^2 + (y/2)^2 = 0 rotated by
// phi = 36.87 degrees (such that sin(phi) = 0.6, cos(phi) = 0.8), // phi = 36.87 degrees (such that sin(phi) = 0.6, cos(phi) = 0.8),
// yielding: 58x^2 + 72y^2 - 48xy - 360 = 0. // yielding: 58x^2 + 72y^2 - 48xy - 360 = 0.
insert(arr, Conic_arc (58, 72, -48, 0, 0, -360)); insert(arr, ctr_cv(58, 72, -48, 0, 0, -360));
// Insert the segment (C3) (1, 1) -- (0, -3). // Insert the segment (C3) (1, 1) -- (0, -3).
insert(arr, Conic_arc(Rat_segment(Rat_point(1, 1), Rat_point(0, -3)))); insert(arr, ctr_cv(Rat_segment(Rat_point(1, 1), Rat_point(0, -3))));
// Insert a circular arc (C4) supported by the circle x^2 + y^2 = 5^2, // Insert a circular arc (C4) supported by the circle x^2 + y^2 = 5^2,
// with (-3, 4) and (4, 3) as its endpoints. We want the arc to be // with (-3, 4) and (4, 3) as its endpoints. We want the arc to be
// clockwise-oriented, so it passes through (0, 5) as well. // clockwise-oriented, so it passes through (0, 5) as well.
Conic_arc c4(Rat_point(-3, 4), Rat_point(0, 5), Rat_point(4, 3)); insert(arr, ctr_cv(Rat_point(-3, 4), Rat_point(0, 5), Rat_point(4, 3)));
insert(arr, c4);
// Insert a full unit circle (C5) that is centered at (0, 4). // Insert a full unit circle (C5) that is centered at (0, 4).
insert(arr, Conic_arc(Rat_circle(Rat_point(0,4), 1))); insert(arr, ctr_cv(Rat_circle(Rat_point(0,4), 1)));
// Insert a parabolic arc (C6) supported by the parabola y = -x^2 with // Insert a parabolic arc (C6) supported by the parabola y = -x^2 with
// endpoints (-sqrt(3),-3) (~(-1.73,-3)) and (sqrt(2),-2) (~(1.41,-2)). // endpoints (-sqrt(3),-3) (~(-1.73,-3)) and (sqrt(2),-2) (~(1.41,-2)).
@ -41,18 +41,18 @@ int main() {
// we specify them as the intersections of the parabola with the lines // we specify them as the intersections of the parabola with the lines
// y = -3 and y = -2, respectively. The arc is clockwise-oriented. // y = -3 and y = -2, respectively. The arc is clockwise-oriented.
Conic_arc c6 = Conic_arc c6 =
Conic_arc(1, 0, 0, 0, 1, 0, CGAL::CLOCKWISE, // The parabola. ctr_cv(1, 0, 0, 0, 1, 0, CGAL::CLOCKWISE, // The parabola.
Point(-1.73, -3), // approximation of the source. Point(-1.73, -3), // approximation of the source.
0, 0, 0, 0, 1, 3, // the line: y = -3. 0, 0, 0, 0, 1, 3, // the line: y = -3.
Point(1.41, -2), // approximation of the target. Point(1.41, -2), // approximation of the target.
0, 0, 0, 0, 1, 2); // the line: y = -2. 0, 0, 0, 0, 1, 2); // the line: y = -2.
insert(arr, c6); insert(arr, c6);
// Insert the right half of the circle centered at (4, 2.5) whose radius // Insert the right half of the circle centered at (4, 2.5) whose radius
// is 1/2 (therefore its squared radius is 1/4) (C7). // is 1/2 (therefore its squared radius is 1/4) (C7).
Rat_circle circ7(Rat_point(4, Rational(5,2)), Rational(1,4)); Rat_circle circ7(Rat_point(4, Rational(5,2)), Rational(1,4));
insert(arr, Conic_arc(circ7, CGAL::CLOCKWISE, Point(4, 3), Point(4, 2))); insert(arr, ctr_cv(circ7, CGAL::CLOCKWISE, Point(4, 3), Point(4, 2)));
print_arrangement_size(arr); print_arrangement_size(arr);
return 0; return 0;
@ -62,8 +62,7 @@ int main() {
#include <iostream> #include <iostream>
int main () int main() {
{
std::cout << "Sorry, this example needs GMP and CORE\n"; std::cout << "Sorry, this example needs GMP and CORE\n";
return 0; return 0;
} }

View File

@ -0,0 +1,110 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Arrangement_2.h>
#include <CGAL/Arr_segment_traits_2.h>
#include <CGAL/draw_arrangement_2.h>
using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel;
using Traits = CGAL::Arr_segment_traits_2<Kernel>;
using Point = Traits::Point_2;
using Arrangement_2 = CGAL::Arrangement_2<Traits>;
/*! Convert HSV to RGB color space
* Converts a given set of HSV values `h', `s', `v' into RGB coordinates.
* The output RGB values are in the range [0, 255], and the input HSV values
* are in the ranges h = [0, 360], and s, v = [0, 1], respectively.
*
* \param hue Hue component range: [0, 360]
* \param sat Saturation component range: [0, 1]
* \param value Value component range: [0, 1]
* \return tuple<red, green, blue>, where each component is in the range [0, 255]
*/
std::tuple<float, float, float>
hsv_to_rgb(float hue, float sat, float value) {
float red, green, blue;
float fc = value * sat; // Chroma
float hue_prime = fmod(hue / 60.0, 6);
float fx = fc * (1.0 - fabs(fmod(hue_prime, 2) - 1.0));
float fm = value - fc;
if(0 <= hue_prime && hue_prime < 1) {
red = fc;
green = fx;
blue = 0;
}
else if(1 <= hue_prime && hue_prime < 2) {
red = fx;
green = fc;
blue = 0;
}
else if(2 <= hue_prime && hue_prime < 3) {
red = 0;
green = fc;
blue = fx;
}
else if(3 <= hue_prime && hue_prime < 4) {
red = 0;
green = fx;
blue = fc;
}
else if(4 <= hue_prime && hue_prime < 5) {
red = fx;
green = 0;
blue = fc;
}
else if(5 <= hue_prime && hue_prime < 6) {
red = fc;
green = 0;
blue = fx;
}
else {
red = 0;
green = 0;
blue = 0;
}
red += fm;
green += fm;
blue += fm;
red *= 255;
green *= 255;
blue *= 255;
return std::make_tuple(red, green, blue);
}
int main() {
Traits traits;
Arrangement_2 arr(&traits);
auto ctr_xcv = traits.construct_x_monotone_curve_2_object();
CGAL::insert(arr, ctr_xcv(Point(-2,-2), Point(2,-2)));
CGAL::insert(arr, ctr_xcv(Point(2,-2), Point(2,2)));
CGAL::insert(arr, ctr_xcv(Point(2,2), Point(-2,2)));
CGAL::insert(arr, ctr_xcv(Point(-2,2), Point(-2,-2)));
CGAL::insert(arr, ctr_xcv(Point(-1,-1), Point(1,-1)));
CGAL::insert(arr, ctr_xcv(Point(1,-1), Point(1,1)));
CGAL::insert(arr, ctr_xcv(Point(1,1), Point(-1,1)));
CGAL::insert(arr, ctr_xcv(Point(-1,1), Point(-1,-1)));
CGAL::insert(arr, ctr_xcv(Point(-2,-2), Point(-2,-4)));
CGAL::insert(arr, ctr_xcv(Point(2,-2), Point(4,-2)));
CGAL::insert(arr, ctr_xcv(Point(0,0), Point(0,-3)));
std::cout << arr.number_of_vertices() << ", "
<< arr.number_of_edges() << ", "
<< arr.number_of_faces() << std::endl;
std::size_t id(0);
CGAL::draw(arr, [&] (Arrangement_2::Face_const_handle) -> CGAL::IO::Color {
float h = 360.0 * id++ / arr.number_of_faces();
float s = 0.5;
float v = 0.5;
float r, g, b;
std::tie(r, g, b) = hsv_to_rgb(h, s, v);
return CGAL::IO::Color(r, g, b);
}, "hsv colors", true);
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,57 @@
//! \file examples/Arrangement_on_surface_2/conics.cpp
// Constructing an arrangement of various conic arcs.
#include <CGAL/config.h>
#ifdef CGAL_USE_CORE
#include <CGAL/basic.h>
#include <CGAL/draw_arrangement_2.h>
#include "arr_conics.h"
#include "arr_print.h"
int main() {
Traits traits;
Arrangement arr(&traits);
auto ctr_cv = traits.construct_curve_2_object();
// Insert a full x-major ellipse
CGAL::insert(arr, ctr_cv(1, 4, 0, 0, 0, -16, CGAL::COUNTERCLOCKWISE,
Point(4,0), Point(0,2)));
CGAL::insert(arr, ctr_cv(1, 4, 0, 0, 0, -16, CGAL::COUNTERCLOCKWISE,
Point(0,2), Point(-4,0)));
CGAL::insert(arr, ctr_cv(1, 4, 0, 0, 0, -16, CGAL::COUNTERCLOCKWISE,
Point(-4,0), Point(0,-2)));
CGAL::insert(arr, ctr_cv(1, 4, 0, 0, 0, -16, CGAL::COUNTERCLOCKWISE,
Point(0,-2), Point(4,0)));
// Insert a full y-major ellipse
CGAL::insert(arr, ctr_cv(4, 1, 0, 0, 0, -16));
// Insert the full ellipse (x/4)^2 + (y/2)^2 = 1 clockwise rotated by
// phi = 36.87 degrees (such that sin(phi) = 0.6, cos(phi) = 0.8),
CGAL::insert(arr, ctr_cv(52, 73, 72, 0, 0, -400));
// Insert the full ellipse (x/4)^2 + (y/2)^2 = 1 counter clockwise rotated by
// phi = 36.87 degrees (such that sin(phi) = 0.6, cos(phi) = 0.8),
CGAL::insert(arr, ctr_cv(52, 73, -72, 0, 0, -400));
print_arrangement_size(arr);
CGAL::draw(arr);
return 0;
}
#else
#include <iostream>
int main() {
std::cout << "Sorry, this example needs GMP and CORE\n";
return 0;
}
#endif

View File

@ -0,0 +1,93 @@
//! \file examples/Arrangement_on_surface_2/conics.cpp
// Constructing an arrangement of various conic arcs.
#include <CGAL/config.h>
#ifdef CGAL_USE_CORE
#include <CGAL/basic.h>
#include <CGAL/draw_arrangement_2.h>
#include "arr_conics.h"
#include "arr_print.h"
int main() {
Traits traits;
Arrangement arr(&traits);
auto ctr_cv = traits.construct_curve_2_object();
// Insert a hyperbolic arc (C1), supported by the hyperbola y = 1/x
// (or: xy - 1 = 0) with the endpoints (1/4, 4) and (2, 1/2).
// The arc is counterclockwise oriented.
CGAL::insert(arr, ctr_cv(0, 0, 1, 0, 0, -1, CGAL::COUNTERCLOCKWISE,
Point(Rational(1,4), 4), Point(2, Rational(1,2))));
CGAL::insert(arr, ctr_cv(0, 0, -1, 0, 0, -1, CGAL::CLOCKWISE,
Point(Rational(-1,4), 4), Point(-2, Rational(1,2))));
CGAL::insert(arr, ctr_cv(2, -1, 0, 0, 0, -2, CGAL::COUNTERCLOCKWISE,
Point(3, 4), Point(1, 0)));
CGAL::insert(arr, ctr_cv(2, -1, 0, 0, 0, -2, CGAL::COUNTERCLOCKWISE,
Point(1, 0), Point(3, -4)));
CGAL::insert(arr, ctr_cv(2, -1, 0, 0, 0, -2, CGAL::CLOCKWISE,
Point(-3, 4), Point(-1, 0)));
CGAL::insert(arr, ctr_cv(2, -1, 0, 0, 0, -2, CGAL::CLOCKWISE,
Point(-1, 0), Point(-3, -4)));
CGAL::insert(arr, ctr_cv(-1, 2, 0, 0, 0, -2, CGAL::CLOCKWISE,
Point(4, 3), Point(0, 1)));
CGAL::insert(arr, ctr_cv(-1, 2, 0, 0, 0, -2, CGAL::CLOCKWISE,
Point(0, 1), Point(-4, 3)));
CGAL::insert(arr, ctr_cv(-1, 2, 0, 0, 0, -2, CGAL::COUNTERCLOCKWISE,
Point(4, -3), Point(0, -1)));
CGAL::insert(arr, ctr_cv(-1, 2, 0, 0, 0, -2, CGAL::COUNTERCLOCKWISE,
Point(0, -1), Point(-4, -3)));
CGAL::insert(arr, ctr_cv(4, 46, -144, 0, 0, -100, CGAL::COUNTERCLOCKWISE,
Point(-5, 0),
Point(Rational(14, 10), Rational(48, 10))));
CGAL::insert(arr, ctr_cv(4, 46, -144, 0, 0, -100, CGAL::COUNTERCLOCKWISE,
Point(5, 0),
Point(Rational(-14, 10), Rational(-48, 10))));
// 4*x*x + 46*y*y - 144*x*y - 100
CGAL::insert(arr, ctr_cv(46, 4, -144, 0, 0, -100, CGAL::CLOCKWISE,
Point(0, -5),
Point(Rational(48, 10), Rational(14, 10))));
CGAL::insert(arr, ctr_cv(46, 4, -144, 0, 0, -100, CGAL::CLOCKWISE,
Point(0, 5),
Point(Rational(-48, 10), Rational(-14, 10))));
// 46*x*x + 4*y*y - 144*x*y - 100
CGAL::insert(arr, ctr_cv(4, 46, 144, 0, 0, -100, CGAL::CLOCKWISE,
Point(-5, 0),
Point(Rational(14,10), Rational(-48,10))));
CGAL::insert(arr, ctr_cv(4, 46, 144, 0, 0, -100, CGAL::CLOCKWISE,
Point(5, 0),
Point(Rational(-14,10), Rational(48,10))));
// 4*x*x + 46*y*y + 144*x*y - 100
CGAL::insert(arr, ctr_cv(46, 4, 144, 0, 0, -100, CGAL::COUNTERCLOCKWISE,
Point(0, -5),
Point(Rational(-48,10), Rational(14,10))));
CGAL::insert(arr, ctr_cv(46, 4, 144, 0, 0, -100, CGAL::COUNTERCLOCKWISE,
Point(0, 5),
Point(Rational(48,10), Rational(-14,10))));
print_arrangement_size(arr);
CGAL::draw(arr);
return 0;
}
#else
#include <iostream>
int main() {
std::cout << "Sorry, this example needs GMP and CORE\n";
return 0;
}
#endif

View File

@ -0,0 +1,74 @@
//! \file examples/Arrangement_on_surface_2/conics.cpp
// Constructing an arrangement of various conic arcs.
#include <CGAL/config.h>
#ifdef CGAL_USE_CORE
#include <CGAL/basic.h>
#include <CGAL/draw_arrangement_2.h>
#include "arr_conics.h"
#include "arr_print.h"
int main() {
Traits traits;
Arrangement arr(&traits);
auto ctr_cv = traits.construct_curve_2_object();
Point p0(0, 0);
Point p1(-1, 0);
Point p2(0, -1);
Point p3(0, 1);
Point p4(1, 0);
Point p5(Rational(1,2),Rational(1,2));
Point p6(Rational(-1,2),Rational(1,2));
Rat_point rp0(0, 0);
Rat_point rp1(1, 0);
Rat_point rp2(0, 1);
Rat_point rp3(0, -1);
// horizontal
// insert the segment (0, 0)--(1, 0).
CGAL::insert(arr, ctr_cv(Rat_segment(rp0, rp1)));
// insert the segment (0, 0)--(-1, 0).
CGAL::insert(arr, ctr_cv(0, 0, 0, 0, 1, 0, CGAL::COLLINEAR, p0, p1));
// vertical
// insert the segment (0, -1)--(0, 0).
CGAL::insert(arr, ctr_cv(Rat_segment(rp3, rp0)));
// translated
// insert the segment (0, -1)--(1, 0).
CGAL::insert(arr, ctr_cv(Rat_segment(rp3, rp1)));
// insert the segment (0, -1)--(-1, 0).
CGAL::insert(arr, ctr_cv(0, 0, 0, -1, -1, -1, CGAL::COLLINEAR, p2, p1));
// Special segments
// horizontal special segment
CGAL::insert(arr, ctr_cv(p5, p6));
// vertical special segment
CGAL::insert(arr, ctr_cv(p0, p3));
// special translated
CGAL::insert(arr, ctr_cv(p1, p3));
CGAL::insert(arr, ctr_cv(p3, p4));
print_arrangement_size(arr);
CGAL::draw(arr);
return 0;
}
#else
#include <iostream>
int main() {
std::cout << "Sorry, this example needs GMP and CORE\n";
return 0;
}
#endif

View File

@ -0,0 +1,91 @@
//! \file examples/Arrangement_on_surface_2/conics.cpp
// Constructing an arrangement of various conic arcs.
#include <CGAL/config.h>
#ifdef CGAL_USE_CORE
#include <CGAL/basic.h>
#include <CGAL/draw_arrangement_2.h>
#include "arr_conics.h"
#include "arr_print.h"
int main() {
Traits traits;
Arrangement arr(&traits);
auto ctr_cv = traits.construct_curve_2_object();
// x-major
// insert the parabola y = x^2; (-1,1)--(1,1)
CGAL::insert(arr, ctr_cv(1, 0, 0, 0, -1, 0, CGAL::COUNTERCLOCKWISE,
Point(-1, 1), Point(1, 1)));
// translated
// Insert the parabola y = x^2 - 2x + 2; (1,1)--(2,2)
CGAL::insert(arr, ctr_cv(1, 0, 0, -2, -1, 2, CGAL::COUNTERCLOCKWISE,
Point(1, 1), Point(2, 2)));
CGAL::insert(arr, ctr_cv(1, 0, 0, 2, -1, 2, CGAL::COUNTERCLOCKWISE,
Point(-2, 2), Point(-1, 1)));
// rotated
// Insert the parabola y = x^2 rotated clockwise about theta, such that
// sin(theta) = 0.6, cos(theta) = 0.8
CGAL::insert(arr, ctr_cv(16, 9, -24, -15, -20, 0, CGAL::COUNTERCLOCKWISE,
Point(Rational(-2,10), Rational(14,10)),
Point(Rational(14,10), Rational(2,10))));
CGAL::insert(arr, ctr_cv(16, 9, 24, 15, -20, 0, CGAL::CLOCKWISE,
Point(Rational(2,10), Rational(14,10)),
Point(Rational(-14,10), Rational(2,10))));
CGAL::insert(arr, ctr_cv(16, 9, 24, -15, 20, 0, CGAL::COUNTERCLOCKWISE,
Point(Rational(14,10), Rational(-2,10)),
Point(Rational(-2,10), Rational(-14,10))));
CGAL::insert(arr, ctr_cv(16, 9, -24, 15, 20, 0, CGAL::COUNTERCLOCKWISE,
Point(Rational(2,10), Rational(-14,10)),
Point(Rational(-14,10), Rational(-2,10))));
// 16*x*x+9*y*y-24*x*y-15*x-20*y
CGAL::insert(arr, ctr_cv(9, 16, -24, -20, -15, 0, CGAL::COUNTERCLOCKWISE,
Point(Rational(2,10), Rational(14,10)),
Point(Rational(14,10), Rational(-2,10))));
CGAL::insert(arr, ctr_cv(9, 16, 24, -20, 15, 0, CGAL::CLOCKWISE,
Point(Rational(2,10), Rational(-14,10)),
Point(Rational(14,10), Rational(2,10))));
CGAL::insert(arr, ctr_cv(9, 16, 24, 20, -15, 0, CGAL::COUNTERCLOCKWISE,
Point(Rational(-14,10), Rational(-2,10)),
Point(Rational(-2,10), Rational(14,10))));
CGAL::insert(arr, ctr_cv(9, 16, -24, 20, 15, 0, CGAL::COUNTERCLOCKWISE,
Point(Rational(-2,10), Rational(-14,10)),
Point(Rational(-14,10), Rational(2,10))));
// 9*x*x+16*y*y-24*x*y+20*x+15*y
// rotated & translated
CGAL::insert(arr, ctr_cv(16, 9, -24, -23, -14, 36, CGAL::COUNTERCLOCKWISE,
Point(Rational(8,10), Rational(24,10)),
Point(Rational(24,10), Rational(12,10))));
CGAL::insert(arr, ctr_cv(16, 9, 24, 23, -14, 36, CGAL::CLOCKWISE,
Point(Rational(-8,10), Rational(24,10)),
Point(Rational(-24,10), Rational(12,10))));
// 16*x*x+9*y*y-24*x*y-23*x-14*y+36
print_arrangement_size(arr);
CGAL::draw(arr);
return 0;
}
#else
#include <iostream>
int main() {
std::cout << "Sorry, this example needs GMP and CORE\n";
return 0;
}
#endif

View File

@ -27,7 +27,10 @@ typedef Polycurve_conic_traits_2::Curve_2 Polycurve;
typedef CGAL::Arrangement_2<Polycurve_conic_traits_2> Polycurve_conic_arrangment; typedef CGAL::Arrangement_2<Polycurve_conic_traits_2> Polycurve_conic_arrangment;
int main() { int main() {
Polycurve_conic_traits_2 traits; Traits sub_traits;
Polycurve_conic_traits_2 traits(&sub_traits);
auto ctr_sub_cv = sub_traits.construct_curve_2_object();
auto ctr_sub_xcv = sub_traits.construct_x_monotone_curve_2_object();
// Polycurve construction functors // Polycurve construction functors
auto ctr_xpolycurve = traits.construct_x_monotone_curve_2_object(); auto ctr_xpolycurve = traits.construct_x_monotone_curve_2_object();
@ -39,27 +42,27 @@ int main() {
// Create polycurves // Create polycurves
// y=x^2 // y=x^2
Conic_arc c3(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE, Conic_arc c3 = ctr_sub_cv(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE,
Point(Algebraic(0), Algebraic(0)), Point(Algebraic(0), Algebraic(0)),
Point(Algebraic(3), Algebraic(9))); Point(Algebraic(3), Algebraic(9)));
Conic_arc c4(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE, Conic_arc c4 = ctr_sub_cv(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE,
Point(Algebraic(3), Algebraic(9)), Point(Algebraic(3), Algebraic(9)),
Point(Algebraic(5), Algebraic(25))); Point(Algebraic(5), Algebraic(25)));
Conic_arc c5(0,1,0,1,0,0, CGAL::COUNTERCLOCKWISE, Conic_arc c5 = ctr_sub_cv(0,1,0,1,0,0, CGAL::COUNTERCLOCKWISE,
Point(Algebraic(-25), Algebraic(-5)), Point(Algebraic(-25), Algebraic(-5)),
Point(Algebraic(0), Algebraic(0))); Point(Algebraic(0), Algebraic(0)));
Conic_arc c6(1,1,0,6,-26,162,CGAL::COUNTERCLOCKWISE, Conic_arc c6 = ctr_sub_cv(1,1,0,6,-26,162,CGAL::COUNTERCLOCKWISE,
Point(Algebraic(-7), Algebraic(13)), Point(Algebraic(-7), Algebraic(13)),
Point(Algebraic(-3), Algebraic(9))); Point(Algebraic(-3), Algebraic(9)));
Conic_arc c7(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE, Conic_arc c7 = ctr_sub_cv(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE,
Point(Algebraic(-3), Algebraic(9)), Point(Algebraic(-3), Algebraic(9)),
Point(Algebraic(0), Algebraic(0))); Point(Algebraic(0), Algebraic(0)));
Conic_arc c8(0,1,0,-1,0,0, CGAL::COUNTERCLOCKWISE, Conic_arc c8 = ctr_sub_cv(0,1,0,-1,0,0, CGAL::COUNTERCLOCKWISE,
Point(Algebraic(0), Algebraic(0)), Point(Algebraic(0), Algebraic(0)),
Point(Algebraic(4), Algebraic(-2))); Point(Algebraic(4), Algebraic(-2)));
Conic_arc c9(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE, Conic_arc c9 = ctr_sub_cv(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE,
Point(Algebraic(-5), Algebraic(25)), Point(Algebraic(-5), Algebraic(25)),
Point(Algebraic(5), Algebraic(25))); Point(Algebraic(5), Algebraic(25)));
@ -69,10 +72,10 @@ int main() {
Polycurve conic_polycurve_1 = Polycurve conic_polycurve_1 =
ctr_polycurve(conic_curves.begin(), conic_curves.end()); ctr_polycurve(conic_curves.begin(), conic_curves.end());
Conic_arc c11(0,1,0,-1,0,0,CGAL::COUNTERCLOCKWISE, Conic_arc c11 = ctr_sub_cv(0,1,0,-1,0,0,CGAL::COUNTERCLOCKWISE,
Point(Algebraic(25), Algebraic(-5)), Point(Algebraic(25), Algebraic(-5)),
Point(Algebraic(0), Algebraic(0))); Point(Algebraic(0), Algebraic(0)));
Conic_arc c12(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE, Conic_arc c12 = ctr_sub_cv(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE,
Point(Algebraic(0), Algebraic(0)), Point(Algebraic(0), Algebraic(0)),
Point(Algebraic(5), Algebraic(25))); Point(Algebraic(5), Algebraic(25)));
@ -84,12 +87,12 @@ int main() {
ctr_polycurve(conic_curves.begin(), conic_curves.end()); ctr_polycurve(conic_curves.begin(), conic_curves.end());
// Construct x-monotone conic curves from conic curves // Construct x-monotone conic curves from conic curves
X_monotone_conic_arc xc3(c3); X_monotone_conic_arc xc3 = ctr_sub_xcv(c3);
X_monotone_conic_arc xc4(c4); X_monotone_conic_arc xc4 = ctr_sub_xcv(c4);
X_monotone_conic_arc xc5(c5); X_monotone_conic_arc xc5 = ctr_sub_xcv(c5);
X_monotone_conic_arc xc6(c6); X_monotone_conic_arc xc6 = ctr_sub_xcv(c6);
X_monotone_conic_arc xc7(c7); X_monotone_conic_arc xc7 = ctr_sub_xcv(c7);
X_monotone_conic_arc xc8(c8); X_monotone_conic_arc xc8 = ctr_sub_xcv(c8);
// Construct x-monotone poly-curve from x-monotone conic curves. // Construct x-monotone poly-curve from x-monotone conic curves.
xmono_conic_curves_2.clear(); xmono_conic_curves_2.clear();

View File

@ -4,6 +4,8 @@
#include <vector> #include <vector>
#include <list> #include <list>
#include <CGAL/draw_arrangement_2.h>
#include "arr_polylines.h" #include "arr_polylines.h"
#include "arr_print.h" #include "arr_print.h"
@ -44,5 +46,6 @@ int main() {
insert(arr, pi2); insert(arr, pi2);
insert(arr, pi3); insert(arr, pi3);
print_arrangement_size(arr); // print the arrangement size print_arrangement_size(arr); // print the arrangement size
CGAL::draw(arr);
return 0; return 0;
} }

View File

@ -23,13 +23,16 @@
* The header file for the Arr_circle_segment_traits_2<Kernel> class. * The header file for the Arr_circle_segment_traits_2<Kernel> class.
*/ */
#include <CGAL/tags.h> // Keep the following 2 lines first.
#include <CGAL/Arr_tags.h> #include <cmath>
#include <CGAL/Arr_geometry_traits/Circle_segment_2.h>
#include <fstream> #include <fstream>
#include <atomic> #include <atomic>
#include <CGAL/tags.h>
#include <CGAL/Arr_tags.h>
#include <CGAL/Cartesian.h>
#include <CGAL/Arr_geometry_traits/Circle_segment_2.h>
namespace CGAL { namespace CGAL {
/*! \class /*! \class
@ -378,6 +381,183 @@ public:
} }
//@} //@}
/// \name Functor definitions for approximations. Used by the landmarks
// point-location strategy and the drawing procedure.
//@{
typedef double Approximate_number_type;
typedef CGAL::Cartesian<Approximate_number_type> Approximate_kernel;
typedef Approximate_kernel::Point_2 Approximate_point_2;
class Approximate_2 {
protected:
using Traits = Arr_circle_segment_traits_2<Kernel, Filter>;
/*! The traits (in case it has state) */
const Traits& m_traits;
/*! Constructor
* \param traits the traits.
*/
Approximate_2(const Traits& traits) : m_traits(traits) {}
friend class Arr_circle_segment_traits_2<Kernel, Filter>;
public:
/*! Obtain an approximation of a point coordinate.
* \param p the exact point.
* \param i the coordinate index (either 0 or 1).
* \pre i is either 0 or 1.
* \return An approximation of p's x-coordinate (if i == 0), or an
* approximation of p's y-coordinate (if i == 1).
*/
Approximate_number_type operator()(const Point_2& p, int i) const {
CGAL_precondition((i == 0) || (i == 1));
return (i == 0) ? (CGAL::to_double(p.x())) : (CGAL::to_double(p.y()));
}
/*! Obtain an approximation of a point.
*/
Approximate_point_2 operator()(const Point_2& p) const
{ return Approximate_point_2(operator()(p, 0), operator()(p, 1)); }
/*! Obtain an approximation of an \f$x\f$-monotone curve.
*/
template <typename OutputIterator>
OutputIterator operator()(const X_monotone_curve_2& xcv, double error,
OutputIterator oi, bool l2r = true) const {
if (xcv.is_linear()) return approximate_segment(xcv, oi, l2r);
return approximate_arc(xcv, error, oi, l2r);;
}
private:
/*! Handle segments.
*/
template <typename OutputIterator>
OutputIterator approximate_segment(const X_monotone_curve_2& xcv,
OutputIterator oi,
bool l2r = true) const {
// std::cout << "SEGMENT\n";
auto min_vertex = m_traits.construct_min_vertex_2_object();
auto max_vertex = m_traits.construct_max_vertex_2_object();
const auto& src = (l2r) ? min_vertex(xcv) : max_vertex(xcv);
const auto& trg = (l2r) ? max_vertex(xcv) : min_vertex(xcv);
auto xs = CGAL::to_double(src.x());
auto ys = CGAL::to_double(src.y());
auto xt = CGAL::to_double(trg.x());
auto yt = CGAL::to_double(trg.y());
*oi++ = Approximate_point_2(xs, ys);
*oi++ = Approximate_point_2(xt, yt);
return oi;
}
template <typename OutputIterator, typename Op, typename Transform>
OutputIterator add_points(double x1, double y1, double t1,
double x2, double y2, double t2,
double error, OutputIterator oi,
Op op, Transform transform) const {
auto tm = (t1 + t2)*0.5;
// Compute the canocal point where the error is maximal.
double xm, ym;
op(tm, xm, ym);
auto dx = x2 - x1;
auto dy = y2 - y1;
// Compute the error; abort if it is below the threshold
auto l = std::sqrt(dx*dx + dy*dy);
auto e = std::abs((xm*dy - ym*dx + x2*y1 - x1*y2) / l);
if (e < error) return oi;
double x, y;
transform(xm, ym, x, y);
add_points(x1, y1, t1, xm, ym, tm, error, oi, op, transform);
*oi++ = Approximate_point_2(x, y);
add_points(xm, ym, tm, x2, y2, t2, error, oi, op, transform);
return oi;
}
/*! Compute the circular point given the parameter t and the transform
* data, that is, the center (translation) and the sin and cos of the
* rotation angle.
*/
void circular_point(double r, double t, double& x, double& y) const {
x = r * std::cos(t);
y = r * std::sin(t);
}
/*! Transform a point. In particular, rotate the canonical point
* (`xc`,`yc`) by an angle, the sine and cosine of which are `sint` and
* `cost`, respectively, and translate by (`cx`,`cy`).
*/
void transform_point(double xc, double yc, double cx, double cy,
double& x, double& y) const {
x = xc + cx;
y = yc + cy;
}
/*! Handle circular arcs.
*/
template <typename OutputIterator>
OutputIterator approximate_arc(const X_monotone_curve_2& xcv,
double error, OutputIterator oi,
bool l2r = true) const {
auto min_vertex = m_traits.construct_min_vertex_2_object();
auto max_vertex = m_traits.construct_max_vertex_2_object();
const auto& src = (l2r) ? min_vertex(xcv) : max_vertex(xcv);
const auto& trg = (l2r) ? max_vertex(xcv) : min_vertex(xcv);
auto xs = CGAL::to_double(src.x());
auto ys = CGAL::to_double(src.y());
auto xt = CGAL::to_double(trg.x());
auto yt = CGAL::to_double(trg.y());
const typename Kernel::Circle_2& circ = xcv.supporting_circle();
auto r_sqr = circ.squared_radius();
auto r = std::sqrt(CGAL::to_double(r_sqr));
// Obtain the center:
auto cx = CGAL::to_double(circ.center().x());
auto cy = CGAL::to_double(circ.center().y());
// Inverse transform the source and target
auto xs_t = xs - cx;
auto ys_t = ys - cy;
auto xt_t = xt - cx;
auto yt_t = yt - cy;
// Compute the parameters ts and tt such that
// source == (x(ts),y(ts)), and
// target == (x(tt),y(tt))
auto ts = std::atan2(r*ys_t, r*xs_t);
if (ts < 0) ts += 2*CGAL_PI;
auto tt = std::atan2(r*yt_t, r*xt_t);
if (tt < 0) tt += 2*CGAL_PI;
auto orient(xcv.orientation());
if (xcv.source() != src) orient = CGAL::opposite(orient);
if (orient == COUNTERCLOCKWISE) {
if (tt < ts) tt += 2*CGAL_PI;
}
else {
if (ts < tt) ts += 2*CGAL_PI;
}
*oi++ = Approximate_point_2(xs, ys);
add_points(xs_t, ys_t, ts, xt_t, yt_t, tt, error, oi,
[&](double tm, double& xm, double& ym) {
circular_point(r, tm, xm, ym);
},
[&](double xc, double& yc, double& x, double& y) {
transform_point(xc, yc, cx, cy, x, y);
});
*oi++ = Approximate_point_2(xt, yt);
return oi;
}
};
/*! Obtain an Approximate_2 functor object. */
Approximate_2 approximate_2_object() const { return Approximate_2(*this); }
//@}
/// \name Intersections, subdivisions, and mergings /// \name Intersections, subdivisions, and mergings
//@{ //@{

File diff suppressed because it is too large Load Diff

View File

@ -29,6 +29,7 @@
#include <boost/variant.hpp> #include <boost/variant.hpp>
#include <CGAL/config.h> #include <CGAL/config.h>
#include <CGAL/Cartesian.h>
#include <CGAL/tags.h> #include <CGAL/tags.h>
#include <CGAL/tss.h> #include <CGAL/tss.h>
#include <CGAL/intersections.h> #include <CGAL/intersections.h>
@ -2835,10 +2836,11 @@ public:
/// \name Functor definitions for the landmarks point-location strategy. /// \name Functor definitions for the landmarks point-location strategy.
//@{ //@{
typedef double Approximate_number_type; typedef double Approximate_number_type;
typedef CGAL::Cartesian<Approximate_number_type> Approximate_kernel;
typedef Approximate_kernel::Point_2 Approximate_point_2;
class Approximate_2 { class Approximate_2 {
public: public:
/*! Return an approximation of a point coordinate. /*! Return an approximation of a point coordinate.
* \param p the exact point. * \param p the exact point.
* \param i the coordinate index (either 0 or 1). * \param i the coordinate index (either 0 or 1).
@ -2846,11 +2848,23 @@ public:
* \return an approximation of p's x-coordinate (if i == 0), or an * \return an approximation of p's x-coordinate (if i == 0), or an
* approximation of p's y-coordinate (if i == 1). * approximation of p's y-coordinate (if i == 1).
*/ */
Approximate_number_type operator()(const Point_2& p, int i) const Approximate_number_type operator()(const Point_2& p, int i) const {
{ CGAL_precondition((i == 0) || (i == 1));
CGAL_precondition(i == 0 || i == 1);
return (i == 0) ? CGAL::to_double(p.x()) : CGAL::to_double(p.y()); return (i == 0) ? CGAL::to_double(p.x()) : CGAL::to_double(p.y());
} }
/*! Obtain an approximation of a point.
*/
Approximate_point_2 operator()(const Point_2& p) const
{ return Approximate_point_2(operator()(p, 0), operator()(p, 1)); }
/*! Obtain an approximation of an \f$x\f$-monotone curve.
*/
template <typename OutputIterator>
OutputIterator operator()(const X_monotone_curve_2& /* xcv */, double /* error */,
OutputIterator /* oi */, bool /* l2r */ = true) const {
CGAL_error_msg("Not implemented yet!");
}
}; };
/*! Obtain an Approximate_2 function object */ /*! Obtain an Approximate_2 function object */

View File

@ -24,8 +24,7 @@
namespace CGAL { namespace CGAL {
/*! /*! Compute the roots of the resultants of the two bivariate polynomials:
* Compute the roots of the resultants of the two bivariate polynomials:
* C1: r1*x^2 + s1*y^2 + t1*xy + u1*x + v1*y + w1 = 0 * C1: r1*x^2 + s1*y^2 + t1*xy + u1*x + v1*y + w1 = 0
* C2: r2*x^2 + s2*y^2 + t2*xy + u2*x + v2*y + w2 = 0 * C2: r2*x^2 + s2*y^2 + t2*xy + u2*x + v2*y + w2 = 0
* \param deg1 The degree of the first curve. * \param deg1 The degree of the first curve.
@ -35,9 +34,8 @@ namespace CGAL {
* \pre xs must be a vector of size 4. * \pre xs must be a vector of size 4.
* \return The number of distinct roots found. * \return The number of distinct roots found.
*/ */
template <class Nt_traits> template <typename Nt_traits>
int int compute_resultant_roots(const Nt_traits& nt_traits,
_compute_resultant_roots (Nt_traits& nt_traits,
const typename Nt_traits::Integer& r1, const typename Nt_traits::Integer& r1,
const typename Nt_traits::Integer& s1, const typename Nt_traits::Integer& s1,
const typename Nt_traits::Integer& t1, const typename Nt_traits::Integer& t1,
@ -54,11 +52,10 @@ int
const int& deg2, const int& deg2,
typename Nt_traits::Algebraic* xs) typename Nt_traits::Algebraic* xs)
{ {
if (deg1 == 2 && deg2 == 1) if ((deg1 == 2) && (deg2 == 1)) {
{
// If necessary, swap roles between the two curves, so that the first // If necessary, swap roles between the two curves, so that the first
// curve always has the minimal degree. // curve always has the minimal degree.
return (_compute_resultant_roots (nt_traits, return (compute_resultant_roots(nt_traits,
r2, s2, t2, u2, v2, w2, r2, s2, t2, u2, v2, w2,
deg2, deg2,
r1, s1, t1, u1, v1, w1, r1, s1, t1, u1, v1, w1,
@ -67,52 +64,46 @@ int
} }
// Act according to the degree of the first conic curve. // Act according to the degree of the first conic curve.
const typename Nt_traits::Integer _two = 2; const typename Nt_traits::Integer two = 2;
typename Nt_traits::Integer c[5]; typename Nt_traits::Integer c[5];
unsigned int degree = 4; unsigned int degree = 4;
typename Nt_traits::Algebraic* xs_end; typename Nt_traits::Algebraic* xs_end;
if (deg1 == 1) if (deg1 == 1) {
{
// The first curve has no quadratic coefficients, and represents a line. // The first curve has no quadratic coefficients, and represents a line.
if (CGAL::sign (v1) == ZERO) if (CGAL::sign (v1) == ZERO) {
{
// The first line is u1*x + w1 = 0, therefore: // The first line is u1*x + w1 = 0, therefore:
xs[0] = nt_traits.convert(-w1) / nt_traits.convert(u1); xs[0] = nt_traits.convert(-w1) / nt_traits.convert(u1);
return (1); return 1;
} }
// We can write the first curve as: y = -(u1*x + w1) / v1. // We can write the first curve as: y = -(u1*x + w1) / v1.
if (deg2 == 1) if (deg2 == 1) {
{
// The second curve is also a line. We therefore get the linear // The second curve is also a line. We therefore get the linear
// equation c[1]*x + c[0] = 0: // equation c[1]*x + c[0] = 0:
c[1] = v1*u2 - u1*v2; c[1] = v1*u2 - u1*v2;
c[0] = v1*w2 - w1*v2; c[0] = v1*w2 - w1*v2;
if (CGAL::sign (c[1]) == ZERO) // Return if the two lines are parallel
// The two lines are parallel: if (CGAL::sign (c[1]) == ZERO) return 0;
return (0);
xs[0] = nt_traits.convert(-c[0]) / nt_traits.convert(c[1]); xs[0] = nt_traits.convert(-c[0]) / nt_traits.convert(c[1]);
return (1); return 1;
} }
// We substitute this expression into the equation of the second // We substitute this expression into the equation of the second
// conic, and get the quadratic equation c[2]*x^2 + c[1]*x + c[0] = 0: // conic, and get the quadratic equation c[2]*x^2 + c[1]*x + c[0] = 0:
c[2] = u1*u1*s2 - u1*v1*t2 + v1*v1*r2; c[2] = u1*u1*s2 - u1*v1*t2 + v1*v1*r2;
c[1] = _two*u1*w1*s2 - u1*v1*v2 - v1*w1*t2 + v1*v1*u2; c[1] = two*u1*w1*s2 - u1*v1*v2 - v1*w1*t2 + v1*v1*u2;
c[0] = w1*w1*s2 - v1*w1*v2 + v1*v1*w2; c[0] = w1*w1*s2 - v1*w1*v2 + v1*v1*w2;
xs_end = nt_traits.solve_quadratic_equation (c[2], c[1], c[0], xs_end = nt_traits.solve_quadratic_equation(c[2], c[1], c[0], xs);
xs);
return static_cast<int>(xs_end - xs); return static_cast<int>(xs_end - xs);
} }
// At this stage, both curves have degree 2. We obtain a qaurtic polynomial // At this stage, both curves have degree 2. We obtain a qaurtic polynomial
// whose roots are the x-coordinates of the intersection points. // whose roots are the x-coordinates of the intersection points.
if (CGAL::sign (s1) == ZERO && CGAL::sign (s2) == ZERO) if (CGAL::sign (s1) == ZERO && CGAL::sign (s2) == ZERO) {
{
// If both s1 and s2 are zero, we can write the two curves as: // If both s1 and s2 are zero, we can write the two curves as:
// C1: (t1*x + v1)*y + (r1*x^2 + u1*x + w1) = 0 // C1: (t1*x + v1)*y + (r1*x^2 + u1*x + w1) = 0
// C2: (t2*x + v2)*y + (r2*x^2 + u2*x + w2) = 0 // C2: (t2*x + v2)*y + (r2*x^2 + u2*x + w2) = 0
@ -125,35 +116,34 @@ int
degree = 3; degree = 3;
} }
else else {
{
// We can write the two curves as: // We can write the two curves as:
// C1: (s1)*y^2 + (t1*x + v1)*y + (r1*x^2 + u1*x + w1) = 0 // C1: (s1)*y^2 + (t1*x + v1)*y + (r1*x^2 + u1*x + w1) = 0
// C2: (s2)*y^2 + (t2*x + v2)*y + (r2*x^2 + u2*x + w2) = 0 // C2: (s2)*y^2 + (t2*x + v2)*y + (r2*x^2 + u2*x + w2) = 0
// By writing the resultant of these two polynomials we get a quartic // By writing the resultant of these two polynomials we get a quartic
// polynomial, whose coefficients are given by: // polynomial, whose coefficients are given by:
c[4] = -_two*s1*s2*r1*r2 + s1*t2*t2*r1 - s1*t2*t1*r2 + c[4] = -two*s1*s2*r1*r2 + s1*t2*t2*r1 - s1*t2*t1*r2 +
s1*s1*r2*r2 - s2*t1*r1*t2 + s2*t1*t1*r2 + s2*s2*r1*r1; s1*s1*r2*r2 - s2*t1*r1*t2 + s2*t1*t1*r2 + s2*s2*r1*r1;
c[3] = -t2*r1*v1*s2 - u2*t1*t2*s1 - v2*r1*t1*s2 - c[3] = -t2*r1*v1*s2 - u2*t1*t2*s1 - v2*r1*t1*s2 -
r2*t1*v2*s1 - _two*s1*s2*r1*u2 - t2*u1*t1*s2 + u2*t1*t1*s2 - r2*t1*v2*s1 - two*s1*s2*r1*u2 - t2*u1*t1*s2 + u2*t1*t1*s2 -
r2*v1*t2*s1 + u1*t2*t2*s1 + _two*v2*r1*t2*s1 + _two*u2*r2*s1*s1 + r2*v1*t2*s1 + u1*t2*t2*s1 + two*v2*r1*t2*s1 + two*u2*r2*s1*s1 +
_two*r2*v1*t1*s2 + _two*u1*r1*s2*s2 - _two*s1*s2*u1*r2; two*r2*v1*t1*s2 + two*u1*r1*s2*s2 - two*s1*s2*u1*r2;
c[2] = -r2*v1*v2*s1 + u2*u2*s1*s1 + _two*w2*r2*s1*s1 + c[2] = -r2*v1*v2*s1 + u2*u2*s1*s1 + two*w2*r2*s1*s1 +
_two*u2*v1*t1*s2 - u2*v1*t2*s1 + w2*t1*t1*s2 - _two*s1*s2*u1*u2 - two*u2*v1*t1*s2 - u2*v1*t2*s1 + w2*t1*t1*s2 - two*s1*s2*u1*u2 -
w2*t1*t2*s1 + v2*v2*r1*s1 + u1*u1*s2*s2 - v2*r1*v1*s2 + w2*t1*t2*s1 + v2*v2*r1*s1 + u1*u1*s2*s2 - v2*r1*v1*s2 +
_two*w1*r1*s2*s2 - u2*t1*v2*s1 - t2*u1*v1*s2 - _two*s1*s2*r1*w2 - two*w1*r1*s2*s2 - u2*t1*v2*s1 - t2*u1*v1*s2 - two*s1*s2*r1*w2 -
_two*s1*s2*w1*r2 + r2*v1*v1*s2 + w1*t2*t2*s1 - v2*u1*t1*s2 - two*s1*s2*w1*r2 + r2*v1*v1*s2 + w1*t2*t2*s1 - v2*u1*t1*s2 -
t2*w1*t1*s2 + _two*v2*u1*t2*s1; t2*w1*t1*s2 + two*v2*u1*t2*s1;
c[1] = _two*w2*u2*s1*s1 + _two*w2*v1*t1*s2 - w2*v1*t2*s1 + c[1] = two*w2*u2*s1*s1 + two*w2*v1*t1*s2 - w2*v1*t2*s1 +
_two*v2*w1*t2*s1 + _two*w1*u1*s2*s2 - v2*u1*v1*s2 - _two*s1*s2*u1*w2 - two*v2*w1*t2*s1 + two*w1*u1*s2*s2 - v2*u1*v1*s2 - two*s1*s2*u1*w2 -
v2*w1*t1*s2 + u2*v1*v1*s2 - t2*w1*v1*s2 - w2*t1*v2*s1 + v2*w1*t1*s2 + u2*v1*v1*s2 - t2*w1*v1*s2 - w2*t1*v2*s1 +
v2*v2*u1*s1 - u2*v1*v2*s1 - _two*s1*s2*w1*u2; v2*v2*u1*s1 - u2*v1*v2*s1 - two*s1*s2*w1*u2;
c[0] = s2*v1*v1*w2 - s1*v2*v1*w2 - s2*v1*w1*v2 + s2*s2*w1*w1 - c[0] = s2*v1*v1*w2 - s1*v2*v1*w2 - s2*v1*w1*v2 + s2*s2*w1*w1 -
_two*s1*s2*w1*w2 + s1*w1*v2*v2 + s1*s1*w2*w2; two*s1*s2*w1*w2 + s1*w1*v2*v2 + s1*s1*w2*w2;
degree = 4; degree = 4;
} }
@ -162,13 +152,11 @@ int
typename Nt_traits::Polynomial poly = typename Nt_traits::Polynomial poly =
nt_traits.construct_polynomial(c, degree); nt_traits.construct_polynomial(c, degree);
xs_end = nt_traits.compute_polynomial_roots (poly, xs_end = nt_traits.compute_polynomial_roots(poly, xs);
xs);
return static_cast<int>(xs_end - xs); return static_cast<int>(xs_end - xs);
} }
/*! /*! Compute the roots of the resultants of the two bivariate polynomials:
* Compute the roots of the resultants of the two bivariate polynomials:
* C1: r*x^2 + s*y^2 + t*xy + u*x + v*y + w = 0 * C1: r*x^2 + s*y^2 + t*xy + u*x + v*y + w = 0
* C2: A*x + B*y + C = 0 * C2: A*x + B*y + C = 0
* \param deg1 The degree of the first curve. * \param deg1 The degree of the first curve.
@ -177,9 +165,8 @@ int
* \pre xs must be a vector of size 4. * \pre xs must be a vector of size 4.
* \return The number of distinct roots found. * \return The number of distinct roots found.
*/ */
template <class Nt_traits> template <typename Nt_traits>
int int compute_resultant_roots(const Nt_traits& nt_traits,
_compute_resultant_roots (Nt_traits& nt_traits,
const typename Nt_traits::Algebraic& r, const typename Nt_traits::Algebraic& r,
const typename Nt_traits::Algebraic& s, const typename Nt_traits::Algebraic& s,
const typename Nt_traits::Algebraic& t, const typename Nt_traits::Algebraic& t,
@ -192,40 +179,36 @@ _compute_resultant_roots (Nt_traits& nt_traits,
const typename Nt_traits::Algebraic& C, const typename Nt_traits::Algebraic& C,
typename Nt_traits::Algebraic* xs) typename Nt_traits::Algebraic* xs)
{ {
if (deg1 == 1) if (deg1 == 1) {
{
// We should actually compute the intersection of two line: // We should actually compute the intersection of two line:
// (u*x + v*y + w = 0) and (A*x + B*y + C = 0): // (u*x + v*y + w = 0) and (A*x + B*y + C = 0):
const typename Nt_traits::Algebraic denom = A*v - B*u; const typename Nt_traits::Algebraic denom = A*v - B*u;
if (CGAL::sign (denom) == CGAL::ZERO) // Return if the two lines are parallel and do not intersect.
// The two lines are parallel and do not intersect. if (CGAL::sign(denom) == CGAL::ZERO) return 0;
return (0);
xs[0] = (B*w - C*v) / denom; xs[0] = (B*w - C*v) / denom;
return (1); return 1;
} }
if (CGAL::sign (B) == CGAL::ZERO) if (CGAL::sign(B) == CGAL::ZERO) {
{
// The first line is A*x + C = 0, therefore: // The first line is A*x + C = 0, therefore:
xs[0] = -C / A; xs[0] = -C / A;
return (1); return 1;
} }
// We can write the first curve as: y = -(A*x + C) / B. // We can write the first curve as: y = -(A*x + C) / B.
// We substitute this expression into the equation of the conic, and get // We substitute this expression into the equation of the conic, and get
// the quadratic equation c[2]*x^2 + c[1]*x + c[0] = 0: // the quadratic equation c[2]*x^2 + c[1]*x + c[0] = 0:
const typename Nt_traits::Algebraic _two = 2; const typename Nt_traits::Algebraic two = 2;
typename Nt_traits::Algebraic c[3]; typename Nt_traits::Algebraic c[3];
typename Nt_traits::Algebraic* xs_end; typename Nt_traits::Algebraic* xs_end;
c[2] = A*A*s - A*B*t + B*B*r; c[2] = A*A*s - A*B*t + B*B*r;
c[1] = _two*A*C*s - A*B*v - B*C*t + B*B*u; c[1] = two*A*C*s - A*B*v - B*C*t + B*B*u;
c[0] = C*C*s - B*C*v + B*B*w; c[0] = C*C*s - B*C*v + B*B*w;
xs_end = nt_traits.solve_quadratic_equation (c[2], c[1], c[0], xs_end = nt_traits.solve_quadratic_equation(c[2], c[1], c[0], xs);
xs);
return static_cast<int>(xs_end - xs); return static_cast<int>(xs_end - xs);
} }

View File

@ -9,124 +9,89 @@
// //
// //
// Author(s): Ron Wein <wein@post.tau.ac.il> // Author(s): Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efifogel@gmail.com>
#ifndef CGAL_CONIC_POINT_2_H #ifndef CGAL_CONIC_POINT_2_H
#define CGAL_CONIC_POINT_2_H #define CGAL_CONIC_POINT_2_H
#include <CGAL/license/Arrangement_on_surface_2.h> #include <CGAL/license/Arrangement_on_surface_2.h>
/*! \file /*! \file
* Header file for the _Conic_point_2<Alg_kernel> class. * Header file for the Conic_point_2<Alg_kernel> class.
*/ */
#include <list> #include <list>
#include <CGAL/assertions.h> #include <CGAL/assertions.h>
namespace CGAL { namespace CGAL {
/*! /*! \class
* \class A class that stores additional information with the point's * A class that stores additional information with the point's
* coordinates, namely the conic IDs of the generating curves. * coordinates, namely the conic IDs of the generating curves.
*/ */
template <class Alg_kernel_> template <typename AlgKernel>
class _Conic_point_2 : public Alg_kernel_::Point_2 class Conic_point_2 : public AlgKernel::Point_2 {
{
public: public:
typedef AlgKernel Alg_kernel;
typedef Alg_kernel_ Alg_kernel;
typedef typename Alg_kernel::Point_2 Base; typedef typename Alg_kernel::Point_2 Base;
typedef _Conic_point_2<Alg_kernel> Self; typedef Conic_point_2<Alg_kernel> Self;
typedef typename Alg_kernel::FT Algebraic; typedef typename Alg_kernel::FT Algebraic;
/*! \class /*! \class
* Representation of an ID of a conic arc. * Representation of an ID of a conic arc.
*/ */
class Conic_id class Conic_id {
{
private: private:
size_t index; // the index of the conic arc
unsigned int index; // The index of the conic arc.
public: public:
/*! Default constructor. */ /*! Default constructor. */
Conic_id () : Conic_id() : index(0) {}
index (0)
{}
/*! Constructor. */ /*! Constructor. */
Conic_id (unsigned int ind) : Conic_id(size_t ind) : index(ind) { CGAL_precondition(ind != 0); }
index (ind)
{
CGAL_precondition (ind != 0);
}
/*! Check if the ID is valid. */ /*! Check if the ID is valid. */
bool is_valid () const bool is_valid() const { return (index != 0); }
{
return (index != 0);
}
/*! Equality operator. */ /*! Equality operator. */
bool operator== (const Conic_id& id) const bool operator==(const Conic_id& id) const { return (index == id.index); }
{
return (index == id.index);
}
/*! Inequality operator. */ /*! Inequality operator. */
bool operator!= (const Conic_id& id) const bool operator!=(const Conic_id& id) const { return (index != id.index); }
{
return (index != id.index);
}
/*! Less-than operator. */ /*! Less-than operator. */
bool operator< (const Conic_id& id) const bool operator<(const Conic_id& id) const { return (index < id.index); }
{
return (index < id.index);
}
/*! Greater-than operator. */ /*! Greater-than operator. */
bool operator> (const Conic_id& id) const bool operator>(const Conic_id& id) const { return (index > id.index); }
{
return (index > id.index);
}
}; };
private: private:
typedef std::list<Conic_id> Ids_container; typedef std::list<Conic_id> Ids_container;
typedef typename std::list<Conic_id>::const_iterator Ids_iterator; typedef typename std::list<Conic_id>::const_iterator Ids_iterator;
Ids_container conic_ids; // The IDs of the generating conics. Ids_container conic_ids; // the IDs of the generating conics.
public: public:
/// \name Constructors. /// \name Constructors.
//@{ //@{
/*! Default constructors. */ /*! Default constructors. */
_Conic_point_2 () : Conic_point_2() : Base() {}
Base()
{}
/*! Constructor from the base class. */ /*! Constrcutor from the base class. */
_Conic_point_2 (const Base& p) : Conic_point_2(const Base& p) : Base(p) {}
Base (p)
{}
/*! Constructor with homogeneous coordinates. */ /*! Constructor with homegeneous coordinates. */
_Conic_point_2 (const Algebraic& hx, Conic_point_2(const Algebraic& hx, const Algebraic& hy, const Algebraic& hz) :
const Algebraic& hy,
const Algebraic& hz) :
Base(hx, hy, hz) Base(hx, hy, hz)
{} {}
/*! Constructor with Cartesian coordinates. */ /*! Constructor with Cartesian coordinates. */
_Conic_point_2 (const Algebraic& x, const Algebraic& y) : Conic_point_2(const Algebraic& x, const Algebraic& y) : Base(x, y) {}
Base (x, y)
{}
//@} //@}
/// \name Maintaining the generating conic IDs. /// \name Maintaining the generating conic IDs.
@ -134,28 +99,14 @@ private:
/*! Add a generating conic ID. */ /*! Add a generating conic ID. */
void set_generating_conic(const Conic_id& id) void set_generating_conic(const Conic_id& id)
{ { if (id.is_valid()) conic_ids.push_back(id); }
if (id.is_valid())
conic_ids.push_back (id);
return;
}
/*! Check if the given conic generates the point. */ /*! Check if the given conic generates the point. */
bool is_generating_conic (const Conic_id& id) const bool is_generating_conic(const Conic_id& id) const {
{ if (! id.is_valid()) return false;
if (! id.is_valid()) for (auto it = conic_ids.begin(); it != conic_ids.end(); ++it)
return (false); if (*it == id) return true;
return false;
Ids_iterator it;
for (it = conic_ids.begin(); it != conic_ids.end(); ++it)
{
if (*it == id)
return (true);
}
return (false);
} }
//@} //@}

View File

@ -30,6 +30,7 @@
* functors required by the concept it models. * functors required by the concept it models.
*/ */
#include <CGAL/Cartesian.h>
#include <CGAL/Algebraic_structure_traits.h> #include <CGAL/Algebraic_structure_traits.h>
#include <CGAL/number_utils.h> #include <CGAL/number_utils.h>
#include <CGAL/tags.h> #include <CGAL/tags.h>
@ -231,36 +232,62 @@ public:
/// \name Functor definitions for the landmarks point-location strategy. /// \name Functor definitions for the landmarks point-location strategy.
//@{ //@{
typedef double Approximate_number_type; typedef double Approximate_number_type;
typedef CGAL::Cartesian<Approximate_number_type> Approximate_kernel;
typedef Approximate_kernel::Point_2 Approximate_point_2;
class Approximate_2 {
protected:
using Traits = Arr_non_caching_segment_basic_traits_2<Kernel>;
/*! The traits (in case it has state) */
const Traits& m_traits;
/*! Constructor
* \param traits the traits.
*/
Approximate_2(const Traits& traits) : m_traits(traits) {}
friend class Arr_non_caching_segment_basic_traits_2<Kernel>;
class Approximate_2
{
public: public:
/*! Return an approximation of a point coordinate.
/*!
* Return an approximation of a point coordinate.
* \param p The exact point. * \param p The exact point.
* \param i The coordinate index (either 0 or 1). * \param i The coordinate index (either 0 or 1).
* \pre i is either 0 or 1. * \pre i is either 0 or 1.
* \return An approximation of p's x-coordinate (if i == 0), or an * \return An approximation of p's x-coordinate (if i == 0), or an
* approximation of p's y-coordinate (if i == 1). * approximation of p's y-coordinate (if i == 1).
*/ */
Approximate_number_type operator() (const Point_2& p, Approximate_number_type operator() (const Point_2& p, int i) const {
int i) const
{
CGAL_precondition (i == 0 || i == 1); CGAL_precondition (i == 0 || i == 1);
return (i == 0) ? (CGAL::to_double(p.x())) : (CGAL::to_double(p.y()));
}
if (i == 0) /*! Obtain an approximation of a point.
return (CGAL::to_double(p.x())); */
else Approximate_point_2 operator()(const Point_2& p) const
return (CGAL::to_double(p.y())); { return Approximate_point_2(operator()(p, 0), operator()(p, 1)); }
/*! Obtain an approximation of an \f$x\f$-monotone curve.
*/
template <typename OutputIterator>
OutputIterator operator()(const X_monotone_curve_2& xcv, double /* error */,
OutputIterator oi, bool l2r = true) const {
auto min_vertex = m_traits.construct_min_vertex_2_object();
auto max_vertex = m_traits.construct_max_vertex_2_object();
const auto& src = (l2r) ? min_vertex(xcv) : max_vertex(xcv);
const auto& trg = (l2r) ? max_vertex(xcv) : min_vertex(xcv);
auto xs = CGAL::to_double(src.x());
auto ys = CGAL::to_double(src.y());
auto xt = CGAL::to_double(trg.x());
auto yt = CGAL::to_double(trg.y());
*oi++ = Approximate_point_2(xs, ys);
*oi++ = Approximate_point_2(xt, yt);
return oi;
} }
}; };
/*! Get an Approximate_2 functor object. */ /*! Get an Approximate_2 functor object. */
Approximate_2 approximate_2_object () const Approximate_2 approximate_2_object () const { return Approximate_2(*this); }
{
return Approximate_2();
}
typedef typename Kernel::Construct_segment_2 Construct_x_monotone_curve_2; typedef typename Kernel::Construct_segment_2 Construct_x_monotone_curve_2;

View File

@ -1088,59 +1088,66 @@ public:
// ArrangementLandmarkTraits concept. // ArrangementLandmarkTraits concept.
//@{ //@{
#if 0
// The following block assumes that the subcurve traits template parameter
// is a model of the ArrangementLandmarkTraits concept; in other words, it
// defines the nested types Approximate_number_type and Approximate_2 and
// the member function approximate_2_object(). It cannot be used as is if
// the subcurve traits does not model the ArrangementLandmarkTraits concept.
// The functor Construct_x_monotone_curve_2 is provided regardless of the
// subcurve traits.
typedef typename Subcurve_traits_2::Approximate_number_type
Approximate_number_type;
typedef typename Subcurve_traits_2::Approximate_2 Approximate_2;
/*! Obtain an Approximate_2 functor object. */
Approximate_2 approximate_2_object() const
{ return subcurve_traits_2()->approximate_2_object(); }
#else
// The following block defines the nested types Approximate_number_type and // The following block defines the nested types Approximate_number_type and
// Approximate_2 and the member function approximate_2_object() based on the // Approximate_2 and the member function approximate_2_object() based on the
// corresponding types and function definitions of the subcurve traits. If // corresponding types and function definitions of the subcurve traits. If
// the subcurve traits does not provide these definitions, they are defined // the subcurve traits does not provide these definitions, they are defined
// as dummies. Essentially, the polycurve traits becomes a practical model of // as dummies. Essentially, the polycurve traits becomes a model of the
// the ArrangementLandmarkTraits concept only if the subcurve traits is a // ArrangementLandmarkTraits concept only if the subcurve traits is a model
// model of this concept. // of this concept.
// //
// The following implementation is inspired by // The following implementation is inspired by
// https://stackoverflow.com/a/11816999/1915421 // https://stackoverflow.com/a/11816999/1915421
template <typename T> template <typename... Ts> using void_t = void;
struct Void {
typedef void type;
};
template <typename T, typename _ = void> template <typename T, typename = void>
struct has_approximate_2 { struct has_approximate_2 {
// Generic implementation // Generic implementation
typedef void Approximate_number_type; using Approximate_number_type = void;
typedef void Approximate_2; using Approximate_point_2 = void;
struct Approximate_2 {
/*! Obtain an approximation of a point coordinate.
* \param p the exact point.
* \param i the coordinate index (either 0 or 1).
* \pre i is either 0 or 1.
* \return An approximation of p's x-coordinate (if i == 0), or an
* approximation of p's y-coordinate (if i == 1).
*/
Approximate_number_type operator()(const Point_2&, int) const
{ CGAL_error_msg("The subtraits does not define Approximate_2!"); }
/*! Obtain an approximation of a point.
*/
Approximate_point_2 operator()(const Point_2&) const
{ CGAL_error_msg("The subtraits does not define Approximate_2!"); }
/*! Obtain an approximation of an \f$x\f$-monotone curve.
*/
template <typename OutputIterator>
OutputIterator operator()(const X_monotone_curve_2&, double,
OutputIterator oi, bool = true) const {
CGAL_error_msg("The subtraits does not define Approximate_2!");
return oi;
}
};
}; };
template <typename T> template <typename T>
struct has_approximate_2<T, typename Void<typename T::Approximate_2>::type> struct has_approximate_2<T, void_t<typename T::Approximate_2>> {
{
// Specialization for types holding a nested type T::Approximate_2 // Specialization for types holding a nested type T::Approximate_2
typedef typename T::Approximate_number_type using Approximate_number_type = typename T::Approximate_number_type;
Approximate_number_type; using Approximate_2 = typename T::Approximate_2;
typedef typename T::Approximate_2 Approximate_2; using Approximate_point_2 = typename T::Approximate_point_2;
}; };
typedef typename has_approximate_2<Subcurve_traits_2>::Approximate_number_type using Approximate_number_type =
Approximate_number_type; typename has_approximate_2<Subcurve_traits_2>::Approximate_number_type;
typedef typename has_approximate_2<Subcurve_traits_2>::Approximate_2 using Approximate_2 =
Approximate_2; typename has_approximate_2<Subcurve_traits_2>::Approximate_2;
using Approximate_point_2 =
typename has_approximate_2<Subcurve_traits_2>::Approximate_point_2;
/*! Obtain an Approximate_2 functor object. */ /*! Obtain an Approximate_2 functor object. */
Approximate_2 approximate_2_object_impl(std::false_type) const Approximate_2 approximate_2_object_impl(std::false_type) const
@ -1148,13 +1155,12 @@ public:
Approximate_2 approximate_2_object_impl(std::true_type) const { } Approximate_2 approximate_2_object_impl(std::true_type) const { }
Approximate_2 approximate_2_object() const Approximate_2 approximate_2_object() const {
{ using Is_void = typename std::is_same<void, Approximate_2>::type;
typedef typename std::is_same<void, Approximate_2>::type Is_void;
return approximate_2_object_impl(Is_void()); return approximate_2_object_impl(Is_void());
} }
#endif
//
class Construct_x_monotone_curve_2 { class Construct_x_monotone_curve_2 {
protected: protected:
typedef Arr_polycurve_basic_traits_2<Subcurve_traits_2> typedef Arr_polycurve_basic_traits_2<Subcurve_traits_2>

View File

@ -98,7 +98,6 @@ public:
typedef typename Base::Equal_2 Equal_2; typedef typename Base::Equal_2 Equal_2;
typedef typename Base::Compare_endpoints_xy_2 Compare_endpoints_xy_2; typedef typename Base::Compare_endpoints_xy_2 Compare_endpoints_xy_2;
typedef typename Base::Construct_opposite_2 Construct_opposite_2; typedef typename Base::Construct_opposite_2 Construct_opposite_2;
typedef typename Base::Approximate_2 Approximate_2;
typedef typename Base::Parameter_space_in_x_2 Parameter_space_in_x_2; typedef typename Base::Parameter_space_in_x_2 Parameter_space_in_x_2;
typedef typename Base::Parameter_space_in_y_2 Parameter_space_in_y_2; typedef typename Base::Parameter_space_in_y_2 Parameter_space_in_y_2;
typedef typename Base::Compare_x_on_boundary_2 Compare_x_on_boundary_2; typedef typename Base::Compare_x_on_boundary_2 Compare_x_on_boundary_2;
@ -595,6 +594,62 @@ public:
Construct_x_monotone_curve_2 construct_x_monotone_curve_2_object() const Construct_x_monotone_curve_2 construct_x_monotone_curve_2_object() const
{ return Construct_x_monotone_curve_2(*this); } { return Construct_x_monotone_curve_2(*this); }
//
using Approximate_number_type = typename Base::Approximate_number_type;
using Approximate_point_2 = typename Base::Approximate_point_2;
class Approximate_2 : public Base::Approximate_2 {
protected:
using Traits = Arr_polyline_traits_2<Segment_traits_2>;
/*! The traits (in case it has state) */
const Traits& m_traits;
/*! Constructor
* \param traits the traits.
*/
Approximate_2(const Traits& traits) :
Base::Approximate_2(*(traits.subcurve_traits_2())),
m_traits(traits)
{}
friend class Arr_polyline_traits_2<Segment_traits_2>;
public:
Approximate_number_type operator()(const Point_2& p, int i) const
{ return Base::Approximate_2::operator()(p, i); }
Approximate_point_2 operator()(const Point_2& p) const
{ return Base::Approximate_2::operator()(p); }
/*! Obtain an approximation of an \f$x\f$-monotone curve.
*/
template <typename OutputIterator>
OutputIterator operator()(const X_monotone_curve_2& xcv, double /* error */,
OutputIterator oi, bool l2r = true) const {
if (l2r) {
for (auto it = xcv.points_begin(); it != xcv.points_end(); ++it) {
const auto& p = *it;
auto x = CGAL::to_double(p.x());
auto y = CGAL::to_double(p.y());
*oi++ = Approximate_point_2(x, y);
}
return oi;
}
for (auto it = xcv.points_rbegin(); it != xcv.points_rend(); ++it) {
const auto& p = *it;
auto x = CGAL::to_double(p.x());
auto y = CGAL::to_double(p.y());
*oi++ = Approximate_point_2(x, y);
}
return oi;
}
};
/*! Obtain an Approximate_2 functor object. */
Approximate_2 approximate_2_object() const { return Approximate_2(*this); }
/*! Deprecated! /*! Deprecated!
* Obtain the segment traits. * Obtain the segment traits.
* \return the segment traits. * \return the segment traits.

View File

@ -28,6 +28,7 @@
#include <boost/variant.hpp> #include <boost/variant.hpp>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h> #include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Cartesian.h>
#include <CGAL/tags.h> #include <CGAL/tags.h>
#include <CGAL/intersections.h> #include <CGAL/intersections.h>
#include <CGAL/Arr_tags.h> #include <CGAL/Arr_tags.h>
@ -880,8 +881,23 @@ public:
/// \name Functor definitions for the landmarks point-location strategy. /// \name Functor definitions for the landmarks point-location strategy.
//@{ //@{
typedef double Approximate_number_type; typedef double Approximate_number_type;
typedef CGAL::Cartesian<Approximate_number_type> Approximate_kernel;
typedef Approximate_kernel::Point_2 Approximate_point_2;
class Approximate_2 { class Approximate_2 {
protected:
using Traits = Arr_segment_traits_2<Kernel>;
/*! The traits (in case it has state) */
const Traits& m_traits;
/*! Constructor
* \param traits the traits.
*/
Approximate_2(const Traits& traits) : m_traits(traits) {}
friend class Arr_segment_traits_2<Kernel>;
public: public:
/*! Obtain an approximation of a point coordinate. /*! Obtain an approximation of a point coordinate.
* \param p the exact point. * \param p the exact point.
@ -890,15 +906,37 @@ public:
* \return An approximation of p's x-coordinate (if i == 0), or an * \return An approximation of p's x-coordinate (if i == 0), or an
* approximation of p's y-coordinate (if i == 1). * approximation of p's y-coordinate (if i == 1).
*/ */
Approximate_number_type operator()(const Point_2& p, int i) const Approximate_number_type operator()(const Point_2& p, int i) const {
{
CGAL_precondition((i == 0) || (i == 1)); CGAL_precondition((i == 0) || (i == 1));
return (i == 0) ? (CGAL::to_double(p.x())) : (CGAL::to_double(p.y())); return (i == 0) ? (CGAL::to_double(p.x())) : (CGAL::to_double(p.y()));
} }
/*! Obtain an approximation of a point.
*/
Approximate_point_2 operator()(const Point_2& p) const
{ return Approximate_point_2(operator()(p, 0), operator()(p, 1)); }
/*! Obtain an approximation of an \f$x\f$-monotone curve.
*/
template <typename OutputIterator>
OutputIterator operator()(const X_monotone_curve_2& xcv, double /* error */,
OutputIterator oi, bool l2r = true) const {
auto min_vertex = m_traits.construct_min_vertex_2_object();
auto max_vertex = m_traits.construct_max_vertex_2_object();
const auto& src = (l2r) ? min_vertex(xcv) : max_vertex(xcv);
const auto& trg = (l2r) ? max_vertex(xcv) : min_vertex(xcv);
auto xs = CGAL::to_double(src.x());
auto ys = CGAL::to_double(src.y());
auto xt = CGAL::to_double(trg.x());
auto yt = CGAL::to_double(trg.y());
*oi++ = Approximate_point_2(xs, ys);
*oi++ = Approximate_point_2(xt, yt);
return oi;
}
}; };
/*! Obtain an Approximate_2 functor object. */ /*! Obtain an Approximate_2 functor object. */
Approximate_2 approximate_2_object() const { return Approximate_2(); } Approximate_2 approximate_2_object() const { return Approximate_2(*this); }
//! Functor //! Functor
class Construct_x_monotone_curve_2 { class Construct_x_monotone_curve_2 {

View File

@ -64,11 +64,12 @@ public:
typedef typename Base::Point Point; typedef typename Base::Point Point;
/*! Constructor */ /*! Constructor */
Arr_polyhedral_sgm_polyhedron_3_vertex() : Base(), m_marked(false) {} Arr_polyhedral_sgm_polyhedron_3_vertex() :
Base(), m_processed(false), m_marked(false) {}
/*! Constructor */ /*! Constructor */
Arr_polyhedral_sgm_polyhedron_3_vertex(const Point & p) : Arr_polyhedral_sgm_polyhedron_3_vertex(const Point & p) :
Base(p), m_marked(false) {} Base(p), m_processed(false), m_marked(false) {}
/*! Obtain the mutable (geometrical) point. Delegate */ /*! Obtain the mutable (geometrical) point. Delegate */
Point & point() { return Base::point(); } Point & point() { return Base::point(); }

View File

@ -154,7 +154,7 @@ protected:
// the right endpoint it its interior. // the right endpoint it its interior.
Point_2 m_intersect_p; // The next intersection point. Point_2 m_intersect_p; // The next intersection point.
unsigned int m_ip_multiplicity; // Its multiplicity Multiplicity m_ip_multiplicity; // Its multiplicity
// (0 in case of an overlap). // (0 in case of an overlap).
bool m_found_intersect; // An intersection has been found. bool m_found_intersect; // An intersection has been found.
// (or an overlap). // (or an overlap).

View File

@ -76,8 +76,7 @@ public:
typedef typename Curve_kernel_2::Curve_analysis_2 Curve_analysis_2; typedef typename Curve_kernel_2::Curve_analysis_2 Curve_analysis_2;
//! default constructor //! default constructor
Point_2_rep() { Point_2_rep() : _m_location(CGAL::ARR_INTERIOR) {}
}
//! constructs a "finite" point on curve, //! constructs a "finite" point on curve,
//! implies CGAL::NO_BOUNDARY in x/y //! implies CGAL::NO_BOUNDARY in x/y

View File

@ -0,0 +1,609 @@
// Copyright (c) 2012
// Utrecht University (The Netherlands),
// ETH Zurich (Switzerland),
// INRIA Sophia-Antipolis (France),
// Max-Planck-Institute Saarbruecken (Germany),
// and Tel-Aviv University (Israel). All rights reserved.
//
// This file is part of CGAL (www.cgal.org)
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s): Efi Fogel <efifogel@gmail.com>
#ifndef CGAL_DRAW_ARRANGEMENT_2_H
#define CGAL_DRAW_ARRANGEMENT_2_H
#include <CGAL/config.h>
#include <unordered_map>
#include <cstdlib>
#include <random>
#include <CGAL/Qt/Basic_viewer_qt.h>
#ifdef CGAL_USE_BASIC_VIEWER
#include <type_traits>
#include <CGAL/Qt/init_ogl_context.h>
#include <CGAL/Arrangement_2.h>
namespace CGAL {
struct Default_color_generator {
/*! Obtain color
*/
template <typename HalfedgeHandle>
CGAL::IO::Color operator()(HalfedgeHandle /* h */) {
static std::random_device rd;
static std::mt19937 rng(rd());
static std::uniform_int_distribution<int> uni(0, 255);
return CGAL::IO::Color(uni(rng), uni(rng), uni(rng));
}
};
// Viewer class for`< Polygon_2
template <typename Arrangement_2_,
typename ColorGenerator = Default_color_generator>
class Arr_2_basic_viewer_qt : public Basic_viewer_qt {
using Arr = Arrangement_2_;
using Color_generator = ColorGenerator;
using Base = Basic_viewer_qt;
using Gt = typename Arr::Geometry_traits_2;
using Point = typename Arr::Point_2;
using X_monotone_curve = typename Arr::X_monotone_curve_2;
using Vertex_const_handle = typename Arr::Vertex_const_handle;
using Halfedge_const_handle = typename Arr::Halfedge_const_handle;
using Face_const_handle = typename Arr::Face_const_handle;
using Ccb_halfedge_const_circulator =
typename Arr::Ccb_halfedge_const_circulator;
public:
/// Construct the viewer.
/// @param arr the arrangement to view
/// @param title the title of the window
Arr_2_basic_viewer_qt(QWidget* parent, const Arr& arr,
Color_generator color_generator,
const char* title = "2D Arrangement Basic Viewer",
bool draw_vertices = false) :
// First draw: vertices; edges, faces; multi-color; no inverse normal
Base(parent, title, draw_vertices, true, true, false, false),
m_arr(arr),
m_color_generator(color_generator)
{
// mimic the computation of Camera::pixelGLRatio()
auto bbox = bounding_box();
CGAL::qglviewer::Vec minv(bbox.xmin(), bbox.ymin(), 0);
CGAL::qglviewer::Vec maxv(bbox.xmax(), bbox.ymax(), 0);
auto diameter = (maxv - minv).norm();
m_pixel_ratio = diameter / m_height;
}
/*! Intercept the resizing of the window.
*/
virtual void resizeGL(int width, int height) {
CGAL::QGLViewer::resizeGL(width, height);
m_width = width;
m_height = height;
CGAL::qglviewer::Vec p;
auto ratio = camera()->pixelGLRatio(p);
if (ratio != m_pixel_ratio) {
m_pixel_ratio = ratio;
add_elements();
}
}
/*! Compute an approximation of the bounding box of a point.
* \param[in] p the (exact) point.
* Call this member function only if the geometry traits is equipped with
* the coordinate-approximation functionality of a point coordinate.
* This function must be inlined (e.g., a template) to enable the
* compiled-time dispatching in the function `bounding_box()`.
*/
template <typename Point, typename Approximate>
CGAL::Bbox_2 approximate_bbox(const Point& p, const Approximate& approx) {
auto x = approx(p, 0);
auto y = approx(p, 1);
return CGAL::Bbox_2(x, y, x, y);
}
/*! Obtain the bounding box of a point.
* \param[in] p the point.
* We assume that if the coordinate-approximation functionality is not
* supported, the point supports the member function `bbox()`.
* This function must be inlined (e.g., a template) to enable the
* compiled-time dispatching in the function `bounding_box()`.
*/
template <typename Point>
CGAL::Bbox_2 exact_bbox(const Point& p) { return p.bbox(); }
/*! Compile time dispatching
*/
#if 0
template <typename T>
void bounding_box_impl2(CGAL::Bbox_2& bbox, const Point& p, T const&, long)
{ bbox += exact_bbox(p); }
template <typename T>
auto bounding_box_impl2(CGAL::Bbox_2& bbox, const Point& p, T const& approx,
int) -> decltype(approx.operator()(p), void())
{ bbox += approximate_bbox(p, approx); }
template <typename T>
void bounding_box_impl1(CGAL::Bbox_2& bbox, const Point& p, T const&, long)
{ bbox += exact_bbox(p); }
template <typename T>
auto bounding_box_impl1(CGAL::Bbox_2& bbox, const Point& p, T const& traits,
int) ->
decltype(traits.approximate_2_object(), void()) {
using Approximate = typename Gt::Approximate_2;
bounding_box_impl2<Approximate>(bbox, p, traits.approximate_2_object(), 0);
}
#else
template <typename T>
void bounding_box_impl1(CGAL::Bbox_2& bbox, const Point& p, T const& traits,
int)
{ bbox += approximate_bbox(p, traits.approximate_2_object()); }
#endif
/*! Compute the bounding box.
*/
CGAL::Bbox_2 bounding_box() {
CGAL::Bbox_2 bbox;
const auto* traits = this->m_arr.geometry_traits();
// At this point we assume that the arrangement is not open, and thus the
// bounding box is defined by the vertices.
for (auto it = m_arr.vertices_begin(); it != m_arr.vertices_end(); ++it)
bounding_box_impl1(bbox, it->point(), *traits, 0);
return bbox;
}
/*! Add all elements to be drawn.
*/
void add_elements() {
// std::cout << "ratio: " << this->pixel_ratio() << std::endl;
clear();
m_visited.clear();
if (m_arr.is_empty()) return;
for (auto it = m_arr.unbounded_faces_begin();
it != m_arr.unbounded_faces_end(); ++it)
add_face(it);
// Add edges that do not separe faces.
for (auto it = m_arr.edges_begin(); it != m_arr.edges_end(); ++it)
if (it->face() == it->twin()->face()) draw_curve(it->curve());
// Add all points
for (auto it = m_arr.vertices_begin(); it != m_arr.vertices_end(); ++it)
draw_point(it->point());
m_visited.clear();
}
/*/ Obtain the pixel ratio
*/
double pixel_ratio() const { return m_pixel_ratio; }
protected:
/*! Find the halfedge incident to the lexicographically smallest vertex
* along the CCB, such that there is no other halfedge underneath.
*/
Halfedge_const_handle find_smallest(Ccb_halfedge_const_circulator circ) {
const auto* traits = this->m_arr.geometry_traits();
auto cmp_xy = traits->compare_xy_2_object();
auto cmp_y = traits->compare_y_at_x_right_2_object();
// Find the first halfedge directed from left to right
auto curr = circ;
do if (curr->direction() == CGAL::ARR_LEFT_TO_RIGHT) break;
while (++curr != circ);
Halfedge_const_handle ext = curr;
// Find the halfedge incident to the lexicographically smallest vertex,
// such that there is no other halfedge underneath.
do {
// Discard edges not directed from left to right:
if (curr->direction() != CGAL::ARR_LEFT_TO_RIGHT) continue;
auto res = cmp_xy(curr->source()->point(), ext->source()->point());
// Discard the edges inciden to a point strictly larger than the point
// incident to the stored extreme halfedge:
if (res == LARGER) continue;
// Store the edge inciden to a point strictly smaller:
if (res == SMALLER) {
ext = curr;
continue;
}
// The incident points are equal; compare the halfedges themselves:
if (cmp_y(curr->curve(), ext->curve(), curr->source()->point()) ==
SMALLER)
ext = curr;
} while (++curr != circ);
return ext;
}
/*! Draw a region using aproximate coordinates.
* Call this member function only if the geometry traits is equipped with
* the coordinate-approximation functionality of a curve.
* This function must be inlined (e.g., a template) to enable the
* compiled-time dispatching in the function `draw_region()`.
*/
template <typename Approximate>
void draw_approximate_region(Halfedge_const_handle curr,
const Approximate& approx) {
std::vector<typename Gt::Approximate_point_2> polyline;
double error(this->pixel_ratio());
bool l2r = curr->direction() == ARR_LEFT_TO_RIGHT;
approx(curr->curve(), error, std::back_inserter(polyline), l2r);
if (polyline.empty()) return;
auto it = polyline.begin();
auto prev = it++;
for (; it != polyline.end(); prev = it++) {
this->add_segment(*prev, *it);
this->add_point_in_face(*prev);
}
}
/*! Draw an exact curve.
*/
template <typename XMonotoneCurve>
void draw_exact_curve(const XMonotoneCurve& curve) {
const auto* traits = this->m_arr.geometry_traits();
auto ctr_min = traits->construct_min_vertex_2_object();
auto ctr_max = traits->construct_max_vertex_2_object();
this->add_segment(ctr_min(curve), ctr_max(curve));
}
/*! Draw an exact region.
*/
void draw_exact_region(Halfedge_const_handle curr) {
this->add_point_in_face(curr->source()->point());
draw_exact_curve(curr->curve());
}
/*! Compile time dispatching
*/
#if 0
template <typename T, typename I = void>
void draw_region_impl2(Halfedge_const_handle curr, T const&, long)
{ draw_exact_region(curr); }
template <typename T, typename I>
auto draw_region_impl2(Halfedge_const_handle curr, T const& approx, int) ->
decltype(approx.template operator()<I>(X_monotone_curve{}, double{}, I{},
bool{}), void())
{ draw_approximate_region(curr, approx); }
template <typename T>
void draw_region_impl1(Halfedge_const_handle curr, T const&, long)
{ draw_exact_region(curr); }
template <typename T>
auto draw_region_impl1(Halfedge_const_handle curr, T const& traits, int) ->
decltype(traits.approximate_2_object(), void()) {
using Approximate = typename Gt::Approximate_2;
draw_region_impl2<Approximate, int>(curr, traits.approximate_2_object(), 0);
}
#else
template <typename T>
void draw_region_impl1(Halfedge_const_handle curr, T const& traits, int)
{ draw_approximate_region(curr, traits.approximate_2_object()); }
#endif
/*! Draw a region.
*/
void draw_region(Ccb_halfedge_const_circulator circ) {
/* Check whether the traits has a member function called
* approximate_2_object() and if so check whether the return type, namely
* `Approximate_2` has an appropriate operator.
*
* C++20 supports concepts and `requires` expression; see, e.g.,
* https://en.cppreference.com/w/cpp/language/constraints; thus, the first
* condition above can be elegantly verified as follows:
* constexpr bool has_approximate_2_object =
* requires(const Gt& traits) { traits.approximate_2_object(); };
*
* C++17 has experimental constructs called is_detected and
* is_detected_v that can be used to achieve the same goal.
*
* For now we use C++14 features.
*/
auto color = m_color_generator(circ->face());
this->face_begin(color);
const auto* traits = this->m_arr.geometry_traits();
auto ext = find_smallest(circ);
auto curr = ext;
do {
// Skip halfedges that are "antenas":
while (curr->face() == curr->twin()->face()) curr = curr->twin()->next();
draw_region_impl1(curr, *traits, 0);
curr = curr->next();
} while (curr != ext);
this->face_end();
}
/*! Draw a curve using aproximate coordinates.
* Call this member function only of the geometry traits is equipped with
* the coordinate-aproximation functionality of a curve.
* This function must be inlined (e.g., a template) to enable the
* compiled-time dispatching in the function `draw_curve()`.
*/
template <typename XMonotoneCurve, typename Approximate>
void draw_approximate_curve(const XMonotoneCurve& curve,
const Approximate& approx) {
std::vector<typename Gt::Approximate_point_2> polyline;
double error(this->pixel_ratio());
approx(curve, error, std::back_inserter(polyline));
if (polyline.empty()) return;
auto it = polyline.begin();
auto prev = it++;
for (; it != polyline.end(); prev = it++) this->add_segment(*prev, *it);
}
/*! Compile time dispatching
*/
#if 0
template <typename T, typename I = void>
void draw_curve_impl2(const X_monotone_curve& xcv, T const&, long)
{ draw_exact_curve(xcv); }
template <typename T, typename I>
auto draw_curve_impl2(const X_monotone_curve& xcv, T const& approx, int) ->
decltype(approx.template operator()<I>(X_monotone_curve{}, double{}, I{},
bool{}), void())
{ draw_approximate_curve(xcv, approx); }
template <typename T>
void draw_curve_impl1(const X_monotone_curve& xcv, T const&, long)
{ draw_exact_curve(xcv); }
template <typename T>
auto draw_curve_impl1(const X_monotone_curve& xcv, T const& traits, int) ->
decltype(traits.approximate_2_object(), void()) {
using Approximate = typename Gt::Approximate_2;
draw_curve_impl2<Approximate, int>(xcv, traits.approximate_2_object(), 0);
}
#else
template <typename T>
void draw_curve_impl1(const X_monotone_curve& xcv, T const& traits, int)
{ draw_approximate_curve(xcv, traits.approximate_2_object()); }
#endif
/*! Draw a curve.
*/
template <typename XMonotoneCurve>
void draw_curve(const XMonotoneCurve& curve) {
/* Check whether the traits has a member function called
* approximate_2_object() and if so check whether the return type, namely
* `Approximate_2` has an appropriate operator.
*
* C++20 supports concepts and `requires` expression; see, e.g.,
* https://en.cppreference.com/w/cpp/language/constraints; thus, the first
* condition above can be elegantly verified as follows:
* constexpr bool has_approximate_2_object =
* requires(const Gt& traits) { traits.approximate_2_object(); };
*
* C++17 has experimental constructs called is_detected and
* is_detected_v that can be used to achieve the same goal.
*
* For now we use C++14 features.
*/
#if 0
if constexpr (std::experimental::is_detected_v<approximate_2_object_t, Gt>)
{
const auto* traits = this->m_arr.geometry_traits();
auto approx = traits->approximate_2_object();
draw_approximate_curve(curve, approx);
return;
}
draw_exact_curve(curve);
#else
const auto* traits = this->m_arr.geometry_traits();
draw_curve_impl1(curve, *traits, 0);
#endif
}
/*! Compile time dispatching
*/
#if 0
template <typename T>
void draw_point_impl2(const Point& p, T const&, long) { add_point(p); }
template <typename T>
auto draw_point_impl2(const Point& p, T const& approx, int) ->
decltype(approx.operator()(p), void())
{ add_point(approx(p)); }
template <typename T>
void draw_point_impl1(const Point& p, T const&, long) { add_point(p); }
template <typename T>
auto draw_point_impl1(const Point& p, T const& traits, int) ->
decltype(traits.approximate_2_object(), void()) {
using Approximate = typename Gt::Approximate_2;
draw_point_impl2<Approximate>(p, traits.approximate_2_object(), true);
}
#else
template <typename T>
void draw_point_impl1(const Point& p, T const& traits, int)
{ add_point(traits.approximate_2_object()(p)); }
#endif
/*! Draw a point.
*/
void draw_point(const Point& p) {
const auto* traits = m_arr.geometry_traits();
draw_point_impl1(p, *traits, 0);
}
/*! Add a Connected Component of the Boundary.
*/
void add_ccb(Ccb_halfedge_const_circulator circ) {
auto curr = circ;
do {
auto new_face = curr->twin()->face();
if (m_visited.find(new_face) != m_visited.end()) continue;
m_visited[new_face] = true;
add_face(new_face);
} while (++curr != circ);
}
/*! Add a face.
*/
void add_face(Face_const_handle face) {
using Inner_ccb_const_iterator = typename Arr::Inner_ccb_const_iterator;
using Outer_ccb_const_iterator = typename Arr::Outer_ccb_const_iterator;
for (Inner_ccb_const_iterator it = face->inner_ccbs_begin();
it != face->inner_ccbs_end(); ++it)
add_ccb(*it);
for (Outer_ccb_const_iterator it = face->outer_ccbs_begin();
it != face->outer_ccbs_end(); ++it) {
add_ccb(*it);
draw_region(*it);
}
}
//!
virtual void keyPressEvent(QKeyEvent* e) {
// Test key pressed:
// const ::Qt::KeyboardModifiers modifiers = e->modifiers();
// if ((e->key()==Qt::Key_PageUp) && (modifiers==Qt::NoButton)) { ... }
// Call: * add_elements() if the model changed, followed by
// * redraw() if some viewing parameters changed that implies some
// modifications of the buffers
// (eg. type of normal, color/mono)
// * update() just to update the drawing
// Call the base method to process others/classicals key
Base::keyPressEvent(e);
}
protected:
//! The window width in pixels.
int m_width = CGAL_BASIC_VIEWER_INIT_SIZE_X;
//! The window height in pixels.
int m_height = CGAL_BASIC_VIEWER_INIT_SIZE_Y;
//! The ratio between pixel and opengl units (in world coordinate system).
double m_pixel_ratio = 1;
//! The arrangement to draw.
const Arr& m_arr;
//! The color generator.
Color_generator m_color_generator;
std::unordered_map<Face_const_handle, bool> m_visited;
};
//! Basic viewer of a 2D arrangement.
template <typename Arrangement_2_,
typename ColorGenerator = Default_color_generator>
class Arr_2_viewer_qt : public Arr_2_basic_viewer_qt<Arrangement_2_,
ColorGenerator> {
public:
using Arr = Arrangement_2_;
using Color_generator = ColorGenerator;
using Base = Arr_2_basic_viewer_qt<Arr, Color_generator>;
using Point = typename Arr::Point_2;
using X_monotone_curve = typename Arr::X_monotone_curve_2;
using Halfedge_const_handle = typename Arr::Halfedge_const_handle;
using Face_const_handle = typename Arr::Face_const_handle;
using Ccb_halfedge_const_circulator =
typename Arr::Ccb_halfedge_const_circulator;
/// Construct the viewer.
/// @param arr the arrangement to view
/// @param title the title of the window
Arr_2_viewer_qt(QWidget* parent, const Arr& arr,
Color_generator color_generator,
const char* title = "2D Arrangement Basic Viewer",
bool draw_vertices = false) :
Base(parent, arr, color_generator, title, draw_vertices)
{}
};
/*! Draw an arrangement.
*/
template <typename GeometryTraits_2, typename Dcel>
void draw(const Arrangement_2<GeometryTraits_2, Dcel>& arr,
const char* title = "2D Arrangement Basic Viewer",
bool draw_vertices = false) {
#if defined(CGAL_TEST_SUITE)
bool cgal_test_suite=true;
#else
bool cgal_test_suite = qEnvironmentVariableIsSet("CGAL_TEST_SUITE");
#endif
if (cgal_test_suite) return;
using Gt = GeometryTraits_2;
using Arr = CGAL::Arrangement_2<Gt, Dcel>;
using Viewer = Arr_2_viewer_qt<Arr, Default_color_generator>;
CGAL::Qt::init_ogl_context(4,3);
int argc = 1;
const char* argv[2] = {"t2_viewer", nullptr};
QApplication app(argc, const_cast<char**>(argv));
Default_color_generator color_generator;
Viewer mainwindow(app.activeWindow(), arr, color_generator, title,
draw_vertices);
mainwindow.add_elements();
mainwindow.show();
app.exec();
}
/*! Draw an arrangement using a given color generator.
*/
template <typename GeometryTraits_2, typename Dcel,
typename ColorGenerator>
void draw(const Arrangement_2<GeometryTraits_2, Dcel>& arr,
ColorGenerator color_generator,
const char* title = "2D Arrangement Basic Viewer",
bool draw_vertices = false) {
#if defined(CGAL_TEST_SUITE)
bool cgal_test_suite=true;
#else
bool cgal_test_suite = qEnvironmentVariableIsSet("CGAL_TEST_SUITE");
#endif
if (cgal_test_suite) return;
using Color_generator = ColorGenerator;
using Gt = GeometryTraits_2;
using Arr = CGAL::Arrangement_2<Gt, Dcel>;
using Viewer = Arr_2_viewer_qt<Arr, Color_generator>;
CGAL::Qt::init_ogl_context(4,3);
int argc = 1;
const char* argv[2] = {"t2_viewer", nullptr};
QApplication app(argc, const_cast<char**>(argv));
Viewer mainwindow(app.activeWindow(), arr, color_generator, title,
draw_vertices);
mainwindow.add_elements();
mainwindow.show();
app.exec();
}
}
#endif
#endif

View File

@ -10,6 +10,7 @@ Circulator
Distance_2 Distance_2
Distance_3 Distance_3
Filtered_kernel Filtered_kernel
GraphicsView
HalfedgeDS HalfedgeDS
Hash_map Hash_map
Homogeneous_kernel Homogeneous_kernel

View File

@ -239,14 +239,15 @@ bool read_orientation_and_end_points(InputStream_& is,
} }
/*! */ /*! */
template <typename InputStream_, typename Curve> template <typename InputStream_, typename Traits>
bool read_general_arc(InputStream_& is, Curve& cv) bool read_general_arc(InputStream_& is, typename Traits::Curve_2& cv,
const Traits& traits)
{ {
// Read a general conic, given by its coefficients <r,s,t,u,v,w>. // Read a general conic, given by its coefficients <r,s,t,u,v,w>.
Rational r, s, t, u, v, w; // The conic coefficients. Rational r, s, t, u, v, w; // The conic coefficients.
is >> r >> s >> t >> u >> v >> w; is >> r >> s >> t >> u >> v >> w;
// Read the orientation. // Read the orientation.
int i_orient = 0; int i_orient(0);
is >> i_orient; is >> i_orient;
CGAL::Orientation orient = (i_orient > 0) ? CGAL::COUNTERCLOCKWISE : CGAL::Orientation orient = (i_orient > 0) ? CGAL::COUNTERCLOCKWISE :
(i_orient < 0) ? CGAL::CLOCKWISE : CGAL::COLLINEAR; (i_orient < 0) ? CGAL::CLOCKWISE : CGAL::COLLINEAR;
@ -269,28 +270,30 @@ bool read_general_arc(InputStream_& is, Curve& cv)
is >> r2 >> s2 >> t2 >> u2 >> v2 >> w2; is >> r2 >> s2 >> t2 >> u2 >> v2 >> w2;
// Create the conic arc. // Create the conic arc.
cv = Curve(r, s, t, u, v, w, orient, auto ctr_cv = traits.construct_curve_2_object();
cv = ctr_cv(r, s, t, u, v, w, orient,
app_source, r1, s1, t1, u1, v1, w1, app_source, r1, s1, t1, u1, v1, w1,
app_target, r2, s2, t2, u2, v2, w2); app_target, r2, s2, t2, u2, v2, w2);
return true; return true;
} }
/*! */ /*! */
template <typename InputStream_, typename Curve> template <typename InputStream_, typename Traits>
bool read_general_conic(InputStream_& is, Curve& cv) bool read_general_conic(InputStream_& is, typename Traits::Curve_2& cv,
{ const Traits& traits) {
// Read a general conic, given by its coefficients <r,s,t,u,v,w>. // Read a general conic, given by its coefficients <r,s,t,u,v,w>.
Rational r, s, t, u, v, w; Rational r, s, t, u, v, w;
is >> r >> s >> t >> u >> v >> w; is >> r >> s >> t >> u >> v >> w;
// Create a full conic (should work only for ellipses). // Create a full conic (should work only for ellipses).
cv = Curve(r, s, t, u, v, w); auto ctr_cv = traits.construct_curve_2_object();
cv = ctr_cv(r, s, t, u, v, w);
return true; return true;
} }
/*! */ /*! */
template <typename InputStream_, typename Curve> template <typename InputStream_, typename Traits>
bool read_general_curve(InputStream_& is, Curve& cv) bool read_general_curve(InputStream_& is, typename Traits::Curve_2& cv,
{ const Traits& traits) {
Rational r, s, t, u, v, w; // The conic coefficients. Rational r, s, t, u, v, w; // The conic coefficients.
// Read a general conic, given by its coefficients <r,s,t,u,v,w>. // Read a general conic, given by its coefficients <r,s,t,u,v,w>.
is >> r >> s >> t >> u >> v >> w; is >> r >> s >> t >> u >> v >> w;
@ -300,7 +303,8 @@ bool read_general_curve(InputStream_& is, Curve& cv)
return false; return false;
// Create the conic (or circular) arc. // Create the conic (or circular) arc.
cv = Curve(r, s, t, u, v, w, orient, source, target); auto ctr_cv = traits.construct_curve_2_object();
cv = ctr_cv(r, s, t, u, v, w, orient, source, target);
return true; return true;
} }
@ -308,8 +312,7 @@ bool read_general_curve(InputStream_& is, Curve& cv)
template <> template <>
template <typename InputStream_> template <typename InputStream_>
bool IO_base_test<Base_geom_traits>::read_xcurve(InputStream_& is, bool IO_base_test<Base_geom_traits>::read_xcurve(InputStream_& is,
X_monotone_curve_2& xcv) X_monotone_curve_2& xcv) {
{
// since we are dealing with polycurve, we will make more than 1 conic curves // since we are dealing with polycurve, we will make more than 1 conic curves
// (polycurve compatible) and return the x-monotone-constructed polycurve. // (polycurve compatible) and return the x-monotone-constructed polycurve.
@ -324,24 +327,24 @@ bool IO_base_test<Base_geom_traits>::read_xcurve(InputStream_& is,
is >> type; is >> type;
//get number of x-monotone conic-arcs. //get number of x-monotone conic-arcs.
unsigned int number_of_curves; size_t number_of_curves;
is >> number_of_curves; is >> number_of_curves;
const auto& sub_traits = *(m_geom_traits.subcurve_traits_2());
auto ctr_xcv = sub_traits.construct_x_monotone_curve_2_object();
for (unsigned int i=0; i<number_of_curves; ++i) { for (unsigned int i=0; i<number_of_curves; ++i) {
if ((type == 'a') || (type == 'A')) { if ((type == 'a') || (type == 'A')) {
if (!read_general_curve(is, tmp_cv)) return false; if (! read_general_curve(is, tmp_cv, sub_traits)) return false;
X_monotone_subcurve_2 tmp_xcv(tmp_cv); conic_x_monotone_segments.push_back(ctr_xcv(tmp_cv));
conic_x_monotone_segments.push_back(tmp_xcv);
} }
else if ((type == 'c') || (type == 'C')) { else if ((type == 'c') || (type == 'C')) {
if (!read_general_conic(is, tmp_cv)) return false; if (! read_general_conic(is, tmp_cv, sub_traits)) return false;
X_monotone_subcurve_2 tmp_xcv(tmp_cv); conic_x_monotone_segments.push_back(ctr_xcv(tmp_cv));
conic_x_monotone_segments.push_back(tmp_xcv);
} }
else if ((type == 'i') || (type == 'I')) { else if ((type == 'i') || (type == 'I')) {
if (!read_general_arc(is, tmp_cv)) return false; if (! read_general_arc(is, tmp_cv, sub_traits)) return false;
X_monotone_subcurve_2 tmp_xcv(tmp_cv); conic_x_monotone_segments.push_back(ctr_xcv(tmp_cv));
conic_x_monotone_segments.push_back(tmp_xcv);
} }
else { else {
std::cerr << "Illegal conic type specification: " << type << "." std::cerr << "Illegal conic type specification: " << type << "."
@ -361,8 +364,7 @@ bool IO_base_test<Base_geom_traits>::read_xcurve(InputStream_& is,
/*! Read a conic poly-curve */ /*! Read a conic poly-curve */
template <> template <>
template <typename InputStream_> template <typename InputStream_>
bool IO_base_test<Base_geom_traits>::read_curve(InputStream_& is, Curve_2& cv) bool IO_base_test<Base_geom_traits>::read_curve(InputStream_& is, Curve_2& cv) {
{
// since we are dealing with polycurve, we will make more than 1 conic curves // since we are dealing with polycurve, we will make more than 1 conic curves
// (polycurve compatible) and return the constructed polycurve. // (polycurve compatible) and return the constructed polycurve.
@ -376,20 +378,21 @@ bool IO_base_test<Base_geom_traits>::read_curve(InputStream_& is, Curve_2& cv)
is >> type; is >> type;
//get number of xmonotone-conic arcs. //get number of xmonotone-conic arcs.
unsigned int number_of_curves; size_t number_of_curves;
is >> number_of_curves; is >> number_of_curves;
const auto& sub_traits = *(m_geom_traits.subcurve_traits_2());
for (unsigned int i = 0; i < number_of_curves; ++i) { for (unsigned int i = 0; i < number_of_curves; ++i) {
if ((type == 'a') || (type == 'A')) { if ((type == 'a') || (type == 'A')) {
if (!read_general_curve(is, tmp_cv)) return false; if (! read_general_curve(is, tmp_cv, sub_traits)) return false;
conic_segments.push_back(tmp_cv); conic_segments.push_back(tmp_cv);
} }
else if ((type == 'c') || (type == 'C')) { else if ((type == 'c') || (type == 'C')) {
if (!read_general_conic(is, tmp_cv)) return false; if (! read_general_conic(is, tmp_cv, sub_traits)) return false;
conic_segments.push_back(tmp_cv); conic_segments.push_back(tmp_cv);
} }
else if ((type == 'i') || (type == 'I')) { else if ((type == 'i') || (type == 'I')) {
if (!read_general_arc(is, tmp_cv)) return false; if (! read_general_arc(is, tmp_cv, sub_traits)) return false;
conic_segments.push_back(tmp_cv); conic_segments.push_back(tmp_cv);
} }
@ -422,11 +425,10 @@ template <typename InputStream_>
bool IO_base_test<Base_geom_traits>::read_segment(InputStream_& is, bool IO_base_test<Base_geom_traits>::read_segment(InputStream_& is,
Subcurve_2& seg) Subcurve_2& seg)
{ {
Subcurve_2 tmp_seg;
char type; char type;
is >> type; is >> type;
if (!read_general_curve(is, tmp_seg)) return false; const auto& sub_traits = *(m_geom_traits.subcurve_traits_2());
seg = tmp_seg; if (! read_general_curve(is, seg, sub_traits)) return false;
return true; return true;
} }
@ -438,8 +440,10 @@ bool IO_base_test<Base_geom_traits>::read_xsegment(InputStream_& is,
char type; char type;
is >> type; is >> type;
Subcurve_2 tmp_seg; Subcurve_2 tmp_seg;
if (!read_general_curve(is, tmp_seg)) return false; const auto& sub_traits = *(m_geom_traits.subcurve_traits_2());
xseg = X_monotone_subcurve_2(tmp_seg); if (! read_general_curve(is, tmp_seg, sub_traits)) return false;
auto ctr_xcv = sub_traits.construct_x_monotone_curve_2_object();
xseg = ctr_xcv(tmp_seg);
return true; return true;
} }
@ -1037,9 +1041,9 @@ bool read_ellipse(InputStream_& is, bool& is_circle, Rat_circle& circle,
} }
/*! */ /*! */
template <typename InputStream_, typename Curve> template <typename InputStream_, typename Traits>
bool read_partial_ellipse(InputStream_& is, Curve& cv) bool read_partial_ellipse(InputStream_& is, typename Traits::Curve_2& cv,
{ const Traits& traits) {
bool is_circle; // Is this a circle. bool is_circle; // Is this a circle.
Rat_circle circle; Rat_circle circle;
Rational r, s, t, u, v, w; Rational r, s, t, u, v, w;
@ -1050,15 +1054,16 @@ bool read_partial_ellipse(InputStream_& is, Curve& cv)
return false; return false;
// Create the conic (or circular) arc. // Create the conic (or circular) arc.
cv = (is_circle) ? Curve(circle, orient, source, target) : auto ctr_cv = traits.construct_curve_2_object();
Curve(r, s, t, u, v, w, orient, source, target); cv = (is_circle) ? ctr_cv(circle, orient, source, target) :
ctr_cv(r, s, t, u, v, w, orient, source, target);
return true; return true;
} }
/*! */ /*! */
template <typename InputStream_, typename Curve> template <typename InputStream_, typename Traits>
bool read_full_ellipse(InputStream_& is, Curve& cv) bool read_full_ellipse(InputStream_& is, typename Traits::Curve_2& cv,
{ const Traits& traits) {
bool is_circle; // Is this a circle. bool is_circle; // Is this a circle.
Rat_circle circle; Rat_circle circle;
Rational r, s, t, u, v, w; Rational r, s, t, u, v, w;
@ -1066,14 +1071,14 @@ bool read_full_ellipse(InputStream_& is, Curve& cv)
return false; return false;
// Create a full ellipse (or circle). // Create a full ellipse (or circle).
cv = (is_circle) ? Curve(circle) : Curve(r, s, t, u, v, w); auto ctr_cv = traits.construct_curve_2_object();
cv = (is_circle) ? ctr_cv(circle) : ctr_cv(r, s, t, u, v, w);
return true; return true;
} }
/*! Read a hyperbola */ /*! Read a hyperbola */
template <typename InputStream_, typename Curve> template <typename InputStream_, typename Curve, typename Traits>
bool read_hyperbola(InputStream_& is, Curve& cv) bool read_hyperbola(InputStream_& is, Curve& cv, const Traits& traits) {
{
// Read the hyperbola (using the format "a b x0 y0"): // Read the hyperbola (using the format "a b x0 y0"):
// 2 2 // 2 2
// ( x - x0 ) ( y - y0 ) // ( x - x0 ) ( y - y0 )
@ -1096,14 +1101,15 @@ bool read_hyperbola(InputStream_& is, Curve& cv)
return false; return false;
// Create the conic (or circular) arc. // Create the conic (or circular) arc.
cv = Curve(r, s, t, u, v, w, orient, source, target); auto ctr_cv = traits.construct_curve_2_object();
cv = ctr_cv(r, s, t, u, v, w, orient, source, target);
return true; return true;
} }
/*! Read a hyperbola */ /*! Read a hyperbola */
template <typename InputStream_, typename Curve> template <typename InputStream_, typename Traits>
bool read_parabola(InputStream_& is, Curve& cv) bool read_parabola(InputStream_& is, typename Traits::Curve_2& cv,
{ const Traits& traits) {
// Read the parabola (using the format "c x0 y0"): // Read the parabola (using the format "c x0 y0"):
// //
// 2 // 2
@ -1125,15 +1131,15 @@ bool read_parabola(InputStream_& is, Curve& cv)
return false; return false;
// Create the conic (or circular) arc. // Create the conic (or circular) arc.
cv = Curve(r, s, t, u, v, w, orient, source, target); auto ctr_cv = traits.construct_curve_2_object();
cv = ctr_cv(r, s, t, u, v, w, orient, source, target);
return true; return true;
} }
/*! */ /*! */
template <typename InputStream_, typename Curve> template <typename InputStream_, typename Traits>
bool read_segment(InputStream_& is, Curve& cv) bool read_segment(InputStream_& is, typename Traits::Curve_2& cv,
{ const Traits& traits) {
// Read a segment, given by its endpoints (x1,y1) and (x2,y2); // Read a segment, given by its endpoints (x1,y1) and (x2,y2);
Rational x1, y1, x2, y2; Rational x1, y1, x2, y2;
is >> x1 >> y1 >> x2 >> y2; is >> x1 >> y1 >> x2 >> y2;
@ -1143,19 +1149,20 @@ bool read_segment(InputStream_& is, Curve& cv)
Rat_segment segment(source, target); Rat_segment segment(source, target);
// Create the segment. // Create the segment.
cv = Curve(segment); auto ctr_cv = traits.construct_curve_2_object();
cv = ctr_cv(segment);
return true; return true;
} }
/*! */ /*! */
template <typename InputStream_, typename Curve> template <typename InputStream_, typename Traits>
bool read_general_arc(InputStream_& is, Curve& cv) bool read_general_arc(InputStream_& is, typename Traits::Curve_2& cv,
{ const Traits& traits) {
// Read a general conic, given by its coefficients <r,s,t,u,v,w>. // Read a general conic, given by its coefficients <r,s,t,u,v,w>.
Rational r, s, t, u, v, w; // The conic coefficients. Rational r, s, t, u, v, w; // The conic coefficients.
is >> r >> s >> t >> u >> v >> w; is >> r >> s >> t >> u >> v >> w;
// Read the orientation. // Read the orientation.
int i_orient = 0; int i_orient(0);
is >> i_orient; is >> i_orient;
CGAL::Orientation orient = (i_orient > 0) ? CGAL::COUNTERCLOCKWISE : CGAL::Orientation orient = (i_orient > 0) ? CGAL::COUNTERCLOCKWISE :
(i_orient < 0) ? CGAL::CLOCKWISE : CGAL::COLLINEAR; (i_orient < 0) ? CGAL::CLOCKWISE : CGAL::COLLINEAR;
@ -1178,16 +1185,17 @@ bool read_general_arc(InputStream_& is, Curve& cv)
is >> r2 >> s2 >> t2 >> u2 >> v2 >> w2; is >> r2 >> s2 >> t2 >> u2 >> v2 >> w2;
// Create the conic arc. // Create the conic arc.
cv = Curve(r, s, t, u, v, w, orient, auto ctr_cv = traits.construct_curve_2_object();
cv = ctr_cv(r, s, t, u, v, w, orient,
app_source, r1, s1, t1, u1, v1, w1, app_source, r1, s1, t1, u1, v1, w1,
app_target, r2, s2, t2, u2, v2, w2); app_target, r2, s2, t2, u2, v2, w2);
return true; return true;
} }
/*! */ /*! */
template <typename InputStream_, typename Curve> template <typename InputStream_, typename Traits>
bool read_general_curve(InputStream_& is, Curve& cv) bool read_general_curve(InputStream_& is, typename Traits::Curve_2& cv,
{ const Traits& traits) {
Rational r, s, t, u, v, w; // The conic coefficients. Rational r, s, t, u, v, w; // The conic coefficients.
// Read a general conic, given by its coefficients <r,s,t,u,v,w>. // Read a general conic, given by its coefficients <r,s,t,u,v,w>.
is >> r >> s >> t >> u >> v >> w; is >> r >> s >> t >> u >> v >> w;
@ -1197,7 +1205,8 @@ bool read_general_curve(InputStream_& is, Curve& cv)
return false; return false;
// Create the conic (or circular) arc. // Create the conic (or circular) arc.
cv = Curve(r, s, t, u, v, w, orient, source, target); auto ctr_cv = traits.construct_curve_2_object();
cv = ctr_cv(r, s, t, u, v, w, orient, source, target);
return true; return true;
} }
@ -1205,11 +1214,11 @@ bool read_general_curve(InputStream_& is, Curve& cv)
template <> template <>
template <typename InputStream_> template <typename InputStream_>
bool IO_base_test<Base_geom_traits>::read_xcurve(InputStream_& is, bool IO_base_test<Base_geom_traits>::read_xcurve(InputStream_& is,
X_monotone_curve_2& xcv) X_monotone_curve_2& xcv) {
{
Curve_2 tmp_cv; Curve_2 tmp_cv;
if (! read_curve(is, tmp_cv)) return false; if (! read_curve(is, tmp_cv)) return false;
xcv = X_monotone_curve_2(tmp_cv); auto ctr_xcv = m_geom_traits.construct_x_monotone_curve_2_object();
xcv = ctr_xcv(tmp_cv);
return true; return true;
} }
@ -1221,25 +1230,37 @@ bool IO_base_test<Base_geom_traits>::read_curve(InputStream_& is, Curve_2& cv)
// Get the arc type: // Get the arc type:
char type; char type;
is >> type; is >> type;
if ((type == 'f') || (type == 'F')) return read_full_ellipse(is, cv); switch (type) {
else if ((type == 's') || (type == 'S')) return read_segment(is, cv); case 'f':
else if ((type == 'i') || (type == 'I')) return read_general_arc(is, cv); case 'F': return read_full_ellipse(is, cv, m_geom_traits);
else if ((type == 'c') || (type == 'C')) { case 's':
case 'S': return read_segment(is, cv, m_geom_traits);
case 'i':
case 'I': return read_general_arc(is, cv, m_geom_traits);
case 'c':
case 'C':
{
// Read a general conic, given by its coefficients <r,s,t,u,v,w>. // Read a general conic, given by its coefficients <r,s,t,u,v,w>.
Rational r, s, t, u, v, w; Rational r, s, t, u, v, w;
is >> r >> s >> t >> u >> v >> w; is >> r >> s >> t >> u >> v >> w;
// Create a full conic (should work only for ellipses). // Create a full conic (should work only for ellipses).
cv = Curve_2(r, s, t, u, v, w); auto ctr_cv = m_geom_traits.construct_curve_2_object();
cv = ctr_cv(r, s, t, u, v, w);
return true; return true;
} }
else if ((type == 'e') || (type == 'E')) return read_partial_ellipse(is, cv); case 'e':
else if ((type == 'h') || (type == 'H')) return read_hyperbola(is, cv); case 'E': return read_partial_ellipse(is, cv, m_geom_traits);
else if ((type == 'p') || (type == 'P')) return read_parabola(is, cv); case 'h':
else if ((type == 'a') || (type == 'A')) return read_general_curve(is, cv); case 'H': return read_hyperbola(is, cv, m_geom_traits);
case 'p':
case 'P': return read_parabola(is, cv, m_geom_traits);
case 'a':
case 'A': return read_general_curve(is, cv, m_geom_traits);
default:
// If we reached here, we have an unknown conic type: // If we reached here, we have an unknown conic type:
std::cerr << "Illegal conic type specification: " << type << "." std::cerr << "Illegal conic type specification: " << type << "."
<< std::endl; << std::endl;
}
return false; return false;
} }
@ -1446,7 +1467,7 @@ bool IO_base_test<Base_geom_traits>::read_curve(InputStream_& is, Curve_2& cv)
// If we reached here, we have an unknown rational arc type: // If we reached here, we have an unknown rational arc type:
std::cerr << "Illegal rational arc type specification: " << type << "." std::cerr << "Illegal rational arc type specification: " << type << "."
<< std::endl; << std::endl;
return (false); return false;
} }
// Bezier // Bezier

View File

@ -50,43 +50,41 @@ typedef Polycurve_conic_traits_2::Point_2 Pc_point_2;
// CGAL::CORE_algebraic_number_traits> // CGAL::CORE_algebraic_number_traits>
// >::Point_2 test_point_2; // >::Point_2 test_point_2;
void check_equal() void check_equal() {
{
bool are_equal; bool are_equal;
Polycurve_conic_traits_2 traits; Conic_traits_2 sub_traits;
Polycurve_conic_traits_2::Equal_2 equal = traits.equal_2_object(); Polycurve_conic_traits_2 traits(&sub_traits);
Polycurve_conic_traits_2::Construct_x_monotone_curve_2 auto equal = traits.equal_2_object();
construct_x_monotone_curve_2 = traits.construct_x_monotone_curve_2_object(); auto ctr_xcv = traits.construct_x_monotone_curve_2_object();
auto ctr_sub_cv = sub_traits.construct_curve_2_object();
//create some curves //create some curves
Conic_point_2 ps1(Rational(1,4), 4); Conic_point_2 ps1(Rational(1,4), 4);
Conic_point_2 pt1(2, Rational(1,2)); Conic_point_2 pt1(2, Rational(1,2));
Conic_curve_2 c1(0, 0, 1, 0, 0, -1, CGAL::COUNTERCLOCKWISE, ps1, pt1); Conic_curve_2 c1 =
ctr_sub_cv(0, 0, 1, 0, 0, -1, CGAL::COUNTERCLOCKWISE, ps1, pt1);
Conic_point_2 ps2(Rational(1,4), 4); Conic_point_2 ps2(Rational(1,4), 4);
Conic_point_2 pt2(2, Rational(1,2)); Conic_point_2 pt2(2, Rational(1,2));
Conic_curve_2 c2(0, 0, 1, 0, 0, -1, CGAL::COUNTERCLOCKWISE, ps2, pt2); Conic_curve_2 c2 =
ctr_sub_cv(0, 0, 1, 0, 0, -1, CGAL::COUNTERCLOCKWISE, ps2, pt2);
Rat_point_2 ps3(Rational(1,4), 4); Rat_point_2 ps3(Rational(1,4), 4);
Rat_point_2 pmid3(Rational(3,2), 2); Rat_point_2 pmid3(Rational(3,2), 2);
Rat_point_2 pt3(2, Rational(1,3)); Rat_point_2 pt3(2, Rational(1,3));
Conic_curve_2 c3(ps3, pmid3, pt3); Conic_curve_2 c3 = ctr_sub_cv(ps3, pmid3, pt3);
Rat_point_2 ps4(1, 5); Rat_point_2 ps4(1, 5);
Rat_point_2 pmid4(Rational(3,2), 3); Rat_point_2 pmid4(Rational(3,2), 3);
Rat_point_2 pt4(3, Rational(1,3)); Rat_point_2 pt4(3, Rational(1,3));
Conic_curve_2 c4(ps4, pmid4, pt4); Conic_curve_2 c4 = ctr_sub_cv(ps4, pmid4, pt4);
// //make x_monotone // //make x_monotone
Polycurve_conic_traits_2::X_monotone_curve_2 xmc1 = Polycurve_conic_traits_2::X_monotone_curve_2 xmc1 = ctr_xcv(c1);
construct_x_monotone_curve_2(c1); Polycurve_conic_traits_2::X_monotone_curve_2 xmc2 = ctr_xcv(c2);
Polycurve_conic_traits_2::X_monotone_curve_2 xmc2 = Polycurve_conic_traits_2::X_monotone_curve_2 xmc3 = ctr_xcv(c3);
construct_x_monotone_curve_2(c2); Polycurve_conic_traits_2::X_monotone_curve_2 xmc4 = ctr_xcv(c4);
Polycurve_conic_traits_2::X_monotone_curve_2 xmc3 =
construct_x_monotone_curve_2(c3);
Polycurve_conic_traits_2::X_monotone_curve_2 xmc4 =
construct_x_monotone_curve_2(c4);
are_equal = equal(xmc1, xmc2); are_equal = equal(xmc1, xmc2);
std::cout << "Two equal conic arcs are computed as: " std::cout << "Two equal conic arcs are computed as: "
@ -104,8 +102,7 @@ void check_equal()
template <typename Traits> template <typename Traits>
void check_intersect(typename Traits::X_monotone_curve_2& xcv1, void check_intersect(typename Traits::X_monotone_curve_2& xcv1,
typename Traits::X_monotone_curve_2& xcv2, typename Traits::X_monotone_curve_2& xcv2,
const Traits& traits) const Traits& traits) {
{
typedef typename Traits::Multiplicity Multiplicity; typedef typename Traits::Multiplicity Multiplicity;
typedef typename Traits::Point_2 Point_2; typedef typename Traits::Point_2 Point_2;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2; typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
@ -114,8 +111,8 @@ void check_equal()
Intersection_result; Intersection_result;
std::vector<Intersection_result> intersection_points; std::vector<Intersection_result> intersection_points;
traits.intersect_2_object()(xcv1, xcv2, auto intersect = traits.intersect_2_object();
std::back_inserter(intersection_points)); intersect(xcv1, xcv2, std::back_inserter(intersection_points));
std::cout<< "Number of intersection Points: " << intersection_points.size() std::cout<< "Number of intersection Points: " << intersection_points.size()
<< std::endl; << std::endl;
@ -133,13 +130,12 @@ void check_equal()
// } // }
} }
void check_compare_end_points_xy_2() void check_compare_end_points_xy_2() {
{ Conic_traits_2 sub_traits;
Polycurve_conic_traits_2 traits; Polycurve_conic_traits_2 traits(&sub_traits);
Polycurve_conic_traits_2::Construct_x_monotone_curve_2 auto ctr_xcv = traits.construct_x_monotone_curve_2_object();
construct_x_monotone_curve_2 = traits.construct_x_monotone_curve_2_object(); auto cmp_endpoints = traits.compare_endpoints_xy_2_object();
Polycurve_conic_traits_2::Compare_endpoints_xy_2 compare_endpoints_xy_2 = auto ctr_sub_cv = sub_traits.construct_curve_2_object();
traits.compare_endpoints_xy_2_object();
//create some curves //create some curves
Conic_point_2 ps1(Rational(1,4), 4); Conic_point_2 ps1(Rational(1,4), 4);
@ -153,7 +149,7 @@ void check_compare_end_points_xy_2()
// as the intersections of the parabola with the lines y = -3 and y = -2. // as the intersections of the parabola with the lines y = -3 and y = -2.
// Note that the arc is clockwise oriented. // Note that the arc is clockwise oriented.
Conic_curve_2 Conic_curve_2
c2 = Conic_curve_2(1, 0, 0, 0, 1, 0, // The parabola. c2 = ctr_sub_cv(1, 0, 0, 0, 1, 0, // The parabola.
CGAL::CLOCKWISE, CGAL::CLOCKWISE,
Conic_point_2(-1.73, -3), // Approximation of the source. Conic_point_2(-1.73, -3), // Approximation of the source.
0, 0, 0, 0, 1, 3, // The line: y = -3. 0, 0, 0, 0, 1, 3, // The line: y = -3.
@ -162,60 +158,60 @@ void check_compare_end_points_xy_2()
assert(c2.is_valid()); assert(c2.is_valid());
//make polyline x-monotone curves //make polyline x-monotone curves
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc1 = Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc1 = ctr_xcv(c1);
construct_x_monotone_curve_2(c1); Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc2 = ctr_xcv(c2);
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc2 =
construct_x_monotone_curve_2(c2);
CGAL::Comparison_result res = compare_endpoints_xy_2(polyline_xmc1); CGAL::Comparison_result res = cmp_endpoints(polyline_xmc1);
std::cout << "compare_end_points_xy_2 for counterclockwise curve: " std::cout << "compare_end_points_xy_2 for counterclockwise curve: "
<< (res == CGAL::SMALLER ? "SMALLER": << (res == CGAL::SMALLER ? "SMALLER":
(res == CGAL::LARGER ? "LARGER" : "EQUAL")) << std::endl; (res == CGAL::LARGER ? "LARGER" : "EQUAL")) << std::endl;
res = compare_endpoints_xy_2(polyline_xmc2); res = cmp_endpoints(polyline_xmc2);
std::cout<< "compare_end_points_xy_2 for clockwise curve: " std::cout<< "compare_end_points_xy_2 for clockwise curve: "
<< (res == CGAL::SMALLER ? "SMALLER": << (res == CGAL::SMALLER ? "SMALLER":
(res == CGAL::LARGER ? "LARGER" : "EQUAL")) << std::endl; (res == CGAL::LARGER ? "LARGER" : "EQUAL")) << std::endl;
} }
template <typename Curve_type> template <typename Curve_type>
void check_split(Curve_type &xcv1, Curve_type &xcv2) void check_split(Curve_type& xcv1, Curve_type& xcv2) {
{ Conic_traits_2 sub_traits;
Polycurve_conic_traits_2 traits; Polycurve_conic_traits_2 traits(&sub_traits);
auto ctr_sub_cv = sub_traits.construct_curve_2_object();
auto ctr_sub_xcv = sub_traits.construct_x_monotone_curve_2_object();
//split x poly-curves //split x poly-curves
Conic_curve_2 c6(1,1,0,6,-26,162,CGAL::COUNTERCLOCKWISE, Conic_curve_2 c6 = ctr_sub_cv(1,1,0,6,-26,162,CGAL::COUNTERCLOCKWISE,
Conic_point_2(Algebraic(-7), Algebraic(13)), Conic_point_2(Algebraic(-7), Algebraic(13)),
Conic_point_2(Algebraic(-3), Algebraic(9))); Conic_point_2(Algebraic(-3), Algebraic(9)));
Conic_curve_2 c7(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE, Conic_curve_2 c7 = ctr_sub_cv(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE,
Conic_point_2(Algebraic(-3), Algebraic(9)), Conic_point_2(Algebraic(-3), Algebraic(9)),
Conic_point_2(Algebraic(0), Algebraic(0))); Conic_point_2(Algebraic(0), Algebraic(0)));
Conic_curve_2 c8(0,1,0,-1,0,0, CGAL::COUNTERCLOCKWISE, Conic_curve_2 c8 = ctr_sub_cv(0,1,0,-1,0,0, CGAL::COUNTERCLOCKWISE,
Conic_point_2(Algebraic(0), Algebraic(0)), Conic_point_2(Algebraic(0), Algebraic(0)),
Conic_point_2(Algebraic(4), Algebraic(-2))); Conic_point_2(Algebraic(4), Algebraic(-2)));
Conic_x_monotone_curve_2 xc6(c6); Conic_x_monotone_curve_2 xc6 = ctr_sub_xcv(c6);
Conic_x_monotone_curve_2 xc7(c7); Conic_x_monotone_curve_2 xc7 = ctr_sub_xcv(c7);
Conic_x_monotone_curve_2 xc8(c8); Conic_x_monotone_curve_2 xc8 = ctr_sub_xcv(c8);
std::vector<Conic_x_monotone_curve_2> xmono_conic_curves_2; std::vector<Conic_x_monotone_curve_2> xmono_conic_curves_2;
auto ctr_xcv = traits.construct_x_monotone_curve_2_object();
xmono_conic_curves_2.push_back(xc6); xmono_conic_curves_2.push_back(xc6);
xmono_conic_curves_2.push_back(xc7); xmono_conic_curves_2.push_back(xc7);
Pc_x_monotone_curve_2 split_expected_1 = Pc_x_monotone_curve_2 split_expected_1 =
traits.construct_x_monotone_curve_2_object()(xmono_conic_curves_2.begin(), ctr_xcv(xmono_conic_curves_2.begin(), xmono_conic_curves_2.end());
xmono_conic_curves_2.end());
xmono_conic_curves_2.clear(); xmono_conic_curves_2.clear();
xmono_conic_curves_2.push_back(xc8); xmono_conic_curves_2.push_back(xc8);
Pc_x_monotone_curve_2 split_expected_2 = Pc_x_monotone_curve_2 split_expected_2 =
traits.construct_x_monotone_curve_2_object()(xmono_conic_curves_2.begin(), ctr_xcv(xmono_conic_curves_2.begin(), xmono_conic_curves_2.end());
xmono_conic_curves_2.end());
Polycurve_conic_traits_2::X_monotone_curve_2 split_curve_1, split_curve_2; Polycurve_conic_traits_2::X_monotone_curve_2 split_curve_1, split_curve_2;
Polycurve_conic_traits_2::Point_2 Polycurve_conic_traits_2::Point_2 point_of_split =
point_of_split = Polycurve_conic_traits_2::Point_2(0,0); Polycurve_conic_traits_2::Point_2(0,0);
//Split functor //Split functor
traits.split_2_object()(xcv2, point_of_split, split_curve_1, split_curve_2); traits.split_2_object()(xcv2, point_of_split, split_curve_1, split_curve_2);
@ -229,23 +225,21 @@ void check_split(Curve_type &xcv1, Curve_type &xcv2)
std::cout << "Something is wrong with split" << std::endl; std::cout << "Something is wrong with split" << std::endl;
} }
void check_is_vertical() void check_is_vertical() {
{ Conic_traits_2 sub_traits;
Polycurve_conic_traits_2 traits; Polycurve_conic_traits_2 traits(&sub_traits);
Polycurve_conic_traits_2::Construct_x_monotone_curve_2 auto ctr_sub_cv = sub_traits.construct_curve_2_object();
construct_x_monotone_curve_2 = traits.construct_x_monotone_curve_2_object(); auto ctr_xcv = traits.construct_x_monotone_curve_2_object();
Polycurve_conic_traits_2::Is_vertical_2 is_vertical = auto is_vertical = traits.is_vertical_2_object();
traits.is_vertical_2_object();
//create a curve //create a curve
Rat_point_2 ps1(1, 10); Rat_point_2 ps1(1, 10);
Rat_point_2 pmid1(5, 4); Rat_point_2 pmid1(5, 4);
Rat_point_2 pt1(10, 1); Rat_point_2 pt1(10, 1);
Conic_curve_2 c1(ps1, pmid1, pt1); Conic_curve_2 c1 = ctr_sub_cv(ps1, pmid1, pt1);
//make x-monotone curve //make x-monotone curve
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc1 = Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc1 = ctr_xcv(c1);
construct_x_monotone_curve_2(c1);
bool result = is_vertical(polyline_xmc1); bool result = is_vertical(polyline_xmc1);
std::cout << "Is_verticle:: Expected first result is not vertivle: Computed: " std::cout << "Is_verticle:: Expected first result is not vertivle: Computed: "
@ -254,8 +248,7 @@ void check_is_vertical()
/*! */ /*! */
template <typename stream> template <typename stream>
bool read_orientation(stream& is, CGAL::Orientation& orient) bool read_orientation(stream& is, CGAL::Orientation& orient) {
{
int i_orient; int i_orient;
is >> i_orient; is >> i_orient;
orient = (i_orient > 0) ? CGAL::COUNTERCLOCKWISE : orient = (i_orient > 0) ? CGAL::COUNTERCLOCKWISE :
@ -265,8 +258,7 @@ bool read_orientation(stream& is, CGAL::Orientation& orient)
/*! */ /*! */
template <typename stream> template <typename stream>
bool read_app_point(stream& is, Conic_point_2& p) bool read_app_point(stream& is, Conic_point_2& p) {
{
//waqar: original //waqar: original
double x, y; double x, y;
is >> x >> y; is >> x >> y;
@ -299,9 +291,9 @@ bool read_orientation_and_end_points(stream& is, CGAL::Orientation& orient,
} }
/*! */ /*! */
template <typename stream, typename Curve> template <typename stream, typename Traits>
bool read_general_arc(stream& is, Curve& cv) bool read_general_arc(stream& is, typename Traits::Curve_2& cv,
{ const Traits& traits) {
// Read a general conic, given by its coefficients <r,s,t,u,v,w>. // Read a general conic, given by its coefficients <r,s,t,u,v,w>.
Rational r, s, t, u, v, w; // The conic coefficients. Rational r, s, t, u, v, w; // The conic coefficients.
is >> r >> s >> t >> u >> v >> w; is >> r >> s >> t >> u >> v >> w;
@ -333,28 +325,30 @@ bool read_general_arc(stream& is, Curve& cv)
<< r2 << s2 << t2 << u2 << v2 << w2 << std::endl; << r2 << s2 << t2 << u2 << v2 << w2 << std::endl;
// Create the conic arc. // Create the conic arc.
cv = Curve(r, s, t, u, v, w, orient, auto ctr_cv = traits.construct_curve_2_object();
cv = ctr_cv(r, s, t, u, v, w, orient,
app_source, r1, s1, t1, u1, v1, w1, app_source, r1, s1, t1, u1, v1, w1,
app_target, r2, s2, t2, u2, v2, w2); app_target, r2, s2, t2, u2, v2, w2);
return true; return true;
} }
/*! */ /*! */
template <typename stream, typename Curve> template <typename stream, typename Traits>
bool read_general_conic(stream& is, Curve& cv) bool read_general_conic(stream& is, typename Traits::Curve_2& cv,
{ const Traits& traits) {
// Read a general conic, given by its coefficients <r,s,t,u,v,w>. // Read a general conic, given by its coefficients <r,s,t,u,v,w>.
Rational r, s, t, u, v, w; Rational r, s, t, u, v, w;
is >> r >> s >> t >> u >> v >> w; is >> r >> s >> t >> u >> v >> w;
// Create a full conic (should work only for ellipses). // Create a full conic (should work only for ellipses).
cv = Curve(r, s, t, u, v, w); auto ctr_cv = traits.construct_curve_2_object();
cv = ctr_cv(r, s, t, u, v, w);
return true; return true;
} }
// /*! */ // /*! */
template <typename stream, typename Curve> template <typename stream, typename Traits>
bool read_general_curve(stream& is, Curve& cv) bool read_general_curve(stream& is, typename Traits::Curve_2& cv,
{ const Traits& traits) {
Rational r, s, t, u, v, w; // The conic coefficients. Rational r, s, t, u, v, w; // The conic coefficients.
// Read a general conic, given by its coefficients <r,s,t,u,v,w>. // Read a general conic, given by its coefficients <r,s,t,u,v,w>.
is >> r >> s >> t >> u >> v >> w; is >> r >> s >> t >> u >> v >> w;
@ -368,26 +362,25 @@ bool read_general_curve(stream& is, Curve& cv)
// << u << " " << v << " " << w << std::endl; // << u << " " << v << " " << w << std::endl;
// std::cout << "Read Points : " << source.x() << " " << source.y() << " " // std::cout << "Read Points : " << source.x() << " " << source.y() << " "
// << target.x() << " " << target.y() << std::endl; // << target.x() << " " << target.y() << std::endl;
cv = Curve(r, s, t, u, v, w, orient, source, target); auto ctr_cv = traits.construct_curve_2_object();
cv = ctr_cv(r, s, t, u, v, w, orient, source, target);
return true; return true;
} }
std::istream& skip_comments(std::istream& is, std::string& line) std::istream& skip_comments(std::istream& is, std::string& line) {
{
while (std::getline(is, line)) while (std::getline(is, line))
if (!line.empty() && (line[0] != '#')) break; if (!line.empty() && (line[0] != '#')) break;
return is; return is;
} }
bool check_compare_y_at_x_2() bool check_compare_y_at_x_2() {
{ Conic_traits_2 sub_traits;
Polycurve_conic_traits_2 traits; Polycurve_conic_traits_2 traits(&sub_traits);
Polycurve_conic_traits_2::Compare_y_at_x_2 cmp_y_at_x_2 = auto ctr_sub_cv = sub_traits.construct_curve_2_object();
traits.compare_y_at_x_2_object(); auto ctr_sub_xcv = sub_traits.construct_x_monotone_curve_2_object();
auto cmp_y_at_x_2 = traits.compare_y_at_x_2_object();
//polycurve constructors //polycurve constructors
Polycurve_conic_traits_2::Construct_x_monotone_curve_2 auto construct_x_mono_polycurve = traits.construct_x_monotone_curve_2_object();
construct_x_mono_polycurve = traits.construct_x_monotone_curve_2_object(); auto ctr_cv = traits.construct_curve_2_object();
Polycurve_conic_traits_2::Construct_curve_2 construct_polycurve =
traits.construct_curve_2_object();
//create a curve //create a curve
Rat_point_2 ps1(1, 10); Rat_point_2 ps1(1, 10);
@ -399,12 +392,12 @@ bool check_compare_y_at_x_2()
Rat_point_2 ps2(10, 1); Rat_point_2 ps2(10, 1);
Rat_point_2 pmid2(15, 5); Rat_point_2 pmid2(15, 5);
Rat_point_2 pt2(20, 10); Rat_point_2 pt2(20, 10);
Conic_curve_2 c2(ps2, pmid2, pt2); Conic_curve_2 c2 = ctr_sub_cv(ps2, pmid2, pt2);
Conic_curve_2 c3(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE, Conic_curve_2 c3 = ctr_sub_cv(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE,
Conic_point_2(Algebraic(0), Algebraic(0)), Conic_point_2(Algebraic(0), Algebraic(0)),
Conic_point_2(Algebraic(3), Algebraic(9))); Conic_point_2(Algebraic(3), Algebraic(9)));
Conic_curve_2 c4(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE, Conic_curve_2 c4 = ctr_sub_cv(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE,
Conic_point_2(Algebraic(3), Algebraic(9)), Conic_point_2(Algebraic(3), Algebraic(9)),
Conic_point_2(Algebraic(5), Algebraic(25))); Conic_point_2(Algebraic(5), Algebraic(25)));
@ -415,10 +408,10 @@ bool check_compare_y_at_x_2()
//conic_curves_2.push_back(c3); //conic_curves_2.push_back(c3);
//conic_curves_2.push_back(c4); //conic_curves_2.push_back(c4);
Conic_x_monotone_curve_2 xc1(c1); Conic_x_monotone_curve_2 xc1 = ctr_sub_xcv(c1);
Conic_x_monotone_curve_2 xc2(c2); Conic_x_monotone_curve_2 xc2 = ctr_sub_xcv(c2);
Conic_x_monotone_curve_2 xc3(c3); Conic_x_monotone_curve_2 xc3 = ctr_sub_xcv(c3);
Conic_x_monotone_curve_2 xc4(c4); Conic_x_monotone_curve_2 xc4 = ctr_sub_xcv(c4);
std::vector<Conic_x_monotone_curve_2> xmono_conic_curves, xmono_conic_curves_2; std::vector<Conic_x_monotone_curve_2> xmono_conic_curves, xmono_conic_curves_2;
/* VERY IMPORTANT /* VERY IMPORTANT
@ -441,13 +434,13 @@ bool check_compare_y_at_x_2()
//construct poly-curve //construct poly-curve
Polycurve_conic_traits_2::Curve_2 conic_polycurve = Polycurve_conic_traits_2::Curve_2 conic_polycurve =
construct_polycurve(conic_curves.begin(), conic_curves.end()); ctr_cv(conic_curves.begin(), conic_curves.end());
//Polycurve_conic_traits_2::Curve_2 conic_polycurve_2 = //Polycurve_conic_traits_2::Curve_2 conic_polycurve_2 =
// construct_polycurve(conic_curves_2.begin(), conic_curves_2.end()); // ctr_cv(conic_curves_2.begin(), conic_curves_2.end());
//make x-monotone curve //make x-monotone curve
//Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc1 = //Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc1 =
// construct_x_monotone_curve_2(c1); // ctr_xcv(c1);
//create points //create points
Polycurve_conic_traits_2::Point_2 Polycurve_conic_traits_2::Point_2
@ -475,37 +468,33 @@ bool check_compare_y_at_x_2()
return true; return true;
} }
void check_are_mergable() void check_are_mergable() {
{ Conic_traits_2 sub_traits;
Polycurve_conic_traits_2 traits; Polycurve_conic_traits_2 traits(&sub_traits);
Polycurve_conic_traits_2::Construct_x_monotone_curve_2 auto ctr_sub_cv = sub_traits.construct_curve_2_object();
construct_x_monotone_curve_2 = traits.construct_x_monotone_curve_2_object(); auto ctr_xcv = traits.construct_x_monotone_curve_2_object();
Polycurve_conic_traits_2::Are_mergeable_2 are_mergeable_2 = auto are_mergeable_2 = traits.are_mergeable_2_object();
traits.are_mergeable_2_object();
//create a curve //create a curve
Rat_point_2 ps1(1, 10); Rat_point_2 ps1(1, 10);
Rat_point_2 pmid1(5, 4); Rat_point_2 pmid1(5, 4);
Rat_point_2 pt1(10, 1); Rat_point_2 pt1(10, 1);
Conic_curve_2 c1(ps1, pmid1, pt1); Conic_curve_2 c1 = ctr_sub_cv(ps1, pmid1, pt1);
Rat_point_2 ps2(10, 1); Rat_point_2 ps2(10, 1);
Rat_point_2 pmid2(15, 14); Rat_point_2 pmid2(15, 14);
Rat_point_2 pt2(20, 20); Rat_point_2 pt2(20, 20);
Conic_curve_2 c2(ps2, pmid2, pt2); Conic_curve_2 c2 = ctr_sub_cv(ps2, pmid2, pt2);
Rat_point_2 ps3(Rational(1,4), 4); Rat_point_2 ps3(Rational(1,4), 4);
Rat_point_2 pmid3(Rational(3,2), 2); Rat_point_2 pmid3(Rational(3,2), 2);
Rat_point_2 pt3(2, Rational(1,3)); Rat_point_2 pt3(2, Rational(1,3));
Conic_curve_2 c3(ps3, pmid3, pt3); Conic_curve_2 c3 = ctr_sub_cv(ps3, pmid3, pt3);
//construct x-monotone curve(compatible with polyline class) //construct x-monotone curve(compatible with polyline class)
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc1 = Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc1 = ctr_xcv(c1);
construct_x_monotone_curve_2(c1); Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc2 = ctr_xcv(c2);
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc2 = Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc3 = ctr_xcv(c3);
construct_x_monotone_curve_2(c2);
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc3 =
construct_x_monotone_curve_2(c3);
bool result = are_mergeable_2(polyline_xmc1, polyline_xmc2); bool result = are_mergeable_2(polyline_xmc1, polyline_xmc2);
std::cout << "Are_mergeable:: Mergeable x-monotone polycurves are Computed as: " std::cout << "Are_mergeable:: Mergeable x-monotone polycurves are Computed as: "
@ -516,29 +505,27 @@ void check_are_mergable()
<< ((result)? "Mergeable" : "Not-Mergeable") << std::endl; << ((result)? "Mergeable" : "Not-Mergeable") << std::endl;
} }
void check_merge_2() void check_merge_2() {
{ Conic_traits_2 sub_traits;
Polycurve_conic_traits_2 traits; Polycurve_conic_traits_2 traits(&sub_traits);
Polycurve_conic_traits_2::Construct_x_monotone_curve_2 auto ctr_sub_cv = sub_traits.construct_curve_2_object();
construct_x_monotone_curve_2 = traits.construct_x_monotone_curve_2_object(); auto ctr_xcv = traits.construct_x_monotone_curve_2_object();
Polycurve_conic_traits_2::Merge_2 merge_2 = traits.merge_2_object(); auto merge_2 = traits.merge_2_object();
//create a curve //create a curve
Rat_point_2 ps1(1, 10); Rat_point_2 ps1(1, 10);
Rat_point_2 pmid1(5, 4); Rat_point_2 pmid1(5, 4);
Rat_point_2 pt1(10, 1); Rat_point_2 pt1(10, 1);
Conic_curve_2 c1(ps1, pmid1, pt1); Conic_curve_2 c1 = ctr_sub_cv(ps1, pmid1, pt1);
Rat_point_2 ps2(10, 1); Rat_point_2 ps2(10, 1);
Rat_point_2 pmid2(15, 14); Rat_point_2 pmid2(15, 14);
Rat_point_2 pt2(20, 20); Rat_point_2 pt2(20, 20);
Conic_curve_2 c2(ps2, pmid2, pt2); Conic_curve_2 c2 = ctr_sub_cv(ps2, pmid2, pt2);
//construct x-monotone curve (compatible with polyline class) //construct x-monotone curve (compatible with polyline class)
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc1 = Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc1 = ctr_xcv(c1);
construct_x_monotone_curve_2(c1); Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc2 = ctr_xcv(c2);
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc2 =
construct_x_monotone_curve_2(c2);
Polycurve_conic_traits_2::X_monotone_curve_2 merged_xmc; Polycurve_conic_traits_2::X_monotone_curve_2 merged_xmc;
@ -547,101 +534,93 @@ void check_merge_2()
<< std:: endl; << std:: endl;
} }
void check_construct_opposite() void check_construct_opposite() {
{ Conic_traits_2 sub_traits;
Polycurve_conic_traits_2 traits; Polycurve_conic_traits_2 traits(&sub_traits);
Polycurve_conic_traits_2::Construct_x_monotone_curve_2 auto ctr_sub_cv = sub_traits.construct_curve_2_object();
construct_x_monotone_curve_2 = traits.construct_x_monotone_curve_2_object(); auto ctr_xcv = traits.construct_x_monotone_curve_2_object();
Polycurve_conic_traits_2::Construct_opposite_2 construct_opposite_2 = auto ctr_opposite = traits.construct_opposite_2_object();
traits.construct_opposite_2_object();
//create a curve //create a curve
Rat_point_2 ps1(1, 10); Rat_point_2 ps1(1, 10);
Rat_point_2 pmid1(5, 4); Rat_point_2 pmid1(5, 4);
Rat_point_2 pt1(10, 1); Rat_point_2 pt1(10, 1);
Conic_curve_2 c1(ps1, pmid1, pt1); Conic_curve_2 c1 = ctr_sub_cv(ps1, pmid1, pt1);
//construct x-monotone curve (compatible with polyline class) //construct x-monotone curve (compatible with polyline class)
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc1 = Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc1 =
construct_x_monotone_curve_2(c1); ctr_xcv(c1);
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_opposite_curve = Polycurve_conic_traits_2::X_monotone_curve_2 polyline_opposite_curve =
construct_opposite_2(polyline_xmc1); ctr_opposite(polyline_xmc1);
std::cout<< "Construct_opposite_2:: Opposite curve created"; std::cout<< "Construct_opposite_2:: Opposite curve created";
} }
void check_compare_y_at_x_right() void check_compare_y_at_x_right() {
{ Conic_traits_2 sub_traits;
Polycurve_conic_traits_2 traits; Polycurve_conic_traits_2 traits(&sub_traits);
Polycurve_conic_traits_2::Construct_x_monotone_curve_2 auto ctr_sub_cv = sub_traits.construct_curve_2_object();
construct_x_monotone_curve_2 = traits.construct_x_monotone_curve_2_object(); auto ctr_xcv = traits.construct_x_monotone_curve_2_object();
Polycurve_conic_traits_2::Compare_y_at_x_right_2 cmp_y_at_x_right_2 = auto cmp_y_at_x_right = traits.compare_y_at_x_right_2_object();
traits.compare_y_at_x_right_2_object();
//create constructing curves //create constructing curves
Rat_point_2 ps2(1, 10); Rat_point_2 ps2(1, 10);
Rat_point_2 pmid2(5, 4); Rat_point_2 pmid2(5, 4);
Rat_point_2 pt2(10, 1); Rat_point_2 pt2(10, 1);
Conic_curve_2 c1(ps2, pmid2, pt2); Conic_curve_2 c1 = ctr_sub_cv(ps2, pmid2, pt2);
Rat_point_2 ps3(10, 1); Rat_point_2 ps3(10, 1);
Rat_point_2 pmid3(5, 4); Rat_point_2 pmid3(5, 4);
Rat_point_2 pt3(1, 10); Rat_point_2 pt3(1, 10);
Conic_curve_2 c2(ps3, pmid3, pt3); Conic_curve_2 c2 = ctr_sub_cv(ps3, pmid3, pt3);
//construct x-monotone curve (compatible with polyline class) //construct x-monotone curve (compatible with polyline class)
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc1 = Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc1 = ctr_xcv(c1);
construct_x_monotone_curve_2(c1); Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc2 = ctr_xcv(c2);
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc2 =
construct_x_monotone_curve_2(c2);
Polycurve_conic_traits_2::Point_2 intersection_point = Polycurve_conic_traits_2::Point_2 intersection_point =
Polycurve_conic_traits_2::Point_2(5,4); Polycurve_conic_traits_2::Point_2(5,4);
CGAL::Comparison_result result; CGAL::Comparison_result result;
result = cmp_y_at_x_right_2(polyline_xmc1, polyline_xmc2, intersection_point); result = cmp_y_at_x_right(polyline_xmc1, polyline_xmc2, intersection_point);
std::cout << "Compare_y_at_x_right:: Expected Answer: equal, Computed answer: " std::cout << "Compare_y_at_x_right:: Expected Answer: equal, Computed answer: "
<< (result == CGAL::SMALLER ? "smaller": << (result == CGAL::SMALLER ? "smaller":
(result == CGAL::LARGER ? "Larger" : "equal")) << std::endl; (result == CGAL::LARGER ? "Larger" : "equal")) << std::endl;
} }
void check_compare_y_at_x_left() void check_compare_y_at_x_left() {
{ Conic_traits_2 sub_traits;
Polycurve_conic_traits_2 traits; Polycurve_conic_traits_2 traits(&sub_traits);
Polycurve_conic_traits_2::Construct_x_monotone_curve_2 auto ctr_sub_cv = sub_traits.construct_curve_2_object();
construct_x_monotone_curve_2 = traits.construct_x_monotone_curve_2_object(); auto ctr_xcv = traits.construct_x_monotone_curve_2_object();
Polycurve_conic_traits_2::Compare_y_at_x_left_2 cmp_y_at_x_left_2 = auto cmp_y_at_x_left = traits.compare_y_at_x_left_2_object();
traits.compare_y_at_x_left_2_object();
//create constructing curves //create constructing curves
Rat_point_2 ps2(1, 10); Rat_point_2 ps2(1, 10);
Rat_point_2 pmid2(5, 4); Rat_point_2 pmid2(5, 4);
Rat_point_2 pt2(10, 1); Rat_point_2 pt2(10, 1);
Conic_curve_2 c1(ps2, pmid2, pt2); Conic_curve_2 c1 = ctr_sub_cv(ps2, pmid2, pt2);
Rat_point_2 ps3(10, 1); Rat_point_2 ps3(10, 1);
Rat_point_2 pmid3(5, 4); Rat_point_2 pmid3(5, 4);
Rat_point_2 pt3(1, 10); Rat_point_2 pt3(1, 10);
Conic_curve_2 c2(ps3, pmid3, pt3); Conic_curve_2 c2 = ctr_sub_cv(ps3, pmid3, pt3);
//construct x-monotone curve(compatible with polyline class) //construct x-monotone curve(compatible with polyline class)
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc1 = Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc1 = ctr_xcv(c1);
construct_x_monotone_curve_2(c1); Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc2 = ctr_xcv(c2);
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc2 =
construct_x_monotone_curve_2(c2);
Polycurve_conic_traits_2::Point_2 intersection_point = Polycurve_conic_traits_2::Point_2 intersection_point =
Polycurve_conic_traits_2::Point_2(5,4); Polycurve_conic_traits_2::Point_2(5,4);
CGAL::Comparison_result result; CGAL::Comparison_result result;
result = cmp_y_at_x_left_2(polyline_xmc1, polyline_xmc2, intersection_point); result = cmp_y_at_x_left(polyline_xmc1, polyline_xmc2, intersection_point);
std::cout << "Compare_y_at_x_left:: Expected Answer: equal, Computed answer: " std::cout << "Compare_y_at_x_left:: Expected Answer: equal, Computed answer: "
<< (result == CGAL::SMALLER ? "smaller": << (result == CGAL::SMALLER ? "smaller":
(result == CGAL::LARGER ? "Larger" : "equal")) << std::endl; (result == CGAL::LARGER ? "Larger" : "equal")) << std::endl;
} }
template <typename GeometryTraits> template <typename GeometryTraits>
void check_make_x_monotne_curve(const typename GeometryTraits::Curve_2& c1) void check_make_x_monotne_curve(const typename GeometryTraits::Curve_2& c1) {
{
typename GeometryTraits::Point_2 Point_2; typename GeometryTraits::Point_2 Point_2;
typename GeometryTraits::X_monotone_curve_2 X_monotone_curve_2; typename GeometryTraits::X_monotone_curve_2 X_monotone_curve_2;
typedef boost::variant<Point_2, X_monotone_curve_2> Make_x_monotone_result; typedef boost::variant<Point_2, X_monotone_curve_2> Make_x_monotone_result;
@ -662,8 +641,7 @@ void check_make_x_monotne_curve(const typename GeometryTraits::Curve_2& c1)
} }
template<typename Curve, typename Segment> template<typename Curve, typename Segment>
void check_push_front(Curve base_curve, Segment curve_tobe_pushed) void check_push_front(Curve base_curve, Segment curve_tobe_pushed) {
{
Polycurve_conic_traits_2 traits; Polycurve_conic_traits_2 traits;
std::cout << "Base curve: " << base_curve << std::endl; std::cout << "Base curve: " << base_curve << std::endl;
@ -674,8 +652,7 @@ void check_push_front(Curve base_curve, Segment curve_tobe_pushed)
} }
template<typename Curve, typename Segment> template<typename Curve, typename Segment>
void check_push_back(Curve& base_curve, Segment curve_tobe_pushed) void check_push_back(Curve& base_curve, Segment curve_tobe_pushed) {
{
Polycurve_conic_traits_2 traits; Polycurve_conic_traits_2 traits;
std::cout << "Base curve: " << base_curve << std::endl; std::cout << "Base curve: " << base_curve << std::endl;
@ -687,8 +664,7 @@ void check_push_back(Curve& base_curve, Segment curve_tobe_pushed)
} }
template<typename Segment> template<typename Segment>
void check_compare_x_2(const Segment& seg1, const Segment& seg2) void check_compare_x_2(const Segment& seg1, const Segment& seg2) {
{
Polycurve_conic_traits_2 traits; Polycurve_conic_traits_2 traits;
CGAL::Comparison_result result; CGAL::Comparison_result result;
@ -706,16 +682,14 @@ void check_compare_x_2(const Segment& seg1, const Segment& seg2)
} }
template<typename Curve> template<typename Curve>
void check_compare_points(Curve& cv) void check_compare_points(Curve& cv) {
{
Polycurve_conic_traits_2 traits; Polycurve_conic_traits_2 traits;
CGAL::Arr_parameter_space result = CGAL::Arr_parameter_space result =
traits.parameter_space_in_x_2_object()(cv, CGAL::ARR_MAX_END); traits.parameter_space_in_x_2_object()(cv, CGAL::ARR_MAX_END);
} }
template <typename curve> template <typename curve>
void check_trim(curve& xcv, int sx, int sy, int tx, int ty) void check_trim(curve& xcv, int sx, int sy, int tx, int ty) {
{
Polycurve_conic_traits_2 traits; Polycurve_conic_traits_2 traits;
// Conic_point_2 source(Algebraic(-16), Algebraic(-4)); // Conic_point_2 source(Algebraic(-16), Algebraic(-4));
@ -731,39 +705,41 @@ void check_trim(curve& xcv, int sx, int sy, int tx, int ty)
} }
int main(int argc, char* argv[]) int main(int argc, char* argv[]) {
{ Conic_traits_2 sub_traits;
Polycurve_conic_traits_2 traits; Polycurve_conic_traits_2 traits(&sub_traits);
auto ctr_sub_cv = sub_traits.construct_curve_2_object();
auto ctr_sub_xcv = sub_traits.construct_x_monotone_curve_2_object();
//polycurve constructors //polycurve constructors
auto construct_x_mono_polycurve = traits.construct_x_monotone_curve_2_object(); auto ctr_xcv = traits.construct_x_monotone_curve_2_object();
auto construct_polycurve = traits.construct_curve_2_object(); auto ctr_cv = traits.construct_curve_2_object();
//create a curve //create a curve
Conic_curve_2 c3(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE, Conic_curve_2 c3 = ctr_sub_cv(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE,
Conic_point_2(Algebraic(0), Algebraic(0)), Conic_point_2(Algebraic(0), Algebraic(0)),
Conic_point_2(Algebraic(3), Algebraic(9))); Conic_point_2(Algebraic(3), Algebraic(9)));
Conic_curve_2 c4(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE, Conic_curve_2 c4 = ctr_sub_cv(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE,
Conic_point_2(Algebraic(3), Algebraic(9)), Conic_point_2(Algebraic(3), Algebraic(9)),
Conic_point_2(Algebraic(5), Algebraic(25))); Conic_point_2(Algebraic(5), Algebraic(25)));
Conic_curve_2 c5(0,1,0,1,0,0, CGAL::COUNTERCLOCKWISE, Conic_curve_2 c5 = ctr_sub_cv(0,1,0,1,0,0, CGAL::COUNTERCLOCKWISE,
Conic_point_2(Algebraic(-25), Algebraic(-5)), Conic_point_2(Algebraic(-25), Algebraic(-5)),
Conic_point_2(Algebraic(0), Algebraic(0))); Conic_point_2(Algebraic(0), Algebraic(0)));
Conic_curve_2 c6(1,1,0,6,-26,162,CGAL::COUNTERCLOCKWISE, Conic_curve_2 c6 = ctr_sub_cv(1,1,0,6,-26,162,CGAL::COUNTERCLOCKWISE,
Conic_point_2(Algebraic(-7), Algebraic(13)), Conic_point_2(Algebraic(-7), Algebraic(13)),
Conic_point_2(Algebraic(-3), Algebraic(9))); Conic_point_2(Algebraic(-3), Algebraic(9)));
Conic_curve_2 c7(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE, Conic_curve_2 c7 = ctr_sub_cv(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE,
Conic_point_2(Algebraic(-3), Algebraic(9)), Conic_point_2(Algebraic(-3), Algebraic(9)),
Conic_point_2(Algebraic(0), Algebraic(0))); Conic_point_2(Algebraic(0), Algebraic(0)));
Conic_curve_2 c8(0,1,0,-1,0,0, CGAL::COUNTERCLOCKWISE, Conic_curve_2 c8 = ctr_sub_cv(0,1,0,-1,0,0, CGAL::COUNTERCLOCKWISE,
Conic_point_2(Algebraic(0), Algebraic(0)), Conic_point_2(Algebraic(0), Algebraic(0)),
Conic_point_2(Algebraic(4), Algebraic(-2))); Conic_point_2(Algebraic(4), Algebraic(-2)));
Conic_curve_2 c9(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE, Conic_curve_2 c9 = ctr_sub_cv(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE,
Conic_point_2(Algebraic(-5), Algebraic(25)), Conic_point_2(Algebraic(-5), Algebraic(25)),
Conic_point_2(Algebraic(5), Algebraic(25))); Conic_point_2(Algebraic(5), Algebraic(25)));
Conic_curve_2 c10(58, 72, -48, 0, 0, -360); Conic_curve_2 c10 = ctr_sub_cv(58, 72, -48, 0, 0, -360);
//This vector is used to store curves that will be used to create polycurve //This vector is used to store curves that will be used to create polycurve
std::vector<Conic_curve_2> conic_curves; std::vector<Conic_curve_2> conic_curves;
@ -771,12 +747,12 @@ int main(int argc, char* argv[])
//construct poly-curve //construct poly-curve
Polycurve_conic_traits_2::Curve_2 conic_polycurve = Polycurve_conic_traits_2::Curve_2 conic_polycurve =
construct_polycurve(conic_curves.begin(), conic_curves.end()); ctr_cv(conic_curves.begin(), conic_curves.end());
Conic_curve_2 c11(0,1,0,-1,0,0,CGAL::COUNTERCLOCKWISE, Conic_curve_2 c11 = ctr_sub_cv(0,1,0,-1,0,0,CGAL::COUNTERCLOCKWISE,
Conic_point_2(Algebraic(25), Algebraic(-5)), Conic_point_2(Algebraic(25), Algebraic(-5)),
Conic_point_2(Algebraic(0), Algebraic(0))); Conic_point_2(Algebraic(0), Algebraic(0)));
Conic_curve_2 c12(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE, Conic_curve_2 c12 = ctr_sub_cv(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE,
Conic_point_2(Algebraic(0), Algebraic(0)), Conic_point_2(Algebraic(0), Algebraic(0)),
Conic_point_2(Algebraic(5), Algebraic(25))); Conic_point_2(Algebraic(5), Algebraic(25)));
conic_curves.clear(); conic_curves.clear();
@ -785,7 +761,7 @@ int main(int argc, char* argv[])
//construct poly-curve //construct poly-curve
Polycurve_conic_traits_2::Curve_2 conic_polycurve_2 = Polycurve_conic_traits_2::Curve_2 conic_polycurve_2 =
construct_polycurve(conic_curves.begin(), conic_curves.end()); ctr_cv(conic_curves.begin(), conic_curves.end());
/* VERY IMPORTANT /* VERY IMPORTANT
* For efficiency reasons, we recommend users not to construct * For efficiency reasons, we recommend users not to construct
@ -793,13 +769,12 @@ int main(int argc, char* argv[])
* functor supplied by the conic-arc traits class to convert conic curves * functor supplied by the conic-arc traits class to convert conic curves
* to x-monotone curves. * to x-monotone curves.
*/ */
Conic_x_monotone_curve_2 xc3(c3); Conic_x_monotone_curve_2 xc3 = ctr_sub_xcv(c3);
Conic_x_monotone_curve_2 xc4(c4); Conic_x_monotone_curve_2 xc4 = ctr_sub_xcv(c4);
Conic_x_monotone_curve_2 xc5(c5); Conic_x_monotone_curve_2 xc5 = ctr_sub_xcv(c5);
Conic_x_monotone_curve_2 xc6(c6); Conic_x_monotone_curve_2 xc6 = ctr_sub_xcv(c6);
Conic_x_monotone_curve_2 xc7(c7); Conic_x_monotone_curve_2 xc7 = ctr_sub_xcv(c7);
Conic_x_monotone_curve_2 xc8(c8); Conic_x_monotone_curve_2 xc8 = ctr_sub_xcv(c8);
//This vector is used to store curves that will be used to create //This vector is used to store curves that will be used to create
//X-monotone-polycurve //X-monotone-polycurve
@ -808,11 +783,9 @@ int main(int argc, char* argv[])
xmono_conic_curves_2.push_back(xc3); xmono_conic_curves_2.push_back(xc3);
xmono_conic_curves_2.push_back(xc4); xmono_conic_curves_2.push_back(xc4);
//construct x-monotone poly-curve //construct x-monotone poly-curve
Pc_x_monotone_curve_2 conic_x_mono_polycurve_1 = Pc_x_monotone_curve_2 conic_x_mono_polycurve_1 =
construct_x_mono_polycurve(xmono_conic_curves_2.begin(), ctr_xcv(xmono_conic_curves_2.begin(), xmono_conic_curves_2.end());
xmono_conic_curves_2.end());
xmono_conic_curves_2.clear(); xmono_conic_curves_2.clear();
xmono_conic_curves_2.push_back(xc6); xmono_conic_curves_2.push_back(xc6);
@ -820,15 +793,13 @@ int main(int argc, char* argv[])
xmono_conic_curves_2.push_back(xc8); xmono_conic_curves_2.push_back(xc8);
//construct x-monotone poly-curve //construct x-monotone poly-curve
Pc_x_monotone_curve_2 conic_x_mono_polycurve_2 = Pc_x_monotone_curve_2 conic_x_mono_polycurve_2 =
construct_x_mono_polycurve(xmono_conic_curves_2.begin(), ctr_xcv(xmono_conic_curves_2.begin(), xmono_conic_curves_2.end());
xmono_conic_curves_2.end());
xmono_conic_curves_2.clear(); xmono_conic_curves_2.clear();
xmono_conic_curves_2.push_back(xc5); xmono_conic_curves_2.push_back(xc5);
Pc_x_monotone_curve_2 x_polycurve_push = Pc_x_monotone_curve_2 x_polycurve_push =
construct_x_mono_polycurve(xmono_conic_curves_2.begin(), ctr_xcv(xmono_conic_curves_2.begin(), xmono_conic_curves_2.end());
xmono_conic_curves_2.end());
Polycurve_conic_traits_2::X_monotone_subcurve_2 xcurve_push = Polycurve_conic_traits_2::X_monotone_subcurve_2 xcurve_push =
Polycurve_conic_traits_2::X_monotone_subcurve_2(c5); Polycurve_conic_traits_2::X_monotone_subcurve_2(c5);
//traits.construct_x_monotone_curve_2_object()(c5); //traits.construct_x_monotone_curve_2_object()(c5);
@ -837,28 +808,27 @@ int main(int argc, char* argv[])
xmono_conic_curves_2.push_back(xc3); xmono_conic_curves_2.push_back(xc3);
xmono_conic_curves_2.push_back(xc4); xmono_conic_curves_2.push_back(xc4);
Pc_x_monotone_curve_2 base_curve = Pc_x_monotone_curve_2 base_curve =
construct_x_mono_polycurve(xmono_conic_curves_2.begin(), ctr_xcv(xmono_conic_curves_2.begin(), xmono_conic_curves_2.end());
xmono_conic_curves_2.end());
//curves for push_back //curves for push_back
Conic_curve_2 c13(1,1,0,-50,12,660,CGAL::COUNTERCLOCKWISE, Conic_curve_2 c13 = ctr_sub_cv(1,1,0,-50,12,660,CGAL::COUNTERCLOCKWISE,
Conic_point_2(Algebraic(25), Algebraic(-7)), Conic_point_2(Algebraic(25), Algebraic(-7)),
Conic_point_2(Algebraic(25), Algebraic(-5))); Conic_point_2(Algebraic(25), Algebraic(-5)));
Conic_curve_2 c14(0,1,0,-1,0,0,CGAL::COUNTERCLOCKWISE, Conic_curve_2 c14 = ctr_sub_cv(0,1,0,-1,0,0,CGAL::COUNTERCLOCKWISE,
Conic_point_2(Algebraic(25), Algebraic(-5)), Conic_point_2(Algebraic(25), Algebraic(-5)),
Conic_point_2(Algebraic(0), Algebraic(0))); Conic_point_2(Algebraic(0), Algebraic(0)));
Conic_curve_2 c15(-1,0,0,0,1,0,CGAL::COUNTERCLOCKWISE, Conic_curve_2 c15 = ctr_sub_cv(-1,0,0,0,1,0,CGAL::COUNTERCLOCKWISE,
Conic_point_2(Algebraic(0), Algebraic(0)), Conic_point_2(Algebraic(0), Algebraic(0)),
Conic_point_2(Algebraic(5), Algebraic(25))); Conic_point_2(Algebraic(5), Algebraic(25)));
conic_curves.clear(); conic_curves.clear();
conic_curves.push_back(c13); conic_curves.push_back(c13);
conic_curves.push_back(c14); conic_curves.push_back(c14);
Polycurve_conic_traits_2::Curve_2 base_curve_push_back = Polycurve_conic_traits_2::Curve_2 base_curve_push_back =
construct_polycurve(conic_curves.begin(), conic_curves.end()); ctr_cv(conic_curves.begin(), conic_curves.end());
conic_curves.push_back(c15); conic_curves.push_back(c15);
Polycurve_conic_traits_2::Curve_2 Expected_push_back_result = Polycurve_conic_traits_2::Curve_2 Expected_push_back_result =
construct_polycurve(conic_curves.begin(), conic_curves.end()); ctr_cv(conic_curves.begin(), conic_curves.end());
// //checking the orientattion consistency // //checking the orientattion consistency
// Conic_curve_2 c21(0,1,0,1,0,0,CGAL::CLOCKWISE, // Conic_curve_2 c21(0,1,0,1,0,0,CGAL::CLOCKWISE,
@ -873,7 +843,7 @@ int main(int argc, char* argv[])
// xmono_conic_curves_2.push_back(xc20); // xmono_conic_curves_2.push_back(xc20);
// xmono_conic_curves_2.push_back(xc21); // xmono_conic_curves_2.push_back(xc21);
// Pc_x_monotone_curve_2 eric_polycurve = // Pc_x_monotone_curve_2 eric_polycurve =
// construct_x_mono_polycurve(xmono_conic_curves_2.begin(), // ctr_xcv(xmono_conic_curves_2.begin(),
// xmono_conic_curves_2.end()); // xmono_conic_curves_2.end());
// std::cout << "the polycurve is: " << eric_polycurve << std::endl; // std::cout << "the polycurve is: " << eric_polycurve << std::endl;

View File

@ -1432,6 +1432,106 @@ add_face_to_border(typename boost::graph_traits<Graph>::halfedge_descriptor h1,
return newh; return newh;
} }
/**
* \returns `true` if `e` satisfies the *link condition* \cgalCite{degn-tpec-98}, which guarantees that the surface is also 2-manifold after the edge collapse.
*/
template<typename Graph>
bool
does_satisfy_link_condition(typename boost::graph_traits<Graph>::edge_descriptor e,
const Graph& g)
{
typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor;
typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor;
typedef CGAL::Halfedge_around_source_iterator<Graph> out_edge_iterator;
halfedge_descriptor v0_v1 = halfedge(e,g);
halfedge_descriptor v1_v0 = opposite(v0_v1,g);
vertex_descriptor v0 = target(v1_v0,g), v1 = target(v0_v1,g);
vertex_descriptor vL = target(next(v0_v1,g),g);
vertex_descriptor vR = target(next(v1_v0,g),g);
out_edge_iterator eb1, ee1 ;
out_edge_iterator eb2, ee2 ;
// The following loop checks the link condition for v0_v1.
// Specifically, that for every vertex 'k' adjacent to both 'p and 'q', 'pkq' is a face of the mesh.
//
for ( boost::tie(eb1,ee1) = halfedges_around_source(v0,g) ; eb1 != ee1 ; ++ eb1 )
{
halfedge_descriptor v0_k = *eb1;
if ( v0_k != v0_v1 )
{
vertex_descriptor k = target(v0_k,g);
for ( boost::tie(eb2,ee2) = halfedges_around_source(k,g) ; eb2 != ee2 ; ++ eb2 )
{
halfedge_descriptor k_v1 = *eb2;
if ( target(k_v1,g) == v1 )
{
// At this point we know p-q-k are connected and we need to determine if this triangle is a face of the mesh.
//
// Since the mesh is known to be triangular there are at most two faces sharing the edge p-q.
//
// If p->q is NOT a border edge, the top face is p->q->t where t is target(next(p->q))
// If q->p is NOT a border edge, the bottom face is q->p->b where b is target(next(q->p))
//
// If k is either t or b then p-q-k *might* be a face of the mesh. It won't be if k==t but p->q is border
// or k==b but q->b is a border (because in that case even though there exists triangles p->q->t (or q->p->b)
// they are holes, not faces)
//
bool lIsFace = ( vL == k && (! is_border(v0_v1,g)) )
|| ( vR == k && (! is_border(v1_v0,g)) ) ;
if ( !lIsFace )
{
// CGAL_ECMS_TRACE(3," k=V" << get(Vertex_index_map,k) << " IS NOT in a face with p-q. NON-COLLAPSABLE edge." ) ;
return false ;
}
else
{
//CGAL_ECMS_TRACE(4," k=V" << get(Vertex_index_map,k) << " is in a face with p-q") ;
}
}
}
}
}
// detect isolated triangle (or triangle attached to a mesh with non-manifold vertices)
if (!is_border(v0_v1,g) && is_border(opposite(next(v0_v1,g), g), g)
&& is_border(opposite(prev(v0_v1,g), g), g) ) return false;
if (!is_border(v1_v0,g) && is_border(opposite(next(v1_v0,g), g), g)
&& is_border(opposite(prev(v1_v0,g), g), g) ) return false;
if ( !is_border(v0_v1,g) && !is_border(v1_v0,g) )
{
if ( is_border(v0,g) && is_border(v1,g) )
{
//CGAL_ECMS_TRACE(3," both p and q are boundary vertices but p-q is not. NON-COLLAPSABLE edge." ) ;
return false ;
}
else
{
if ( is_tetrahedron(v0_v1,g) )
{
//CGAL_ECMS_TRACE(3," p-q belongs to a tetrahedron. NON-COLLAPSABLE edge." ) ;
return false ;
}
if ( next(v0_v1, g) == opposite(prev(v1_v0, g), g) &&
prev(v0_v1, g) == opposite(next(v1_v0, g), g) )
{
//CGAL_ECMS_TRACE(3," degenerate volume." ) ;
return false ;
}
}
}
return true ;
}
/** /**
* collapses an edge in a graph. * collapses an edge in a graph.
@ -1464,6 +1564,7 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor e,
typedef typename Traits::halfedge_descriptor halfedge_descriptor; typedef typename Traits::halfedge_descriptor halfedge_descriptor;
CGAL_precondition(is_valid_edge_descriptor(e, g)); CGAL_precondition(is_valid_edge_descriptor(e, g));
CGAL_precondition(does_satisfy_link_condition(e,g));
halfedge_descriptor pq = halfedge(e,g); halfedge_descriptor pq = halfedge(e,g);
halfedge_descriptor qp = opposite(pq, g); halfedge_descriptor qp = opposite(pq, g);
@ -1584,6 +1685,7 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
typedef typename Traits::halfedge_descriptor halfedge_descriptor; typedef typename Traits::halfedge_descriptor halfedge_descriptor;
CGAL_precondition(is_valid_edge_descriptor(v0v1, g)); CGAL_precondition(is_valid_edge_descriptor(v0v1, g));
CGAL_precondition(does_satisfy_link_condition(v0v1,g));
CGAL_precondition(!get(Edge_is_constrained_map, v0v1)); CGAL_precondition(!get(Edge_is_constrained_map, v0v1));
halfedge_descriptor pq = halfedge(v0v1,g); halfedge_descriptor pq = halfedge(v0v1,g);
@ -1754,109 +1856,6 @@ flip_edge(typename boost::graph_traits<Graph>::halfedge_descriptor h,
set_halfedge(foh,oh,g); set_halfedge(foh,oh,g);
} }
/**
* \returns `true` if `e` satisfies the *link condition* \cgalCite{degn-tpec-98}, which guarantees that the surface is also 2-manifold after the edge collapse.
*/
template<typename Graph>
bool
does_satisfy_link_condition(typename boost::graph_traits<Graph>::edge_descriptor e,
const Graph& g)
{
typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor;
typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor;
typedef CGAL::Halfedge_around_source_iterator<Graph> out_edge_iterator;
CGAL_precondition(is_valid_edge_descriptor(e, g));
halfedge_descriptor v0_v1 = halfedge(e,g);
halfedge_descriptor v1_v0 = opposite(v0_v1,g);
vertex_descriptor v0 = target(v1_v0,g), v1 = target(v0_v1,g);
vertex_descriptor vL = target(next(v0_v1,g),g);
vertex_descriptor vR = target(next(v1_v0,g),g);
out_edge_iterator eb1, ee1 ;
out_edge_iterator eb2, ee2 ;
// The following loop checks the link condition for v0_v1.
// Specifically, that for every vertex 'k' adjacent to both 'p and 'q', 'pkq' is a face of the mesh.
//
for ( boost::tie(eb1,ee1) = halfedges_around_source(v0,g) ; eb1 != ee1 ; ++ eb1 )
{
halfedge_descriptor v0_k = *eb1;
if ( v0_k != v0_v1 )
{
vertex_descriptor k = target(v0_k,g);
for ( boost::tie(eb2,ee2) = halfedges_around_source(k,g) ; eb2 != ee2 ; ++ eb2 )
{
halfedge_descriptor k_v1 = *eb2;
if ( target(k_v1,g) == v1 )
{
// At this point we know p-q-k are connected and we need to determine if this triangle is a face of the mesh.
//
// Since the mesh is known to be triangular there are at most two faces sharing the edge p-q.
//
// If p->q is NOT a border edge, the top face is p->q->t where t is target(next(p->q))
// If q->p is NOT a border edge, the bottom face is q->p->b where b is target(next(q->p))
//
// If k is either t or b then p-q-k *might* be a face of the mesh. It won't be if k==t but p->q is border
// or k==b but q->b is a border (because in that case even though there exists triangles p->q->t (or q->p->b)
// they are holes, not faces)
//
bool lIsFace = ( vL == k && (! is_border(v0_v1,g)) )
|| ( vR == k && (! is_border(v1_v0,g)) ) ;
if ( !lIsFace )
{
// CGAL_ECMS_TRACE(3," k=V" << get(Vertex_index_map,k) << " IS NOT in a face with p-q. NON-COLLAPSABLE edge." ) ;
return false ;
}
else
{
//CGAL_ECMS_TRACE(4," k=V" << get(Vertex_index_map,k) << " is in a face with p-q") ;
}
}
}
}
}
// detect isolated triangle (or triangle attached to a mesh with non-manifold vertices)
if (!is_border(v0_v1,g) && is_border(opposite(next(v0_v1,g), g), g)
&& is_border(opposite(prev(v0_v1,g), g), g) ) return false;
if (!is_border(v1_v0,g) && is_border(opposite(next(v1_v0,g), g), g)
&& is_border(opposite(prev(v1_v0,g), g), g) ) return false;
if ( !is_border(v0_v1,g) && !is_border(v1_v0,g) )
{
if ( is_border(v0,g) && is_border(v1,g) )
{
//CGAL_ECMS_TRACE(3," both p and q are boundary vertices but p-q is not. NON-COLLAPSABLE edge." ) ;
return false ;
}
else
{
if ( is_tetrahedron(v0_v1,g) )
{
//CGAL_ECMS_TRACE(3," p-q belongs to a tetrahedron. NON-COLLAPSABLE edge." ) ;
return false ;
}
if ( next(v0_v1, g) == opposite(prev(v1_v0, g), g) &&
prev(v0_v1, g) == opposite(next(v1_v0, g), g) )
{
//CGAL_ECMS_TRACE(3," degenerate volume." ) ;
return false ;
}
}
}
return true ;
}
#ifndef CGAL_NO_DEPRECATED_CODE #ifndef CGAL_NO_DEPRECATED_CODE
/// \cond SKIP_IN_MANUAL /// \cond SKIP_IN_MANUAL
template<typename Graph> template<typename Graph>

View File

@ -213,16 +213,10 @@ public:
{} {}
#ifndef DOXYGEN_RUNNING #ifndef DOXYGEN_RUNNING
// design pattern: "safe bool"
// will be replaced by explicit operator bool with C++11
typedef void (Halfedge_around_source_iterator::*bool_type)() const;
void this_type_does_not_support_comparisons() const {} explicit operator bool() const
operator bool_type() const
{ {
return (! (this->base() == nullptr)) ? return (! (this->base() == nullptr));
&Halfedge_around_source_iterator::this_type_does_not_support_comparisons : 0;
} }
bool operator==( const Self& i) const { bool operator==( const Self& i) const {
@ -313,16 +307,10 @@ public:
{} {}
#ifndef DOXYGEN_RUNNING #ifndef DOXYGEN_RUNNING
// design pattern: "safe bool"
// will be replaced by explicit operator bool with C++11
typedef void (Halfedge_around_target_iterator::*bool_type)() const;
void this_type_does_not_support_comparisons() const {} explicit operator bool() const
operator bool_type() const
{ {
return (! (this->base() == nullptr)) ? return (! (this->base() == nullptr));
&Halfedge_around_target_iterator::this_type_does_not_support_comparisons : 0;
} }
bool operator==( const Self& i) const { bool operator==( const Self& i) const {
@ -412,16 +400,9 @@ public:
pointer operator -> ( ) { return &pos; } pointer operator -> ( ) { return &pos; }
const value_type* operator -> ( ) const { return &pos; } const value_type* operator -> ( ) const { return &pos; }
// design pattern: "safe bool" explicit operator bool() const
// will be replaced by explicit operator bool with C++11
typedef void (Halfedge_around_face_iterator::*bool_type)() const;
void this_type_does_not_support_comparisons() const {}
operator bool_type() const
{ {
return (! (this->base() == nullptr)) ? return (! (this->base() == nullptr));
&Halfedge_around_face_iterator::this_type_does_not_support_comparisons : 0;
} }
bool operator==( const Self& i) const { bool operator==( const Self& i) const {
@ -522,16 +503,10 @@ public:
Halfedge_around_source_circulator(vertex_descriptor vd, const Graph& g) Halfedge_around_source_circulator(vertex_descriptor vd, const Graph& g)
: Halfedge_around_source_circulator::iterator_adaptor_(Halfedge_around_target_circulator<Graph>(halfedge(vd,g),g)), opp(g) : Halfedge_around_source_circulator::iterator_adaptor_(Halfedge_around_target_circulator<Graph>(halfedge(vd,g),g)), opp(g)
{} {}
// design pattern: "safe bool"
// will be replaced by explicit operator bool with C++11
typedef void (Halfedge_around_source_circulator::*bool_type)() const;
void this_type_does_not_support_comparisons() const {} explicit operator bool() const
operator bool_type() const
{ {
return (! (this->base_reference() == nullptr)) ? return (! (this->base_reference() == nullptr));
&Halfedge_around_source_circulator::this_type_does_not_support_comparisons : 0;
} }
bool operator== (void*) const bool operator== (void*) const
@ -539,6 +514,11 @@ public:
return this->base_reference() == nullptr; return this->base_reference() == nullptr;
} }
bool operator!= (void*) const
{
return this->base_reference() != nullptr;
}
private: private:
friend class boost::iterator_core_access; friend class boost::iterator_core_access;
typename boost::graph_traits<Graph>::halfedge_descriptor dereference() const { return opp(*this->base_reference()); } typename boost::graph_traits<Graph>::halfedge_descriptor dereference() const { return opp(*this->base_reference()); }
@ -580,16 +560,9 @@ public:
#ifndef DOXYGEN_RUNNING #ifndef DOXYGEN_RUNNING
typedef std::size_t size_type; typedef std::size_t size_type;
// design pattern: "safe bool" explicit operator bool() const
// will be replaced by explicit operator bool with C++11
typedef void (Face_around_target_circulator::*bool_type)() const;
void this_type_does_not_support_comparisons() const {}
operator bool_type() const
{ {
return (! (this->base_reference() == nullptr)) ? return (! (this->base_reference() == nullptr));
&Face_around_target_circulator::this_type_does_not_support_comparisons : 0;
} }
bool operator== (void*) const bool operator== (void*) const
@ -597,6 +570,11 @@ public:
return this->base_reference() == nullptr; return this->base_reference() == nullptr;
} }
bool operator!= (void*) const
{
return this->base_reference() != nullptr;
}
private: private:
friend class boost::iterator_core_access; friend class boost::iterator_core_access;
@ -654,17 +632,9 @@ public:
bool operator == ( const Self& other) const { return g == other.g && pos == other.pos; } bool operator == ( const Self& other) const { return g == other.g && pos == other.pos; }
bool operator != ( const Self& other) const { return g != other.g || pos != other.pos; } bool operator != ( const Self& other) const { return g != other.g || pos != other.pos; }
explicit operator bool() const
// design pattern: "safe bool"
// will be replaced by explicit operator bool with C++11
typedef void (Halfedge_around_target_circulator::*bool_type)() const;
void this_type_does_not_support_comparisons() const {}
operator bool_type() const
{ {
return (! (g == nullptr)) ? return (! (g == nullptr));
&Halfedge_around_target_circulator::this_type_does_not_support_comparisons : 0;
} }
@ -673,6 +643,11 @@ public:
return g == nullptr; return g == nullptr;
} }
bool operator!= (void* ) const
{
return g != nullptr;
}
Self& operator++() Self& operator++()
{ {
@ -751,17 +726,9 @@ public:
bool operator == ( const Self& other) const { return g == other.g && pos == other.pos; } bool operator == ( const Self& other) const { return g == other.g && pos == other.pos; }
bool operator != ( const Self& other) const { return g != other.g || pos != other.pos; } bool operator != ( const Self& other) const { return g != other.g || pos != other.pos; }
explicit operator bool() const
// design pattern: "safe bool"
// will be replaced by explicit operator bool with C++11
typedef void (Halfedge_around_face_circulator::*bool_type)() const;
void this_type_does_not_support_comparisons() const {}
operator bool_type() const
{ {
return (! (g == nullptr)) ? return (! (g == nullptr));
&Halfedge_around_face_circulator::this_type_does_not_support_comparisons : 0;
} }
bool operator== (void* ) const bool operator== (void* ) const
@ -769,6 +736,11 @@ public:
return g == nullptr; return g == nullptr;
} }
bool operator!= (void* ) const
{
return g != nullptr;
}
Self& operator++() Self& operator++()
{ {
CGAL_assertion(g != nullptr); CGAL_assertion(g != nullptr);
@ -1014,22 +986,22 @@ public:
{} {}
#ifndef DOXYGEN_RUNNING #ifndef DOXYGEN_RUNNING
// design pattern: "safe bool"
// will be replaced by explicit operator bool with C++11
typedef void (Vertex_around_face_circulator::*bool_type)() const;
void this_type_does_not_support_comparisons() const {} explicit operator bool() const
operator bool_type() const
{ {
return (! (this->base_reference() == nullptr)) ? return (! (this->base_reference() == nullptr));
&Vertex_around_face_circulator::this_type_does_not_support_comparisons : 0;
} }
bool operator== (void*) const bool operator== (void*) const
{ {
return this->base_reference()== nullptr; return this->base_reference()== nullptr;
} }
bool operator!= (void*) const
{
return this->base_reference()!= nullptr;
}
private: private:
friend class boost::iterator_core_access; friend class boost::iterator_core_access;
typename boost::graph_traits<Graph>::vertex_descriptor dereference() const { return fct(*this->base_reference()); } typename boost::graph_traits<Graph>::vertex_descriptor dereference() const { return fct(*this->base_reference()); }
@ -1068,16 +1040,10 @@ public:
{} {}
#ifndef DOXYGEN_RUNNING #ifndef DOXYGEN_RUNNING
// design pattern: "safe bool"
// will be replaced by explicit operator bool with C++11
typedef void (Vertex_around_face_iterator::*bool_type)() const;
void this_type_does_not_support_comparisons() const {} explicit operator bool() const
operator bool_type() const
{ {
return (! (this->base_reference() == nullptr)) ? return (! (this->base_reference() == nullptr));
&Vertex_around_face_iterator::this_type_does_not_support_comparisons : 0;
} }
bool operator== (void*) const bool operator== (void*) const
@ -1198,16 +1164,10 @@ public:
{} {}
#ifndef DOXYGEN_RUNNING #ifndef DOXYGEN_RUNNING
// design pattern: "safe bool"
// will be replaced by explicit operator bool with C++11
typedef void (Vertex_around_target_circulator::*bool_type)() const;
void this_type_does_not_support_comparisons() const {} explicit operator bool() const
operator bool_type() const
{ {
return (! (this->base_reference() == nullptr)) ? return (! (this->base_reference() == nullptr));
&Vertex_around_target_circulator::this_type_does_not_support_comparisons : 0;
} }
bool operator== (void*) const bool operator== (void*) const
@ -1215,6 +1175,11 @@ public:
return this->base_reference()== nullptr; return this->base_reference()== nullptr;
} }
bool operator!= (void*) const
{
return this->base_reference()!= nullptr;
}
private: private:
friend class boost::iterator_core_access; friend class boost::iterator_core_access;
typename boost::graph_traits<Graph>::vertex_descriptor dereference() const { return fct(*this->base_reference()); } typename boost::graph_traits<Graph>::vertex_descriptor dereference() const { return fct(*this->base_reference()); }
@ -1256,16 +1221,10 @@ public:
{} {}
#ifndef DOXYGEN_RUNNING #ifndef DOXYGEN_RUNNING
// design pattern: "safe bool"
// will be replaced by explicit operator bool with C++11
typedef void (Vertex_around_target_iterator::*bool_type)() const;
void this_type_does_not_support_comparisons() const {} explicit operator bool() const
operator bool_type() const
{ {
return (! (this->base_reference() == nullptr)) ? return (! (this->base_reference() == nullptr));
&Vertex_around_target_iterator::this_type_does_not_support_comparisons : 0;
} }
private: private:
friend class boost::iterator_core_access; friend class boost::iterator_core_access;
@ -1343,16 +1302,9 @@ public:
Out_edge_iterator(halfedge_descriptor h, const Graph& g, int n = 0) Out_edge_iterator(halfedge_descriptor h, const Graph& g, int n = 0)
: Out_edge_iterator::iterator_adaptor_(Halfedge_around_target_iterator<Graph>(h,g,(h==halfedge_descriptor())?1:n)), opp(g) {} : Out_edge_iterator::iterator_adaptor_(Halfedge_around_target_iterator<Graph>(h,g,(h==halfedge_descriptor())?1:n)), opp(g) {}
// design pattern: "safe bool" explicit operator bool() const
// will be replaced by explicit operator bool with C++11
typedef void (Out_edge_iterator::*bool_type)() const;
void this_type_does_not_support_comparisons() const {}
operator bool_type() const
{ {
return (! (this->base_reference() == nullptr)) ? return (! (this->base_reference() == nullptr));
&Out_edge_iterator::this_type_does_not_support_comparisons : 0;
} }
@ -1385,16 +1337,9 @@ public:
: In_edge_iterator::iterator_adaptor_(Halfedge_around_target_iterator<Graph>(h,g,(h==halfedge_descriptor())?1:n)), fct(g) : In_edge_iterator::iterator_adaptor_(Halfedge_around_target_iterator<Graph>(h,g,(h==halfedge_descriptor())?1:n)), fct(g)
{} {}
// design pattern: "safe bool" explicit operator bool() const
// will be replaced by explicit operator bool with C++11
typedef void (In_edge_iterator::*bool_type)() const;
void this_type_does_not_support_comparisons() const {}
operator bool_type() const
{ {
return (! (this->base_reference() == nullptr)) ? return (! (this->base_reference() == nullptr));
&In_edge_iterator::this_type_does_not_support_comparisons : 0;
} }
private: private:

View File

@ -337,7 +337,7 @@ why we highly recommend reading this section in order to learn what can be expec
each coordinate function. If you want to get more mathematical details about each coordinate each coordinate function. If you want to get more mathematical details about each coordinate
function as well as the complete history and theory behind barycentric coordinates, you should function as well as the complete history and theory behind barycentric coordinates, you should
read \cgalCite{cgal:bc:hs-gbcicg-17}. You can also read an overview read \cgalCite{cgal:bc:hs-gbcicg-17}. You can also read an overview
<a href="https://www.anisimovdmitry.com/assets/files/phd_thesis_anisimov.pdf">here</a> <a href="https://susi.usi.ch/usi/documents/318813">here</a>
(chapters 1 and 2). (chapters 1 and 2).
@ -563,7 +563,7 @@ After the normalization of these weights as before
\f$b_i = \frac{w_i}{W^{mv}}\qquad\f$ with \f$\qquad W^{mv} = \sum_{j=1}^n w_j\f$ \f$b_i = \frac{w_i}{W^{mv}}\qquad\f$ with \f$\qquad W^{mv} = \sum_{j=1}^n w_j\f$
</center> </center>
we obtain the max precision \f$O(n^2)\f$ algorithm. The max speed O(n) algorithm computes the we obtain the max precision \f$O(n^2)\f$ algorithm. The max speed \f$O(n)\f$ algorithm computes the
weights \f$w_i\f$ using the pseudocode from <a href="https://www.inf.usi.ch/hormann/nsfworkshop/presentations/Hormann.pdf">here</a>. weights \f$w_i\f$ using the pseudocode from <a href="https://www.inf.usi.ch/hormann/nsfworkshop/presentations/Hormann.pdf">here</a>.
These weights These weights
@ -584,7 +584,7 @@ one should be cautious when using the unnormalized mean value weights. In that c
The harmonic coordinates are computed by solving the Laplace equation The harmonic coordinates are computed by solving the Laplace equation
<center> <center>
\f$\Delta \boldsymbol{b} = \boldsymbol{0}\f$ \f$\Delta b = 0\f$
</center> </center>
subject to suitable Dirichlet boundary conditions. Harmonic coordinates are the only coordinates subject to suitable Dirichlet boundary conditions. Harmonic coordinates are the only coordinates

View File

@ -40,31 +40,30 @@ typedef Traits_2::Point_2 Point_2;
// Insert a conic arc as a polygon edge: Subdivide the arc into x-monotone // Insert a conic arc as a polygon edge: Subdivide the arc into x-monotone
// sub-arcs and append these sub-arcs as polygon edges. // sub-arcs and append these sub-arcs as polygon edges.
void append_conic_arc (Polygon_2& polygon, const Curve_2& arc) void append_conic_arc(Polygon_2& polygon, const Curve_2& arc) {
{
Conic_traits_2 traits; Conic_traits_2 traits;
std::list<CGAL::Object> objects; std::list<CGAL::Object> objects;
std::list<CGAL::Object>::iterator it;
X_monotone_curve_2 xarc; X_monotone_curve_2 xarc;
traits.make_x_monotone_2_object() (arc, std::back_inserter(objects)); traits.make_x_monotone_2_object() (arc, std::back_inserter(objects));
for (it = objects.begin(); it != objects.end(); ++it) for (auto it = objects.begin(); it != objects.end(); ++it) {
{
if (CGAL::assign (xarc, *it)) if (CGAL::assign (xarc, *it))
polygon.push_back (xarc); polygon.push_back (xarc);
} }
} }
int main () int main() {
{ Conic_traits_2 traits;
auto ctr_cv = traits.construct_curve_2_object();
// Construct a parabolic arc supported by a parabola: x^2 + 2y - 4 = 0, // Construct a parabolic arc supported by a parabola: x^2 + 2y - 4 = 0,
// and whose endpoints lie on the line y = 0: // and whose endpoints lie on the line y = 0:
Curve_2 parabola1 = Curve_2 (1, 0, 0, 0, 2, -4, CGAL::COUNTERCLOCKWISE, Curve_2 parabola1 = ctr_cv(1, 0, 0, 0, 2, -4, CGAL::COUNTERCLOCKWISE,
Point_2(2, 0), Point_2(-2, 0)); Point_2(2, 0), Point_2(-2, 0));
// Construct a parabolic arc supported by a parabola: x^2 - 2y - 4 = 0, // Construct a parabolic arc supported by a parabola: x^2 - 2y - 4 = 0,
// and whose endpoints lie on the line y = 0: // and whose endpoints lie on the line y = 0:
Curve_2 parabola2 = Curve_2 (1, 0, 0, 0, -2, -4, CGAL::COUNTERCLOCKWISE, Curve_2 parabola2 = ctr_cv(1, 0, 0, 0, -2, -4, CGAL::COUNTERCLOCKWISE,
Point_2(-2, 0), Point_2(2, 0)); Point_2(-2, 0), Point_2(2, 0));
// Construct a polygon from these two parabolic arcs. // Construct a polygon from these two parabolic arcs.
@ -74,7 +73,7 @@ int main ()
// Construct a polygon that corresponds to the ellipse: x^2 + 9y^2 - 9 = 0: // Construct a polygon that corresponds to the ellipse: x^2 + 9y^2 - 9 = 0:
Polygon_2 Q; Polygon_2 Q;
append_conic_arc (Q, Curve_2 (-1, -9, 0, 0, 0, 9)); append_conic_arc(Q, ctr_cv(-1, -9, 0, 0, 0, 9));
// Compute the intersection of the two polygons. // Compute the intersection of the two polygons.
std::list<Polygon_with_holes_2> res; std::list<Polygon_with_holes_2> res;
@ -84,7 +83,7 @@ int main ()
std::ostream_iterator<Polygon_with_holes_2>(std::cout, "\n")); std::ostream_iterator<Polygon_with_holes_2>(std::cout, "\n"));
std::cout << std::endl; std::cout << std::endl;
return (0); return 0;
} }
#endif #endif

View File

@ -17,19 +17,22 @@
#ifndef CGAL_DRAW_POLYGON_SET_2_H #ifndef CGAL_DRAW_POLYGON_SET_2_H
#define CGAL_DRAW_POLYGON_SET_2_H #define CGAL_DRAW_POLYGON_SET_2_H
#include <CGAL/draw_polygon_with_holes_2.h> #include <CGAL/Qt/Basic_viewer_qt.h>
#ifdef DOXYGEN_RUNNING #ifdef DOXYGEN_RUNNING
namespace CGAL { namespace CGAL {
/*! /*!
\ingroup PkgDrawPolygonSet2 * \ingroup PkgDrawPolygonSet2
*
opens a new window and draws `aps`, an instance of the `CGAL::Polygon_set_2` class. A call to this function is blocking, that is the program continues as soon as the user closes the window. This function requires `CGAL_Qt5`, and is only available if the macro `CGAL_USE_BASIC_VIEWER` is defined. * opens a new window and draws `aps`, an instance of the `CGAL::Polygon_set_2`
Linking with the cmake target `CGAL::CGAL_Basic_viewer` will link with `CGAL_Qt5` and add the definition `CGAL_USE_BASIC_VIEWER`. * class. A call to this function is blocking, that is the program continues as
\tparam PS an instance of the `CGAL::Polygon_set_2` class. * soon as the user closes the window. This function requires `CGAL_Qt5`, and is
\param aps the polygon set to draw. * only available if the macro `CGAL_USE_BASIC_VIEWER` is defined. Linking with
* the cmake target `CGAL::CGAL_Basic_viewer` will link with `CGAL_Qt5` and add
* the definition `CGAL_USE_BASIC_VIEWER`.
* \tparam PS an instance of the `CGAL::Polygon_set_2` class.
* \param aps the polygon set to draw.
*/ */
template<class PS> template<class PS>
void draw(const PS& aps); void draw(const PS& aps);
@ -38,35 +41,158 @@ void draw(const PS& aps);
#endif #endif
#ifdef CGAL_USE_BASIC_VIEWER #ifdef CGAL_USE_BASIC_VIEWER
#include <CGAL/Qt/init_ogl_context.h>
#include <CGAL/Polygon_set_2.h> #include <CGAL/Polygon_set_2.h>
namespace CGAL namespace CGAL {
{
template<class PS2> template <typename PolygonSet_2>
class SimplePolygonSet2ViewerQt : class Polygon_set_2_basic_viewer_qt : public Basic_viewer_qt {
public SimplePolygonWithHoles2ViewerQt<typename PS2::Polygon_with_holes_2> using Base = Basic_viewer_qt;
{ using Ps = PolygonSet_2;
typedef SimplePolygonWithHoles2ViewerQt<typename PS2::Polygon_with_holes_2> Base; using Pwh = typename Ps::Polygon_with_holes_2;
using Pgn = typename Ps::Polygon_2;
using Pnt = typename Pgn::Point_2;
public: public:
SimplePolygonSet2ViewerQt(QWidget* parent, const PS2& aps2, Polygon_set_2_basic_viewer_qt(QWidget* parent, const Ps& ps,
const char* title="Basic Polygon_set_2 Viewer") : const char* title = "Basic Polygon_set_2 Viewer",
Base(parent, title) bool draw_unbounded = false,
bool draw_vertices = false) :
Base(parent, title, draw_vertices),
m_ps(ps),
m_draw_unbounded(draw_unbounded)
{ {
std::vector<typename PS2::Polygon_with_holes_2> polygons; if (ps.is_empty()) return;
aps2.polygons_with_holes(std::back_inserter(polygons));
for (typename PS2::Polygon_with_holes_2& P: polygons) { // mimic the computation of Camera::pixelGLRatio()
Base::compute_elements(P); auto bbox = bounding_box();
CGAL::qglviewer::Vec minv(bbox.xmin(), bbox.ymin(), 0);
CGAL::qglviewer::Vec maxv(bbox.xmax(), bbox.ymax(), 0);
auto diameter = (maxv - minv).norm();
m_pixel_ratio = diameter / m_height;
}
/*! Intercept the resizing of the window.
*/
virtual void resizeGL(int width, int height) {
CGAL::QGLViewer::resizeGL(width, height);
m_width = width;
m_height = height;
CGAL::qglviewer::Vec p;
auto ratio = camera()->pixelGLRatio(p);
if (ratio != m_pixel_ratio) {
m_pixel_ratio = ratio;
add_elements();
} }
} }
/*! Compute the elements of a polygon set.
*/
virtual void add_elements() {
clear();
std::vector<Pwh> pwhs;
m_ps.polygons_with_holes(std::back_inserter(pwhs));
for (const auto& pwh : pwhs) add_elements(pwh);
}
/*! Obtain the pixel ratio.
*/
double pixel_ratio() const { return m_pixel_ratio; }
/*! Compute the bounding box.
*/
CGAL::Bbox_2 bounding_box() {
Bbox_2 bbox;
std::vector<Pwh> pwhs;
m_ps.polygons_with_holes(std::back_inserter(pwhs));
for (const auto& pwh : pwhs) {
if (! pwh.is_unbounded()) {
bbox += pwh.outer_boundary().bbox();
continue;
}
for (auto it = pwh.holes_begin(); it != pwh.holes_end(); ++it)
bbox += it->bbox();
}
return bbox;
}
protected:
/*! Compute the elements of a polygon with holes.
*/
void add_elements(const Pwh& pwh) {
if (! m_draw_unbounded && pwh.outer_boundary().is_empty()) return;
CGAL::IO::Color c(75,160,255);
face_begin(c);
const Pnt* point_in_face;
if (pwh.outer_boundary().is_empty()) {
Pgn pgn;
pgn.push_back(Pnt(-m_width, -m_height));
pgn.push_back(Pnt(m_width, -m_height));
pgn.push_back(Pnt(m_width, m_height));
pgn.push_back(Pnt(-m_width, m_height));
compute_loop(pgn, false);
point_in_face = &(pgn.vertex(pgn.size()-1));
}
else {
const auto& outer_boundary = pwh.outer_boundary();
compute_loop(outer_boundary, false);
point_in_face = &(outer_boundary.vertex(outer_boundary.size()-1));
}
for (auto it = pwh.holes_begin(); it != pwh.holes_end(); ++it) {
compute_loop(*it, true);
add_point_in_face(*point_in_face);
}
face_end();
}
void compute_loop(const Pgn& p, bool hole) {
if (hole) add_point_in_face(p.vertex(p.size()-1));
auto prev = p.vertices_begin();
auto it = prev;
add_point(*it);
add_point_in_face(*it);
for (++it; it != p.vertices_end(); ++it) {
add_point(*it); // add vertex
add_segment(*prev, *it); // add segment with previous point
add_point_in_face(*it); // add point in face
prev = it;
}
// Add the last segment between the last point and the first one
add_segment(*prev, *(p.vertices_begin()));
}
private:
//! The window width in pixels.
int m_width = CGAL_BASIC_VIEWER_INIT_SIZE_X;
//! The window height in pixels.
int m_height = CGAL_BASIC_VIEWER_INIT_SIZE_Y;
//! The ratio between pixel and opengl units (in world coordinate system).
double m_pixel_ratio = 1;
//! The polygon set to draw.
const Ps& m_ps;
//! Indicates whether to draw unbounded polygons with holes.
bool m_draw_unbounded = false;
}; };
// Specialization of draw function. // Specialization of draw function.
template<class T, class C> template<class T, class C, class D>
void draw(const CGAL::Polygon_set_2<T, C>& aps2, void draw(const CGAL::Polygon_set_2<T, C, D>& ps,
const char* title="Polygon_set_2 Basic Viewer") const char* title = "Polygon_set_2 Basic Viewer",
bool draw_vertices = false,
bool draw_unbounded = false)
{ {
#if defined(CGAL_TEST_SUITE) #if defined(CGAL_TEST_SUITE)
bool cgal_test_suite = true; bool cgal_test_suite = true;
@ -74,14 +200,15 @@ void draw(const CGAL::Polygon_set_2<T, C>& aps2,
bool cgal_test_suite = qEnvironmentVariableIsSet("CGAL_TEST_SUITE"); bool cgal_test_suite = qEnvironmentVariableIsSet("CGAL_TEST_SUITE");
#endif #endif
if (!cgal_test_suite) if (! cgal_test_suite) {
{ using Ps = CGAL::Polygon_set_2<T, C, D>;
using Viewer = Polygon_set_2_basic_viewer_qt<Ps>;
CGAL::Qt::init_ogl_context(4,3); CGAL::Qt::init_ogl_context(4,3);
int argc = 1; int argc = 1;
const char* argv[2] = {"t2_viewer", nullptr}; const char* argv[2] = {"t2_viewer", nullptr};
QApplication app(argc, const_cast<char**>(argv)); QApplication app(argc, const_cast<char**>(argv));
SimplePolygonSet2ViewerQt<CGAL::Polygon_set_2<T, C> > Viewer mainwindow(app.activeWindow(), ps, title, draw_unbounded, draw_vertices);
mainwindow(app.activeWindow(), aps2, title); mainwindow.add_elements();
mainwindow.show(); mainwindow.show();
app.exec(); app.exec();
} }

View File

@ -19,7 +19,7 @@ typedef CGAL::Ostream_iterator<Point,std::ostream> OIterator;
int main() int main()
{ {
int n = 10; int n = 10;
int p = 2; int p = 3;
OIterator cout_ip(std::cout); OIterator cout_ip(std::cout);
CGAL::IO::set_pretty_mode(std::cout); CGAL::IO::set_pretty_mode(std::cout);
@ -31,7 +31,7 @@ int main()
FT p_radius; FT p_radius;
std::cout << "\n\n" << p << "-centers:\n"; std::cout << "\n\n" << p << "-centers:\n";
CGAL::rectangular_p_center_2( CGAL::rectangular_p_center_2(
points.begin(), points.end(), cout_ip, p_radius, 3); points.begin(), points.end(), cout_ip, p_radius, p);
std::cout << "\n\n" << p << "-radius = " << p_radius << std::endl; std::cout << "\n\n" << p << "-radius = " << p_radius << std::endl;
return 0; return 0;

View File

@ -1371,9 +1371,8 @@ CGAL_3CENTER_REPEAT_CHECK:
// try rho_min // try rho_min
CGAL_assertion(rho_min <= rho_max); CGAL_assertion(rho_min <= rho_max);
CGAL_assertion(rho_min >= 0);
FT rad_2 = q_t_q_r_cover_at_rho_min; FT rad_2 = q_t_q_r_cover_at_rho_min;
if (s_at_rho_min != e_at_rho_min) { if (rho_min >= 0 && s_at_rho_min != e_at_rho_min) {
auto mydist = [&q_t_at_rho_min, &q_r_at_rho_min, &op](const Point& p) auto mydist = [&q_t_at_rho_min, &q_r_at_rho_min, &op](const Point& p)
{ return Min<FT>()( op.distance()(q_t_at_rho_min, p), { return Min<FT>()( op.distance()(q_t_at_rho_min, p),
op.distance()(q_r_at_rho_min, p)); }; op.distance()(q_r_at_rho_min, p)); };

View File

@ -0,0 +1,39 @@
#include <CGAL/Simple_cartesian.h>
#include <CGAL/point_generators_2.h>
#include <CGAL/rectangular_p_center_2.h>
#include <CGAL/IO/Ostream_iterator.h>
#include <CGAL/algorithm.h>
#include <iostream>
#include <algorithm>
#include <vector>
typedef double FT;
typedef CGAL::Simple_cartesian<FT> Kernel;
typedef Kernel::Point_2 Point;
typedef std::vector<Point> Cont;
typedef CGAL::Random_points_in_square_2<Point> Generator;
typedef CGAL::Ostream_iterator<Point,std::ostream> OIterator;
int main()
{
CGAL::get_default_random() = CGAL::Random(1518508913);
int n = 10;
int p = 3;
OIterator cout_ip(std::cout);
CGAL::IO::set_pretty_mode(std::cout);
Cont points;
std::copy_n(Generator(1), n, std::back_inserter(points));
std::cout << "Generated Point Set:\n";
std::copy(points.begin(), points.end(), cout_ip);
FT p_radius;
std::cout << "\n\n" << p << "-centers:\n";
CGAL::rectangular_p_center_2(
points.begin(), points.end(), cout_ip, p_radius, p);
std::cout << "\n\n" << p << "-radius = " << p_radius << std::endl;
return 0;
}

View File

@ -150,6 +150,10 @@ public:
float ty() const { return image_ptr->ty; } float ty() const { return image_ptr->ty; }
float tz() const { return image_ptr->tz; } float tz() const { return image_ptr->tz; }
float& tx(){ return image_ptr->tx; }
float& ty(){ return image_ptr->ty; }
float& tz(){ return image_ptr->tz; }
float value(const std::size_t i, float value(const std::size_t i,
const std::size_t j, const std::size_t j,
const std::size_t k) const const std::size_t k) const

View File

@ -108,8 +108,8 @@ void IpeletMesh2::protected_run(int fn)
mesher.refine_mesh(); mesher.refine_mesh();
} }
else else
CGAL::refine_Delaunay_mesh_2(cdt,list_of_seeds.begin(), list_of_seeds.end(), CGAL::refine_Delaunay_mesh_2(cdt,
Criteria(0.125, alpha)); CGAL::parameters::criteria(Criteria(0.125, alpha)).seeds(list_of_seeds));
for (CDT::Finite_edges_iterator it=cdt.finite_edges_begin(); it!=cdt.finite_edges_end();++it) for (CDT::Finite_edges_iterator it=cdt.finite_edges_begin(); it!=cdt.finite_edges_end();++it)

View File

@ -0,0 +1,466 @@
// Copyright (c) 2022 GeometryFactory Sarl (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org)
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Laurent Rineau
#ifndef CGAL_CARTESIAN_IS_TRIVIAL_CONSTRUCTION_H
#define CGAL_CARTESIAN_IS_TRIVIAL_CONSTRUCTION_H
#include <CGAL/type_traits/is_iterator.h>
#include <CGAL/Kernel/Return_base_tag.h>
#include <CGAL/tags.h>
#include <CGAL/enum.h>
#include <CGAL/type_traits.h>
namespace CGAL {
namespace CartesianFunctors {
template <class Construction, typename ...Args>
struct Is_trivial_construction_base
{
// If the return type of the construction, with the specified arguments, is a
// reference or an iterator, them the construction is necessarily trivial.
using return_type = decltype(std::declval<Construction>()(std::declval<Args>()...));
enum {
value = std::is_reference<return_type>::value || CGAL::is_iterator<return_type>::value
};
};
template <class Construction, typename ...Args>
struct Is_trivial_construction : public Is_trivial_construction_base<Construction, Args...>
{};
template <typename K, typename... Args>
struct Is_trivial_construction<CommonKernelFunctors::Assign_2<K>, Args...>
: public Tag_true
{};
template <typename K, typename... Args>
struct Is_trivial_construction<CommonKernelFunctors::Assign_3<K>, Args...>
: public Tag_true
{};
template <typename K, typename... Args>
struct Is_trivial_construction<CGAL::CartesianKernelFunctors::Construct_point_2<K>, Args...>
{
typedef typename K::RT RT;
static Tag_true trivial(Return_base_tag, Origin);
static Tag_true trivial(Return_base_tag, RT, RT);
static Tag_true trivial(Origin);
static Tag_true trivial(RT, RT);
static Tag_false trivial(...);
enum { value = decltype(trivial(std::declval<CGAL::cpp20::remove_cvref_t<Args>>()...))::value ||
Is_trivial_construction_base<CGAL::CartesianKernelFunctors::Construct_point_2<K>, Args...>::value
};
};
template <typename K, typename... Args>
struct Is_trivial_construction<CGAL::CartesianKernelFunctors::Construct_point_3<K>, Args...>
{
typedef typename K::RT RT;
static Tag_true trivial(Return_base_tag, Origin);
static Tag_true trivial(Return_base_tag, RT, RT, RT);
static Tag_true trivial(Origin);
static Tag_true trivial(RT, RT, RT);
static Tag_false trivial(...);
enum { value = decltype(trivial(std::declval<CGAL::cpp20::remove_cvref_t<Args>>()...))::value ||
Is_trivial_construction_base<CGAL::CartesianKernelFunctors::Construct_point_3<K>, Args...>::value
};
};
template <typename K, typename... Args>
struct Is_trivial_construction<CGAL::CartesianKernelFunctors::Construct_weighted_point_2<K>, Args...>
{
typedef typename K::FT FT;
typedef typename K::Point_2 Point_2;
static Tag_true trivial(Return_base_tag, Origin);
static Tag_true trivial(Return_base_tag, Point_2, FT);
static Tag_true trivial(Return_base_tag, FT, FT);
static Tag_true trivial(Point_2, FT);
static Tag_true trivial(Origin);
static Tag_true trivial(FT, FT);
static Tag_false trivial(...);
enum { value = decltype(trivial(std::declval<CGAL::cpp20::remove_cvref_t<Args>>()...))::value ||
Is_trivial_construction_base<CGAL::CartesianKernelFunctors::Construct_weighted_point_2<K>, Args...>::value
};
};
template <typename K, typename... Args>
struct Is_trivial_construction<CGAL::CartesianKernelFunctors::Construct_weighted_point_3<K>, Args...>
{
typedef typename K::FT FT;
typedef typename K::Point_3 Point_3;
static Tag_true trivial(Return_base_tag, Origin);
static Tag_true trivial(Return_base_tag, Point_3, FT);
static Tag_true trivial(Return_base_tag, FT, FT, FT);
static Tag_true trivial(Point_3, FT);
static Tag_true trivial(Origin);
static Tag_true trivial(FT, FT, FT);
static Tag_false trivial(...);
enum { value = decltype(trivial(std::declval<CGAL::cpp20::remove_cvref_t<Args>>()...))::value ||
Is_trivial_construction_base<CGAL::CartesianKernelFunctors::Construct_weighted_point_3<K>, Args...>::value
};
};
template <typename K, typename... Args>
struct Is_trivial_construction<CGAL::CartesianKernelFunctors::Construct_vector_2<K>, Args...>
{
typedef typename K::RT RT;
typedef typename K::Point_2 Point_2;
static Tag_true trivial(Return_base_tag, Null_vector);
static Tag_true trivial(Return_base_tag, Origin, Point_2);
static Tag_true trivial(Return_base_tag, RT, RT);
static Tag_true trivial(Null_vector);
static Tag_true trivial(Origin, Point_2);
static Tag_true trivial(RT, RT);
static Tag_false trivial(...);
enum { value = decltype(trivial(std::declval<CGAL::cpp20::remove_cvref_t<Args>>()...))::value ||
Is_trivial_construction_base<CGAL::CartesianKernelFunctors::Construct_vector_2<K>, Args...>::value
};
};
template <typename K, typename... Args>
struct Is_trivial_construction<CGAL::CartesianKernelFunctors::Construct_vector_3<K>, Args...>
{
typedef typename K::RT RT;
typedef typename K::Point_3 Point;
typedef typename K::Line_3 Line;
static Tag_true trivial(Return_base_tag, Null_vector);
static Tag_true trivial(Return_base_tag, Origin, Point);
static Tag_true trivial(Return_base_tag, RT, RT, RT);
static Tag_true trivial(Return_base_tag, Line);
static Tag_true trivial(Null_vector);
static Tag_true trivial(Origin, Point);
static Tag_true trivial(RT, RT, RT);
static Tag_true trivial(Line);
static Tag_false trivial(...);
enum { value = decltype(trivial(std::declval<CGAL::cpp20::remove_cvref_t<Args>>()...))::value ||
Is_trivial_construction_base<CGAL::CartesianKernelFunctors::Construct_vector_3<K>, Args...>::value
};
};
template <typename K, typename... Args>
struct Is_trivial_construction<CGAL::CartesianKernelFunctors::Construct_direction_2<K>, Args...>
{
typedef typename K::RT RT;
typedef typename K::Vector_2 Vector;
static Tag_true trivial(Return_base_tag, RT, RT);
static Tag_true trivial(Return_base_tag, Vector);
static Tag_true trivial(RT, RT);
static Tag_true trivial(Vector);
static Tag_false trivial(...);
enum { value = decltype(trivial(std::declval<CGAL::cpp20::remove_cvref_t<Args>>()...))::value ||
Is_trivial_construction_base<CGAL::CartesianKernelFunctors::Construct_direction_2<K>, Args...>::value
};
};
template <typename K, typename... Args>
struct Is_trivial_construction<CGAL::CartesianKernelFunctors::Construct_direction_3<K>, Args...>
{
typedef typename K::RT RT;
typedef typename K::Vector_3 Vector;
static Tag_true trivial(Return_base_tag, RT, RT, RT);
static Tag_true trivial(Return_base_tag, Vector);
static Tag_true trivial(RT, RT, RT);
static Tag_true trivial(Vector);
static Tag_false trivial(...);
enum { value = decltype(trivial(std::declval<CGAL::cpp20::remove_cvref_t<Args>>()...))::value ||
Is_trivial_construction_base<CGAL::CartesianKernelFunctors::Construct_direction_3<K>, Args...>::value
};
};
template <typename K, typename... Args>
struct Is_trivial_construction<CGAL::CartesianKernelFunctors::Construct_line_2<K>, Args...>
{
typedef typename K::RT RT;
static Tag_true trivial(Return_base_tag, RT, RT, RT);
static Tag_true trivial(RT, RT, RT);
static Tag_false trivial(...);
enum { value = decltype(trivial(std::declval<CGAL::cpp20::remove_cvref_t<Args>>()...))::value ||
Is_trivial_construction_base<CGAL::CartesianKernelFunctors::Construct_line_2<K>, Args...>::value
};
};
template <typename K, typename... Args>
struct Is_trivial_construction<CGAL::CartesianKernelFunctors::Construct_line_3<K>, Args...>
{
typedef typename K::Point_3 Point;
typedef typename K::Vector_3 Vector;
typedef typename K::Direction_3 Direction;
static Tag_true trivial(Return_base_tag, Point, Vector);
static Tag_true trivial(Return_base_tag, Point, Direction);
static Tag_true trivial(Point, Vector);
static Tag_true trivial(Point, Direction);
static Tag_false trivial(...);
enum { value = decltype(trivial(std::declval<CGAL::cpp20::remove_cvref_t<Args>>()...))::value ||
Is_trivial_construction_base<CGAL::CartesianKernelFunctors::Construct_line_3<K>, Args...>::value
};
};
template <typename K, typename... Args>
struct Is_trivial_construction<CGAL::CommonKernelFunctors::Construct_segment_2<K>, Args...>
{
typedef typename K::Point_2 Point;
static Tag_true trivial(Return_base_tag, Point, Point);
static Tag_true trivial(Point, Point);
static Tag_false trivial(...);
enum { value = decltype(trivial(std::declval<CGAL::cpp20::remove_cvref_t<Args>>()...))::value ||
Is_trivial_construction_base<CGAL::CommonKernelFunctors::Construct_segment_2<K>, Args...>::value
};
};
template <typename K, typename... Args>
struct Is_trivial_construction<CGAL::CommonKernelFunctors::Construct_segment_3<K>, Args...>
{
typedef typename K::Point_3 Point;
static Tag_true trivial(Return_base_tag, Point, Point);
static Tag_true trivial(Point, Point);
static Tag_false trivial(...);
enum { value = decltype(trivial(std::declval<CGAL::cpp20::remove_cvref_t<Args>>()...))::value ||
Is_trivial_construction_base<CGAL::CommonKernelFunctors::Construct_segment_3<K>, Args...>::value
};
};
template <typename K, typename... Args>
struct Is_trivial_construction<CGAL::CommonKernelFunctors::Construct_circle_2<K>, Args...>
{
typedef typename K::FT FT;
typedef typename K::Point_2 Point;
static Tag_true trivial(Return_base_tag, Point, FT, Orientation);
static Tag_true trivial(Return_base_tag, Point, Orientation);
static Tag_true trivial(Point, FT, Orientation);
static Tag_true trivial(Point, Orientation);
static Tag_false trivial(...);
enum { value = decltype(trivial(std::declval<CGAL::cpp20::remove_cvref_t<Args>>()...))::value ||
Is_trivial_construction_base<CGAL::CartesianKernelFunctors::Construct_circle_2<K>, Args...>::value
};
};
template <typename K, typename... Args>
struct Is_trivial_construction<CGAL::CartesianKernelFunctors::Compute_squared_radius_2<K>, Args...>
{
typedef typename K::Point_2 Point_2;
typedef typename K::Circle_2 Circle_2;
static Tag_true trivial(Point_2);
static Tag_true trivial(Circle_2);
static Tag_false trivial(...);
enum { value = decltype(trivial(std::declval<CGAL::cpp20::remove_cvref_t<Args>>()...))::value ||
Is_trivial_construction_base<CGAL::CartesianKernelFunctors::Compute_squared_radius_2<K>, Args...>::value
};
};
template <typename K, typename... Args>
struct Is_trivial_construction<CGAL::CartesianKernelFunctors::Compute_squared_radius_3<K>, Args...>
{
typedef typename K::Point_3 Point_3;
typedef typename K::Circle_3 Circle_3;
typedef typename K::Sphere_3 Sphere_3;
static Tag_true trivial(Point_3);
static Tag_true trivial(Circle_3);
static Tag_true trivial(Sphere_3);
static Tag_false trivial(...);
enum { value = decltype(trivial(std::declval<CGAL::cpp20::remove_cvref_t<Args>>()...))::value ||
Is_trivial_construction_base<CGAL::CartesianKernelFunctors::Compute_squared_radius_3<K>, Args...>::value
};
};
template <typename K, typename... Args>
struct Is_trivial_construction<CGAL::CartesianKernelFunctors::Construct_iso_rectangle_2<K>, Args...>
{
typedef typename K::Point_2 Point;
typedef typename K::RT RT;
static Tag_true trivial(Return_base_tag, Point, Point);
static Tag_true trivial(Return_base_tag, Point, Point, int);
static Tag_true trivial(Return_base_tag, Point, Point, Point, Point);
static Tag_true trivial(Return_base_tag, RT, RT, RT, RT);
static Tag_true trivial(Point, Point);
static Tag_true trivial(Point, Point, int);
static Tag_true trivial(Point, Point, Point, Point);
static Tag_true trivial(RT, RT, RT, RT);
static Tag_false trivial(...);
enum { value = decltype(trivial(std::declval<CGAL::cpp20::remove_cvref_t<Args>>()...))::value ||
Is_trivial_construction_base<CGAL::CartesianKernelFunctors::Construct_iso_rectangle_2<K>, Args...>::value
};
};
template <typename K, typename... Args>
struct Is_trivial_construction<CGAL::CartesianKernelFunctors::Construct_iso_cuboid_3<K>, Args...>
{
typedef typename K::Point_3 Point;
typedef typename K::RT RT;
static Tag_true trivial(Return_base_tag, Point, Point);
static Tag_true trivial(Return_base_tag, Point, Point, int);
static Tag_true trivial(Return_base_tag, Point, Point, Point, Point, Point, Point);
static Tag_true trivial(Return_base_tag, RT, RT, RT, RT, RT, RT);
static Tag_true trivial(Point, Point);
static Tag_true trivial(Point, Point, int);
static Tag_true trivial(Point, Point, Point, Point, Point, Point);
static Tag_true trivial(RT, RT, RT, RT, RT, RT);
\
static Tag_false trivial(...);
enum { value = decltype(trivial(std::declval<CGAL::cpp20::remove_cvref_t<Args>>()...))::value ||
Is_trivial_construction_base<CGAL::CartesianKernelFunctors::Construct_iso_cuboid_3<K>, Args...>::value
};
};
template <typename K, typename... Args>
struct Is_trivial_construction<CGAL::CommonKernelFunctors::Construct_ray_2<K>, Args...>
{
typedef typename K::Point_2 Point;
static Tag_true trivial(Return_base_tag, Point, Point);
static Tag_true trivial(Point, Point);
\
static Tag_false trivial(...);
enum { value = decltype(trivial(std::declval<CGAL::cpp20::remove_cvref_t<Args>>()...))::value ||
Is_trivial_construction_base<CGAL::CommonKernelFunctors::Construct_ray_2<K>, Args...>::value
};
};
template <typename K, typename... Args>
struct Is_trivial_construction<CGAL::CommonKernelFunctors::Construct_ray_3<K>, Args...>
{
typedef typename K::Point_3 Point;
static Tag_true trivial(Return_base_tag, Point, Point);
static Tag_true trivial(Point, Point);
\
static Tag_false trivial(...);
enum { value = decltype(trivial(std::declval<CGAL::cpp20::remove_cvref_t<Args>>()...))::value ||
Is_trivial_construction_base<CGAL::CommonKernelFunctors::Construct_ray_3<K>, Args...>::value
};
};
template <typename K, typename... Args>
struct Is_trivial_construction<CGAL::CommonKernelFunctors::Construct_triangle_2<K>, Args...> : public Tag_true
{};
template <typename K, typename... Args>
struct Is_trivial_construction<CGAL::CommonKernelFunctors::Construct_triangle_3<K>, Args...> : public Tag_true
{};
template <typename K, typename... Args>
struct Is_trivial_construction<CGAL::CommonKernelFunctors::Construct_plane_3<K>, Args...>
{
typedef typename K::RT RT;
typedef typename K::Circle_3 Circle;
static Tag_true trivial(Return_base_tag, RT, RT, RT, RT);
static Tag_true trivial(Return_base_tag, Circle);
static Tag_true trivial(RT, RT, RT, RT);
static Tag_true trivial(Circle);
static Tag_false trivial(...);
enum { value = decltype(trivial(std::declval<CGAL::cpp20::remove_cvref_t<Args>>()...))::value ||
Is_trivial_construction_base<CGAL::CommonKernelFunctors::Construct_plane_3<K>, Args...>::value
};
};
template <typename K, typename... Args>
struct Is_trivial_construction<CGAL::CommonKernelFunctors::Construct_sphere_3<K>, Args...>
{
typedef typename K::FT FT;
typedef typename K::Point_3 Point_3;
typedef typename K::Circle_3 Circle_3;
static Tag_true trivial(Return_base_tag, Point_3, FT, Orientation);
static Tag_true trivial(Return_base_tag, Point_3, Orientation);
static Tag_true trivial(Return_base_tag, Circle_3);
static Tag_true trivial(Point_3, FT, Orientation);
static Tag_true trivial(Point_3, Orientation);
static Tag_true trivial(Circle_3);
static Tag_false trivial(...);
enum { value = decltype(trivial(std::declval<CGAL::cpp20::remove_cvref_t<Args>>()...))::value ||
Is_trivial_construction_base<CGAL::CartesianKernelFunctors::Construct_sphere_3<K>, Args...>::value
};
};
template <typename K, typename... Args>
struct Is_trivial_construction<CGAL::CommonKernelFunctors::Construct_circle_3<K>, Args...>
{
typedef typename K::Plane_3 Plane_3;
typedef typename K::Sphere_3 Sphere_3;
static Tag_true trivial(Return_base_tag, Plane_3, Sphere_3, int);
static Tag_true trivial(Plane_3, Sphere_3, int);
static Tag_true trivial(Sphere_3, Plane_3, int);
static Tag_false trivial(...);
enum { value = decltype(trivial(std::declval<CGAL::cpp20::remove_cvref_t<Args>>()...))::value ||
Is_trivial_construction_base<CGAL::CartesianKernelFunctors::Construct_circle_3<K>, Args...>::value
};
};
template <typename K, typename... Args>
struct Is_trivial_construction<CGAL::CommonKernelFunctors::Construct_second_point_3<K>, Args...> : public Tag_true
{};
template <typename K, typename... Args>
struct Is_trivial_construction<CGAL::CommonKernelFunctors::Construct_tetrahedron_3<K>, Args...> : public Tag_true
{};
} // end namespace CartesianFunctors
} // end namespace CGAL
#endif // CGAL_CARTESIAN_IS_TRIVIAL_CONSTRUCTION_H

View File

@ -30,6 +30,7 @@
#include <CGAL/Bbox_2.h> #include <CGAL/Bbox_2.h>
#include <CGAL/Bbox_3.h> #include <CGAL/Bbox_3.h>
#include <CGAL/Origin.h> #include <CGAL/Origin.h>
#include <CGAL/Kernel/Return_base_tag.h>
#include <CGAL/Kernel/Type_mapper.h> #include <CGAL/Kernel/Type_mapper.h>
#include <vector> #include <vector>
#include <boost/mpl/lambda.hpp> #include <boost/mpl/lambda.hpp>
@ -108,6 +109,12 @@ public:
return n; return n;
} }
Return_base_tag
operator()(Return_base_tag o) const
{
return o;
}
const Bbox_2& const Bbox_2&
operator()(const Bbox_2& b) const operator()(const Bbox_2& b) const
{ {

View File

@ -12,7 +12,7 @@ endif()
find_package(CGAL REQUIRED OPTIONAL_COMPONENTS Qt5) find_package(CGAL REQUIRED OPTIONAL_COMPONENTS Qt5)
find_package(Qt5 QUIET COMPONENTS Script OpenGL) find_package(Qt5 QUIET COMPONENTS Widgets OpenGL)
if(CGAL_Qt5_FOUND AND Qt5_FOUND) if(CGAL_Qt5_FOUND AND Qt5_FOUND)
@ -23,7 +23,7 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND)
add_to_cached_list(CGAL_EXECUTABLE_TARGETS Circular_kernel_3) add_to_cached_list(CGAL_EXECUTABLE_TARGETS Circular_kernel_3)
target_link_libraries(Circular_kernel_3 PRIVATE CGAL::CGAL CGAL::CGAL_Qt5 target_link_libraries(Circular_kernel_3 PRIVATE CGAL::CGAL CGAL::CGAL_Qt5
Qt5::OpenGL Qt5::Gui) Qt5::Widgets Qt5::OpenGL)
include(${CGAL_MODULES_DIR}/CGAL_add_test.cmake) include(${CGAL_MODULES_DIR}/CGAL_add_test.cmake)
cgal_add_compilation_test(Circular_kernel_3) cgal_add_compilation_test(Circular_kernel_3)

14550
Data/data/points_3/ocean_r.xyz Normal file

File diff suppressed because it is too large Load Diff

View File

@ -251,7 +251,7 @@ set(CGAL_DOC_DXY_DIR "${CMAKE_BINARY_DIR}/doc_dxy")
file(MAKE_DIRECTORY "${CGAL_DOC_DXY_DIR}") file(MAKE_DIRECTORY "${CGAL_DOC_DXY_DIR}")
#Setting the resource directory depending on the version of doxygen #Setting the resource directory depending on the version of doxygen
set(CGAL_DOC_RESOURCE_DIR_DEFAULT "${CMAKE_CURRENT_LIST_DIR}/resources/1.9.3") set(CGAL_DOC_RESOURCE_DIR_DEFAULT "${CMAKE_CURRENT_LIST_DIR}/resources/1.9.6")
# first look if resources for the specific doxygen version is available, fallback # first look if resources for the specific doxygen version is available, fallback
# on the default otherwise # on the default otherwise

View File

@ -11,11 +11,11 @@ supporting C++17 or later.
| Operating System | Compiler | | Operating System | Compiler |
| :---------- | :--------------- | | :---------- | :--------------- |
| Linux | \gnu `g++` 10.2.1 or later\cgalFootnote{<A HREF="https://gcc.gnu.org/">\cgalFootnoteCode{https://gcc.gnu.org/}</A>} | | Linux | \gnu `g++` 11.3.0 or later\cgalFootnote{<A HREF="https://gcc.gnu.org/">\cgalFootnoteCode{https://gcc.gnu.org/}</A>} |
| | `Clang` \cgalFootnote{<A HREF="https://clang.llvm.org/">\cgalFootnoteCode{https://clang.llvm.org/}</A>} compiler version 13.0.1 | | | `Clang` \cgalFootnote{<A HREF="https://clang.llvm.org/">\cgalFootnoteCode{https://clang.llvm.org/}</A>} compiler version 15.0.7 |
| \ms Windows | \gnu `g++` 10.2.1 or later\cgalFootnote{<A HREF="https://gcc.gnu.org/">\cgalFootnoteCode{https://gcc.gnu.org/}</A>} | | \ms Windows | \gnu `g++` 10.2.1 or later\cgalFootnote{<A HREF="https://gcc.gnu.org/">\cgalFootnoteCode{https://gcc.gnu.org/}</A>} |
| | \ms Visual `C++` 15.9, 16.10, 17.0 (\visualstudio 2017, 2019, and 2022)\cgalFootnote{<A HREF="https://visualstudio.microsoft.com/">\cgalFootnoteCode{https://visualstudio.microsoft.com/}</A>} | | | \ms Visual `C++` 15.9, 16.10, 17.0 (\visualstudio 2017, 2019, and 2022)\cgalFootnote{<A HREF="https://visualstudio.microsoft.com/">\cgalFootnoteCode{https://visualstudio.microsoft.com/}</A>} |
| MacOS X | \gnu `g++` 10.2.1 or later\cgalFootnote{<A HREF="https://gcc.gnu.org/">\cgalFootnoteCode{https://gcc.gnu.org/}</A>} | | MacOS X | \gnu `g++` 11.3.0 or later\cgalFootnote{<A HREF="https://gcc.gnu.org/">\cgalFootnoteCode{https://gcc.gnu.org/}</A>} |
| | Apple `Clang` compiler versions 10.0.1, 12.0.5, and 13.0.0 | | | Apple `Clang` compiler versions 10.0.1, 12.0.5, and 13.0.0 |
<!-- Windows supported version are also listed on windows.html (must change both) --> <!-- Windows supported version are also listed on windows.html (must change both) -->

View File

@ -290,7 +290,7 @@ by the user at runtime with the second argument.
\section TutorialsReconstruction_pipeline Full Pipeline Images \section TutorialsReconstruction_pipeline Full Pipeline Images
The following figure an example of a full reconstruction pipeline The following figures show a full reconstruction pipeline
applied to a bear statue (courtesy _EPFL Computer Graphics and applied to a bear statue (courtesy _EPFL Computer Graphics and
Geometry Laboratory_ \cgalCite{cgal:e-esmr}). Two mesh processing Geometry Laboratory_ \cgalCite{cgal:e-esmr}). Two mesh processing
algorithms (hole filling and isotropic remeshing) are also applied algorithms (hole filling and isotropic remeshing) are also applied

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 406 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 390 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 317 B

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,25 +0,0 @@
<!-- HTML footer for doxygen 1.8.13-->
<!-- start footer part -->
<!-- The footer div is not part of the default but we require it to
move the footer to the bottom of the page. -->
<div id="footer">
<!--BEGIN GENERATE_TREEVIEW-->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
<ul>
$navpath
<li class="footer">$generatedby
<a href="https://www.doxygen.nl/">
<img class="footer" src="$relpath^doxygen.png" alt="doxygen"/></a> $doxygenversion </li>
</ul>
</div>
<!--END GENERATE_TREEVIEW-->
<!--BEGIN !GENERATE_TREEVIEW-->
<hr class="footer"/><address class="footer"><small>
$generatedby &#160;<a href="https://www.doxygen.nl/index.html">
<img class="footer" src="$relpath^doxygen.png" alt="doxygen"/>
</a> $doxygenversion
</small></address>
<!--END !GENERATE_TREEVIEW-->
</div>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 406 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 390 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 317 B

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,34 +0,0 @@
//<![CDATA[
MathJax.Hub.Config(
{
TeX: {
Macros: {
qprel: [ "{\\gtreqless}", 0],
qpx: [ "{\\mathbf{x}}", 0],
qpl: [ "{\\mathbf{l}}", 0],
qpu: [ "{\\mathbf{u}}", 0],
qpc: [ "{\\mathbf{c}}", 0],
qpb: [ "{\\mathbf{b}}", 0],
qpy: [ "{\\mathbf{y}}", 0],
qpw: [ "{\\mathbf{w}}", 0],
qplambda: [ "{\\mathbf{\\lambda}}", 0],
ssWpoint: [ "{\\bf #1}", 1],
ssWeight: [ "{w_{#1}}", 1],
dabs: [ "{\\parallel\\! #1 \\!\\parallel}", 1],
E: [ "{\\mathrm{E}}", 0],
A: [ "{\\mathrm{A}}", 0],
R: [ "{\\mathrm{R}}", 0],
N: [ "{\\mathrm{N}}", 0],
Q: [ "{\\mathrm{Q}}", 0],
Z: [ "{\\mathrm{Z}}", 0],
ccSum: [ "{\\sum_{#1}^{#2}{#3}}", 3],
ccProd: [ "{\\prod_{#1}^{#2}{#3}}", 3],
pyr: [ "{\\operatorname{Pyr}}", 0],
aff: [ "{\\operatorname{aff}}", 0],
Ac: [ "{\\cal A}", 0],
Sc: [ "{\\cal S}", 0],
}
}
}
);
//]]>

View File

@ -1,177 +0,0 @@
<doxygenlayout version="1.0">
<!-- Navigation index tabs for HTML output -->
<navindex>
<tab type="mainpage" visible="yes" title=""/>
<tab type="modules" visible="yes" title="" intro=""/>
<tab type="pages" visible="yes" title="" intro=""/>
<tab type="classlist" visible="no" title="Class and Concept List" intro="Here is the list of all concepts and classes of the CGAL Library. Classes are inside the namespace CGAL. Concepts are in the global namespace."/>
<tab type="examples" visible="no" title="" intro=""/>
<!-- <tab type="user" url="@ref how_to_cite_cgal" title="Acknowledging CGAL"/> -->
</navindex>
<!-- Layout definition for a class page -->
<class>
<briefdescription visible="no"/>
<detaileddescription title=" "/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<inheritancegraph visible="$CLASS_GRAPH"/>
<collaborationgraph visible="$COLLABORATION_GRAPH"/>
<allmemberslink visible="yes"/>
<memberdecl>
<nestedclasses visible="yes" title=""/>
<publictypes title=""/>
<publicslots title=""/>
<signals title=""/>
<publicmethods title=""/>
<publicstaticmethods title=""/>
<publicattributes title=""/>
<publicstaticattributes title=""/>
<protectedtypes title=""/>
<protectedslots title=""/>
<protectedmethods title=""/>
<protectedstaticmethods title=""/>
<protectedattributes title=""/>
<protectedstaticattributes title=""/>
<packagetypes title=""/>
<packagemethods title=""/>
<packagestaticmethods title=""/>
<packageattributes title=""/>
<packagestaticattributes title=""/>
<properties title=""/>
<events title=""/>
<privatetypes title=""/>
<privateslots title=""/>
<privatemethods title=""/>
<privatestaticmethods title=""/>
<privateattributes title=""/>
<privatestaticattributes title=""/>
<friends title=""/>
<related title="" subtitle=""/>
<membergroups visible="yes"/>
</memberdecl>
<memberdef>
<inlineclasses title=""/>
<typedefs title=""/>
<enums title=""/>
<constructors title=""/>
<functions title=""/>
<related title=""/>
<variables title=""/>
<properties title=""/>
<events title=""/>
</memberdef>
<usedfiles visible="$SHOW_USED_FILES"/>
<authorsection visible="yes"/>
</class>
<!-- Layout definition for a namespace page -->
<namespace>
<briefdescription visible="yes"/>
<memberdecl>
<nestednamespaces visible="yes" title=""/>
<classes visible="yes" title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<inlineclasses title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection visible="yes"/>
</namespace>
<!-- Layout definition for a file page -->
<file>
<briefdescription visible="yes"/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<includegraph visible="$INCLUDE_GRAPH"/>
<includedbygraph visible="$INCLUDED_BY_GRAPH"/>
<sourcelink visible="yes"/>
<memberdecl>
<classes visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection/>
</file>
<!-- Layout definition for a group page -->
<group>
<detaileddescription title=" "/>
<authorsection visible="yes"/>
<groupgraph visible="$GROUP_GRAPHS"/>
<memberdef>
<pagedocs/>
</memberdef>
<memberdecl>
<nestedgroups visible="yes" title=""/>
<dirs visible="yes" title=""/>
<files visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<classes visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
<membergroups visible="yes"/>
</memberdecl>
<memberdef>
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
</memberdef>
</group>
<!-- Layout definition for a directory page -->
<directory>
<briefdescription visible="yes"/>
<directorygraph visible="yes"/>
<memberdecl>
<dirs visible="yes"/>
<files visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
</directory>
</doxygenlayout>

View File

@ -1,178 +0,0 @@
<doxygenlayout version="1.0">
<!-- Navigation index tabs for HTML output -->
<navindex>
<tab type="mainpage" visible="yes" title=""/>
<tab type="modules" visible="yes" title="Reference Manual" intro=""/>
<tab type="pages" visible="yes" title="Pages" intro=""/>
<tab type="classlist" visible="yes" title="Class and Concept List" intro="Here is the list of all concepts and classes of this package. Classes are inside the namespace CGAL. Concepts are in the global namespace."/>
<tab type="filelist" visible="yes" title="" intro=""/>
<tab type="examples" visible="yes" title="" intro=""/>
</navindex>
<!-- Layout definition for a class page -->
<class>
<briefdescription visible="no"/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<inheritancegraph visible="$CLASS_GRAPH"/>
<detaileddescription title="Definition"/>
<collaborationgraph visible="$COLLABORATION_GRAPH"/>
<allmemberslink visible="yes"/>
<memberdecl>
<nestedclasses visible="yes" title=""/>
<!-- Disable the naming of the public types group -->
<publictypes title=""/>
<publicslots title=""/>
<signals title=""/>
<publicmethods title=""/>
<publicstaticmethods title=""/>
<publicattributes title=""/>
<publicstaticattributes title=""/>
<protectedtypes title=""/>
<protectedslots title=""/>
<protectedmethods title=""/>
<protectedstaticmethods title=""/>
<protectedattributes title=""/>
<protectedstaticattributes title=""/>
<packagetypes title=""/>
<packagemethods title=""/>
<packagestaticmethods title=""/>
<packageattributes title=""/>
<packagestaticattributes title=""/>
<properties title=""/>
<events title=""/>
<privatetypes title=""/>
<privateslots title=""/>
<privatemethods title=""/>
<privatestaticmethods title=""/>
<privateattributes title=""/>
<privatestaticattributes title=""/>
<friends title=""/>
<related title="" subtitle=""/>
<membergroups visible="yes"/>
</memberdecl>
<memberdef>
<inlineclasses title=""/>
<typedefs title=""/>
<enums title=""/>
<constructors title=""/>
<functions title=""/>
<related title=""/>
<variables title=""/>
<properties title=""/>
<events title=""/>
</memberdef>
<usedfiles visible="$SHOW_USED_FILES"/>
<authorsection visible="yes"/>
</class>
<!-- Layout definition for a namespace page -->
<namespace>
<briefdescription visible="yes"/>
<memberdecl>
<nestednamespaces visible="yes" title=""/>
<classes visible="yes" title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title="Definition"/>
<memberdef>
<inlineclasses title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection visible="yes"/>
</namespace>
<!-- Layout definition for a file page -->
<file>
<briefdescription visible="yes"/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<includegraph visible="$INCLUDE_GRAPH"/>
<includedbygraph visible="$INCLUDED_BY_GRAPH"/>
<sourcelink visible="yes"/>
<memberdecl>
<classes visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection/>
</file>
<!-- Layout definition for a group page -->
<group>
<detaileddescription title=" "/>
<authorsection visible="yes"/>
<groupgraph visible="$GROUP_GRAPHS"/>
<memberdef>
<pagedocs/>
</memberdef>
<memberdecl>
<nestedgroups visible="yes" title=""/>
<dirs visible="yes" title=""/>
<files visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<classes visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
<membergroups visible="yes"/>
</memberdecl>
<memberdef>
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
</memberdef>
</group>
<!-- Layout definition for a directory page -->
<directory>
<briefdescription visible="yes"/>
<directorygraph visible="yes"/>
<memberdecl>
<dirs visible="yes"/>
<files visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
</directory>
</doxygenlayout>

View File

@ -1,386 +0,0 @@
body, table, div, p, dl {
font: Lucida Grande,sans-serif;
}
.textsc {
font-variant: small-caps;
}
#projectnumber {
display: none;
}
#back-nav {
border-bottom: 1px solid;
padding: 0.5em;
background-color: #FAF9FB;
}
#back-nav h2 {
display: inline;
}
#back-nav ul
{
display: inline;
padding: 0;
margin: 0;
}
#back-nav li
{
display: inline;
list-style-type: none;
padding-right: 20px;
}
.tparams .paramname {
font-weight: bold;
vertical-align: top;
}
h1 {
font-size: 180%;
}
h2 {
font-size: 120%;
}
.icon-namespace {
font-family: Arial, Helvetica;
font-weight: bold;
font-size: 12px;
height: 14px;
width: 16px;
display: inline-block;
background-color: #FF0000;
color: white;
text-align: center;
border-radius: 4px;
margin-left: 2px;
margin-right: 2px;
}
.icon-class {
font-family: Arial, Helvetica;
font-weight: bold;
font-size: 12px;
height: 14px;
width: 16px;
display: inline-block;
background-color: #0000FF;
color: white;
text-align: center;
border-radius: 4px;
margin-left: 2px;
margin-right: 2px;
}
.icon-concept {
font-family: Arial, Helvetica;
font-weight: bold;
font-size: 12px;
height: 14px;
width: 16px;
display: inline-block;
background-color: #67489A;
color: white;
text-align: center;
border-radius: 4px;
margin-left: 2px;
margin-right: 2px;
}
h1.groupheader {
font-size: 150%;
}
/* enable this to make sections more alike */
/* h2.groupheader { */
/* border-bottom: none; */
/* color: black; */
/* font-size: 100%; */
/* font-weight: bold; */
/* margin-top: 1.75em; */
/* padding-bottom: 0; */
/* padding-top: 0; */
/* width: 100%; */
/* } */
a.el {
font-weight: normal;
}
.memproto a {
font-weight: bold;
}
.PkgSummary {
width: 60%;
}
.PkgShortInfo {
width: 20%;
}
.PkgSummary, .PkgShortInfo, .PkgImage, .PkgImage .image {
display:inline-block;
padding:5px;
vertical-align:middle;
}
.PkgAuthors {
font-style: italic;
}
.PkgDescription {
padding-top: 5px;
padding-bottom: 5px;
text-align: justify;
}
/* footnote support */
blockquote sup {
position: absolute;
right: 3px;
top: 3px;
}
.footnote ol li:hover {
text-decoration: underline;
}
a.footnoteBackref, a.footnoteLink {
text-decoration: none;
}
ol.footnotesList {
margin: 0;
font-size: 0.8em;
padding-top: 5px;
}
ol.footnotesList > li {
text-indent: -1.5em;
padding-left: 1.5em;
vertical-align: top;
}
.footnoteBackReferenceGroup {
padding-right: 0.5em;
}
.footnoteBackref {
padding-right: 0.25em;
}
span.footnoteContent {
}
span.footnoteContent > p:first-child, span.footnoteContent > div:first-child {
display: inline;
}
span.footnoteContent p, span.footnoteContent div {
text-indent: 0em;
}
/* footnote support end */
dl
{
padding: 0 0 0 0;
}
dl.section, dl.hasModels, dl.debugs, dl.models, dl.refines, dl.requires
{
margin-left: 0px;
padding-left: 0px;
}
dl.section dt a, dl.hasModels dt a, dl.debugs dt a,
dl.models dt a, dl.refines dt a, dl.advanced dt a,
dl.requires dt a, dl.todo dt a, dl.bug dt a, dl.test dt a
{
font-weight: bold;
color: black;
}
div.toc {
width: auto;
}
.ui-resizable-e {
background-repeat: repeat-y;
}
div.cgal_figure_caption {
text-align: center;
}
div.cgal_video_caption {
text-align: center;
}
div.groupText {
font-style: none;
}
#projectname
{
font: 200% Tahoma, Arial,sans-serif;
}
#titlearea {
background: white;
}
#MSearchResultsWindow {
z-index: 2;
}
dl.note, dl.warning, dl.attention,
dl.pre, dl.post, dl.invariant, dl.deprecated,
dl.todo, dl.test, dl.bug
{
margin-left:-7px;
padding-left: 3px;
}
div.CGALAdvanced
{
background: #eeb;
border: 1px solid #9e9e7d;
box-shadow: 0.5ex 0.5ex #ccc;
}
div.CGALDebug
{
background: #c8a8d0;
border: 1px solid #846f8a;
box-shadow: 0.5ex 0.5ex #777;
}
dl.deprecated
{
border-left: 4px solid;
border-color: #505050;
background: #d8c0a0;
border: 1px solid #94836e;
box-shadow: 0.5ex 0.5ex #aaa;
}
div.CGALAdvanced,
div.CGALDebug,
dl.deprecated
{
border-radius: 1ex;
padding-top: 0.5ex;
padding-bottom: 0.25ex;
padding-left: 1ex;
padding-right: 1ex;
margin-bottom: 1ex;
}
div.CGALModification
{
background: #f85858;
border: 1px solid #000000;
box-shadow: 0.5ex 0.5ex #777;
border-radius: 1ex;
padding-top: 0.5ex;
padding-bottom: 0.25ex;
padding-left: 1ex;
padding-right: 1ex;
margin-bottom: 1ex;
}
.Modification
{
background: #f85858;
border: 0px;
padding-top: 0ex;
padding-bottom: 0ex;
padding-left: 0ex;
padding-right: 0ex;
margin-bottom: 0ex;
}
/* The first div in CGALAdvanced sections is the "Advanced" header */
div.CGALAdvanced > div,
div.CGALDebug > div,
dl.deprecated > dt > b > a
{
font-style: italic;
font-weight: bold;
}
/* Everything else is noise and should stay in the normal font */
div.CGALAdvanced > div ~ div,
div.CGALDebug > div ~ div,
dl.deprecated > dt ~ dt
{
font-style: normal;
font-weight: normal;
}
/* More indentation for the text body */
div.CGALAdvanced > p,
div.CGALDebug > p,
dl.deprecated > dd
{
margin-left: 0;
margin-top: 1ex;
margin-bottom: 1ex;
padding-left: 1em;
padding-right: 1em;
}
/* Adjust the top and bottom margins of div.fragment */
div.fragment {
padding: 4px;
margin: 1em 4px 1em 4px;
}
/* Make summary smaller to avoid wrapping of classes and concepts */
div.summary
{
width: auto;
}
.collapsible {
background-color: white;
color: #602020;
cursor: pointer;
padding: 3px;
width: 100%;
border: none;
text-align: left;
outline: none;
font: 14px Roboto,sans-serif;
user-select: auto;
}
.active, .collapsible:hover {
background-color: white;
}
.collapsible:after {
content: '\25B6';
color: #7A93C5;
font-weight: bold;
float: left;
margin-left: -20px;
margin-right: 5px;
}
.active:after {
content: "\25BC";
}
.content {
padding: 0 18px;
color: black;
max-height: 0;
overflow: hidden;
transition: max-height 0.2s ease-out;
background-color: white;
}

Some files were not shown because too many files have changed in this diff Show More