Merge pull request #6721 from efifogel/Aos_2-conics-efif

Resurect The Conic Traits
This commit is contained in:
Laurent Rineau 2023-05-11 16:55:35 +02:00
commit 9bafd13b00
66 changed files with 10483 additions and 6422 deletions

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.
typename Nt_traits_> template <typename Arrangement, typename Rat_kernel_, typename Alg_kernel_,
struct ArrReader< typename Nt_traits_>
Arrangement, CGAL::Arr_conic_traits_2<Rat_kernel_, Alg_kernel_, Nt_traits_>> struct ArrReader<Arrangement,
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,9 +138,9 @@ 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;
auto arr_obj = arr_pair.first; auto arr_obj = arr_pair.first;
@ -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 std::vector<X_monotone_curve_2> parts;
visibleParts = this->visibleParts(curve); parts = this->visibleParts(curve);
for (auto& part : parts) paint_curve(part);
for (auto& visiblePart : visibleParts) paintCurve(visiblePart); return *this;
}
else
{ // draw the whole curve
paintCurve(curve);
} }
// 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,80 +529,63 @@ 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); break;
break; }
} case ARR_TOP_BOUNDARY: {
case ARR_TOP_BOUNDARY: { lambda(min_x, std::numeric_limits<double>::infinity());
lambda(min_x, std::numeric_limits<double>::infinity()); break;
break; }
} case ARR_BOTTOM_BOUNDARY: {
case ARR_BOTTOM_BOUNDARY: { lambda(min_x, -std::numeric_limits<double>::infinity());
lambda(min_x, -std::numeric_limits<double>::infinity()); break;
break; }
} default: {
default: { CGAL_error();
CGAL_error(); }
}
} }
} }
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; }
} case ARR_TOP_BOUNDARY: {
case ARR_TOP_BOUNDARY: { last_pt = {max_x, std::numeric_limits<double>::infinity()};
last_pt = {max_x, std::numeric_limits<double>::infinity()}; break;
break; }
} case ARR_BOTTOM_BOUNDARY: {
case ARR_BOTTOM_BOUNDARY: { last_pt = {max_x, -std::numeric_limits<double>::infinity()};
last_pt = {max_x, -std::numeric_limits<double>::infinity()}; break;
break; }
} default: { CGAL_error(); }
default: {
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

@ -100,11 +100,9 @@ static constexpr TraitsType enumFromArrType()
return details::EnumFromTraits<typename T::Geometry_traits_2>::value; return details::EnumFromTraits<typename T::Geometry_traits_2>::value;
} }
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

@ -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,9 +33,13 @@ 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;
template<class OutputIterator> // Cnstruct from traits.
int read_data(std::ifstream & inp, OutputIterator curves_out, Conic_reader(const Traits& traits) : m_traits(traits) {}
CGAL::Bbox_2 & bbox)
//
template <class OutputIterator>
int read_data(std::ifstream& inp, OutputIterator curves_out,
CGAL::Bbox_2& bbox)
{ {
Curve_2 cv; Curve_2 cv;
@ -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];
@ -67,12 +74,11 @@ public:
std::istringstream str_line (one_line); std::istringstream str_line (one_line);
// Read the arc type and act accordingly. // Read the arc type and act accordingly.
char type; char type;
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.
@ -81,49 +87,46 @@ public:
//str_line >> x1 >> y1 >> x2 >> y2; //str_line >> x1 >> y1 >> x2 >> y2;
str_line >> buf; str_line >> buf;
x1 = Algebraic( buf ).BigRatValue( ); x1 = Algebraic( buf ).BigRatValue();
str_line >> buf; str_line >> buf;
y1 = Algebraic( buf ).BigRatValue( ); y1 = Algebraic( buf ).BigRatValue();
str_line >> buf; str_line >> buf;
x2 = Algebraic( buf ).BigRatValue( ); x2 = Algebraic( buf ).BigRatValue();
str_line >> buf; str_line >> buf;
y2 = Algebraic( buf ).BigRatValue( ); y2 = Algebraic( buf ).BigRatValue();
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
// radius. // radius.
Rational x0, y0, R_sq; Rational x0, y0, R_sq;
str_line >> x0 >> y0 >> R_sq; str_line >> x0 >> y0 >> R_sq;
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.
Rational x1, y1, x2, y2, x3, y3; Rational x1, y1, x2, y2, x3, y3;
str_line >> x1 >> y1 >> x2 >> y2 >> x3 >> y3; str_line >> x1 >> y1 >> x2 >> y2 >> x3 >> y3;
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)
@ -144,16 +146,13 @@ public:
str_line >> r >> s >> t >> u >> v >> w; str_line >> r >> s >> t >> u >> v >> w;
// Read the orientation. // Read the orientation.
int i_orient; int i_orient;
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,16 +187,15 @@ 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
int x0, y0, r1, r2; int x0, y0, r1, r2;
Rational sqr_r1, sqr_r2; Rational sqr_r1, sqr_r2;
Rational R, S, T, U, V, W; Rational R, S, T, U, V, W;
str_line >> r1 >> r2 >> x0 >> y0; str_line >> r1 >> r2 >> x0 >> y0;
@ -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,48 +23,47 @@
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 ); void insert(const Point_2& point);
void insert( const Point_2& point ); void clear();
void clear( );
public Q_SLOTS: public Q_SLOTS:
void modelChanged( ) override; void modelChanged() override;
const QColor& edgeColor( ) const; const QColor& edgeColor() const;
void setEdgeColor( const QColor& color ); void setEdgeColor(const QColor& color);
int edgeWidth( ) const; int edgeWidth() const;
void setEdgeWidth( int width ); void setEdgeWidth(int width);
const QColor& vertexColor( ) const; const QColor& vertexColor() const;
void setVertexColor( const QColor& color ); void setVertexColor(const QColor& color);
int vertexRadius( ) const; int vertexRadius() const;
void setVertexRadius( int radius ); void setVertexRadius(int radius);
protected: // methods protected: // methods
void updateBoundingBox( ); void updateBoundingBox( );
protected: // fields protected: // fields
std::vector< X_monotone_curve_2 > curves; const Traits& m_traits;
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();
@ -107,7 +111,7 @@ EnvelopeCallback<Arr_>::EnvelopeCallback(Arrangement* arr_, QObject* parent) :
} }
template < typename Arr_ > template < typename Arr_ >
void EnvelopeCallback<Arr_>::setEnvelopeEdgeColor( const QColor& color ) void EnvelopeCallback<Arr_>::setEnvelopeEdgeColor(const QColor& color)
{ {
this->lowerEnvelope->setEdgeColor( color ); this->lowerEnvelope->setEdgeColor( color );
this->upperEnvelope->setEdgeColor( color ); this->upperEnvelope->setEdgeColor( color );

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,103 +37,95 @@ 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::
Callback(parent, scene), GraphicsViewCurveInputBase(QObject* parent, QGraphicsScene* scene) :
inputMethod(nullptr) Callback(parent, scene),
{ 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,
GraphicsViewCurveInputBase(parent, scene), QGraphicsScene* scene) :
arrangement(arrangement_) GraphicsViewCurveInputBase(parent, scene),
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);
}); });
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,
if (it.curveType() == type) [&](auto&& it) {
this->setInputMethod(static_cast<CurveInputMethod*>(&it)); if (it.curveType() == type)
}); 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( CGAL::make_object(this->arrangement), o);
demo_types::enumFromArrType<Arrangement>(),
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;
@ -171,7 +161,7 @@ auto CurveGeneratorBase<ArrTraits_>::generate(
res = generateThreePointCircularArc(clickedPoints); res = generateThreePointCircularArc(clickedPoints);
break; break;
case CurveType::FivePointConicArc: case CurveType::FivePointConicArc:
res = generateFivePointConicArc(clickedPoints); res = generateFivePointConicArc(clickedPoints);
break; break;
case CurveType::Bezier: case CurveType::Bezier:
res = generateBezier(clickedPoints); res = generateBezier(clickedPoints);
@ -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;
} }
@ -237,28 +227,31 @@ auto CurveGenerator<CGAL::Arr_linear_traits_2<Kernel_>>::generateLine(
// CurveGenerator Conic Traits // CurveGenerator Conic Traits
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>>::
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)
-> boost::optional<Curve_2> -> boost::optional<Curve_2>
{ {
auto x1 = (CGAL::min)(points[0].x(), points[1].x()); auto x1 = (CGAL::min)(points[0].x(), points[1].x());
auto y1 = (CGAL::min)(points[0].y(), points[1].y()); auto y1 = (CGAL::min)(points[0].y(), points[1].y());
@ -279,14 +272,16 @@ 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)
-> boost::optional<Curve_2> -> boost::optional<Curve_2>
{ {
auto& qp1 = points[0]; auto& qp1 = points[0];
auto& qp2 = points[1]; auto& qp2 = points[1];
@ -295,22 +290,22 @@ 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)
-> boost::optional<Curve_2> -> boost::optional<Curve_2>
{ {
auto& qp0 = points[0]; auto& qp0 = points[0];
auto& qp1 = points[1]; auto& qp1 = points[1];
@ -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::endl;
std::cout << "Points don't specify a valid conic. Try again!"
<< 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());
@ -389,8 +378,8 @@ auto CurveGenerator<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>::
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 std::vector<Point_2>& points) generateEllipse(const std::vector<Point_2>& points)
-> boost::optional<Curve_2> -> boost::optional<Curve_2>
{ {
auto rx = auto rx =
(points[0].x() - points[1].x()) * (points[0].x() - points[1].x()) / 4.; (points[0].x() - points[1].x()) * (points[0].x() - points[1].x()) / 4.;
@ -401,10 +390,11 @@ 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)
-> boost::optional<Curve_2> -> boost::optional<Curve_2>
{ {
RationalTraits ratTraits; RationalTraits ratTraits;
@ -432,26 +422,23 @@ 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>
{ {
if (clickedPoints.size() < 2) return {}; if (clickedPoints.size() < 2) return {};
return Curve_2{clickedPoints.begin(), clickedPoints.end()}; return Curve_2{clickedPoints.begin(), clickedPoints.end()};
} }
// 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,15 +489,17 @@ 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;
Rational_arr* arr; Rational_arr* arr;
if (!CGAL::assign(arr, arr_obj)) CGAL_error(); if (! CGAL::assign(arr, arr_obj)) CGAL_error();
is_first_curve = (arr->number_of_edges() == 0); is_first_curve = (arr->number_of_edges() == 0);
@ -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,15 +21,14 @@
#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;
typedef typename Arrangement::Halfedge_iterator Halfedge_iterator; typedef typename Arrangement::Halfedge_iterator Halfedge_iterator;
typedef typename Arrangement::Vertex_iterator Vertex_iterator; typedef typename Arrangement::Vertex_iterator Vertex_iterator;
typedef typename Arrangement::Geometry_traits_2 Traits; typedef typename Arrangement::Geometry_traits_2 Traits;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2; typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
MergeEdgeCallback(Arrangement* arr_, QObject* parent_); MergeEdgeCallback(Arrangement* arr_, QObject* parent_);
void setScene(QGraphicsScene* scene_) override; void setScene(QGraphicsScene* scene_) override;
@ -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) this->mergeEdge.areMergeable(arr, h, h2))
return h1;
else if (
this->mergeEdge.areMergeable(arr, h, h1) &&
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;
typename BoundingTraits_> ConstructBoundingBox_impl(const Traits& traits) : m_traits(traits) {}
struct ConstructBoundingBox_impl<CGAL::Arr_Bezier_curve_traits_2<
RatKernel_, AlgKernel_, NtTraits_, BoundingTraits_>> // 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_>
class ConstructBoundingBox_impl<CGAL::Arr_Bezier_curve_traits_2
<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,78 +204,74 @@ 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
{ {
using Rational = typename ArrTraits::Rational; using Rational = typename ArrTraits::Rational;
@ -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,9 +480,9 @@ 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>>::
operator()( operator()(
@ -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,95 +559,93 @@ 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_),
intersectCurves(this->traits->intersect_2_object()) intersectCurves(this->traits->intersect_2_object())
{ {
} }
//
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,9 +770,9 @@ 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>>::
operator()(const X_monotone_curve_2& curve, const Rational& x) -> Algebraic operator()(const X_monotone_curve_2& curve, const Rational& x) -> Algebraic
@ -768,9 +784,9 @@ 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>>::
get_t(const X_monotone_curve_2& curve, const Rational& x) -> Algebraic get_t(const X_monotone_curve_2& curve, const Rational& x) -> Algebraic
@ -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,9 +898,9 @@ 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) {
using Arrangement = typename decltype(type_holder)::type; using Arrangement = typename decltype(type_holder)::type;

View File

@ -21,186 +21,282 @@
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;
typedef typename Kernel::Point_2 Point_2; typedef typename Kernel::Point_2 Point_2;
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;
typedef typename Traits::Multiplicity Multiplicity; typedef typename Traits::Multiplicity Multiplicity;
typedef typename Traits::Intersect_2 Intersect_2; typedef typename Traits::Intersect_2 Intersect_2;
typedef std::pair< typename Traits::Point_2, Multiplicity > typedef std::pair<typename Traits::Point_2, Multiplicity>
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;
}; };
template <typename Coefficient_> // Specialization of `Arr_compute_y_at_x_2` for the conic traits.
class Arr_compute_y_at_x_2< CGAL::Arr_algebraic_segment_traits_2< template <typename RatKernel, typename AlgKernel, typename NtTraits>
Coefficient_ > > : public GraphicsSceneMixin class Arr_compute_y_at_x_2
<CGAL::Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>> :
public GraphicsSceneMixin
{ {
public: public:
typedef Coefficient_ Coefficient; typedef CGAL::Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>
typedef CGAL::Arr_algebraic_segment_traits_2< Coefficient > Traits; Traits;
typedef typename Traits::Algebraic_real_1 CoordinateType; 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::Intersect_2 Intersect_2; typedef typename ArrTraitsAdaptor<Traits>::CoordinateType Coordinate_type;
typedef typename Traits::Multiplicity Multiplicity; typedef typename Traits::Intersect_2 Intersect_2;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_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_>
class Arr_compute_y_at_x_2<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>> :
public GraphicsSceneMixin
{
public:
typedef Coefficient_ Coefficient;
typedef CGAL::Arr_algebraic_segment_traits_2<Coefficient> Traits;
typedef typename Traits::Algebraic_real_1 CoordinateType;
typedef typename Traits::Point_2 Point_2;
typedef typename Traits::Intersect_2 Intersect_2;
typedef typename Traits::Multiplicity Multiplicity;
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
{ {
public: public:
typedef CGAL::Arr_Bezier_curve_traits_2< typedef CGAL::Arr_Bezier_curve_traits_2<
RatKernel, AlgKernel, NtTraits, BoundingTraits> Traits; RatKernel, AlgKernel, NtTraits, BoundingTraits> Traits;
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::Rational Rational; typedef typename Traits::Rational Rational;
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:
typedef CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1> Traits; typedef CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1> Traits;
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::Algebraic_real_1 Algebraic_real_1; typedef typename Traits::Algebraic_real_1 Algebraic_real_1;
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_>
{ };
template <typename 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: using Traits = Traits_;
typedef Kernel_ Kernel; using Base = Compute_squared_distance_2_base<Traits>;
typedef CGAL::Arr_segment_traits_2< Kernel > Traits;
typedef Compute_squared_distance_2_base< Traits > Superclass;
typedef typename Kernel::FT FT;
typedef typename Kernel::Point_2 Point_2;
typedef typename Kernel::Segment_2 Segment_2;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
double operator() ( const Point_2& p, const X_monotone_curve_2& c ) const; public:
// Construct from traits.
Compute_squared_distance_2(const Traits& traits) : Base(traits) {}
}; };
template <typename Kernel_ > // Specialization of `Compute_squared_distance_2` for the segment traits.
class Compute_squared_distance_2< CGAL::Arr_linear_traits_2< Kernel_ > > : template <typename Kernel_>
public Compute_squared_distance_2_base<CGAL::Arr_linear_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: public:
typedef Kernel_ Kernel; typedef Kernel_ Kernel;
typedef CGAL::Arr_linear_traits_2< Kernel > Traits; typedef CGAL::Arr_segment_traits_2<Kernel> Traits;
typedef Compute_squared_distance_2_base< Traits > Superclass; typedef Compute_squared_distance_2_base<Traits> Superclass;
typedef typename Kernel::FT FT; typedef typename Kernel::FT FT;
typedef typename Kernel::Point_2 Point_2; typedef typename Kernel::Point_2 Point_2;
typedef typename Kernel::Segment_2 Segment_2; typedef typename Kernel::Segment_2 Segment_2;
typedef typename Kernel::Ray_2 Ray_2; typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Kernel::Line_2 Line_2;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
double operator() ( const Point_2& p, const X_monotone_curve_2& c ) const; 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;
}; };
template <typename Kernel_ > // Specialization of `Compute_squared_distance_2` for the linear traits.
class Compute_squared_distance_2< CGAL::Arr_polyline_traits_2< Kernel_ > > : template <typename Kernel_>
public Compute_squared_distance_2_base<CGAL::Arr_polyline_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: public:
typedef Kernel_ Kernel; typedef Kernel_ Kernel;
typedef CGAL::Arr_polyline_traits_2< Kernel > Traits; typedef CGAL::Arr_linear_traits_2<Kernel> Traits;
typedef Compute_squared_distance_2_base< Traits > Superclass; typedef Compute_squared_distance_2_base<Traits> Superclass;
typedef typename Kernel::FT FT; typedef typename Kernel::FT FT;
typedef typename Kernel::Point_2 Point_2; typedef typename Kernel::Point_2 Point_2;
typedef typename Kernel::Segment_2 Segment_2; typedef typename Kernel::Segment_2 Segment_2;
typedef typename Traits::Curve_2 Curve_2; typedef typename Kernel::Ray_2 Ray_2;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2; typedef typename Kernel::Line_2 Line_2;
typedef typename Curve_2::Subcurve_const_iterator Seg_const_it; typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
double operator() ( const Point_2& p, const X_monotone_curve_2& c ) const; 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;
}; };
// Specialization of `Compute_squared_distance_2` for the polyline traits.
template <typename 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:
typedef Kernel_ Kernel;
typedef CGAL::Arr_polyline_traits_2<Kernel> Traits;
typedef Compute_squared_distance_2_base<Traits> Superclass;
typedef typename Kernel::FT FT;
typedef typename Kernel::Point_2 Point_2;
typedef typename Kernel::Segment_2 Segment_2;
typedef typename Traits::Curve_2 Curve_2;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
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;
};
// 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,
NtTraits > > : NtTraits>> :
public Compute_squared_distance_2_base< CGAL::Arr_conic_traits_2< RatKernel, public Compute_squared_distance_2_base<CGAL::Arr_conic_traits_2<RatKernel,
AlgKernel, AlgKernel,
NtTraits > > NtTraits>>
{ {
public: public:
typedef AlgKernel Kernel; typedef AlgKernel Kernel;
typedef CGAL::Arr_conic_traits_2< RatKernel, AlgKernel, NtTraits > Traits; typedef CGAL::Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits> Traits;
typedef Compute_squared_distance_2_base< Traits > Superclass; typedef Compute_squared_distance_2_base< Traits > Superclass;
// _Conic_point_2< AlgKernel > : public AlgKernel::Point_2 // _Conic_point_2< AlgKernel > : public AlgKernel::Point_2
typedef typename Traits::Point_2 Conic_point_2; typedef typename Traits::Point_2 Conic_point_2;
@ -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>;
double operator() ( const Point_2& p, const X_monotone_curve_2& c ) const;
};
template < // Construct from traits.
typename RatKernel, typename AlgKernel, typename NtTraits, Compute_squared_distance_2(const Traits& traits) : Base(traits) {}
typename BoundingTraits>
class Compute_squared_distance_2<CGAL::Arr_Bezier_curve_traits_2<
RatKernel, AlgKernel, NtTraits, BoundingTraits>> :
public Compute_squared_distance_2_base<CGAL::Arr_Bezier_curve_traits_2<
RatKernel, AlgKernel, NtTraits, BoundingTraits>>
{
public:
typedef CGAL::Arr_Bezier_curve_traits_2<
RatKernel, AlgKernel, NtTraits, BoundingTraits>
Traits;
typedef typename ArrTraitsAdaptor<Traits>::Kernel Kernel;
typedef typename Kernel::Point_2 Point_2;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
public: // methods //
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 Bezier traits.
template <typename RatKernel, typename AlgKernel, typename NtTraits,
typename BoundingTraits>
class Compute_squared_distance_2
<CGAL::Arr_Bezier_curve_traits_2<RatKernel, AlgKernel, NtTraits,
BoundingTraits>> :
public Compute_squared_distance_2_base
<CGAL::Arr_Bezier_curve_traits_2
<RatKernel, AlgKernel, NtTraits,BoundingTraits>>
{
public:
typedef CGAL::Arr_Bezier_curve_traits_2<RatKernel, AlgKernel, NtTraits,
BoundingTraits> Traits;
typedef typename ArrTraitsAdaptor<Traits>::Kernel Kernel;
typedef typename Kernel::Point_2 Point_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;
};
// 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;
}; };
template <typename Coefficient_ > // Specialization of `Compute_squared_distance_2` for the algebraic traits.
class Compute_squared_distance_2< CGAL::Arr_algebraic_segment_traits_2< template <typename Coefficient_>
Coefficient_ > > : class Compute_squared_distance_2
public Compute_squared_distance_2_base< CGAL::Arr_algebraic_segment_traits_2< <CGAL::Arr_algebraic_segment_traits_2<Coefficient_>> :
Coefficient_ > > public Compute_squared_distance_2_base
<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>
{ {
public: public:
typedef Coefficient_ Coefficient; typedef Coefficient_ Coefficient;
@ -265,8 +380,8 @@ 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;
typedef typename Traits::CKvA_2 CKvA_2; typedef typename Traits::CKvA_2 CKvA_2;
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;
typedef typename X_monotone_curve_2::Curve_analysis_2 Curve; typedef typename X_monotone_curve_2::Curve_analysis_2 Curve;
typedef typename Curve::Polynomial_traits_2 Polynomial_traits_2; typedef typename Curve::Polynomial_traits_2 Polynomial_traits_2;
typedef typename Curve::Polynomial_2 Polynomial_2; typedef typename Curve::Polynomial_2 Polynomial_2;
@ -277,69 +392,75 @@ 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;
}; };
// check if arrangement is a model of the concept ArrangementOpenBoundaryTraits_2 // check if arrangement is a model of the concept ArrangementOpenBoundaryTraits_2
template <typename ArrTraits> template <typename ArrTraits>
struct IsOpenBoundaryArrangement : struct IsOpenBoundaryArrangement :
public CGAL::Boolean_tag< public CGAL::Boolean_tag<
std::is_convertible< std::is_convertible<
typename ArrTraits::Left_side_category, typename ArrTraits::Left_side_category,
CGAL::Arr_open_side_tag>::value && CGAL::Arr_open_side_tag>::value &&
std::is_convertible< std::is_convertible<
typename ArrTraits::Bottom_side_category, typename ArrTraits::Bottom_side_category,
CGAL::Arr_open_side_tag>::value && CGAL::Arr_open_side_tag>::value &&
std::is_convertible< std::is_convertible<
typename ArrTraits::Top_side_category, typename ArrTraits::Top_side_category,
CGAL::Arr_open_side_tag>::value && CGAL::Arr_open_side_tag>::value &&
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,77 +470,77 @@ 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, const boost::optional<Point_2>& pRight);
const boost::optional<Point_2>& pRight );
protected: protected:
const ArrTraits* traits; const ArrTraits* traits;
Split_2 split_2; Split_2 split_2;
Compare_x_2 compare_x_2; Compare_x_2 compare_x_2;
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;
Parameter_space_in_x_2 parameter_space_in_x_2; Parameter_space_in_x_2 parameter_space_in_x_2;
}; // 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>
class Construct_x_monotone_subcurve_2< CGAL::Arr_conic_traits_2< RatKernel, class Construct_x_monotone_subcurve_2<CGAL::Arr_conic_traits_2<RatKernel,
AlgKernel, AlgKernel,
NtTraits > > NtTraits>>
{ {
public: public:
typedef CGAL::Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits> typedef CGAL::Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>
ArrTraits; Traits;
typedef typename ArrTraitsAdaptor<ArrTraits>::Kernel Kernel; typedef typename ArrTraitsAdaptor<Traits>::Kernel Kernel;
typedef typename ArrTraits::X_monotone_curve_2 X_monotone_curve_2; typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
typedef typename ArrTraits::Split_2 Split_2; typedef typename Traits::Split_2 Split_2;
typedef typename ArrTraits::Intersect_2 Intersect_2; typedef typename Traits::Intersect_2 Intersect_2;
typedef typename ArrTraits::Multiplicity Multiplicity; typedef typename Traits::Multiplicity Multiplicity;
typedef typename ArrTraits::Construct_min_vertex_2 Construct_min_vertex_2; typedef typename Traits::Construct_min_vertex_2 Construct_min_vertex_2;
typedef typename ArrTraits::Construct_max_vertex_2 Construct_max_vertex_2; typedef typename Traits::Construct_max_vertex_2 Construct_max_vertex_2;
typedef typename ArrTraits::Compare_x_2 Compare_x_2; typedef typename Traits::Compare_x_2 Compare_x_2;
typedef typename Kernel::FT FT; typedef typename Kernel::FT FT;
typedef typename ArrTraitsAdaptor< ArrTraits >::CoordinateType typedef typename ArrTraitsAdaptor<Traits>::CoordinateType
CoordinateType; CoordinateType;
typedef typename ArrTraits::Point_2 Point_2; typedef typename Traits::Point_2 Point_2;
typedef typename Kernel::Point_2 Kernel_point_2; typedef typename Kernel::Point_2 Kernel_point_2;
Construct_x_monotone_subcurve_2( const ArrTraits* ) // Construct from traits.
{ Construct_x_monotone_subcurve_2(const Traits* traits) : m_traits(*traits) {}
}
/* /* Return the subcurve of curve bracketed by pLeft and pRight.
Return the subcurve of curve bracketed by pLeft and pRight. */
*/ 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, const boost::optional<Point_2>& pRight );
const boost::optional<Point_2>& pRight );
}; // class Construct_x_monotone_subcurve_2 for Arr_conic_traits_2 private:
const Traits& m_traits;
};
template < //
typename RatKernel, typename AlgKernel, typename NtTraits, template <typename RatKernel, typename AlgKernel, typename NtTraits,
typename BoundingTraits> typename BoundingTraits>
class Construct_x_monotone_subcurve_2<CGAL::Arr_Bezier_curve_traits_2< class Construct_x_monotone_subcurve_2
RatKernel, AlgKernel, NtTraits, BoundingTraits>> <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>
ArrTraits; ArrTraits;
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;
@ -430,14 +551,15 @@ public:
typedef typename ArrTraits::Compare_x_2 Compare_x_2; typedef typename ArrTraits::Compare_x_2 Compare_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.
*/ */
X_monotone_curve_2 operator()( X_monotone_curve_2 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); const boost::optional<Point_2>& pRight);
protected: protected:
const ArrTraits* traits; const ArrTraits* traits;
@ -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,33 +594,30 @@ 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, const boost::optional<Point_2>& pRight);
const boost::optional<Point_2>& pRight );
protected: protected:
const Traits* traits; const Traits* traits;
Split_2 split_2; Split_2 split_2;
Compare_x_2 compare_x_2; Compare_x_2 compare_x_2;
Arr_compute_y_at_x_2< Traits > compute_y_at_x; Arr_compute_y_at_x_2<Traits> 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 }; // 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,50 +626,53 @@ 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; typedef typename ArrTraits::X_monotone_curve_2 X_monotone_curve_2;
typedef typename ArrTraits::X_monotone_curve_2 X_monotone_curve_2;
typedef typename ArrTraitsAdaptor<ArrTraits>::Kernel Kernel; typedef typename ArrTraitsAdaptor<ArrTraits>::Kernel Kernel;
typedef typename Kernel::Point_2 Point_2; typedef typename Kernel::Point_2 Point_2;
typedef typename Arrangement::Face_const_handle Face_const_handle; typedef typename Arrangement::Face_const_handle Face_const_handle;
@ -561,49 +684,53 @@ public: // typedefs
public: public:
/*! constructor */ /*! constructor */
Find_nearest_edge( Arrangement* arr_ ) : Find_nearest_edge(Arrangement* arr_) :
Find_nearest_edge_base( ), Find_nearest_edge_base(),
arr( arr_ ) arr(arr_)
{ } {}
/*! Destructor (virtual) */ /*! Destructor (virtual) */
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(this, SIGNAL(modelChanged()), this, SLOT(slotModelChanged()));
QObject::connect(
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

@ -4,22 +4,22 @@ namespace CGAL {
* *
* The class `Arr_conic_traits_2` is a model of the `ArrangementTraits_2` * The class `Arr_conic_traits_2` is a model of the `ArrangementTraits_2`
* concept and can be used to construct and maintain arrangements of bounded * concept and can be used to construct and maintain arrangements of bounded
* segments of algebraic curves of degree \f$ 2\f$ at most, also known as * segments of algebraic curves of degree \f$2\f$ at most, also known as
* <I>conic curves</I>. * <I>conic curves</I>.
* *
* A general conic curve \f$ C\f$ is the locus of all points \f$ (x,y)\f$ * A general conic curve \f$C\f$ is the locus of all points \f$(x,y)\f$
* satisfying the equation: \f$ r x^2 + s y^2 + t x y + u x + v y + w = 0\f$, * satisfying the equation: \f$r x^2 + s y^2 + t x y + u x + v y + w = 0\f$,
* where: * where:
* *
* <UL> * <UL>
* <LI>If \f$ 4 r s - t^2 > 0\f$, \f$ C\f$ is an ellipse. A special case occurs * <LI>If \f$4 r s - t^2 > 0\f$, \f$ C\f$ is an ellipse. A special case occurs
* when \f$ r = s\f$ and \f$ t = 0\f$, when \f$ C\f$ becomes a circle. * when \f$r = s\f$ and \f$ t = 0\f$, when \f$ C\f$ becomes a circle.
* *
* <LI>If \f$ 4 r s - t^2 < 0\f$, \f$ C\f$ is a hyperbola. * <LI>If \f$4 r s - t^2 < 0\f$, \f$ C\f$ is a hyperbola.
* *
* <LI>If \f$ 4 r s - t^2 = 0\f$, \f$ C\f$ is a parabola. A degenerate case * <LI>If \f$4 r s - t^2 = 0\f$, \f$ C\f$ is a parabola. A degenerate case
* occurs when \f$ r = s = t = 0\f$, when \f$ C\f$ is a line. * occurs when \f$r = s = t = 0\f$, when \f$ C\f$ is a line.
* *
* </UL> * </UL>
* *
@ -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
@ -72,7 +72,7 @@ namespace CGAL {
* simple algebraic numbers. * simple algebraic numbers.
* *
* The traits class inherits its point type from `AlgKernel::Point_2`, * The traits class inherits its point type from `AlgKernel::Point_2`,
* and defines a curve and \f$ x\f$-monotone curve types, as detailed below. * and defines a curve and \f$x\f$-monotone curve types, as detailed below.
* *
* While the `Arr_conic_traits_2` models the concept * While the `Arr_conic_traits_2` models the concept
* `ArrangementDirectionalXMonotoneTraits_2`, the implementation of * `ArrangementDirectionalXMonotoneTraits_2`, the implementation of
@ -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,20 +129,19 @@ 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;
/*! determines whether the arc is \f$ x\f$-monotone, namely each vertical /*! determines whether the arc is \f$x\f$-monotone, namely each vertical
* line intersects it at most once. A vertical line segment is also * line intersects it at most once. A vertical line segment is also
* considered (weakly) \f$ x\f$-monotone. * considered (weakly) \f$x\f$-monotone.
*/ */
bool is_x_monotone() const; bool is_x_monotone() const;
/*! determines whether the arc is \f$ y\f$-monotone, namely each horizontal /*! determines whether the arc is \f$y\f$-monotone, namely each horizontal
* line intersects it at most once. A horizontal line segment is also * line intersects it at most once. A horizontal line segment is also
* considered (weakly) \f$ x\f$-monotone. * considered (weakly) \f$x\f$-monotone.
*/ */
bool is_y_monotone() const; bool is_y_monotone() const;
@ -261,23 +159,23 @@ public:
*/ */
/// @{ /// @{
/*! returns the coefficient of \f$ x^2\f$. /*! returns the coefficient of \f$x^2\f$.
*/ */
const typename NtTraits::Integer& r() const; const typename NtTraits::Integer& r() const;
/*! returns the coefficient of \f$ t^2\f$. /*! returns the coefficient of \f$t^2\f$.
*/ */
const typename NtTraits::Integer& s() const; const typename NtTraits::Integer& s() const;
/*! returns the coefficient of \f$ x y\f$. /*! returns the coefficient of \f$x y\f$.
*/ */
const typename NtTraits::Integer& t() const; const typename NtTraits::Integer& t() const;
/*! returns the coefficient of \f$ x\f$. /*! returns the coefficient of \f$x\f$.
*/ */
const typename NtTraits::Integer& u() const; const typename NtTraits::Integer& u() const;
/*! returns the coefficient of \f$ y\f$. /*! returns the coefficient of \f$y\f$.
*/ */
const typename NtTraits::Integer& v() const; const typename NtTraits::Integer& v() 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,15 +216,16 @@ 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.
*/ */
class X_monotone_curve_2 { class X_monotone_curve_2 {
public: public:
@ -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.
/*! Trims the given x-monotone curve to an from src to tgt. * \param target The new target point.
* \ pre `src` and `tgt` lies on the curve * \pre `source` and `target` lies on the arc.
*/ */
X_monotone_curve_2(const X_monotone_curve_2& xcv, X_monotone_curve_2 operator()(const X_monotone_curve_2& xcv,
const Point_2& src, const Point_2& source,
const Point_2& tgt) const; const Point_2& target) const;
/// @} };
}/* end Arr_conic_traits_2::Trim_2 */
/// \name Accessing Functor Objects
/// @{
/*! Obtain a `Construct_curve_2` functor. */
Construct_curve_2 construct_curve_2_object() const;
/*! Obtain a `Construct_x_monotone_curve_2` functor. */
Construct_x_monotone_curve_2 construct_x_monotone_curve_2_object() 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 */ }; /* 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

@ -37,8 +37,8 @@ public:
*/ */
template <typename OutputIterator> template <typename OutputIterator>
OutputIterator operator()(ArrTraits::X_monotone_curve_2 xc1, OutputIterator operator()(ArrTraits::X_monotone_curve_2 xc1,
ArrTraits::X_monotone_curve_2 xc2, ArrTraits::X_monotone_curve_2 xc2,
OutputIterator& oi); OutputIterator& oi);
/// @} /// @}

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,18 +25,20 @@ 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,29 +42,29 @@ 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)));
// Construct poly-curve // Construct poly-curve
conic_curves.clear(); conic_curves.clear();
@ -69,12 +72,12 @@ 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)));
// Construct poly-curve // Construct poly-curve
conic_curves.clear(); conic_curves.clear();
@ -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();
@ -98,7 +101,7 @@ int main() {
xmono_conic_curves_2.push_back(xc4); xmono_conic_curves_2.push_back(xc4);
X_monotone_polycurve conic_x_mono_polycurve_1 = X_monotone_polycurve conic_x_mono_polycurve_1 =
ctr_xpolycurve(xmono_conic_curves_2.begin(), ctr_xpolycurve(xmono_conic_curves_2.begin(),
xmono_conic_curves_2.end()); xmono_conic_curves_2.end());
// Construct x-monotone poly-curve. // Construct x-monotone poly-curve.
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>
@ -2834,11 +2835,12 @@ 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

@ -8,7 +8,7 @@
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
// //
// //
// Author(s) : Ron Wein <wein@post.tau.ac.il> // Author(s): Ron Wein <wein@post.tau.ac.il>
#ifndef CGAL_CONIC_INTERSECTIONS_2_H #ifndef CGAL_CONIC_INTERSECTIONS_2_H
#define CGAL_CONIC_INTERSECTIONS_2_H #define CGAL_CONIC_INTERSECTIONS_2_H
@ -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,84 +34,76 @@ 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, const typename Nt_traits::Integer& u1,
const typename Nt_traits::Integer& u1, const typename Nt_traits::Integer& v1,
const typename Nt_traits::Integer& v1, const typename Nt_traits::Integer& w1,
const typename Nt_traits::Integer& w1, const int& deg1,
const int& deg1, const typename Nt_traits::Integer& r2,
const typename Nt_traits::Integer& r2, const typename Nt_traits::Integer& s2,
const typename Nt_traits::Integer& s2, const typename Nt_traits::Integer& t2,
const typename Nt_traits::Integer& t2, const typename Nt_traits::Integer& u2,
const typename Nt_traits::Integer& u2, const typename Nt_traits::Integer& v2,
const typename Nt_traits::Integer& v2, const typename Nt_traits::Integer& w2,
const typename Nt_traits::Integer& w2, 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,
deg1, deg1,
xs)); xs));
} }
// 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,50 +116,47 @@ 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;
} }
// Compute the roots of the resultant polynomial. // Compute the roots of the resultant polynomial.
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,55 +165,50 @@ 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, const typename Nt_traits::Algebraic& u,
const typename Nt_traits::Algebraic& u, const typename Nt_traits::Algebraic& v,
const typename Nt_traits::Algebraic& v, const typename Nt_traits::Algebraic& w,
const typename Nt_traits::Algebraic& w, const int& deg1,
const int& deg1, const typename Nt_traits::Algebraic& A,
const typename Nt_traits::Algebraic& A, const typename Nt_traits::Algebraic& B,
const typename Nt_traits::Algebraic& B, 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

@ -8,154 +8,105 @@
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
// //
// //
// 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 typename Alg_kernel::Point_2 Base;
typedef Conic_point_2<Alg_kernel> Self;
typedef Alg_kernel_ Alg_kernel; typedef typename Alg_kernel::FT Algebraic;
typedef typename Alg_kernel::Point_2 Base;
typedef _Conic_point_2<Alg_kernel> Self;
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, Base(hx, hy, hz)
const Algebraic& 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.
//@{ //@{
/*! 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>
@ -230,37 +231,63 @@ 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>
@ -879,9 +880,24 @@ 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;
@ -255,7 +256,7 @@ bool read_general_arc(InputStream_& is, Curve& cv)
// <r_1,s_1,t_1,u_1,v_1,w_1> whose intersection with <r,s,t,u,v,w> // <r_1,s_1,t_1,u_1,v_1,w_1> whose intersection with <r,s,t,u,v,w>
// defines the source. // defines the source.
Point_2 app_source; Point_2 app_source;
if (!read_app_point(is, app_source)) return false; if (! read_app_point(is, app_source)) return false;
Rational r1, s1, t1, u1, v1, w1; Rational r1, s1, t1, u1, v1, w1;
is >> r1 >> s1 >> t1 >> u1 >> v1 >> w1; is >> r1 >> s1 >> t1 >> u1 >> v1 >> w1;
@ -263,44 +264,47 @@ bool read_general_arc(InputStream_& is, Curve& cv)
// <r_2,s_2,t_2,u_2,v_2,w_2> whose intersection with <r,s,t,u,v,w> // <r_2,s_2,t_2,u_2,v_2,w_2> whose intersection with <r,s,t,u,v,w>
// defines the target. // defines the target.
Point_2 app_target; Point_2 app_target;
if (!read_app_point(is, app_target)) return false; if (! read_app_point(is, app_target)) return false;
Rational r2, s2, t2, u2, v2, w2; Rational r2, s2, t2, u2, v2, w2;
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;
CGAL::Orientation orient; CGAL::Orientation orient;
Point_2 source, target; Point_2 source, target;
if (!read_orientation_and_end_points(is, orient, source, target)) if (! read_orientation_and_end_points(is, orient, source, target))
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,12 +425,11 @@ 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;
} }
template <> template <>
@ -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;
@ -1164,7 +1171,7 @@ bool read_general_arc(InputStream_& is, Curve& cv)
// <r_1,s_1,t_1,u_1,v_1,w_1> whose intersection with <r,s,t,u,v,w> // <r_1,s_1,t_1,u_1,v_1,w_1> whose intersection with <r,s,t,u,v,w>
// defines the source. // defines the source.
Point_2 app_source; Point_2 app_source;
if (!read_app_point(is, app_source)) return false; if (! read_app_point(is, app_source)) return false;
Rational r1, s1, t1, u1, v1, w1; Rational r1, s1, t1, u1, v1, w1;
is >> r1 >> s1 >> t1 >> u1 >> v1 >> w1; is >> r1 >> s1 >> t1 >> u1 >> v1 >> w1;
@ -1172,32 +1179,34 @@ bool read_general_arc(InputStream_& is, Curve& cv)
// <r_2,s_2,t_2,u_2,v_2,w_2> whose intersection with <r,s,t,u,v,w> // <r_2,s_2,t_2,u_2,v_2,w_2> whose intersection with <r,s,t,u,v,w>
// defines the target. // defines the target.
Point_2 app_target; Point_2 app_target;
if (!read_app_point(is, app_target)) return false; if (! read_app_point(is, app_target)) return false;
Rational r2, s2, t2, u2, v2, w2; Rational r2, s2, t2, u2, v2, w2;
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;
CGAL::Orientation orient; CGAL::Orientation orient;
Point_2 source, target; Point_2 source, target;
if (!read_orientation_and_end_points(is, orient, source, target)) if (! read_orientation_and_end_points(is, orient, source, target))
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':
// Read a general conic, given by its coefficients <r,s,t,u,v,w>. case 'S': return read_segment(is, cv, m_geom_traits);
Rational r, s, t, u, v, w; case 'i':
is >> r >> s >> t >> u >> v >> w; case 'I': return read_general_arc(is, cv, m_geom_traits);
// Create a full conic (should work only for ellipses). case 'c':
cv = Curve_2(r, s, t, u, v, w); case 'C':
return true; {
// Read a general conic, given by its coefficients <r,s,t,u,v,w>.
Rational r, s, t, u, v, w;
is >> r >> s >> t >> u >> v >> w;
// Create a full conic (should work only for ellipses).
auto ctr_cv = m_geom_traits.construct_curve_2_object();
cv = ctr_cv(r, s, t, u, v, w);
return true;
}
case 'e':
case 'E': return read_partial_ellipse(is, cv, m_geom_traits);
case 'h':
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:
std::cerr << "Illegal conic type specification: " << type << "."
<< std::endl;
} }
else if ((type == 'e') || (type == 'E')) return read_partial_ellipse(is, cv);
else if ((type == 'h') || (type == 'H')) return read_hyperbola(is, cv);
else if ((type == 'p') || (type == 'P')) return read_parabola(is, cv);
else if ((type == 'a') || (type == 'A')) return read_general_curve(is, cv);
// If we reached here, we have an unknown conic type:
std::cerr << "Illegal conic type specification: " << type << "."
<< 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,69 +149,69 @@ 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.
Conic_point_2(1.41, -2), // Approximation of the target. Conic_point_2(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.
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;
@ -290,18 +282,18 @@ bool read_orientation_and_end_points(stream& is, CGAL::Orientation& orient,
Conic_point_2& target) Conic_point_2& target)
{ {
// Read the orientation. // Read the orientation.
if (!read_orientation(is, orient)) return false; if (! read_orientation(is, orient)) return false;
// Read the end points of the arc and create it. // Read the end points of the arc and create it.
if (!read_app_point(is, source)) return false; if (! read_app_point(is, source)) return false;
if (!read_app_point(is, target)) return false; if (! read_app_point(is, target)) return false;
return true; return true;
} }
/*! */ /*! */
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;
@ -315,7 +307,7 @@ bool read_general_arc(stream& is, Curve& cv)
// <r_1,s_1,t_1,u_1,v_1,w_1> whose intersection with <r,s,t,u,v,w> // <r_1,s_1,t_1,u_1,v_1,w_1> whose intersection with <r,s,t,u,v,w>
// defines the source. // defines the source.
Conic_point_2 app_source; Conic_point_2 app_source;
if (!read_app_point(is, app_source)) return false; if (! read_app_point(is, app_source)) return false;
Rational r1, s1, t1, u1, v1, w1; Rational r1, s1, t1, u1, v1, w1;
is >> r1 >> s1 >> t1 >> u1 >> v1 >> w1; is >> r1 >> s1 >> t1 >> u1 >> v1 >> w1;
@ -323,7 +315,7 @@ bool read_general_arc(stream& is, Curve& cv)
// <r_2,s_2,t_2,u_2,v_2,w_2> whose intersection with <r,s,t,u,v,w> // <r_2,s_2,t_2,u_2,v_2,w_2> whose intersection with <r,s,t,u,v,w>
// defines the target. // defines the target.
Conic_point_2 app_target; Conic_point_2 app_target;
if (!read_app_point(is, app_target)) return false; if (! read_app_point(is, app_target)) return false;
Rational r2, s2, t2, u2, v2, w2; Rational r2, s2, t2, u2, v2, w2;
is >> r2 >> s2 >> t2 >> u2 >> v2 >> w2; is >> r2 >> s2 >> t2 >> u2 >> v2 >> w2;
@ -333,34 +325,36 @@ 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();
app_source, r1, s1, t1, u1, v1, w1, cv = ctr_cv(r, s, t, u, v, w, orient,
app_target, r2, s2, t2, u2, v2, w2); app_source, r1, s1, t1, u1, v1, w1,
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;
CGAL::Orientation orient; CGAL::Orientation orient;
Conic_point_2 source, target; Conic_point_2 source, target;
if (!read_orientation_and_end_points(is, orient, source, target)) if (! read_orientation_and_end_points(is, orient, source, target))
return false; return false;
// Create the conic (or circular) arc. // Create the conic (or circular) arc.
@ -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,14 +392,14 @@ 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)));
std::vector<Conic_curve_2> conic_curves, conic_curves_2, Conic_curves_3; std::vector<Conic_curve_2> conic_curves, conic_curves_2, Conic_curves_3;
conic_curves.push_back(c1); conic_curves.push_back(c1);
@ -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,21 +747,21 @@ 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();
conic_curves.push_back(c11); conic_curves.push_back(c11);
conic_curves.push_back(c12); conic_curves.push_back(c12);
//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

@ -40,51 +40,50 @@ 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; X_monotone_curve_2 xarc;
std::list<CGAL::Object>::iterator it;
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.
Polygon_2 P; Polygon_2 P;
append_conic_arc (P, parabola1); append_conic_arc(P, parabola1);
append_conic_arc (P, parabola2); append_conic_arc(P, parabola2);
// 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;
CGAL::intersection (P, Q, std::back_inserter(res)); CGAL::intersection(P, Q, std::back_inserter(res));
std::copy (res.begin(), res.end(), // export to standard output std::copy(res.begin(), res.end(), // export to standard output
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

File diff suppressed because it is too large Load Diff

View File

@ -1816,8 +1816,8 @@ protected:
namespace CGAL namespace CGAL
{ {
template<class T> template<class ... T>
void draw(const T&, const char* ="", bool=false) void draw(T...)
{ {
std::cerr<<"Impossible to draw, CGAL_USE_BASIC_VIEWER is not defined."<<std::endl; std::cerr<<"Impossible to draw, CGAL_USE_BASIC_VIEWER is not defined."<<std::endl;
} }

View File

@ -76,6 +76,12 @@ CGAL tetrahedral Delaunay refinement algorithm.
### [2D Arrangements](https://doc.cgal.org/5.6/Manual/packages.html#PkgArrangementOnSurface2) ### [2D Arrangements](https://doc.cgal.org/5.6/Manual/packages.html#PkgArrangementOnSurface2)
- Fixed some code that handles geodesic-curves on spheres that compare x- and y-coordinates on the boundary of the parameter space. It mainly effected the naive point-location. - Fixed some code that handles geodesic-curves on spheres that compare x- and y-coordinates on the boundary of the parameter space. It mainly effected the naive point-location.
- Introduced an overload function template, namely `draw(arr)`, that renders arrangements based on the `Basic_viewer_qt` class template. At this point only 2D arrangements on the plane induced by (i) segments, (ii) conics, and (iii) circular arcs or (linear) segments are supported.
- Improved the traits class template that handles conics, namely `Arr_conic_traits_2`. This includes the following:
1. Fixed a couple of bugs and slightly optimized some functions.
2. Introduced functionality that approximates conics with polylines. (This is used to draw conic curves.)
3. **Breaking change**: Changed the interface to generate conic curves. In the past, curves where generated directly using the constructors of the conic and x-monotone conic constructs. Now, they are constructed via function objects provided by the traits. This eliminates the constructions of temporary kernels. The old functionality is obsolete, but still supported for a limited number of versions. It depends on a static member function of the traits. In a future version this function will no longer be static, implying that the old functionality will no longer be supported.
- Introduced functionality that approximates circular segments with polylines. (This is used to draw conic curves.)
### [2D Convex Hulls](https://doc.cgal.org/5.6/Manual/packages.html#PkgConvexHull2) ### [2D Convex Hulls](https://doc.cgal.org/5.6/Manual/packages.html#PkgConvexHull2)

View File

@ -28,11 +28,9 @@ namespace CGAL {
* A base class for computing the offset of a given polygon by a given * A base class for computing the offset of a given polygon by a given
* radius in an exact manner. * radius in an exact manner.
*/ */
template <class Traits_, class Container_> template <typename Traits_, typename Container_>
class Exact_offset_base_2 class Exact_offset_base_2 {
{
private: private:
typedef Traits_ Traits_2; typedef Traits_ Traits_2;
// Rational kernel types: // Rational kernel types:
@ -48,7 +46,6 @@ protected:
typedef Rational Basic_NT; typedef Rational Basic_NT;
private: private:
// Algebraic kernel types: // Algebraic kernel types:
typedef typename Traits_2::Alg_kernel Alg_kernel; typedef typename Traits_2::Alg_kernel Alg_kernel;
typedef typename Alg_kernel::FT Algebraic; typedef typename Alg_kernel::FT Algebraic;
@ -63,7 +60,6 @@ private:
typedef CGAL::Gps_traits_2<Traits_2> Gps_traits_2; typedef CGAL::Gps_traits_2<Traits_2> Gps_traits_2;
protected: protected:
typedef CGAL::Polygon_2<Rat_kernel, Container_> Polygon_2; typedef CGAL::Polygon_2<Rat_kernel, Container_> Polygon_2;
typedef CGAL::Polygon_with_holes_2<Rat_kernel, typedef CGAL::Polygon_with_holes_2<Rat_kernel,
Container_> Polygon_with_holes_2; Container_> Polygon_with_holes_2;
@ -75,21 +71,15 @@ private:
typedef typename Polygon_2::Vertex_circulator Vertex_circulator; typedef typename Polygon_2::Vertex_circulator Vertex_circulator;
protected: protected:
typedef Arr_labeled_traits_2<Traits_2> Labeled_traits_2; typedef Arr_labeled_traits_2<Traits_2> Labeled_traits_2;
typedef typename Labeled_traits_2::X_monotone_curve_2 Labeled_curve_2; typedef typename Labeled_traits_2::X_monotone_curve_2 Labeled_curve_2;
public: public:
/*! Default constructor. */ /*! Default constructor. */
Exact_offset_base_2 () Exact_offset_base_2() {}
{}
protected: protected:
/*! Compute the curves that constitute the offset of a simple polygon by a
/*!
* Compute the curves that constitute the offset of a simple polygon by a
* given radius. * given radius.
* \param pgn The polygon. * \param pgn The polygon.
* \param orient The orientation to traverse the vertices. * \param orient The orientation to traverse the vertices.
@ -99,16 +89,16 @@ protected:
* \pre The value type of the output iterator is Labeled_curve_2. * \pre The value type of the output iterator is Labeled_curve_2.
* \return A past-the-end iterator for the holes container. * \return A past-the-end iterator for the holes container.
*/ */
template <class OutputIterator> template <typename OutputIterator>
OutputIterator _offset_polygon (const Polygon_2& pgn, OutputIterator _offset_polygon(const Polygon_2& pgn,
CGAL::Orientation orient, CGAL::Orientation orient,
const Rational& r, const Rational& r,
unsigned int cycle_id, unsigned int cycle_id,
OutputIterator oi) const OutputIterator oi) const
{ {
// Prepare circulators over the polygon vertices. // Prepare circulators over the polygon vertices.
const bool forward = (pgn.orientation() == orient); const bool forward = (pgn.orientation() == orient);
Vertex_circulator first, curr, next; Vertex_circulator first, curr, next;
first = pgn.vertices_circulator(); first = pgn.vertices_circulator();
curr = first; curr = first;
@ -116,38 +106,33 @@ protected:
// Traverse the polygon vertices and edges and construct the arcs that // Traverse the polygon vertices and edges and construct the arcs that
// constitute the single convolution cycle. // constitute the single convolution cycle.
Alg_kernel alg_ker; const Rational sqr_r = CGAL::square (r);
typename Alg_kernel::Equal_2 f_equal = alg_ker.equal_2_object(); Rational x1, y1; // The source of the current edge.
Rational x2, y2; // The target of the current edge.
Rational delta_x, delta_y; // (x2 - x1) and (y2 - y1), resp.
Algebraic len; // The length of the current edge.
Algebraic trans_x, trans_y; // The translation vector.
Alg_point_2 op1, op2; // The edge points of the offset edge.
Alg_point_2 first_op; // The first offset point.
Algebraic a, b, c;
Nt_traits nt_traits; unsigned int curve_index(0);
const Rational sqr_r = CGAL::square (r); std::list<Object> xobjs;
const Algebraic alg_r = nt_traits.convert (r);
Rational x1, y1; // The source of the current edge.
Rational x2, y2; // The target of the current edge.
Rational delta_x, delta_y; // (x2 - x1) and (y2 - y1), resp.
Algebraic len; // The length of the current edge.
Algebraic trans_x, trans_y; // The translation vector.
Alg_point_2 op1, op2; // The edge points of the offset edge.
Alg_point_2 first_op; // The first offset point.
Algebraic a, b, c;
unsigned int curve_index = 0; Traits_2 traits;
Traits_2 traits; auto nt_traits = traits.nt_traits();
std::list<Object> xobjs; const Algebraic alg_r = nt_traits->convert(r);
std::list<Object>::iterator xobj_it; auto f_make_x_monotone = traits.make_x_monotone_2_object();
typename Traits_2::Make_x_monotone_2
f_make_x_monotone = traits.make_x_monotone_2_object();
Curve_2 arc;
X_monotone_curve_2 xarc;
bool assign_success;
do auto alg_ker = traits.alg_kernel();
{ auto f_equal = alg_ker->equal_2_object();
bool assign_success;
do {
// Get a circulator for the next vertex (in the proper orientation). // Get a circulator for the next vertex (in the proper orientation).
if (forward) if (forward) ++next;
++next; else --next;
else
--next;
// Compute the vector v = (delta_x, delta_y) of the current edge, // Compute the vector v = (delta_x, delta_y) of the current edge,
// and compute the edge length ||v||. // and compute the edge length ||v||.
@ -158,8 +143,8 @@ protected:
delta_x = x2 - x1; delta_x = x2 - x1;
delta_y = y2 - y1; delta_y = y2 - y1;
len = nt_traits.sqrt (nt_traits.convert (CGAL::square (delta_x) + len = nt_traits->sqrt(nt_traits->convert(CGAL::square(delta_x) +
CGAL::square (delta_y))); CGAL::square(delta_y)));
// The angle theta between the vector v and the x-axis is given by: // The angle theta between the vector v and the x-axis is given by:
// //
@ -174,45 +159,39 @@ protected:
// //
// trans_x = r*cos(alpha - PI/2) = r*sin(alpha) // trans_x = r*cos(alpha - PI/2) = r*sin(alpha)
// trans_y = r*sin(alpha - PI/2) = -r*cos(alpha) // trans_y = r*sin(alpha - PI/2) = -r*cos(alpha)
trans_x = nt_traits.convert (r * delta_y) / len; trans_x = nt_traits->convert(r * delta_y) / len;
trans_y = nt_traits.convert (-r * delta_x) / len; trans_y = nt_traits->convert(-r * delta_x) / len;
// Construct the first offset vertex, which corresponds to the // Construct the first offset vertex, which corresponds to the
// source vertex of the current polygon edge. // source vertex of the current polygon edge.
op1 = Alg_point_2 (nt_traits.convert (x1) + trans_x, op1 = Alg_point_2(nt_traits->convert(x1) + trans_x,
nt_traits.convert (y1) + trans_y); nt_traits->convert(y1) + trans_y);
if (curr == first) if (curr == first) {
{
// This is the first edge we visit -- store op1 for future use. // This is the first edge we visit -- store op1 for future use.
first_op = op1; first_op = op1;
} }
else else {
{ if (! f_equal (op2, op1)) {
if (! f_equal (op2, op1))
{
// Connect op2 (from the previous iteration) and op1 with a circular // Connect op2 (from the previous iteration) and op1 with a circular
// arc, whose supporting circle is (x1, x2) with radius r. // arc, whose supporting circle is (x1, x2) with radius r.
arc = Curve_2 (Rat_circle_2 (*curr, sqr_r), auto ctr_cv = traits.construct_curve_2_object();
CGAL::COUNTERCLOCKWISE, Curve_2 arc = ctr_cv(Rat_circle_2 (*curr, sqr_r),
op2, op1); CGAL::COUNTERCLOCKWISE, op2, op1);
// Subdivide the arc into x-monotone subarcs and append them to the // Subdivide the arc into x-monotone subarcs and append them to the
// convolution cycle. // convolution cycle.
xobjs.clear(); xobjs.clear();
f_make_x_monotone (arc, std::back_inserter(xobjs)); f_make_x_monotone(arc, std::back_inserter(xobjs));
for (xobj_it = xobjs.begin(); xobj_it != xobjs.end(); ++xobj_it) for (auto xobj_it = xobjs.begin(); xobj_it != xobjs.end(); ++xobj_it) {
{ X_monotone_curve_2 xarc;
assign_success = CGAL::assign (xarc, *xobj_it); assign_success = CGAL::assign(xarc, *xobj_it);
CGAL_assertion (assign_success); CGAL_assertion (assign_success);
CGAL_USE(assign_success); CGAL_USE(assign_success);
*oi = Labeled_curve_2 (xarc, *oi++ = Labeled_curve_2(xarc, X_curve_label(xarc.is_directed_right(),
X_curve_label (xarc.is_directed_right(), cycle_id, curve_index));
cycle_id,
curve_index));
++oi;
curve_index++; curve_index++;
} }
} }
@ -220,25 +199,21 @@ protected:
// Construct the second offset vertex, which corresponds to the // Construct the second offset vertex, which corresponds to the
// target vertex of the current polygon edge. // target vertex of the current polygon edge.
op2 = Alg_point_2 (nt_traits.convert (x2) + trans_x, op2 = Alg_point_2(nt_traits->convert(x2) + trans_x,
nt_traits.convert (y2) + trans_y); nt_traits->convert(y2) + trans_y);
// The equation of the line connecting op1 and op2 is given by: // The equation of the line connecting op1 and op2 is given by:
// //
// (y1 - y2)*x + (x2 - x1)*y + (r*len - y1*x2 - x1*y2) = 0 // (y1 - y2)*x + (x2 - x1)*y + (r*len - y1*x2 - x1*y2) = 0
// //
a = nt_traits.convert (-delta_y); a = nt_traits->convert(-delta_y);
b = nt_traits.convert (delta_x); b = nt_traits->convert(delta_x);
c = alg_r*len - nt_traits.convert (y1*x2 - x1*y2); c = alg_r*len - nt_traits->convert(y1*x2 - x1*y2);
xarc = X_monotone_curve_2 (a, b, c, auto ctr_xcv = traits.construct_x_monotone_curve_2_object();
op1, op2); X_monotone_curve_2 xarc = ctr_xcv(a, b, c, op1, op2);
*oi++ = Labeled_curve_2(xarc, X_curve_label(xarc.is_directed_right(),
*oi = Labeled_curve_2 (xarc, cycle_id, curve_index));
X_curve_label (xarc.is_directed_right(),
cycle_id,
curve_index));
++oi;
curve_index++; curve_index++;
// Proceed to the next polygon vertex. // Proceed to the next polygon vertex.
@ -246,42 +221,38 @@ protected:
} while (curr != first); } while (curr != first);
if (! f_equal (op2, first_op)) if (! f_equal (op2, first_op)) {
{
// Close the convolution cycle by creating the final circular arc, // Close the convolution cycle by creating the final circular arc,
// centered at the first vertex. // centered at the first vertex.
arc = Curve_2 (Rat_circle_2 (*first, sqr_r), auto ctr_cv = traits.construct_curve_2_object();
CGAL::COUNTERCLOCKWISE, Curve_2 arc = ctr_cv(Rat_circle_2 (*first, sqr_r),
op2, first_op); CGAL::COUNTERCLOCKWISE, op2, first_op);
// Subdivide the arc into x-monotone subarcs and append them to the // Subdivide the arc into x-monotone subarcs and append them to the
// convolution cycle. // convolution cycle.
bool is_last; bool is_last;
xobjs.clear(); xobjs.clear();
f_make_x_monotone (arc, std::back_inserter(xobjs)); f_make_x_monotone(arc, std::back_inserter(xobjs));
xobj_it = xobjs.begin(); auto xobj_it = xobjs.begin();
while (xobj_it != xobjs.end()) while (xobj_it != xobjs.end()) {
{ X_monotone_curve_2 xarc;
assign_success = CGAL::assign (xarc, *xobj_it); assign_success = CGAL::assign(xarc, *xobj_it);
CGAL_assertion (assign_success); CGAL_assertion (assign_success);
CGAL_USE(assign_success); CGAL_USE(assign_success);
++xobj_it; ++xobj_it;
is_last = (xobj_it == xobjs.end()); is_last = (xobj_it == xobjs.end());
*oi = Labeled_curve_2 (xarc, *oi++ = Labeled_curve_2(xarc, X_curve_label(xarc.is_directed_right(),
X_curve_label (xarc.is_directed_right(), cycle_id, curve_index,
cycle_id, is_last));
curve_index,
is_last));
++oi;
curve_index++; curve_index++;
} }
} }
return (oi); return oi;
} }
}; };

View File

@ -222,7 +222,7 @@ protected:
* \param c2 The second curve. * \param c2 The second curve.
*/ */
void _create_intersection_point(const Point_2& xp, void _create_intersection_point(const Point_2& xp,
unsigned int mult, Multiplicity mult,
Subcurve*& c1, Subcurve*& c1,
Subcurve*& c2); Subcurve*& c2);
}; };

View File

@ -773,7 +773,7 @@ void Surface_sweep_2<Vis>::_intersect(Subcurve* c1, Subcurve* c2,
// //
template <typename Vis> template <typename Vis>
void Surface_sweep_2<Vis>::_create_intersection_point(const Point_2& xp, void Surface_sweep_2<Vis>::_create_intersection_point(const Point_2& xp,
unsigned int multiplicity, Multiplicity multiplicity,
Subcurve*& c1, Subcurve*& c1,
Subcurve*& c2) Subcurve*& c2)
{ {

View File

@ -62,8 +62,8 @@ struct Default_arr_traits<CGAL::internal::Polycurve_2
}; };
template <typename Rat_kernel_, class Alg_kernel_, class Nt_traits_> template <typename Rat_kernel_, class Alg_kernel_, class Nt_traits_>
struct Default_arr_traits<CGAL::_Conic_arc_2<Rat_kernel_, Alg_kernel_, struct Default_arr_traits<CGAL::Conic_arc_2<Rat_kernel_, Alg_kernel_,
Nt_traits_> > Nt_traits_> >
{ {
typedef CGAL::Arr_conic_traits_2<Rat_kernel_, Alg_kernel_, Nt_traits_> typedef CGAL::Arr_conic_traits_2<Rat_kernel_, Alg_kernel_, Nt_traits_>
Traits; Traits;

View File

@ -40,13 +40,15 @@ typedef std::list<Curve_2> CurveList;
typedef std::list<Point_2> PointList; typedef std::list<Point_2> PointList;
typedef PointList::iterator PointListIter; typedef PointList::iterator PointListIter;
/*! Conic reader */ /*! Conic reader */
template <typename Traits> template <typename Traits>
class Conic_reader { class Conic_reader {
private:
Traits_2 m_traits;
public: public:
int ReadData(const char* filename, CurveList& curves, CGAL::Bbox_2& bbox) int read_data(const char* filename, CurveList& curves, CGAL::Bbox_2& bbox,
{ const Traits& traits) {
Curve_2 cv; Curve_2 cv;
char dummy[256]; char dummy[256];
@ -58,10 +60,10 @@ public:
int count; int count;
inp >> count; inp >> count;
inp.getline(dummy, sizeof(dummy)); inp.getline(dummy, sizeof(dummy));
for (int i = 0; i < count; i++) { for (int i = 0; i < count; ++i) {
ReadCurve(inp, cv); read_curve(inp, cv);
curves.push_back(cv); curves.push_back(cv);
CGAL::Bbox_2 curve_bbox = cv.bbox(); CGAL::Bbox_2 curve_bbox = 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;
} }
@ -69,50 +71,47 @@ public:
return 0; return 0;
} }
void ReadCurve(std::ifstream & is, Curve_2 & cv) void 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];
skip_comments (is, one_line); skip_comments(is, one_line);
std::string stringvalues(one_line); std::string stringvalues(one_line);
std::istringstream str_line (stringvalues, std::istringstream::in); std::istringstream str_line(stringvalues, std::istringstream::in);
// Get the arc type. // Get the arc type.
// Supported types are: 'f' - Full ellipse (or circle). // Supported types are: 'f' - Full ellipse (or circle).
// 'e' - Elliptic arc (or circular arc). // 'e' - Elliptic arc (or circular arc).
// 's' - Line segment. // 's' - Line segment.
char type; bool is_circle(false); // Is this a circle.
bool is_circle = false; // Is this a circle.
Rat_circle_2 circle; Rat_circle_2 circle;
Rational r, s, t, u, v, w; // The conic coefficients. Rational r, s, t, u, v, w; // The conic coefficients.
char type;
str_line >> type; str_line >> type;
// An ellipse (full ellipse or a partial ellipse): // An ellipse (full ellipse or a partial ellipse):
if (type == 'f' || type == 'F' || type == 'e' || type == 'E') if (type == 'f' || type == 'F' || type == 'e' || type == 'E') {
{
// Read the ellipse (using the format "a b x0 y0"): // Read the ellipse (using the format "a b x0 y0"):
// //
// x - x0 2 y - y0 2 // x - x0 2 y - y0 2
// ( -------- ) + ( -------- ) = 1 // ( -------- ) + ( -------- ) = 1
// a b // a b
// //
int a, b, x0, y0; int a, b, x0, y0;
str_line >> a >> b >> x0 >> y0; str_line >> a >> b >> x0 >> y0;
Rational a_sq = Rational(a*a); Rational a_sq = Rational(a*a);
Rational b_sq = Rational(b*b); Rational b_sq = Rational(b*b);
if (a == b) if (a == b) {
{
is_circle = true; is_circle = true;
circle = Rat_circle_2 (Rat_point_2 (Rational(x0), Rational(y0)), circle =
Rational(a*b)); Rat_circle_2(Rat_point_2(Rational(x0), Rational(y0)), Rational(a*b));
} }
else else {
{
r = b_sq; r = b_sq;
s = a_sq; s = a_sq;
t = 0; t = 0;
@ -121,54 +120,43 @@ public:
w = Rational(x0*x0*b_sq + y0*y0*a_sq - a_sq*b_sq); w = Rational(x0*x0*b_sq + y0*y0*a_sq - a_sq*b_sq);
} }
if (type == 'f' || type == 'F') if (type == 'f' || type == 'F') {
{
// Create a full ellipse (or circle). // Create a full ellipse (or circle).
if (is_circle) cv = (is_circle) ? ctr_cv(circle) : ctr_cv(r, s, t, u, v, w);
cv = Curve_2 (circle); return;
else
cv = Curve_2 (r, s, t, u, v, w);
} }
else
{
// Read the endpointd of the arc.
int x1, y1, x2, y2;
str_line >> x1 >> y1 >> x2 >> y2; // Read the endpointd of the arc.
int x1, y1, x2, y2;
str_line >> x1 >> y1 >> x2 >> y2;
Point_2 source = Point_2 (Algebraic(x1), Algebraic(y1)); Point_2 source = Point_2 (Algebraic(x1), Algebraic(y1));
Point_2 target = Point_2 (Algebraic(x2), Algebraic(y2)); Point_2 target = Point_2 (Algebraic(x2), Algebraic(y2));
// Create the arc. Note that it is always clockwise oriented. // Create the arc. Note that it is always clockwise oriented.
if (is_circle) cv = (is_circle) ?
cv = Curve_2 (circle, ctr_cv(circle, CGAL::CLOCKWISE, source, target) :
CGAL::CLOCKWISE, ctr_cv(r, s, t, u, v, w, CGAL::CLOCKWISE, source, target);
source, target); return;
else
cv = Curve_2 (r, s, t, u, v, w,
CGAL::CLOCKWISE,
source, target);
}
} }
else if (type == 's' || type == 'S')
{
// Read a segment, given by its endpoints (x1,y1) and (x2,y2);
int x1, y1, x2, y2;
if (type == 's' || type == 'S') {
// Read a segment, given by its endpoints (x1,y1) and (x2,y2);
int x1, y1, x2, y2;
str_line >> x1 >> y1 >> x2 >> y2; str_line >> x1 >> y1 >> x2 >> y2;
// Create the segment. // Create the segment.
Rat_point_2 source = Rat_point_2 (Rational(x1), Rational(y1)); Rat_point_2 source = Rat_point_2(Rational(x1), Rational(y1));
Rat_point_2 target = Rat_point_2 (Rational(x2), Rational(y2)); Rat_point_2 target = Rat_point_2(Rational(x2), Rational(y2));
cv = Curve_2(Rat_segment_2 (source, target)); cv = ctr_cv(Rat_segment_2(source, target));
return;
} }
return; std::cerr << "Invalid type (" << type << ")" << std::endl;
} }
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] != '#' ){ if( one_line[0] != '#' ){
@ -181,42 +169,39 @@ public:
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// The main: // The main:
// //
int main (int argc, char** argv) int main(int argc, char* argv[]) {
{
bool verbose = false; bool verbose = false;
// Define a test objects to read the conic arcs from it. // Define a test objects to read the conic arcs from it.
if (argc<2) if (argc<2) {
{
std::cerr << "Usage: Conic_traits_test <filename>" << std::endl; std::cerr << "Usage: Conic_traits_test <filename>" << std::endl;
exit(1); exit(1);
} }
Traits_2 traits;
CGAL::Bbox_2 bbox; CGAL::Bbox_2 bbox;
CurveList curves; CurveList curves;
Conic_reader<Traits_2> reader; Conic_reader<Traits_2> reader;
reader.ReadData(argv[1], curves, bbox); reader.read_data(argv[1], curves, bbox, traits);
// run the sweep // run the sweep
std::list<X_monotone_curve_2> mylist; std::list<X_monotone_curve_2> mylist;
CGAL::compute_subcurves(curves.begin(), curves.end(), CGAL::compute_subcurves(curves.begin(), curves.end(),
std::back_inserter(mylist), false); std::back_inserter(mylist), false);
PointList point_list_with_ends; PointList point_list_with_ends;
CGAL::compute_intersection_points(curves.begin(), curves.end(), CGAL::compute_intersection_points(curves.begin(), curves.end(),
std::back_inserter(point_list_with_ends), true); std::back_inserter(point_list_with_ends),
true);
std::size_t point_count_with_ends_calculated = point_list_with_ends.size(); std::size_t point_count_with_ends_calculated = point_list_with_ends.size();
// generate the string for the output // generate the string for the output
std::stringstream out1; std::stringstream out1;
for ( std::list<X_monotone_curve_2>::iterator iter = mylist.begin() ; for (auto iter = mylist.begin(); iter != mylist.end(); ++iter)
iter != mylist.end() ; ++iter )
{
out1 << *iter << "\n"; out1 << *iter << "\n";
}
// read the output from the file // read the output from the file
std::stringstream out2; std::stringstream out2;
@ -226,12 +211,10 @@ int main (int argc, char** argv)
std::ifstream in_file(argv[1]); std::ifstream in_file(argv[1]);
in_file >> count; in_file >> count;
in_file.getline(buf, 1024); // to get rid of the new line in_file.getline(buf, 1024); // to get rid of the new line
for ( int i = 0 ; i < count ; i++ ) { for (int i = 0 ; i < count ; ++i) in_file.getline(buf, 1024);
in_file.getline(buf, 1024);
}
in_file >> count; in_file >> count;
in_file.getline(buf, 1024); // to get rid of the new line in_file.getline(buf, 1024); // to get rid of the new line
for (int i = 0; i < count; i++) { for (int i = 0; i < count; ++i) {
in_file.getline(buf, 1024); in_file.getline(buf, 1024);
out2 << buf << "\n"; out2 << buf << "\n";
} }
@ -239,31 +222,28 @@ int main (int argc, char** argv)
in_file >> point_count_with_ends_from_file; in_file >> point_count_with_ends_from_file;
in_file.close(); in_file.close();
if ( verbose ) if (verbose) {
{
std::cout << "Result: \n" << mylist.size() << "\n"; std::cout << "Result: \n" << mylist.size() << "\n";
for ( std::list<X_monotone_curve_2>::iterator i = mylist.begin() ; for (auto i = mylist.begin(); i != mylist.end() ; ++i)
i != mylist.end() ; ++i )
{
std::cout << *i << "\n"; std::cout << *i << "\n";
}
} }
std::string calculated = out1.str(); std::string calculated = out1.str();
std::string infile = out2.str(); std::string infile = out2.str();
if ( infile == calculated ) { if (infile == calculated) {
if ( point_count_with_ends_from_file != if (point_count_with_ends_from_file != point_count_with_ends_calculated) {
point_count_with_ends_calculated ) {
std::cout << "number of intersection points (with ends):" std::cout << "number of intersection points (with ends):"
<< point_count_with_ends_calculated << ". Should be " << point_count_with_ends_calculated << ". Should be "
<< point_count_with_ends_from_file << "\n"; << point_count_with_ends_from_file << "\n";
std::cout << argv[1] << " Error\n"; std::cout << argv[1] << " Error\n";
return -1; return -1;
} else { }
else {
std::cout << argv[1] << " OK!\n"; std::cout << argv[1] << " OK!\n";
} }
} else { }
else {
std::cout << argv[1] << " Error\n"; std::cout << argv[1] << " Error\n";
std::cout << "\ncalculated:\n"; std::cout << "\ncalculated:\n";
std::cout << calculated << std::endl; std::cout << calculated << std::endl;