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

View File

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

View File

@ -18,8 +18,10 @@
#include <string>
template <typename Traits>
class Conic_reader
{
class Conic_reader {
private:
const Traits& m_traits;
public:
typedef typename Traits::Curve_2 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_circle_2 Rat_circle_2;
template<class OutputIterator>
int read_data(std::ifstream & inp, OutputIterator curves_out,
CGAL::Bbox_2 & bbox)
// Cnstruct from traits.
Conic_reader(const Traits& traits) : m_traits(traits) {}
//
template <class OutputIterator>
int read_data(std::ifstream& inp, OutputIterator curves_out,
CGAL::Bbox_2& bbox)
{
Curve_2 cv;
@ -49,7 +55,7 @@ public:
for (int i = 0; i < count; i++) {
if (read_curve(inp, 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;
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.
char one_line[128];
@ -67,12 +74,11 @@ public:
std::istringstream str_line (one_line);
// Read the arc type and act accordingly.
char type;
char type;
str_line >> type;
if (type == 's' || type == 'S')
{
if (type == 's' || type == 'S') {
// Construct a line segment. The line should have the format:
// s <x1> <y1> <x2> <y2>
// where (x1, y1), (x2, y2) are the endpoints of a segment.
@ -81,49 +87,46 @@ public:
//str_line >> x1 >> y1 >> x2 >> y2;
str_line >> buf;
x1 = Algebraic( buf ).BigRatValue( );
x1 = Algebraic( buf ).BigRatValue();
str_line >> buf;
y1 = Algebraic( buf ).BigRatValue( );
y1 = Algebraic( buf ).BigRatValue();
str_line >> buf;
x2 = Algebraic( buf ).BigRatValue( );
x2 = Algebraic( buf ).BigRatValue();
str_line >> buf;
y2 = Algebraic( buf ).BigRatValue( );
y2 = Algebraic( buf ).BigRatValue();
Rat_point_2 p1(x1, y1), p2(x2, y2);
Rat_segment_2 seg (p1, p2);
Rat_point_2 p1(x1, y1), p2(x2, y2);
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:
// c <x0> <y0> <R_sq>
// where (x0, y0) is the center of the circle and R_sq is its squared
// radius.
Rational x0, y0, R_sq;
Rational x0, y0, R_sq;
str_line >> x0 >> y0 >> R_sq;
Rat_point_2 p0(x0, y0);
Rat_circle_2 circ(p0, R_sq);
Rat_point_2 p0(x0, y0);
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:
// t <x1> <y1> <x2> <y2> <x3> <y3>
// 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;
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:
// c <r> <s> <t> <u> <v> <w>
// where r, s, t, u, v, w define the conic equation.
@ -131,10 +134,9 @@ public:
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:
// 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)
@ -144,16 +146,13 @@ public:
str_line >> r >> s >> t >> u >> v >> w;
// Read the orientation.
int i_orient;
int i_orient;
CGAL::Orientation orient;
str_line >> i_orient;
if (i_orient > 0)
orient = CGAL::COUNTERCLOCKWISE;
else if (i_orient < 0)
orient = CGAL::CLOCKWISE;
else
orient = CGAL::COLLINEAR;
if (i_orient > 0) orient = CGAL::COUNTERCLOCKWISE;
else if (i_orient < 0) orient = CGAL::CLOCKWISE;
else orient = CGAL::COLLINEAR;
// Read the end points of the arc and create it.
// Notice we read the coordinates as strings, then we convert them to
@ -175,10 +174,9 @@ public:
Point_2 ps (x1, y1);
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:
// 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
@ -189,16 +187,15 @@ public:
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:
// e <r1_1> <r2_1> <x0_1> <y0_1> // raddi and center of ellipse
int x0, y0, r1, r2;
Rational sqr_r1, sqr_r2;
Rational R, S, T, U, V, W;
int x0, y0, r1, r2;
Rational sqr_r1, sqr_r2;
Rational R, S, T, U, V, W;
str_line >> r1 >> r2 >> x0 >> y0;
@ -211,10 +208,9 @@ public:
V = -2 * sqr_r1 * y0;
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::endl;
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()) {
is.getline(one_line, 128);
if (one_line[0] != '#') break;
@ -234,13 +229,10 @@ public:
// should probably change class name since it reads and writes
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;
for (auto it = begin_; it != end_; ++it)
{
if (it->is_full_conic())
{
for (auto it = begin_; it != end_; ++it) {
if (it->is_full_conic()) {
ofs << "F ";
ofs << it->r() << " ";
ofs << it->s() << " ";
@ -250,15 +242,13 @@ public:
ofs << it->w() << " ";
ofs << std::endl;
}
else if (it->orientation() == CGAL::COLLINEAR)
{
else if (it->orientation() == CGAL::COLLINEAR) {
ofs << "S ";
ofs << it->source() << " ";
ofs << it->target() << " ";
ofs << std::endl;
}
else
{
else {
ofs << "A ";
ofs << it->r() << " ";
ofs << it->s() << " ";
@ -266,12 +256,9 @@ public:
ofs << it->u() << " ";
ofs << it->v() << " ";
ofs << it->w() << " ";
if (it->orientation() == CGAL::COUNTERCLOCKWISE)
ofs << "1 ";
else if (it->orientation() == CGAL::CLOCKWISE)
ofs << "-1 ";
else
ofs << "0 ";
if (it->orientation() == CGAL::COUNTERCLOCKWISE) ofs << "1 ";
else if (it->orientation() == CGAL::CLOCKWISE) ofs << "-1 ";
else ofs << "0 ";
ofs << it->source() << " ";
ofs << it->target() << " ";
ofs << std::endl;

View File

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

View File

@ -23,48 +23,47 @@
namespace CGAL {
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
template < class ArrTraits >
class CurveGraphicsItem : public GraphicsItem, public GraphicsSceneMixin
{
template <typename GeometryTraits>
class CurveGraphicsItem : public GraphicsItem, public GraphicsSceneMixin {
public:
// known curve types
typedef ArrTraits Traits;
typedef typename Traits::Curve_2 Curve_2;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Traits::Point_2 Point_2;
typedef GeometryTraits Traits;
typedef typename Traits::Curve_2 Curve_2;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Traits::Point_2 Point_2;
public: // ctors
CurveGraphicsItem( );
public:
// Construct from traits.
CurveGraphicsItem(const Traits& traits);
public: // methods
void paint(
QPainter* painter, const QStyleOptionGraphicsItem* /* option */,
QWidget* /* widget */) override;
QRectF boundingRect( ) const override;
void insert( const X_monotone_curve_2& curve );
void insert( const Point_2& point );
void clear( );
void paint(QPainter* painter, const QStyleOptionGraphicsItem* /* option */,
QWidget* /* widget */) override;
QRectF boundingRect() const override;
void insert(const X_monotone_curve_2& curve);
void insert(const Point_2& point);
void clear();
public Q_SLOTS:
void modelChanged( ) override;
const QColor& edgeColor( ) const;
void setEdgeColor( const QColor& color );
int edgeWidth( ) const;
void setEdgeWidth( int width );
const QColor& vertexColor( ) const;
void setVertexColor( const QColor& color );
int vertexRadius( ) const;
void setVertexRadius( int radius );
void modelChanged() override;
const QColor& edgeColor() const;
void setEdgeColor(const QColor& color);
int edgeWidth() const;
void setEdgeWidth(int width);
const QColor& vertexColor() const;
void setVertexColor(const QColor& color);
int vertexRadius() const;
void setVertexRadius(int radius);
protected: // methods
void updateBoundingBox( );
protected: // fields
std::vector< X_monotone_curve_2 > curves;
const Traits& m_traits;
std::vector<X_monotone_curve_2> curves;
PointsGraphicsItem pointsGraphicsItem;
CGAL::Bbox_2 bb;

View File

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

View File

@ -84,10 +84,13 @@ struct ExplicitLambda
CGAL::Object& arr_obj;
QObject* parent;
};
} // 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;
ExplicitLambda explicit_lambda{res, arr_obj, parent};
@ -95,11 +98,12 @@ EnvelopeCallbackBase* EnvelopeCallbackBase::create(
return res;
}
//
template <typename Arr_>
EnvelopeCallback<Arr_>::EnvelopeCallback(Arrangement* arr_, QObject* parent) :
EnvelopeCallbackBase(parent), arr(arr_),
lowerEnvelope(new CGAL::Qt::CurveGraphicsItem<Traits>()),
upperEnvelope(new CGAL::Qt::CurveGraphicsItem<Traits>()), showLower(false),
lowerEnvelope(new CGAL::Qt::CurveGraphicsItem<Traits>(*(arr_->geometry_traits()))),
upperEnvelope(new CGAL::Qt::CurveGraphicsItem<Traits>(*(arr_->geometry_traits()))), showLower(false),
showUpper(false)
{
this->lowerEnvelope->hide();
@ -107,7 +111,7 @@ EnvelopeCallback<Arr_>::EnvelopeCallback(Arrangement* arr_, QObject* parent) :
}
template < typename Arr_ >
void EnvelopeCallback<Arr_>::setEnvelopeEdgeColor( const QColor& color )
void EnvelopeCallback<Arr_>::setEnvelopeEdgeColor(const QColor& color)
{
this->lowerEnvelope->setEdgeColor( color );
this->upperEnvelope->setEdgeColor( color );

View File

@ -24,11 +24,10 @@
#include <QEvent>
#include <QKeyEvent>
//
template <std::size_t I = 0, typename FuncT, typename... Tp>
inline std::enable_if_t<I == sizeof...(Tp), void>
for_each(std::tuple<Tp...>&, FuncT)
{
}
inline typename std::enable_if<I == sizeof...(Tp), void>::type
for_each(std::tuple<Tp...>&, FuncT) {}
template <std::size_t I = 0, typename FuncT, typename... Tp>
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);
}
namespace CGAL
{
namespace Qt
{
namespace CGAL {
namespace Qt {
GraphicsViewCurveInputBase::GraphicsViewCurveInputBase(
QObject* parent, QGraphicsScene* scene) :
Callback(parent, scene),
inputMethod(nullptr)
{
}
//
GraphicsViewCurveInputBase::
GraphicsViewCurveInputBase(QObject* parent, QGraphicsScene* scene) :
Callback(parent, scene),
inputMethod(nullptr)
{}
//
void GraphicsViewCurveInputBase::setInputMethod(CurveInputMethod* inputMethod_)
{
this->inputMethod = inputMethod_;
}
{ this->inputMethod = inputMethod_; }
void GraphicsViewCurveInputBase::reset()
{
if (this->inputMethod)
{
//
void GraphicsViewCurveInputBase::reset() {
if (this->inputMethod) {
this->inputMethod->reset();
this->inputMethod = nullptr;
}
}
//
bool GraphicsViewCurveInputBase::eventFilter(QObject* obj, QEvent* event)
{
return this->inputMethod->eventFilter(obj, event);
}
{ return this->inputMethod->eventFilter(obj, event); }
//
void GraphicsViewCurveInputBase::setColor(QColor c)
{
this->inputMethod->setColor(c);
}
{ this->inputMethod->setColor(c); }
//
template <typename Arr_>
GraphicsViewCurveInput<Arr_>::GraphicsViewCurveInput(
Arrangement* arrangement_, QObject* parent, QGraphicsScene* scene) :
GraphicsViewCurveInputBase(parent, scene),
arrangement(arrangement_)
GraphicsViewCurveInput<Arr_>::
GraphicsViewCurveInput(Arrangement* arrangement_, QObject* parent,
QGraphicsScene* scene) :
GraphicsViewCurveInputBase(parent, scene),
arrangement(arrangement_)
{
this->setDefaultInputMethod(
std::integral_constant<
bool, std::tuple_size<InputMethodTuple>::value != 0>{});
this->setDefaultInputMethod(std::integral_constant<bool,
std::tuple_size<InputMethodTuple>::value != 0>{});
for_each(inputMethods, [&](auto&& it) {
it.setScene(scene);
it.setCallback(this);
});
it.setScene(scene);
it.setCallback(this);
});
curveGenerator.setTraits(this->arrangement->traits());
}
//
template <typename Arr_>
void GraphicsViewCurveInput<Arr_>::setCurveType(CurveType type)
{
void GraphicsViewCurveInput<Arr_>::setCurveType(CurveType type) {
this->reset();
for_each(inputMethods, [&](auto&& it) {
if (it.curveType() == type)
this->setInputMethod(static_cast<CurveInputMethod*>(&it));
});
for_each(inputMethods,
[&](auto&& it) {
if (it.curveType() == type)
this->setInputMethod(static_cast<CurveInputMethod*>(&it));
});
}
//
template <typename Arr_>
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>
void GraphicsViewCurveInput<Arr_>::setDefaultInputMethod(std::true_type)
{
this->setInputMethod(&std::get<0>(inputMethods));
}
{ this->setInputMethod(&std::get<0>(inputMethods)); }
//
template <typename Arr_>
void GraphicsViewCurveInput<Arr_>::setDefaultInputMethod(std::false_type)
{
}
{}
//
template <typename Arr_>
void GraphicsViewCurveInput<Arr_>::generate(CGAL::Object o)
{
insertCurve(
demo_types::enumFromArrType<Arrangement>(),
CGAL::make_object(this->arrangement), o);
void GraphicsViewCurveInput<Arr_>::generate(CGAL::Object o) {
insertCurve(demo_types::enumFromArrType<Arrangement>(),
CGAL::make_object(this->arrangement), o);
Q_EMIT CGAL::Qt::GraphicsViewCurveInputBase::modelChanged();
}
//
template <typename Arr_>
void GraphicsViewCurveInput<Arr_>::curveInputDoneEvent(
const std::vector<Point_2>& clickedPoints, CurveType type)
{
void GraphicsViewCurveInput<Arr_>::
curveInputDoneEvent(const std::vector<Point_2>& clickedPoints, CurveType type) {
boost::optional<Curve_2> cv =
this->curveGenerator.generate(clickedPoints, type);
if (cv)
{
if (cv) {
Insert_curve<Arrangement>{}(this->arrangement, *cv);
Q_EMIT this->modelChanged();
}
@ -142,13 +133,12 @@ void GraphicsViewCurveInput<Arr_>::curveInputDoneEvent(
// CurveGeneratorBase
template <typename ArrTraits_>
auto CurveGeneratorBase<ArrTraits_>::generate(
const std::vector<Point_2>& clickedPoints, CurveType type)
auto CurveGeneratorBase<ArrTraits_>::
generate(const std::vector<Point_2>& clickedPoints, CurveType type)
-> boost::optional<Curve_2>
{
boost::optional<Curve_2> res;
switch (type)
{
switch (type) {
case CurveType::Segment:
res = generateSegment(clickedPoints);
break;
@ -171,7 +161,7 @@ auto CurveGeneratorBase<ArrTraits_>::generate(
res = generateThreePointCircularArc(clickedPoints);
break;
case CurveType::FivePointConicArc:
res = generateFivePointConicArc(clickedPoints);
res = generateFivePointConicArc(clickedPoints);
break;
case CurveType::Bezier:
res = generateBezier(clickedPoints);
@ -181,16 +171,16 @@ auto CurveGeneratorBase<ArrTraits_>::generate(
return res;
}
//
template <typename ArrTraits_>
void CurveGeneratorBase<ArrTraits_>::setTraits(const ArrTraits* traits_)
{
this->traits = traits_;
}
{ this->traits = traits_; }
// Curve Generator Segment Traits
template <typename Kernel_>
auto CurveGenerator<CGAL::Arr_segment_traits_2<Kernel_>>::generateSegment(
const std::vector<Point_2>& clickedPoints) -> boost::optional<Curve_2>
auto CurveGenerator<CGAL::Arr_segment_traits_2<Kernel_>>::
generateSegment(const std::vector<Point_2>& clickedPoints)
-> boost::optional<Curve_2>
{
Curve_2 res{clickedPoints[0], clickedPoints[1]};
return res;
@ -211,25 +201,25 @@ auto CurveGenerator<CGAL::Arr_polyline_traits_2<SegmentTraits>>::
// Curve Generator Linear Traits
template <typename Kernel_>
auto CurveGenerator<CGAL::Arr_linear_traits_2<Kernel_>>::generateSegment(
const std::vector<Point_2>& points) -> boost::optional<Curve_2>
auto CurveGenerator<CGAL::Arr_linear_traits_2<Kernel_>>::
generateSegment(const std::vector<Point_2>& points) -> boost::optional<Curve_2>
{
Curve_2 res = Curve_2(Segment_2(points[0], points[1]));
return res;
}
//
template <typename Kernel_>
auto CurveGenerator<CGAL::Arr_linear_traits_2<Kernel_>>::generateRay(
const std::vector<Point_2>& points) -> boost::optional<Curve_2>
{
auto CurveGenerator<CGAL::Arr_linear_traits_2<Kernel_>>::
generateRay(const std::vector<Point_2>& points) -> boost::optional<Curve_2> {
Curve_2 res = Curve_2(Ray_2(points[0], points[1]));
return res;
}
//
template <typename Kernel_>
auto CurveGenerator<CGAL::Arr_linear_traits_2<Kernel_>>::generateLine(
const std::vector<Point_2>& points) -> boost::optional<Curve_2>
{
auto CurveGenerator<CGAL::Arr_linear_traits_2<Kernel_>>::
generateLine(const std::vector<Point_2>& points) -> boost::optional<Curve_2> {
Curve_2 res = Curve_2(Line_2(points[0], points[1]));
return res;
}
@ -237,28 +227,31 @@ auto CurveGenerator<CGAL::Arr_linear_traits_2<Kernel_>>::generateLine(
// CurveGenerator Conic Traits
template <typename RatKernel, typename AlgKernel, typename NtTraits>
auto CurveGenerator<Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>>::
generateSegment(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(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;
}
//
template <typename RatKernel, typename AlgKernel, typename 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 =
(points[0].x() - points[1].x()) * (points[0].x() - points[1].x()) +
(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;
}
//
template <typename RatKernel, typename AlgKernel, typename NtTraits>
auto CurveGenerator<Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>>::
generateEllipse(const std::vector<Point_2>& points)
-> boost::optional<Curve_2>
generateEllipse(const std::vector<Point_2>& points)
-> boost::optional<Curve_2>
{
auto x1 = (CGAL::min)(points[0].x(), points[1].x());
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 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;
}
//
template <typename RatKernel, typename AlgKernel, typename NtTraits>
auto CurveGenerator<Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>>::
generateThreePointCircularArc(const std::vector<Point_2>& points)
-> boost::optional<Curve_2>
generateThreePointCircularArc(const std::vector<Point_2>& points)
-> boost::optional<Curve_2>
{
auto& qp1 = points[0];
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 p3 = Rat_point_2(qp3.x(), qp3.y());
RatKernel ker;
if (!ker.collinear_2_object()(p1, p2, p3))
{
Curve_2 res(p1, p2, p3);
if (! ker.collinear_2_object()(p1, p2, p3)) {
auto ctr_cv = this->traits->construct_curve_2_object();
Curve_2 res = ctr_cv(p1, p2, p3);
return res;
}
else
{
else {
std::cout << "Points don't specify a valid conic." << std::endl;
return {};
}
}
//
template <typename RatKernel, typename AlgKernel, typename NtTraits>
auto CurveGenerator<Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>>::
generateFivePointConicArc(const std::vector<Point_2>& points)
-> boost::optional<Curve_2>
generateFivePointConicArc(const std::vector<Point_2>& points)
-> boost::optional<Curve_2>
{
auto& qp0 = points[0];
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 p3 = Rat_point_2(qp3.x(), qp3.y());
Rat_point_2 p4 = Rat_point_2(qp4.x(), qp4.y());
try
{
Curve_2 res(p0, p1, p2, p3, p4);
if (res.is_valid())
return res;
else
std::cout << "Points don't specify a valid conic. Try again!"
<< std::endl;
try {
auto ctr_cv = this->traits->construct_curve_2_object();
Curve_2 res = ctr_cv(p0, p1, p2, p3, p4);
if (res.is_valid()) return res;
else 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;
}
return {};
@ -341,8 +333,7 @@ auto CurveGenerator<Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>>::
// CurveGenerator Algebraic Traits
template <typename 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;
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 poly;
if (dx != 0)
{
if (dx != 0) {
Rational mRat = dy / dx;
Rational cRat = points[0].y() - mRat * points[0].x();
// 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;
}
// vertical line
else
{
else {
Rational xP = points[0].x();
auto a = ratTraits.numerator(xP);
auto b = ratTraits.denominator(xP);
@ -377,10 +366,10 @@ auto CurveGenerator<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>::
return res;
}
//
template <typename 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 =
(points[0].x() - points[1].x()) * (points[0].x() - points[1].x()) +
(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_>
auto CurveGenerator<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>::
generateEllipse(const std::vector<Point_2>& points)
-> boost::optional<Curve_2>
generateEllipse(const std::vector<Point_2>& points)
-> boost::optional<Curve_2>
{
auto rx =
(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);
}
//
template <typename Coefficient_>
auto CurveGenerator<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>::
generateEllipse_(const Point_2& center, Rational rxRat, Rational ryRat)
-> boost::optional<Curve_2>
generateEllipse_(const Point_2& center, Rational rxRat, Rational ryRat)
-> boost::optional<Curve_2>
{
RationalTraits ratTraits;
@ -432,26 +422,23 @@ auto CurveGenerator<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>::
return res;
}
template <
typename RatKernel, typename AlgKernel, typename NtTraits,
typename BoundingTraits>
auto CurveGenerator<
Arr_Bezier_curve_traits_2<RatKernel, AlgKernel, NtTraits, BoundingTraits>>::
generateBezier(const std::vector<Point_2>& clickedPoints)
-> boost::optional<Curve_2>
//
template <typename RatKernel, typename AlgKernel, typename NtTraits,
typename BoundingTraits>
auto CurveGenerator
<Arr_Bezier_curve_traits_2<RatKernel, AlgKernel, NtTraits, BoundingTraits>>::
generateBezier(const std::vector<Point_2>& clickedPoints)
-> boost::optional<Curve_2>
{
if (clickedPoints.size() < 2) return {};
return Curve_2{clickedPoints.begin(), clickedPoints.end()};
}
// msvc2015 doesn't play well with polymorphic lambdas
namespace
{
struct ExplicitLambda
{
namespace {
struct ExplicitLambda {
template <typename Arrangement>
void operator()(demo_types::TypeHolder<Arrangement>)
{
void operator()(demo_types::TypeHolder<Arrangement>) {
Arrangement* arr = nullptr;
CGAL::assign(arr, arr_obj);
res = new GraphicsViewCurveInput<Arrangement>(arr, parent, scene);
@ -464,6 +451,7 @@ struct ExplicitLambda
};
} // anonymous namespace
//
GraphicsViewCurveInputBase* GraphicsViewCurveInputBase::create(
demo_types::TraitsType tt, CGAL::Object arr_obj, QObject* parent,
QGraphicsScene* scene)
@ -478,8 +466,11 @@ GraphicsViewCurveInputBase* GraphicsViewCurveInputBase::create(
} // namespace CGAL
#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 Alg_seg_arr = demo_types::DemoTypes::Alg_seg_arr;
@ -498,15 +489,17 @@ CGAL::Object algebraicCurveFromExpression(
return CGAL::make_object(cv);
}
CGAL::Object rationalCurveFromExpression(
const CGAL::Object& arr_obj, const std::string& numerator,
const std::string& denominator, bool& is_first_curve)
//
CGAL::Object rationalCurveFromExpression(const CGAL::Object& arr_obj,
const std::string& numerator,
const std::string& denominator,
bool& is_first_curve)
{
using Polynomial_1 = demo_types::DemoTypes::Rational_traits::Polynomial_1;
using Rational_arr = demo_types::DemoTypes::Rational_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);
@ -521,4 +514,5 @@ CGAL::Object rationalCurveFromExpression(
return CGAL::make_object(cv);
}
#endif

View File

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

View File

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

View File

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

View File

@ -16,6 +16,7 @@
#include <CGAL/number_utils.h>
#include <limits>
//
static const CGAL::Bbox_2 inf_bbox = {
-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();
template <typename Traits_>
struct ConstructBoundingBox_impl
{
using Traits = Traits_;
//
template <typename GeometryTraits>
class ConstructBoundingBox_impl {
using Traits = GeometryTraits;
using X_monotone_curve_2 = typename Traits::X_monotone_curve_2;
using Curve_2 = typename Traits::Curve_2;
using Point_2 = typename Traits::Point_2;
CGAL::Bbox_2
operator()(const X_monotone_curve_2& curve)
{
public:
// 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
using Zero_resultant_exception = CGAL::internal::Zero_resultant_exception<
typename demo_types::DemoTypes::Alg_seg_traits::Polynomial_2>;
#endif
CGAL::Bbox_2 bbox;
try
{
try {
bbox = curve.bbox();
}
// algebraic traits sometimes crash when calling bbox
@ -70,13 +73,15 @@ struct ConstructBoundingBox_impl
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 y = CGAL::to_double(point.y());
return {x, y, x, y};
}
private:
const Traits& m_traits;
};
// 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
// and use bbox directly
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 X_monotone_curve_2 = typename Traits::X_monotone_curve_2;
using Curve_2 = typename Traits::Curve_2;
using Point_2 = typename Traits::Point_2;
CGAL::Bbox_2
operator()(const X_monotone_curve_2& curve)
{
return this->operator()(curve.source(), curve.target());
}
public:
// Construct from traits;
ConstructBoundingBox_impl(const Traits& traits) : m_traits(traits) {}
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;
double x1 = CGAL::to_double(p1.x());
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 min_x, max_x, min_y, max_y;
if (x1 < x2)
{
if (x1 < x2) {
min_x = x1;
max_x = x2;
}
else
{
else {
min_x = x2;
max_x = x1;
}
if (y1 < y2)
{
if (y1 < y2) {
min_y = y1;
max_y = y2;
}
else
{
else {
min_y = y2;
max_y = y1;
}
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 y = CGAL::to_double(point.y());
return {x, y, x, y};
}
private:
const Traits& m_traits;
};
//
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 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 Point_2 = typename Traits::Point_2;
CGAL::Bbox_2
operator()(const X_monotone_curve_2& curve)
{
ConstructBoundingBox_impl<SegmentTraits_2> construct_bounding_box;
public:
// Construct from traits;
ConstructBoundingBox_impl(const Traits& traits) : m_traits(traits) {}
//
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();
CGAL::Bbox_2 bbox;
for (std::size_t i = 0; i < n; ++i)
bbox += construct_bounding_box(curve[i]);
for (std::size_t i = 0; i < n; ++i) bbox += ctr_bbox(curve[i]);
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;
double x1 = CGAL::to_double(p1.x());
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 min_x, max_x, min_y, max_y;
if (x1 < x2)
{
if (x1 < x2) {
min_x = x1;
max_x = x2;
}
else
{
else {
min_x = x2;
max_x = x1;
}
if (y1 < y2)
{
if (y1 < y2) {
min_y = y1;
max_y = y2;
}
else
{
else {
min_y = y2;
max_y = y1;
}
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 y = CGAL::to_double(point.y());
return {x, y, x, y};
}
private:
const Traits& m_traits;
};
//
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 X_monotone_curve_2 = typename Traits::X_monotone_curve_2;
using Curve_2 = typename Traits::Curve_2;
using Point_2 = typename Traits::Point_2;
CGAL::Bbox_2
operator()(const X_monotone_curve_2& curve)
{
if (curve.is_segment())
{
return ConstructBoundingBox_impl<CGAL::Arr_segment_traits_2<Kernel_>>{}(
curve.source(), curve.target());
}
else if (curve.is_line())
{
return inf_bbox;
public:
// Construct from traits;
ConstructBoundingBox_impl(const Traits& traits) : m_traits(traits) {}
//
CGAL::Bbox_2 operator()(const X_monotone_curve_2& curve) {
if (curve.is_segment()) {
auto&& seg = curve.segment();
return operator()(seg.source()) + operator()(seg.target());
}
else if (curve.is_line()) return inf_bbox;
// ray
else
{
else {
auto&& ray = curve.ray();
auto&& src = ray.source();
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 dy = CGAL::is_positive(dir.dy());
if (dx && dy)
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)
return {-inf_double, -inf_double, src_x, src_y};
if (dx && dy) 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) return {-inf_double, -inf_double, src_x, src_y};
else // if (dx && !dy)
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 y = CGAL::to_double(point.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 <
typename RatKernel_, typename AlgKernel_, typename NtTraits_,
typename BoundingTraits_>
struct ConstructBoundingBox_impl<CGAL::Arr_Bezier_curve_traits_2<
RatKernel_, AlgKernel_, NtTraits_, BoundingTraits_>>
public:
// Construct from traits;
ConstructBoundingBox_impl(const Traits& traits) : m_traits(traits) {}
// Obtain the bounding box for an x-monotone conic curve.
CGAL::Bbox_2 operator()(const X_monotone_curve_2& xcv)
{ return m_traits.construct_bbox_2_object()(xcv); }
// Obtain the bounding box for an conic point.
CGAL::Bbox_2 operator()(const Point_2& point) {
double x = CGAL::to_double(point.x());
double y = CGAL::to_double(point.y());
return {x, y, x, y};
}
private:
const Traits& m_traits;
};
// Specialization of `ConstructBoundingBox_impl` for the Bezier traits.
template <typename RatKernel_, typename AlgKernel_, typename NtTraits_,
typename BoundingTraits_>
class ConstructBoundingBox_impl<CGAL::Arr_Bezier_curve_traits_2
<RatKernel_, AlgKernel_, NtTraits_,
BoundingTraits_>>
{
using Traits = typename CGAL::Arr_Bezier_curve_traits_2<
RatKernel_, AlgKernel_, NtTraits_, BoundingTraits_>;
using Traits = typename CGAL::Arr_Bezier_curve_traits_2
<RatKernel_, AlgKernel_, NtTraits_, BoundingTraits_>;
using X_monotone_curve_2 = typename Traits::X_monotone_curve_2;
using Curve_2 = typename Traits::Curve_2;
using Point_2 = typename Traits::Point_2;
CGAL::Bbox_2
operator()(const X_monotone_curve_2& curve)
{
public:
// 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
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();
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>
struct ConstructBoundingBox_impl<
CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>>
{
class ConstructBoundingBox_impl<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 Curve_2 = typename Traits::Curve_2;
using Point_2 = typename Traits::Point_2;
CGAL::Bbox_2
operator()(const X_monotone_curve_2& curve)
{
public:
// 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;
if (curve.left_parameter_space_in_x() == CGAL::ARR_INTERIOR)
min_x = CGAL::to_double(curve.left_x());
@ -313,25 +351,26 @@ struct ConstructBoundingBox_impl<
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 y = CGAL::to_double(point.y());
return {x, y, x, y};
}
private:
const Traits& m_traits;
};
//
template <typename Arr_>
CGAL::Bbox_2
ConstructBoundingBox<Arr_>::operator()(const X_monotone_curve_2& curve)
{
return ConstructBoundingBox_impl<Traits>{}(curve);
}
{ return ConstructBoundingBox_impl<Traits>(m_traits)(curve); }
//
template <typename Arr_>
CGAL::Bbox_2 ConstructBoundingBox<Arr_>::operator()(const Point_2& point)
{
return ConstructBoundingBox_impl<Traits>{}(point);
}
{ return ConstructBoundingBox_impl<Traits>(m_traits)(point); }
ARRANGEMENT_DEMO_SPECIALIZE_TRAITS(ConstructBoundingBox)

View File

@ -17,15 +17,23 @@
// bounding box utility for arrangements
// doesn't have to be exact, only good enough for rendering
template <typename Traits_>
class ConstructBoundingBox
{
class ConstructBoundingBox {
public:
using Traits = Traits_;
using X_monotone_curve_2 = typename Traits::X_monotone_curve_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 Point_2& point);
private:
const Traits& m_traits;
};
#endif

View File

@ -23,11 +23,11 @@
#include <CGAL/Arr_default_overlay_traits.h>
#include <CGAL/Arr_overlay_2.h>
//
template <typename Kernel_>
double
Compute_squared_distance_2<CGAL::Arr_segment_traits_2<Kernel_>>::operator()(
const Point_2& p, const X_monotone_curve_2& c) const
{
Compute_squared_distance_2<CGAL::Arr_segment_traits_2<Kernel_>>::
operator()(const Point_2& p, const X_monotone_curve_2& c) const {
Point_2 p1 = c.source();
Point_2 p2 = c.target();
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));
}
//
template <typename Kernel_>
double
Compute_squared_distance_2<CGAL::Arr_linear_traits_2<Kernel_>>::operator()(
const Point_2& p, const X_monotone_curve_2& c) const
{
Compute_squared_distance_2<CGAL::Arr_linear_traits_2<Kernel_>>::
operator()(const Point_2& p, const X_monotone_curve_2& c) const {
Segment_2 seg;
Ray_2 ray;
Line_2 line;
FT res;
if (c.is_segment())
{
if (c.is_segment()) {
seg = c.segment();
res = CGAL::squared_distance(p, seg);
}
else if (c.is_ray())
{
else if (c.is_ray()) {
ray = c.ray();
res = CGAL::squared_distance(p, ray);
}
else // ( c.is_line( ) )
{
else {// ( c.is_line( ) )
line = c.line();
res = CGAL::squared_distance(p, line);
}
return CGAL::to_double(res);
}
//
template <typename Kernel_>
double
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;
FT min_dist = 0;
while (seg_it_s != c.subcurves_end())
{
while (seg_it_s != c.subcurves_end()) {
Segment_2 seg = *seg_it_s;
FT dist = CGAL::squared_distance(p, seg);
if (first || dist < min_dist)
{
if (first || dist < min_dist) {
first = false;
min_dist = dist;
}
@ -88,19 +84,18 @@ Compute_squared_distance_2<CGAL::Arr_polyline_traits_2<Kernel_>>::operator()(
return CGAL::to_double(min_dist);
}
//
template <typename RatKernel, typename AlgKernel, typename NtTraits>
double Compute_squared_distance_2<
CGAL::Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>>::
operator()(const Point_2& p, const X_monotone_curve_2& c) const
{
// Get the coordinates of the curve's source and target.
double Compute_squared_distance_2
<CGAL::Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>>::
operator()(const Point_2& p, const X_monotone_curve_2& c) const {
// Get the coordinates of the curve source and target.
// double sx = CGAL::to_double( c.source( ).x( ) );
// double sy = CGAL::to_double( c.source( ).y( ) );
// double tx = CGAL::to_double( c.target( ).x( ) );
// 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 pt = c.target();
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);
return CGAL::to_double(res);
}
else
{
else {
// If the curve is monotone, than its source and its target has the
// extreme x coordinates on this curve.
// bool is_source_left = (sx < tx);
@ -126,10 +120,11 @@ operator()(const Point_2& p, const X_monotone_curve_2& c) const
// AlgKernel ker;
int n = 100;
if (this->scene != nullptr && this->scene->views().size() != 0)
{ // use the scene to approximate the resolution of the curve
if (this->scene != nullptr && this->scene->views().size() != 0) {
// use the scene to approximate the resolution of the curve
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 xmax = view->mapFromScene(bb.xmax(), bb.ymin()).x();
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 p_curr = app_pts.begin();
auto p_next = p_curr + 1;
do
{
do {
Point_2 p1(p_curr->first, p_curr->second);
Point_2 p2(p_next->first, p_next->second);
Segment_2 seg(p1, p2);
FT dist = CGAL::squared_distance(p, seg);
if (first || dist < min_dist)
{
if (first || dist < min_dist) {
first = false;
min_dist = dist;
}
p_curr++;
p_next++;
++p_curr;
++p_next;
} while (p_next != end_pts);
return CGAL::to_double(min_dist);
}
}
template <
typename RatKernel, typename AlgKernel, typename NtTraits,
typename BoundingTraits>
double Compute_squared_distance_2<CGAL::Arr_Bezier_curve_traits_2<
RatKernel, AlgKernel, NtTraits, BoundingTraits>>::
operator()(const Point_2& p, const X_monotone_curve_2& curve) const
{
//
template <typename RatKernel, typename AlgKernel, typename NtTraits,
typename BoundingTraits>
double Compute_squared_distance_2<CGAL::Arr_Bezier_curve_traits_2
<RatKernel, AlgKernel, NtTraits,
BoundingTraits>>::
operator()(const Point_2& p, const X_monotone_curve_2& curve) const {
// TODO: this should probably be cached!
CGAL::Qt::ArrangementPainterOstream<Traits> painterOstream{nullptr};
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 = {
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);
for (auto& vit : points)
{
for (auto& vit : points) {
QPointF coord(vit.first, vit.second);
float curDist = (vit.first - p_pair.first) * (vit.first - p_pair.first) +
(vit.second - p_pair.second) * (vit.second - p_pair.second);
minDist = curDist < minDist ? curDist : minDist;
float cur_dist = (vit.first - p_pair.first) * (vit.first - p_pair.first) +
(vit.second - p_pair.second) * (vit.second - p_pair.second);
min_dist = cur_dist < min_dist ? cur_dist : min_dist;
}
return minDist;
return min_dist;
}
//
template <typename Coefficient_>
double
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!
CGAL::Qt::ArrangementPainterOstream<Traits> painterOstream{nullptr};
painterOstream.setScene(this->getScene());
@ -212,78 +204,74 @@ operator()(const Point_2& p, const X_monotone_curve_2& curve) const
QPoint p_viewport =
view->mapFromScene(QPointF{p.x().doubleValue(), p.y().doubleValue()});
double minDist = (std::numeric_limits<double>::max)();
for (auto& vec : points)
{
for (auto vit = vec.begin(); vit != vec.end(); ++vit)
{
double min_dist = (std::numeric_limits<double>::max)();
for (auto& vec : points) {
for (auto vit = vec.begin(); vit != vec.end(); ++vit) {
QPoint coord(vit->first, vit->second);
float curDist = QLineF{facadeToViewport.map(coord), p_viewport}.length();
minDist = curDist < minDist ? curDist : minDist;
float cur_dist = QLineF{facadeToViewport.map(coord), p_viewport}.length();
min_dist = cur_dist < min_dist ? cur_dist : min_dist;
}
}
return minDist;
return min_dist;
}
//
template <typename AlgebraicKernel_d_1>
double Compute_squared_distance_2<
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!
CGAL::Qt::ArrangementPainterOstream<Traits> painterOstream{nullptr};
painterOstream.setScene(this->getScene());
CGAL::Qt::ArrangementPainterOstream<Traits> painter_ostream{nullptr};
painter_ostream.setScene(this->getScene());
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)();
auto points_list = painterOstream.getPointsList(curve);
for (auto& points : points_list)
{
for (auto& vit : points)
{
double min_dist = (std::numeric_limits<double>::max)();
auto points_list = painter_ostream.getPointsList(curve);
for (auto& points : points_list) {
for (auto& vit : points) {
QPointF coord(vit.first, vit.second);
float curDist =
float cur_dist =
(vit.first - p_pair.first) * (vit.first - p_pair.first) +
(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>
auto Arr_construct_point_2<ArrTraits>::operator()(const Kernel_point_2& pt)
-> Point_2
{
return (*this)(FT{pt.x()}, FT{pt.y()}, traits);
}
auto Arr_construct_point_2<ArrTraits>::
operator()(const Kernel_point_2& pt) -> Point_2
{ return (*this)(FT{pt.x()}, FT{pt.y()}, traits); }
//
template <typename ArrTraits>
auto Arr_construct_point_2<ArrTraits>::operator()(const FT& x, const FT& y)
-> Point_2
{
return (*this)(x, y, traits);
}
auto Arr_construct_point_2<ArrTraits>::
operator()(const FT& x, const FT& y) -> Point_2
{ return (*this)(x, y, traits); }
//
template <typename ArrTraits>
template <typename TTraits>
auto Arr_construct_point_2<ArrTraits>::operator()(
const FT& x, const FT& y, const TTraits*) -> Point_2
{
auto Arr_construct_point_2<ArrTraits>::
operator()(const FT& x, const FT& y, const TTraits*) -> Point_2 {
CoordinateType xx(x);
CoordinateType yy(y);
Point_2 res(xx, yy);
return res;
}
//
template <typename ArrTraits>
template <typename AlgebraicKernel_d_1>
auto Arr_construct_point_2<ArrTraits>::operator()(
const FT& x, const FT& y,
const CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>*)
auto Arr_construct_point_2<ArrTraits>::
operator()(const FT& x, const FT& y,
const CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>*)
-> Point_2
{
using Rational = typename ArrTraits::Rational;
@ -304,46 +292,44 @@ auto Arr_construct_point_2<ArrTraits>::operator()(
return res;
}
//
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
{
Face_const_handle face =
PointLocationFunctions<Arrangement>{}.getFace(arr, queryPt);
PointLocationFunctions<Arrangement>{}.getFace(arr, query_pt);
bool first = 1;
X_monotone_curve_2 closestCurve;
Halfedge_const_handle closestEdge;
double minDist(0);
double min_dist(0);
if (!face->is_unbounded())
{ // it is an interior face so it has a ccb
const auto& traits = arr->geometry_traits();
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();
do
{
do {
X_monotone_curve_2 curve = cc->curve();
double dist = this->pointCurveDistance(queryPt, curve);
if (first || dist < minDist)
{
double dist = point_curve_distance(query_pt, curve);
if (first || dist < min_dist) {
first = 0;
minDist = dist;
min_dist = dist;
closestEdge = cc;
}
} 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();
do
{
if (cc->is_fictitious()) { continue; }
do {
if (cc->is_fictitious()) continue;
X_monotone_curve_2 curve = cc->curve();
double dist = this->pointCurveDistance(queryPt, curve);
if (first || dist < minDist)
{
double dist = point_curve_distance(query_pt, curve);
if (first || dist < min_dist) {
first = 0;
minDist = dist;
min_dist = dist;
closestEdge = cc;
}
} 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 eit = face->holes_end();
// int counter = 0;
for (hit = face->holes_begin(); hit != eit; ++hit)
{ // check any holes inside this face
for (hit = face->holes_begin(); hit != eit; ++hit) {
// check any holes inside this face
Ccb_halfedge_const_circulator cc = *hit;
do
{
do {
X_monotone_curve_2 curve = cc->curve();
double dist = this->pointCurveDistance(queryPt, curve);
if (first || dist < minDist)
{
double dist = point_curve_distance(query_pt, curve);
if (first || dist < min_dist) {
first = 0;
minDist = dist;
min_dist = dist;
closestEdge = cc;
}
cc++;
@ -371,6 +355,7 @@ auto Find_nearest_edge<Arr_>::operator()(const Point_2& queryPt)
return closestEdge;
}
//
template <typename Arr_>
auto Find_nearest_edge<Arr_>::getFace(const CGAL::Object& obj)
-> Face_const_handle
@ -389,6 +374,7 @@ auto Find_nearest_edge<Arr_>::getFace(const CGAL::Object& obj)
return (eit->face());
}
//
template <typename ArrTraits>
Construct_x_monotone_subcurve_2<ArrTraits>::Construct_x_monotone_subcurve_2(
const ArrTraits* traits_) :
@ -402,6 +388,7 @@ Construct_x_monotone_subcurve_2<ArrTraits>::Construct_x_monotone_subcurve_2(
{
}
//
template <typename ArrTraits>
auto Construct_x_monotone_subcurve_2<ArrTraits>::operator()(
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 unusedTrimmings;
X_monotone_curve_2 finalSubcurve;
if (
pLeft && (unbounded_min || this->compare_x_2(*pLeft, pMin) == CGAL::LARGER))
if (pLeft &&
(unbounded_min || this->compare_x_2(*pLeft, pMin) == CGAL::LARGER))
{
auto y1 = this->compute_y_at_x(curve, pLeft->x());
Point_2 splitPoint = {pLeft->x(), y1};
this->split_2(curve, splitPoint, unusedTrimmings, subcurve);
}
else
{
else {
subcurve = curve;
}
if (
pRight &&
(unbounded_max || this->compare_x_2(*pRight, pMax) == CGAL::SMALLER))
if (pRight &&
(unbounded_max || this->compare_x_2(*pRight, pMax) == CGAL::SMALLER))
{
auto y2 = this->compute_y_at_x(subcurve, pRight->x());
Point_2 splitPoint = {pRight->x(), y2};
this->split_2(subcurve, splitPoint, finalSubcurve, unusedTrimmings);
}
else
{
else {
finalSubcurve = subcurve;
}
return finalSubcurve;
}
//
template <typename RatKernel, typename AlgKernel, typename NtTraits>
auto Construct_x_monotone_subcurve_2<
CGAL::Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>>::
operator()(
const X_monotone_curve_2& curve, const boost::optional<Point_2>& pLeft,
const boost::optional<Point_2>& pRight) -> X_monotone_curve_2
auto Construct_x_monotone_subcurve_2
<CGAL::Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>>::
operator()(const X_monotone_curve_2& curve,
const boost::optional<Point_2>& pLeft,
const boost::optional<Point_2>& pRight) -> X_monotone_curve_2
{
// TODO: handle when pLeft or pRight is null
// find the points on the curve
Point_2 left = curve.point_at_x(*pLeft);
Point_2 right = curve.point_at_x(*pRight);
Point_2 left = m_traits.point_at_x(curve, *pLeft);
Point_2 right = m_traits.point_at_x(curve, *pRight);
// make sure the points are oriented in the direction that the curve is
// going
@ -475,16 +460,17 @@ operator()(
ker.compare_xy_2_object()(left, right) == CGAL::LARGER)))
{ 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;
}
template <
typename RatKernel, typename AlgKernel, typename NtTraits,
typename BoundingTraits>
Construct_x_monotone_subcurve_2<CGAL::Arr_Bezier_curve_traits_2<
RatKernel, AlgKernel, NtTraits,
BoundingTraits>>::Construct_x_monotone_subcurve_2(const ArrTraits* traits_) :
//
template <typename RatKernel, typename AlgKernel, typename NtTraits,
typename BoundingTraits>
Construct_x_monotone_subcurve_2<CGAL::Arr_Bezier_curve_traits_2
<RatKernel, AlgKernel, NtTraits,
BoundingTraits>>::
Construct_x_monotone_subcurve_2(const ArrTraits* traits_) :
traits(traits_),
split_2(this->traits->split_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,
typename BoundingTraits>
//
template <typename RatKernel, typename AlgKernel, typename NtTraits,
typename BoundingTraits>
auto Construct_x_monotone_subcurve_2<CGAL::Arr_Bezier_curve_traits_2<
RatKernel, AlgKernel, NtTraits, BoundingTraits>>::
operator()(
@ -516,40 +502,35 @@ operator()(
// at algebraic "x", so we need to make it rational
auto local_get_t = [&](auto&& point) {
if (point.is_rational())
return this->compute_y_at_x.get_t(
curve, ((typename Point_2::Rat_point_2)point).x());
return this->compute_y_at_x.get_t(curve, ((typename Point_2::Rat_point_2)point).x());
else
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);
Point_2 splitPoint(curve.supporting_curve(), t);
this->split_2(curve, splitPoint, unusedTrimmings, subcurve);
}
else
{
else {
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);
Point_2 splitPoint(curve.supporting_curve(), t);
this->split_2(subcurve, splitPoint, finalSubcurve, unusedTrimmings);
}
else
{
else {
finalSubcurve = subcurve;
}
return finalSubcurve;
}
//
template <typename AlgebraicKernel_d_1>
Construct_x_monotone_subcurve_2<CGAL::Arr_rational_function_traits_2<
AlgebraicKernel_d_1>>::Construct_x_monotone_subcurve_2(const Traits*
traits_) :
AlgebraicKernel_d_1>>::Construct_x_monotone_subcurve_2(const Traits* traits_) :
traits(traits_),
split_2(this->traits->split_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>
auto Construct_x_monotone_subcurve_2<
CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>>::
@ -577,95 +559,93 @@ operator()(
X_monotone_curve_2 subcurve;
X_monotone_curve_2 unusedTrimmings;
X_monotone_curve_2 finalSubcurve;
if (
pLeft && (unbounded_min || this->compare_x_2(*pLeft, pMin) == CGAL::LARGER))
if (pLeft &&
(unbounded_min || this->compare_x_2(*pLeft, pMin) == CGAL::LARGER))
{
Point_2 splitPoint{curve._f, pLeft->x()};
this->split_2(curve, splitPoint, unusedTrimmings, subcurve);
}
else
{
else {
subcurve = curve;
}
if (
pRight &&
(unbounded_max || this->compare_x_2(*pRight, pMax) == CGAL::SMALLER))
if (pRight &&
(unbounded_max || this->compare_x_2(*pRight, pMax) == CGAL::SMALLER))
{
auto y2 = this->compute_y_at_x(subcurve, pRight->x());
Point_2 splitPoint{curve._f, pRight->x()};
this->split_2(subcurve, splitPoint, finalSubcurve, unusedTrimmings);
}
else
{
else {
finalSubcurve = subcurve;
}
return finalSubcurve;
}
//
template <typename ArrTraits>
Arr_compute_y_at_x_2<ArrTraits>::Arr_compute_y_at_x_2(const Traits* traits_) :
traits(traits_),
intersectCurves(this->traits->intersect_2_object())
traits(traits_),
intersectCurves(this->traits->intersect_2_object())
{
}
//
template <typename ArrTraits>
auto Arr_compute_y_at_x_2<ArrTraits>::operator()(
const X_monotone_curve_2& curve, const CoordinateType& x) -> CoordinateType
auto Arr_compute_y_at_x_2<ArrTraits>::
operator()(const X_monotone_curve_2& curve, const CoordinateType& x)
-> CoordinateType
{
typename Traits::Left_side_category category;
return this->operator()(curve, x, this->traits, category);
}
//
template <typename ArrTraits>
double Arr_compute_y_at_x_2<ArrTraits>::approx(
const X_monotone_curve_2& curve, const CoordinateType& x)
double Arr_compute_y_at_x_2<ArrTraits>::
approx(const X_monotone_curve_2& curve, const CoordinateType& x)
{
return CGAL::to_double((*this)(curve, x));
}
//
template <typename ArrTraits>
template <typename TTraits>
auto Arr_compute_y_at_x_2<ArrTraits>::operator()(
const X_monotone_curve_2& curve, const CoordinateType& x,
const TTraits* traits_, CGAL::Arr_oblivious_side_tag) -> CoordinateType
auto Arr_compute_y_at_x_2<ArrTraits>::
operator()(const X_monotone_curve_2& curve, const CoordinateType& x,
const TTraits* traits_, CGAL::Arr_oblivious_side_tag)
-> CoordinateType
{
typedef
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();
auto ctr_xcv = traits_->construct_x_monotone_curve_2_object();
CoordinateType res(0);
CGAL::Bbox_2 clipRect = curve.bbox();
Point_2 p1c1(x, CoordinateType(clipRect.ymin() - 1)); // clicked point
// upper bounding box
Point_2 p2c1(x, CoordinateType(clipRect.ymax() + 1));
const X_monotone_curve_2 verticalLine =
construct_x_monotone_curve_2(p1c1, p2c1);
const X_monotone_curve_2 verticalLine = ctr_xcv(p1c1, p2c1);
CGAL::Object o;
CGAL::Oneset_iterator<CGAL::Object> oi(o);
this->intersectCurves(curve, verticalLine, oi);
IntersectionResult pair;
if (CGAL::assign(pair, o))
{
if (CGAL::assign(pair, o)) {
Point_2 pt = pair.first;
res = pt.y();
}
return res;
}
//
template <typename ArrTraits>
template <typename TTraits>
auto Arr_compute_y_at_x_2<ArrTraits>::operator()(
const X_monotone_curve_2& curve, const CoordinateType& x,
const TTraits* traits_, CGAL::Arr_open_side_tag) -> CoordinateType
auto Arr_compute_y_at_x_2<ArrTraits>::
operator()(const X_monotone_curve_2& curve, const CoordinateType& x,
const TTraits* traits_, CGAL::Arr_open_side_tag) -> CoordinateType
{
typename TTraits::Construct_x_monotone_curve_2 construct_x_monotone_curve_2 =
traits_->construct_x_monotone_curve_2_object();
auto ctr_xcv = traits_->construct_x_monotone_curve_2_object();
CoordinateType res(0);
// QRectF clipRect = this->viewportRect( );
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 p2c1(x, CoordinateType(10000000)); // upper bounding box
const X_monotone_curve_2 verticalLine =
construct_x_monotone_curve_2(p1c1, p2c1);
const X_monotone_curve_2 verticalLine = ctr_xcv(p1c1, p2c1);
CGAL::Object o;
CGAL::Oneset_iterator<CGAL::Object> oi(o);
this->intersectCurves(curve, verticalLine, oi);
IntersectionResult pair;
if (CGAL::assign(pair, o))
{
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>
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_>
auto Arr_compute_y_at_x_2<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>::
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);
intersect(curve, c2, oi);
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;
CoordinateType coord = p.y();
return coord;
}
else
{
else {
std::cout << "Warning: vertical projection failed" << std::endl;
return CoordinateType(0);
}
}
// Specialization for the algebraic traits.
template <typename Coefficient_>
double
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));
}
// Specialization for the algebraic traits.
template <typename Coefficient_>
auto Arr_compute_y_at_x_2<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>::
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
}
//
template <typename Bezier_x_monotone_2>
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);
}
template <
typename RatKernel, typename AlgKernel, typename NtTraits,
typename BoundingTraits>
//
template <typename RatKernel, typename AlgKernel, typename NtTraits,
typename BoundingTraits>
auto Arr_compute_y_at_x_2<CGAL::Arr_Bezier_curve_traits_2<
RatKernel, AlgKernel, NtTraits, BoundingTraits>>::
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());
}
template <
typename RatKernel, typename AlgKernel, typename NtTraits,
typename BoundingTraits>
//
template <typename RatKernel, typename AlgKernel, typename NtTraits,
typename BoundingTraits>
auto Arr_compute_y_at_x_2<CGAL::Arr_Bezier_curve_traits_2<
RatKernel, AlgKernel, NtTraits, BoundingTraits>>::
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_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);
if (res1 == CGAL::EQUAL) return (curve.source().y());
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;
}
template <
typename RatKernel, typename AlgKernel, typename NtTraits,
typename BoundingTraits>
double Arr_compute_y_at_x_2<CGAL::Arr_Bezier_curve_traits_2<
RatKernel, AlgKernel, NtTraits,
BoundingTraits>>::approx(const X_monotone_curve_2& curve, const Rational& x)
{
//
template <typename RatKernel, typename AlgKernel, typename NtTraits,
typename BoundingTraits>
double Arr_compute_y_at_x_2<CGAL::Arr_Bezier_curve_traits_2
<RatKernel, AlgKernel, NtTraits,
BoundingTraits>>::
approx(const X_monotone_curve_2& curve, const Rational& x) {
return CGAL::to_double((*this)(curve, x));
}
//
template <typename AlgebraicKernel_d_1>
auto Arr_compute_y_at_x_2<
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();
}
//
template <typename AlgebraicKernel_d_1>
auto Arr_compute_y_at_x_2<
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);
}
//
template <typename AlgebraicKernel_d_1>
auto Arr_compute_y_at_x_2<
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));
}
//
CGAL::Object createArrangement(demo_types::TraitsType tt)
{
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;
if (arrs.size() == 2)
{
if (arrs.size() == 2) {
demo_types::forEachArrangementType([&](auto type_holder) {
using Arrangement = typename decltype(type_holder)::type;
Arrangement* arr1;
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();
CGAL::Arr_default_overlay_traits<Arrangement> overlay_traits;
@ -881,9 +898,9 @@ CGAL::Object makeOverlayArrangement(const std::vector<CGAL::Object>& arrs)
return arr_obj;
}
void insertCurve(
demo_types::TraitsType tt, const CGAL::Object& arr_obj,
const CGAL::Object& curve_obj)
//
void insertCurve(demo_types::TraitsType tt, const CGAL::Object& arr_obj,
const CGAL::Object& curve_obj)
{
demo_types::visitArrangementType(tt, [&](auto type_holder) {
using Arrangement = typename decltype(type_holder)::type;

View File

@ -21,186 +21,282 @@
class QGraphicsScene;
template <typename ArrTraits >
class Arr_compute_y_at_x_2 : public GraphicsSceneMixin
{
// Genereic `Arr_compute_y_at_x_2`
template <typename Traits_>
class Arr_compute_y_at_x_2 : public GraphicsSceneMixin {
public:
typedef ArrTraits Traits;
typedef typename ArrTraitsAdaptor< Traits >::Kernel Kernel;
typedef typename ArrTraitsAdaptor< Traits >::CoordinateType CoordinateType;
typedef Traits_ Traits;
typedef typename ArrTraitsAdaptor<Traits>::Kernel Kernel;
typedef typename ArrTraitsAdaptor<Traits>::CoordinateType CoordinateType;
// typedef typename Kernel::FT FT;
typedef typename Kernel::Point_2 Point_2;
typedef typename Kernel::Line_2 Line_2;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Traits::Multiplicity Multiplicity;
typedef typename Traits::Intersect_2 Intersect_2;
typedef std::pair< typename Traits::Point_2, Multiplicity >
typedef std::pair<typename Traits::Point_2, Multiplicity>
IntersectionResult;
/*! Constructor */
Arr_compute_y_at_x_2( const Traits* );
Arr_compute_y_at_x_2(const Traits* traits);
//
CoordinateType
operator()(const X_monotone_curve_2& curve, const CoordinateType& x);
//
double approx(const X_monotone_curve_2& curve, const CoordinateType& x);
protected:
//
template <typename TTraits>
CoordinateType operator()(
const X_monotone_curve_2& curve, const CoordinateType& x,
const TTraits* traits_, CGAL::Arr_oblivious_side_tag);
CoordinateType operator()(const X_monotone_curve_2& curve,
const CoordinateType& x, const TTraits* traits_,
CGAL::Arr_oblivious_side_tag);
//
template <typename TTraits>
CoordinateType operator()(
const X_monotone_curve_2& curve, const CoordinateType& x,
const TTraits* traits_, CGAL::Arr_open_side_tag);
CoordinateType operator()(const X_monotone_curve_2& curve,
const CoordinateType& x, const TTraits* traits_,
CGAL::Arr_open_side_tag);
protected:
const Traits* traits;
Intersect_2 intersectCurves;
};
template <typename Coefficient_>
class Arr_compute_y_at_x_2< CGAL::Arr_algebraic_segment_traits_2<
Coefficient_ > > : public GraphicsSceneMixin
// Specialization of `Arr_compute_y_at_x_2` for the conic traits.
template <typename RatKernel, typename AlgKernel, typename NtTraits>
class Arr_compute_y_at_x_2
<CGAL::Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>> :
public GraphicsSceneMixin
{
public:
typedef 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;
typedef CGAL::Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>
Traits;
typedef typename Traits::Point_2 Point_2;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
typedef typename ArrTraitsAdaptor<Traits>::CoordinateType Coordinate_type;
typedef typename Traits::Intersect_2 Intersect_2;
typedef typename Traits::Multiplicity Multiplicity;
typedef std::pair<Point_2, Multiplicity> IntersectionResult;
// Construct from traits.
Arr_compute_y_at_x_2(const Traits* traits) :
m_traits(*traits),
intersect_curves(m_traits.intersect_2_object())
{}
// Compute the y-coordinate at of the curve at a give x-coordinate.
Coordinate_type
operator()(const X_monotone_curve_2& curve, const Coordinate_type& x);
// Compute an approximation of the y-coordinate at of the curve at a give
// x-coordinate.
double approx(const X_monotone_curve_2& curve, const Coordinate_type& x);
private:
const Traits& m_traits;
Intersect_2 intersect_curves;
};
// Specialization of `Arr_compute_y_at_x_2` for the algebraic traits.
template <typename Coefficient_>
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_) { }
//
CoordinateType
operator()(const X_monotone_curve_2& curve, const CoordinateType& x);
//
double approx(const X_monotone_curve_2& curve, const CoordinateType& x);
protected:
//
X_monotone_curve_2 makeVerticalLine(const CoordinateType& x);
const Traits* traits;
};
template <
typename RatKernel, typename AlgKernel, typename NtTraits,
typename BoundingTraits>
// Specialization of `Arr_compute_y_at_x_2` for the Bezier traits.
template <typename RatKernel, typename AlgKernel, typename NtTraits,
typename BoundingTraits>
class Arr_compute_y_at_x_2<CGAL::Arr_Bezier_curve_traits_2<
RatKernel, AlgKernel, NtTraits, BoundingTraits>> : public GraphicsSceneMixin
{
public:
typedef CGAL::Arr_Bezier_curve_traits_2<
RatKernel, AlgKernel, NtTraits, BoundingTraits> Traits;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Traits::Rational Rational;
typedef typename Traits::Algebraic Algebraic;
typedef typename Traits::Point_2 Point_2;
RatKernel, AlgKernel, NtTraits, BoundingTraits> Traits;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Traits::Rational Rational;
typedef typename Traits::Algebraic Algebraic;
typedef typename Traits::Point_2 Point_2;
//
Arr_compute_y_at_x_2(const Traits*) { }
//
Algebraic operator()(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);
};
// Specialization of `Arr_compute_y_at_x_2` for the rational-function traits.
template <typename AlgebraicKernel_d_1>
class Arr_compute_y_at_x_2<
CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>> :
class Arr_compute_y_at_x_2<CGAL::Arr_rational_function_traits_2
<AlgebraicKernel_d_1>> :
public GraphicsSceneMixin
{
public:
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::Algebraic_real_1 Algebraic_real_1;
typedef typename Traits::Point_2 Point_2;
typedef typename Traits::Rational Rational;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Traits::Algebraic_real_1 Algebraic_real_1;
typedef typename Traits::Point_2 Point_2;
typedef typename Traits::Rational Rational;
Arr_compute_y_at_x_2(const Traits*) { }
//
Arr_compute_y_at_x_2(const Traits*) {}
//
Algebraic_real_1
operator()(const X_monotone_curve_2& curve, const Algebraic_real_1& x);
//
Rational
operator()(const X_monotone_curve_2& curve, const Rational& x);
//
double approx(const X_monotone_curve_2& curve, const Rational& x);
};
template <typename ArrTraits>
class Compute_squared_distance_2_base : public GraphicsSceneMixin
{
// Common base class for all `Compute_squared_distance_2`
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 :
public Compute_squared_distance_2_base< ArrTraits >
{ };
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 Compute_squared_distance_2_base<Traits_>
{
public:
typedef Kernel_ Kernel;
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;
using Traits = Traits_;
using Base = Compute_squared_distance_2_base<Traits>;
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_ >
class Compute_squared_distance_2< CGAL::Arr_linear_traits_2< Kernel_ > > :
public Compute_squared_distance_2_base<CGAL::Arr_linear_traits_2<Kernel_> >
// Specialization of `Compute_squared_distance_2` for the segment 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:
typedef Kernel_ Kernel;
typedef CGAL::Arr_linear_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 Kernel::Ray_2 Ray_2;
typedef typename Kernel::Line_2 Line_2;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
typedef Kernel_ Kernel;
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;
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_ >
class Compute_squared_distance_2< CGAL::Arr_polyline_traits_2< Kernel_ > > :
public Compute_squared_distance_2_base<CGAL::Arr_polyline_traits_2<Kernel_> >
// Specialization of `Compute_squared_distance_2` for the linear traits.
template <typename 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:
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;
typedef Kernel_ Kernel;
typedef CGAL::Arr_linear_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 Kernel::Ray_2 Ray_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;
};
// 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>
class Compute_squared_distance_2< CGAL::Arr_conic_traits_2< RatKernel,
AlgKernel,
NtTraits > > :
public Compute_squared_distance_2_base< CGAL::Arr_conic_traits_2< RatKernel,
AlgKernel,
NtTraits > >
class Compute_squared_distance_2<CGAL::Arr_conic_traits_2<RatKernel,
AlgKernel,
NtTraits>> :
public Compute_squared_distance_2_base<CGAL::Arr_conic_traits_2<RatKernel,
AlgKernel,
NtTraits>>
{
public:
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;
// _Conic_point_2< AlgKernel > : public AlgKernel::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::X_monotone_curve_2 X_monotone_curve_2;
public: // methods
double operator() ( const Point_2& p, const X_monotone_curve_2& c ) const;
};
using Base = Compute_squared_distance_2_base<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;
// Construct from traits.
Compute_squared_distance_2(const Traits& traits) : Base(traits) {}
public: // methods
//
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>
class Compute_squared_distance_2<
CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>> :
public Compute_squared_distance_2_base<
CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>>
class Compute_squared_distance_2
<CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>> :
public Compute_squared_distance_2_base
<CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>>
{
public:
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 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;
};
template <typename Coefficient_ >
class Compute_squared_distance_2< CGAL::Arr_algebraic_segment_traits_2<
Coefficient_ > > :
public Compute_squared_distance_2_base< CGAL::Arr_algebraic_segment_traits_2<
Coefficient_ > >
// Specialization of `Compute_squared_distance_2` for the algebraic traits.
template <typename Coefficient_>
class Compute_squared_distance_2
<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>> :
public Compute_squared_distance_2_base
<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>
{
public:
typedef Coefficient_ Coefficient;
@ -265,8 +380,8 @@ public:
typedef typename Kernel::Point_2 Point_2;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Traits::CKvA_2 CKvA_2;
typedef std::pair< double, double > Coord_2;
typedef std::vector< Coord_2 > Coord_vec_2;
typedef std::pair<double, double> Coord_2;
typedef std::vector<Coord_2> Coord_vec_2;
typedef typename X_monotone_curve_2::Curve_analysis_2 Curve;
typedef typename Curve::Polynomial_traits_2 Polynomial_traits_2;
typedef typename Curve::Polynomial_2 Polynomial_2;
@ -277,69 +392,75 @@ public:
Construct_innermost_coefficient_const_iterator_range
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;
};
// check if arrangement is a model of the concept ArrangementOpenBoundaryTraits_2
template <typename ArrTraits>
struct IsOpenBoundaryArrangement :
public CGAL::Boolean_tag<
std::is_convertible<
typename ArrTraits::Left_side_category,
CGAL::Arr_open_side_tag>::value &&
std::is_convertible<
typename ArrTraits::Bottom_side_category,
CGAL::Arr_open_side_tag>::value &&
std::is_convertible<
typename ArrTraits::Top_side_category,
CGAL::Arr_open_side_tag>::value &&
std::is_convertible<
typename ArrTraits::Right_side_category,
CGAL::Arr_open_side_tag>::value>
{
};
public CGAL::Boolean_tag<
std::is_convertible<
typename ArrTraits::Left_side_category,
CGAL::Arr_open_side_tag>::value &&
std::is_convertible<
typename ArrTraits::Bottom_side_category,
CGAL::Arr_open_side_tag>::value &&
std::is_convertible<
typename ArrTraits::Top_side_category,
CGAL::Arr_open_side_tag>::value &&
std::is_convertible<
typename ArrTraits::Right_side_category,
CGAL::Arr_open_side_tag>::value>
{};
//
template <typename ArrTraits, typename=void>
class Param_space_in_x_2
{
class Param_space_in_x_2 {
public:
typedef typename ArrTraits::X_monotone_curve_2 X_monotone_curve_2;
//
Param_space_in_x_2(const ArrTraits*) {}
//
CGAL::Arr_parameter_space
operator()(const X_monotone_curve_2&, CGAL::Arr_curve_end)
{
return CGAL::INTERIOR;
}
{ return CGAL::INTERIOR; }
};
//
template <typename ArrTraits>
class Param_space_in_x_2<
ArrTraits, std::enable_if_t<IsOpenBoundaryArrangement<ArrTraits>::value>>
class Param_space_in_x_2<ArrTraits,
std::enable_if_t<IsOpenBoundaryArrangement<ArrTraits>::
value>>
{
public:
typedef typename ArrTraits::X_monotone_curve_2 X_monotone_curve_2;
typedef typename ArrTraits::Parameter_space_in_x_2 Parameter_space_in_x_2;
//
Param_space_in_x_2(const ArrTraits* traits) :
parameter_space_in_x_2(traits->parameter_space_in_x_2_object())
{
}
{}
//
CGAL::Arr_parameter_space
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:
Parameter_space_in_x_2 parameter_space_in_x_2;
};
//
template <typename ArrTraits>
class Construct_x_monotone_subcurve_2
{
class Construct_x_monotone_subcurve_2 {
public:
typedef typename ArrTraits::X_monotone_curve_2 X_monotone_curve_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 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.
We assume pLeft and pRight don't lie on the curve and always do a vertical
projection.
*/
X_monotone_curve_2 operator() ( const X_monotone_curve_2& curve,
const boost::optional<Point_2>& pLeft,
const boost::optional<Point_2>& 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
* projection.
*/
X_monotone_curve_2 operator()(const X_monotone_curve_2& curve,
const boost::optional<Point_2>& pLeft,
const boost::optional<Point_2>& pRight);
protected:
const ArrTraits* traits;
Split_2 split_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_max_vertex_2 construct_max_vertex_2;
Parameter_space_in_x_2 parameter_space_in_x_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.
*/
template <typename RatKernel, typename AlgKernel, typename NtTraits>
class Construct_x_monotone_subcurve_2< CGAL::Arr_conic_traits_2< RatKernel,
AlgKernel,
NtTraits > >
class Construct_x_monotone_subcurve_2<CGAL::Arr_conic_traits_2<RatKernel,
AlgKernel,
NtTraits>>
{
public:
typedef CGAL::Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>
ArrTraits;
typedef typename ArrTraitsAdaptor<ArrTraits>::Kernel Kernel;
typedef typename ArrTraits::X_monotone_curve_2 X_monotone_curve_2;
typedef typename ArrTraits::Split_2 Split_2;
typedef typename ArrTraits::Intersect_2 Intersect_2;
typedef typename ArrTraits::Multiplicity Multiplicity;
typedef typename ArrTraits::Construct_min_vertex_2 Construct_min_vertex_2;
typedef typename ArrTraits::Construct_max_vertex_2 Construct_max_vertex_2;
typedef typename ArrTraits::Compare_x_2 Compare_x_2;
Traits;
typedef typename ArrTraitsAdaptor<Traits>::Kernel Kernel;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Traits::Split_2 Split_2;
typedef typename Traits::Intersect_2 Intersect_2;
typedef typename Traits::Multiplicity Multiplicity;
typedef typename Traits::Construct_min_vertex_2 Construct_min_vertex_2;
typedef typename Traits::Construct_max_vertex_2 Construct_max_vertex_2;
typedef typename Traits::Compare_x_2 Compare_x_2;
typedef typename Kernel::FT FT;
typedef typename ArrTraitsAdaptor< ArrTraits >::CoordinateType
typedef typename ArrTraitsAdaptor<Traits>::CoordinateType
CoordinateType;
typedef typename ArrTraits::Point_2 Point_2;
typedef typename Traits::Point_2 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.
*/
X_monotone_curve_2 operator() ( const X_monotone_curve_2& curve,
const boost::optional<Point_2>& pLeft,
const boost::optional<Point_2>& pRight );
/* Return the subcurve of curve bracketed by pLeft and pRight.
*/
X_monotone_curve_2 operator()(const X_monotone_curve_2& curve,
const boost::optional<Point_2>& pLeft,
const boost::optional<Point_2>& pRight );
}; // class Construct_x_monotone_subcurve_2 for Arr_conic_traits_2
private:
const Traits& m_traits;
};
template <
typename RatKernel, typename AlgKernel, typename NtTraits,
typename BoundingTraits>
class Construct_x_monotone_subcurve_2<CGAL::Arr_Bezier_curve_traits_2<
RatKernel, AlgKernel, NtTraits, BoundingTraits>>
//
template <typename RatKernel, typename AlgKernel, typename NtTraits,
typename BoundingTraits>
class Construct_x_monotone_subcurve_2
<CGAL::Arr_Bezier_curve_traits_2
<RatKernel, AlgKernel, NtTraits, BoundingTraits>>
{
public:
typedef CGAL::Arr_Bezier_curve_traits_2<
RatKernel, AlgKernel, NtTraits, BoundingTraits>
typedef CGAL::Arr_Bezier_curve_traits_2<RatKernel, AlgKernel, NtTraits,
BoundingTraits>
ArrTraits;
typedef typename ArrTraits::X_monotone_curve_2 X_monotone_curve_2;
typedef typename ArrTraits::Split_2 Split_2;
@ -430,14 +551,15 @@ public:
typedef typename ArrTraits::Compare_x_2 Compare_x_2;
typedef typename ArrTraits::Point_2 Point_2;
//
Construct_x_monotone_subcurve_2(const ArrTraits* traits_);
/*
Return the subcurve of curve bracketed by pLeft and pRight.
*/
X_monotone_curve_2 operator()(
const X_monotone_curve_2& curve, const boost::optional<Point_2>& pLeft,
const boost::optional<Point_2>& pRight);
X_monotone_curve_2 operator()(const X_monotone_curve_2& curve,
const boost::optional<Point_2>& pLeft,
const boost::optional<Point_2>& pRight);
protected:
const ArrTraits* traits;
@ -446,8 +568,9 @@ protected:
Arr_compute_y_at_x_2< ArrTraits > compute_y_at_x;
Construct_min_vertex_2 construct_min_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>
class Construct_x_monotone_subcurve_2<
CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>>
@ -471,33 +594,30 @@ public:
Construct_x_monotone_subcurve_2( const Traits* traits_ );
/*
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
projection.
*/
X_monotone_curve_2 operator() ( const X_monotone_curve_2& curve,
const boost::optional<Point_2>& pLeft,
const boost::optional<Point_2>& 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
* projection.
*/
X_monotone_curve_2 operator()(const X_monotone_curve_2& curve,
const boost::optional<Point_2>& pLeft,
const boost::optional<Point_2>& pRight);
protected:
const Traits* traits;
Split_2 split_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_max_vertex_2 construct_max_vertex_2;
}; // class Construct_x_monotone_subcurve_2
/**
Converts between Kernel points and Arrangement points.
The conversion is not necessarily exact.
*/
/* Converts between Kernel points and Arrangement points.
*
* The conversion is not necessarily exact.
*/
template <typename ArrTraits>
class Arr_construct_point_2
{
class Arr_construct_point_2 {
typedef ArrTraits Traits;
typedef typename ArrTraits::Point_2 Point_2;
typedef typename ArrTraitsAdaptor< ArrTraits >::CoordinateType CoordinateType;
@ -506,50 +626,53 @@ class Arr_construct_point_2
typedef typename Kernel::FT FT;
public:
//
Arr_construct_point_2(const Traits* traits_) : traits(traits_) { }
//
template <typename P>
Point_2 operator()(const P& p)
{
return this->operator()(p.x(), p.y());
}
Point_2 operator()(const P& p) { return this->operator()(p.x(), p.y()); }
//
template <typename T, typename U>
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 FT& x, const FT& y);
protected:
//
template <typename TTraits >
Point_2 operator()(const FT& x, const FT& y, const TTraits*);
//
template <typename AlgebraicKernel_d_1>
Point_2 operator()(
const FT& x, const FT& y,
const CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>*);
Point_2
operator()(const FT& x, const FT& y,
const CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>*);
const Traits* traits;
};
class Find_nearest_edge_base : public GraphicsSceneMixin
{
//
class Find_nearest_edge_base : public GraphicsSceneMixin {
public:
/*! Destructor (virtual) */
/*! Destructor */
virtual ~Find_nearest_edge_base() {}
};
//
template <typename Arr_>
class Find_nearest_edge : public Find_nearest_edge_base
{
public: // typedefs
typedef Arr_ Arrangement;
typedef typename Arrangement::Geometry_traits_2 ArrTraits;
typedef Compute_squared_distance_2< ArrTraits > Point_curve_distance;
typedef typename ArrTraits::X_monotone_curve_2 X_monotone_curve_2;
class Find_nearest_edge : public Find_nearest_edge_base {
public:
typedef Arr_ Arrangement;
typedef typename Arrangement::Geometry_traits_2 ArrTraits;
typedef Compute_squared_distance_2<ArrTraits> Point_curve_distance;
typedef typename ArrTraits::X_monotone_curve_2 X_monotone_curve_2;
typedef typename ArrTraitsAdaptor<ArrTraits>::Kernel Kernel;
typedef typename Kernel::Point_2 Point_2;
typedef typename Arrangement::Face_const_handle Face_const_handle;
@ -561,49 +684,53 @@ public: // typedefs
public:
/*! constructor */
Find_nearest_edge( Arrangement* arr_ ) :
Find_nearest_edge_base( ),
arr( arr_ )
{ }
Find_nearest_edge(Arrangement* arr_) :
Find_nearest_edge_base(),
arr(arr_)
{}
/*! Destructor (virtual) */
virtual ~Find_nearest_edge() {}
public: // member methods
Halfedge_const_handle operator()( const Point_2& queryPt );
//
Halfedge_const_handle operator()(const Point_2& queryPt);
virtual void setScene( QGraphicsScene* scene_ )
{
this->pointCurveDistance.setScene( scene_ );
Find_nearest_edge_base::setScene( scene_ );
//
virtual void setScene(QGraphicsScene* scene_) {
// this->pointCurveDistance.setScene(scene_);
Find_nearest_edge_base::setScene(scene_);
}
protected: // member methods
Face_const_handle getFace( const CGAL::Object& obj );
protected:
//
Face_const_handle getFace(const CGAL::Object& obj);
protected: // member fields
protected:
Arrangement* arr;
Point_curve_distance pointCurveDistance;
}; // class Find_nearest_edge
};
//
template <typename Arr_>
class Insert_curve
{
class Insert_curve {
public:
typedef Arr_ Arrangement;
typedef typename Arrangement::Geometry_traits_2 ArrTraits;
typedef typename ArrTraits::Curve_2 Curve_2;
//
void operator()(Arrangement*, const Curve_2&);
};
// free functions gathered here to speed up compilation of other files
// specializing once in one file is better than in multiple files
CGAL::Object createArrangement(demo_types::TraitsType);
void deleteArrangement(demo_types::TraitsType, const 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

View File

@ -22,8 +22,7 @@
#include <QGraphicsSceneMouseEvent>
template <typename Arr_>
class VerticalRayShootCallback : public VerticalRayShootCallbackBase
{
class VerticalRayShootCallback : public VerticalRayShootCallbackBase {
public:
typedef VerticalRayShootCallbackBase Superclass;
typedef Arr_ Arrangement;
@ -57,13 +56,12 @@ VerticalRayShootCallbackBase::VerticalRayShootCallbackBase(QObject* parent_) :
}
// msvc2015 doesn't play well with polymorphic lambdas
namespace
{
struct ExplicitLambda
{
namespace {
//
struct ExplicitLambda {
template <typename Arrangement>
void operator()(demo_types::TypeHolder<Arrangement>)
{
void operator()(demo_types::TypeHolder<Arrangement>) {
Arrangement* arr = nullptr;
CGAL::assign(arr, arr_obj);
res = new VerticalRayShootCallback<Arrangement>(arr, parent);
@ -73,28 +71,30 @@ struct ExplicitLambda
CGAL::Object& arr_obj;
QObject* parent;
};
} // 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;
ExplicitLambda explicit_lambda{res, arr_obj, parent};
demo_types::visitArrangementType(tt, explicit_lambda);
return res;
}
//
void VerticalRayShootCallbackBase::setShootingUp(bool isShootingUp)
{
this->shootingUp = isShootingUp;
}
{ this->shootingUp = isShootingUp; }
//
template <typename Arr_>
VerticalRayShootCallback<Arr_>::VerticalRayShootCallback(
Arrangement* arr_, QObject* parent_) :
VerticalRayShootCallbackBase(parent_),
arr(arr_),
highlightedCurves(new CGAL::Qt::CurveGraphicsItem<Traits>())
VerticalRayShootCallback<Arr_>::
VerticalRayShootCallback(Arrangement* arr_, QObject* parent_) :
VerticalRayShootCallbackBase(parent_),
arr(arr_),
highlightedCurves(new CGAL::Qt::CurveGraphicsItem<Traits>(*(arr->geometry_traits())))
{
this->rayGraphicsItem.setZValue(100);
@ -102,81 +102,75 @@ VerticalRayShootCallback<Arr_>::VerticalRayShootCallback(
this->highlightedCurves->setVertexColor(this->rayGraphicsItem.color());
this->highlightedCurves->setZValue(100);
QObject::connect(
this, SIGNAL(modelChanged()), this->highlightedCurves,
SLOT(modelChanged()));
QObject::connect(
this, SIGNAL(modelChanged()), this, SLOT(slotModelChanged()));
QObject::connect(this, SIGNAL(modelChanged()), this->highlightedCurves,
SLOT(modelChanged()));
QObject::connect(this, SIGNAL(modelChanged()), this, SLOT(slotModelChanged()));
}
//
template <typename Arr_>
void VerticalRayShootCallback<Arr_>::setEdgeWidth( int width )
{
this->highlightedCurves->setEdgeWidth( width );
this->rayGraphicsItem.setWidth( width );
void VerticalRayShootCallback<Arr_>::setEdgeWidth(int width) {
this->highlightedCurves->setEdgeWidth(width);
this->rayGraphicsItem.setWidth(width);
}
//
template <typename Arr_>
void VerticalRayShootCallback<Arr_>::setEdgeColor( const QColor& color )
{
this->highlightedCurves->setEdgeColor( color );
this->rayGraphicsItem.setColor( color );
void VerticalRayShootCallback<Arr_>::setEdgeColor(const QColor& color) {
this->highlightedCurves->setEdgeColor(color);
this->rayGraphicsItem.setColor(color);
}
//
template <typename Arr_>
const QColor& VerticalRayShootCallback<Arr_>::edgeColor( ) const
{
return this->highlightedCurves->edgeColor( );
}
const QColor& VerticalRayShootCallback<Arr_>::edgeColor() const
{ return this->highlightedCurves->edgeColor(); }
//
template <typename Arr_>
int VerticalRayShootCallback<Arr_>::edgeWidth( ) const
{
return this->highlightedCurves->edgeWidth( );
}
int VerticalRayShootCallback<Arr_>::edgeWidth() const
{ return this->highlightedCurves->edgeWidth(); }
//
template <typename Arr_>
void VerticalRayShootCallback<Arr_>::setScene(QGraphicsScene* scene_)
{
void VerticalRayShootCallback<Arr_>::setScene(QGraphicsScene* scene_) {
CGAL::Qt::Callback::setScene(scene_);
this->highlightedCurves->setScene(scene_);
if (scene_)
{
if (scene_) {
this->scene->addItem(this->highlightedCurves);
this->scene->addItem(&this->rayGraphicsItem);
}
}
//
template <typename Arr_>
void VerticalRayShootCallback<Arr_>::slotModelChanged()
{
}
//
template <typename Arr_>
void VerticalRayShootCallback<Arr_>::reset()
{
void VerticalRayShootCallback<Arr_>::reset() {
this->rayGraphicsItem.reset();
this->highlightedCurves->clear();
Q_EMIT modelChanged();
}
//
template <typename Arr_>
void VerticalRayShootCallback<Arr_>::mousePressEvent(
QGraphicsSceneMouseEvent* event)
{
this->highlightPointLocation(event);
}
void VerticalRayShootCallback<Arr_>::
mousePressEvent(QGraphicsSceneMouseEvent* event)
{ this->highlightPointLocation(event); }
//
template <typename Arr_>
void VerticalRayShootCallback<Arr_>::mouseMoveEvent(
QGraphicsSceneMouseEvent* /* event */)
{
}
void VerticalRayShootCallback<Arr_>::
mouseMoveEvent(QGraphicsSceneMouseEvent* /* event */) {}
//
template <typename Arr_>
void VerticalRayShootCallback<Arr_>::highlightPointLocation(
QGraphicsSceneMouseEvent* event)
{
void VerticalRayShootCallback<Arr_>::
highlightPointLocation(QGraphicsSceneMouseEvent* event) {
this->highlightedCurves->clear();
QPointF queryQPt = event->scenePos();
@ -192,25 +186,21 @@ void VerticalRayShootCallback<Arr_>::highlightPointLocation(
QRectF viewportRect = this->viewportRect();
qreal y2;
if (this->shootingUp)
{ // +y in Qt is towards the bottom
if (this->shootingUp) { // +y in Qt is towards the bottom
y2 = viewportRect.bottom();
}
else
{
else {
y2 = viewportRect.top();
}
Face_const_handle unboundedFace;
Halfedge_const_handle halfedge;
Vertex_const_handle vertex;
if (CGAL::assign(unboundedFace, pointLocationResult))
{
if (CGAL::assign(unboundedFace, pointLocationResult)) {
this->rayGraphicsItem.setSource(queryQPt);
this->rayGraphicsItem.setTargetY(y2);
this->rayGraphicsItem.setIsInfinite(true);
}
else if (CGAL::assign(halfedge, pointLocationResult))
{
else if (CGAL::assign(halfedge, pointLocationResult)) {
this->highlightedCurves->insert(halfedge->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.setIsInfinite(false);
}
else if (CGAL::assign(vertex, pointLocationResult))
{
if (!vertex->is_at_open_boundary())
{
else if (CGAL::assign(vertex, pointLocationResult)) {
if (!vertex->is_at_open_boundary()) {
auto pt = vertex->point();
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/Arrangement_2.h>
typedef CGAL::CORE_algebraic_number_traits Nt_traits;
typedef Nt_traits::Rational Rational;
typedef CGAL::Cartesian<Rational> Rat_kernel;
typedef Rat_kernel::Point_2 Rat_point;
typedef Rat_kernel::Segment_2 Rat_segment;
typedef Rat_kernel::Circle_2 Rat_circle;
typedef Nt_traits::Algebraic Algebraic;
typedef CGAL::Cartesian<Algebraic> Alg_kernel;
typedef CGAL::Arr_conic_traits_2<Rat_kernel, Alg_kernel, Nt_traits>
Traits;
typedef Traits::Point_2 Point;
typedef Traits::Curve_2 Conic_arc;
typedef Traits::X_monotone_curve_2 X_monotone_conic_arc;
typedef CGAL::Arrangement_2<Traits> Arrangement;
using Nt_traits = CGAL::CORE_algebraic_number_traits;
using Rational = Nt_traits::Rational;
using Rat_kernel = CGAL::Cartesian<Rational>;
using Rat_point = Rat_kernel::Point_2;
using Rat_segment = Rat_kernel::Segment_2;
using Rat_circle = Rat_kernel::Circle_2;
using Algebraic = Nt_traits::Algebraic;
using Alg_kernel = CGAL::Cartesian<Algebraic>;
using Traits = CGAL::Arr_conic_traits_2<Rat_kernel, Alg_kernel, Nt_traits>;
using Point = Traits::Point_2;
using Conic_arc = Traits::Curve_2;
using X_monotone_conic_arc = Traits::X_monotone_curve_2;
using Arrangement = CGAL::Arrangement_2<Traits>;
\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}
<!-- ========================================================================= -->
\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
@ -6744,6 +6742,24 @@ arrangement formatter class (see Section \ref arr_ssecarr_io_aux_data)
and defines a simple textual input/output format.
\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
<!-- ========================================================================= -->

View File

@ -4,22 +4,22 @@ namespace CGAL {
*
* 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
* 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>.
*
* 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$,
* 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$,
* where:
*
* <UL>
* <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.
* <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.
*
* <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
* occurs when \f$ r = s = t = 0\f$, when \f$ C\f$ is a line.
* <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.
*
* </UL>
*
@ -34,37 +34,37 @@ namespace CGAL {
* 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
* 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.
*
* </UL>
*
* 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
* interesting applications (e.g. offsetting polygons, motion planning for a
* disc robot, etc.). Circular arcs and line segment are simpler objects and can
* be dealt with more efficiently than arbitrary arcs. For these reasons, it is
* possible to construct conic arcs from segments and from circles. Using these
* constructors is highly recommended: It is more straightforward and also
* speeds up the arrangement construction. However, in case the set of input
* curves contain only circular arcs and line segments, it is recommended to use
* the `Arr_circle_segment_2` class to achieve faster running times.
* interesting applications (e.g., offsetting polygons and motion planning for a
* disc robot). Circular arcs and line segment are simpler objects and can be
* dealt with more efficiently than arbitrary arcs. Indeed, it is possible to
* construct conic arcs from segments and from circles. Using these constructors
* is highly recommended: It is more straightforward and also expedites the
* arrangement construction. However, in case the set of input curves contain
* only circular arcs and line segments, it is recommended using the
* `Arr_circle_segment_2` class to achieve better running times.
*
* In our representation, all conic coefficients (namely \f$ r, s, t, u, v,
* w\f$) must be rational numbers. This guarantees that the coordinates of all
* In our representation, all conic coefficients (namely \f$r, s, t, u, v, w\f$)
* must be rational numbers. This guarantees that the coordinates of all
* arrangement vertices (in particular, those representing intersection points)
* 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
* <I>integer</I> coefficient of degree \f$ d\f$ such that \f$ p(\alpha) =
* 0\f$). We therefore require separate representations of the curve
* 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
* <I>integer</I> coefficient of degree \f$d\f$ such that \f$p(\alpha) = 0\f$).
* We therefore require separate representations of the curve
* 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
* results (for example, it can convert rational numbers to algebraic numbers
* and can compute roots of polynomials with integer coefficients). The other
* template parameters, `RatKernel` and `AlgKernel` should be geometric kernels
* templated with the `NtTraits::Rational` and `NtTraits::Algebraic` number
* types, respectively. It is recommended to instantiate the
* instantiated with the `NtTraits::Rational` and `NtTraits::Algebraic` number
* types, respectively. It is recommended instantiating the
* `CORE_algebraic_number_traits` class as the `NtTraits` parameter, with
* `Cartesian<NtTraits::Rational>` and `Cartesian<NtTraits::Algebraic>`
* instantiating the two kernel types, respectively. The number types in this
@ -72,7 +72,7 @@ namespace CGAL {
* simple algebraic numbers.
*
* 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
* `ArrangementDirectionalXMonotoneTraits_2`, the implementation of
@ -115,110 +115,9 @@ public:
/// \name Creation
/// @{
/*! constructs an arc corresponding to the line segment `seg`.
/*! constructs an empty (invalid) arc.
*/
Curve_2(const typename RatKernel::Segment_2& seg);
/*! 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);
Curve_2();
/// @}
@ -230,20 +129,19 @@ public:
* violation does not cause the program to abort. Instead, the constructed
* arc is invalid (a defaultly constructed arc is also invalid). It is
* however recommended to check that a constructed arc is valid before
* inserting it to an arrangement, as this operation <I>will</I> cause the
* program to abort.
* inserting it to an arrangement.
*/
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
* considered (weakly) \f$ x\f$-monotone.
* considered (weakly) \f$x\f$-monotone.
*/
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
* considered (weakly) \f$ x\f$-monotone.
* considered (weakly) \f$x\f$-monotone.
*/
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;
/*! returns the coefficient of \f$ t^2\f$.
/*! returns the coefficient of \f$t^2\f$.
*/
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;
/*! returns the coefficient of \f$ x\f$.
/*! returns the coefficient of \f$x\f$.
*/
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;
@ -299,10 +197,6 @@ public:
*/
Orientation orientation() const;
/*! return a bounding box of the arc `a`.
*/
Bbox_2 bbox() const;
/// @}
/// \name Operations
@ -322,15 +216,16 @@ public:
}; /* 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
* `Curve_2` type, therefore supports the access methods and the operations
* listed above.
*
* For efficiency reasons, we recommend users not to construct \f$
* x\f$-monotone conic arc directly, but rather use the `Make_x_monotone_2`
* For efficiency reasons, we recommend users not to construct
* \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
* \f$ x\f$-monotone curves.
* \f$x\f$-monotone curves.
*/
class X_monotone_curve_2 {
public:
@ -338,10 +233,9 @@ public:
/// \name Creation
/// @{
/*! converts the given arc to an \f$ x\f$-monotone arc.
* \pre `arc` is \f$ x\f$-monotone.
/*! constructs an empty (invalid) arc.
*/
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 {
public:
/// \name Creation
/// @{
/*! Trims the given x-monotone curve to an from src to tgt.
* \ pre `src` and `tgt` lies on the curve
/*! Trims the given \f$x\f$-monotone arc to new endpoints.
* \param xcv The \f$x\f$-monotone arc
* \param source The new source point.
* \param target The new target point.
* \pre `source` and `target` lies on the arc.
*/
X_monotone_curve_2(const X_monotone_curve_2& xcv,
const Point_2& src,
const Point_2& tgt) const;
X_monotone_curve_2 operator()(const X_monotone_curve_2& xcv,
const Point_2& source,
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 namespace CGAL */

View File

@ -52,6 +52,10 @@ namespace CGAL {
* \sa `PkgArrangementOnSurface2Read`
* \sa `PkgArrangementOnSurface2Write`
*
* Drawing function
*
* \sa `PkgArrangementOnSurface2Draw`
*/
template <typename GeometryTraits, typename TopologyTraits>
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>
OutputIterator operator()(ArrTraits::X_monotone_curve_2 xc1,
ArrTraits::X_monotone_curve_2 xc2,
OutputIterator& oi);
ArrTraits::X_monotone_curve_2 xc2,
OutputIterator& oi);
/// @}

View File

@ -46,6 +46,14 @@ namespace ArrTraits {}
/// \defgroup PkgArrangementOnSurface2Funcs Free Functions
/// \ingroup PkgArrangementOnSurface2Ref
/*!
\code
#include <CGAL/draw_arrangement_2.h>
\endcode
*/
/// \defgroup PkgArrangementOnSurface2Draw Drawing
/// \ingroup PkgArrangementOnSurface2Ref
/// \defgroup PkgArrangementOnSurface2Insert CGAL::insert()
/// \ingroup PkgArrangementOnSurface2Funcs
@ -252,4 +260,7 @@ implemented as peripheral classes or as free (global) functions.
- \link PkgArrangementOnSurface2op_left_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_rational_functions.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)
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
file(
@ -14,3 +14,19 @@ file(
foreach(cppfile ${cppfiles})
create_single_source_cgal_program("${cppfile}")
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/Arrangement_2.h>
typedef CGAL::CORE_algebraic_number_traits Nt_traits;
typedef Nt_traits::Rational Rational;
typedef CGAL::Cartesian<Rational> Rat_kernel;
typedef Rat_kernel::Point_2 Rat_point;
typedef Rat_kernel::Segment_2 Rat_segment;
typedef Rat_kernel::Circle_2 Rat_circle;
typedef Nt_traits::Algebraic Algebraic;
typedef CGAL::Cartesian<Algebraic> Alg_kernel;
typedef CGAL::Arr_conic_traits_2<Rat_kernel, Alg_kernel, Nt_traits>
Traits;
typedef Traits::Point_2 Point;
typedef Traits::Curve_2 Conic_arc;
typedef Traits::X_monotone_curve_2 X_monotone_conic_arc;
typedef CGAL::Arrangement_2<Traits> Arrangement;
using Nt_traits = CGAL::CORE_algebraic_number_traits;
using Rational = Nt_traits::Rational;
using Rat_kernel = CGAL::Cartesian<Rational>;
using Rat_point = Rat_kernel::Point_2;
using Rat_segment = Rat_kernel::Segment_2;
using Rat_circle = Rat_kernel::Circle_2;
using Algebraic = Nt_traits::Algebraic;
using Alg_kernel = CGAL::Cartesian<Algebraic>;
using Traits = CGAL::Arr_conic_traits_2<Rat_kernel, Alg_kernel, Nt_traits>;
using Point = Traits::Point_2;
using Conic_arc = Traits::Curve_2;
using X_monotone_conic_arc = Traits::X_monotone_curve_2;
using Arrangement = CGAL::Arrangement_2<Traits>;
#endif

View File

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

View File

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

View File

@ -14,7 +14,10 @@
typedef CGAL::Arr_naive_point_location<Arrangement> Naive_pl;
int main() {
Arrangement arr;
Traits traits;
auto ctr_cv = traits.construct_curve_2_object();
Arrangement arr(&traits);
Naive_pl pl(arr);
// 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.
Point ps1(-1, Rational(1,2));
Point pt1(Rational(1,2), Rational(1,2));
Conic_arc cv1(1, 0, 1, 0, -1, 0, CGAL::COUNTERCLOCKWISE, ps1, pt1);
insert(arr, cv1, pl);
Conic_arc cv1 = ctr_cv(1, 0, 1, 0, -1, 0, CGAL::COUNTERCLOCKWISE, ps1, pt1);
// insert(arr, cv1, pl);
#if 0
// Insert the bottom half of the circle centered at (0, 1/2) whose radius
// is 1/2 (therefore its squared radius is 1/4).
Rat_circle circ2(Rat_point(0, Rational(1,2)), Rational(1,4));
Point ps2(-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);
#endif
print_arrangement (arr);
print_arrangement(arr);
return 0;
}

View File

@ -9,31 +9,31 @@
#include "arr_print.h"
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
// (or: xy - 1 = 0) with the endpoints (1/4, 4) and (2, 1/2).
// The arc is counterclockwise oriented.
insert(arr, Conic_arc(0, 0, 1, 0, 0, -1, CGAL::COUNTERCLOCKWISE,
Point(Rational(1,4), 4), Point(2, Rational(1,2))));
insert(arr, ctr_cv(0, 0, 1, 0, 0, -1, CGAL::COUNTERCLOCKWISE,
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
// phi = 36.87 degrees (such that sin(phi) = 0.6, cos(phi) = 0.8),
// 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(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,
// 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.
Conic_arc c4(Rat_point(-3, 4), Rat_point(0, 5), Rat_point(4, 3));
insert(arr, c4);
insert(arr, ctr_cv(Rat_point(-3, 4), Rat_point(0, 5), Rat_point(4, 3)));
// 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
// 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
// y = -3 and y = -2, respectively. The arc is clockwise-oriented.
Conic_arc c6 =
Conic_arc(1, 0, 0, 0, 1, 0, CGAL::CLOCKWISE, // The parabola.
Point(-1.73, -3), // approximation of the source.
0, 0, 0, 0, 1, 3, // the line: y = -3.
Point(1.41, -2), // approximation of the target.
0, 0, 0, 0, 1, 2); // the line: y = -2.
ctr_cv(1, 0, 0, 0, 1, 0, CGAL::CLOCKWISE, // The parabola.
Point(-1.73, -3), // approximation of the source.
0, 0, 0, 0, 1, 3, // the line: y = -3.
Point(1.41, -2), // approximation of the target.
0, 0, 0, 0, 1, 2); // the line: y = -2.
insert(arr, c6);
// 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).
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);
return 0;
@ -62,8 +62,7 @@ int main() {
#include <iostream>
int main ()
{
int main() {
std::cout << "Sorry, this example needs GMP and CORE\n";
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;
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
auto ctr_xpolycurve = traits.construct_x_monotone_curve_2_object();
@ -39,29 +42,29 @@ int main() {
// Create polycurves
// y=x^2
Conic_arc c3(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE,
Point(Algebraic(0), Algebraic(0)),
Point(Algebraic(3), Algebraic(9)));
Conic_arc c4(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE,
Point(Algebraic(3), Algebraic(9)),
Point(Algebraic(5), Algebraic(25)));
Conic_arc c5(0,1,0,1,0,0, CGAL::COUNTERCLOCKWISE,
Point(Algebraic(-25), Algebraic(-5)),
Point(Algebraic(0), Algebraic(0)));
Conic_arc c3 = ctr_sub_cv(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE,
Point(Algebraic(0), Algebraic(0)),
Point(Algebraic(3), Algebraic(9)));
Conic_arc c4 = ctr_sub_cv(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE,
Point(Algebraic(3), Algebraic(9)),
Point(Algebraic(5), Algebraic(25)));
Conic_arc c5 = ctr_sub_cv(0,1,0,1,0,0, CGAL::COUNTERCLOCKWISE,
Point(Algebraic(-25), Algebraic(-5)),
Point(Algebraic(0), Algebraic(0)));
Conic_arc c6(1,1,0,6,-26,162,CGAL::COUNTERCLOCKWISE,
Point(Algebraic(-7), Algebraic(13)),
Point(Algebraic(-3), Algebraic(9)));
Conic_arc c7(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE,
Point(Algebraic(-3), Algebraic(9)),
Point(Algebraic(0), Algebraic(0)));
Conic_arc c8(0,1,0,-1,0,0, CGAL::COUNTERCLOCKWISE,
Point(Algebraic(0), Algebraic(0)),
Point(Algebraic(4), Algebraic(-2)));
Conic_arc c6 = ctr_sub_cv(1,1,0,6,-26,162,CGAL::COUNTERCLOCKWISE,
Point(Algebraic(-7), Algebraic(13)),
Point(Algebraic(-3), Algebraic(9)));
Conic_arc c7 = ctr_sub_cv(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE,
Point(Algebraic(-3), Algebraic(9)),
Point(Algebraic(0), Algebraic(0)));
Conic_arc c8 = ctr_sub_cv(0,1,0,-1,0,0, CGAL::COUNTERCLOCKWISE,
Point(Algebraic(0), Algebraic(0)),
Point(Algebraic(4), Algebraic(-2)));
Conic_arc c9(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE,
Point(Algebraic(-5), Algebraic(25)),
Point(Algebraic(5), Algebraic(25)));
Conic_arc c9 = ctr_sub_cv(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE,
Point(Algebraic(-5), Algebraic(25)),
Point(Algebraic(5), Algebraic(25)));
// Construct poly-curve
conic_curves.clear();
@ -69,12 +72,12 @@ int main() {
Polycurve conic_polycurve_1 =
ctr_polycurve(conic_curves.begin(), conic_curves.end());
Conic_arc c11(0,1,0,-1,0,0,CGAL::COUNTERCLOCKWISE,
Point(Algebraic(25), Algebraic(-5)),
Point(Algebraic(0), Algebraic(0)));
Conic_arc c12(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE,
Point(Algebraic(0), Algebraic(0)),
Point(Algebraic(5), Algebraic(25)));
Conic_arc c11 = ctr_sub_cv(0,1,0,-1,0,0,CGAL::COUNTERCLOCKWISE,
Point(Algebraic(25), Algebraic(-5)),
Point(Algebraic(0), Algebraic(0)));
Conic_arc c12 = ctr_sub_cv(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE,
Point(Algebraic(0), Algebraic(0)),
Point(Algebraic(5), Algebraic(25)));
// Construct poly-curve
conic_curves.clear();
@ -84,12 +87,12 @@ int main() {
ctr_polycurve(conic_curves.begin(), conic_curves.end());
// Construct x-monotone conic curves from conic curves
X_monotone_conic_arc xc3(c3);
X_monotone_conic_arc xc4(c4);
X_monotone_conic_arc xc5(c5);
X_monotone_conic_arc xc6(c6);
X_monotone_conic_arc xc7(c7);
X_monotone_conic_arc xc8(c8);
X_monotone_conic_arc xc3 = ctr_sub_xcv(c3);
X_monotone_conic_arc xc4 = ctr_sub_xcv(c4);
X_monotone_conic_arc xc5 = ctr_sub_xcv(c5);
X_monotone_conic_arc xc6 = ctr_sub_xcv(c6);
X_monotone_conic_arc xc7 = ctr_sub_xcv(c7);
X_monotone_conic_arc xc8 = ctr_sub_xcv(c8);
// Construct x-monotone poly-curve from x-monotone conic curves.
xmono_conic_curves_2.clear();
@ -98,7 +101,7 @@ int main() {
xmono_conic_curves_2.push_back(xc4);
X_monotone_polycurve conic_x_mono_polycurve_1 =
ctr_xpolycurve(xmono_conic_curves_2.begin(),
xmono_conic_curves_2.end());
xmono_conic_curves_2.end());
// Construct x-monotone poly-curve.
xmono_conic_curves_2.clear();

View File

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

View File

@ -23,13 +23,16 @@
* The header file for the Arr_circle_segment_traits_2<Kernel> class.
*/
#include <CGAL/tags.h>
#include <CGAL/Arr_tags.h>
#include <CGAL/Arr_geometry_traits/Circle_segment_2.h>
// Keep the following 2 lines first.
#include <cmath>
#include <fstream>
#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 {
/*! \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
//@{

File diff suppressed because it is too large Load Diff

View File

@ -29,6 +29,7 @@
#include <boost/variant.hpp>
#include <CGAL/config.h>
#include <CGAL/Cartesian.h>
#include <CGAL/tags.h>
#include <CGAL/tss.h>
#include <CGAL/intersections.h>
@ -2834,11 +2835,12 @@ public:
/// \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 {
public:
/*! Return an approximation of a point coordinate.
* \param p the exact point.
* \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
* 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);
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 {
CGAL_error_msg("Not implemented yet!");
}
};
/*! Obtain an Approximate_2 function object */

View File

@ -8,7 +8,7 @@
// 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
#define CGAL_CONIC_INTERSECTIONS_2_H
@ -24,8 +24,7 @@
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
* C2: r2*x^2 + s2*y^2 + t2*xy + u2*x + v2*y + w2 = 0
* \param deg1 The degree of the first curve.
@ -35,84 +34,76 @@ namespace CGAL {
* \pre xs must be a vector of size 4.
* \return The number of distinct roots found.
*/
template <class Nt_traits>
int
_compute_resultant_roots (Nt_traits& nt_traits,
const typename Nt_traits::Integer& r1,
const typename Nt_traits::Integer& s1,
const typename Nt_traits::Integer& t1,
const typename Nt_traits::Integer& u1,
const typename Nt_traits::Integer& v1,
const typename Nt_traits::Integer& w1,
const int& deg1,
const typename Nt_traits::Integer& r2,
const typename Nt_traits::Integer& s2,
const typename Nt_traits::Integer& t2,
const typename Nt_traits::Integer& u2,
const typename Nt_traits::Integer& v2,
const typename Nt_traits::Integer& w2,
const int& deg2,
typename Nt_traits::Algebraic *xs)
template <typename Nt_traits>
int compute_resultant_roots(const Nt_traits& nt_traits,
const typename Nt_traits::Integer& r1,
const typename Nt_traits::Integer& s1,
const typename Nt_traits::Integer& t1,
const typename Nt_traits::Integer& u1,
const typename Nt_traits::Integer& v1,
const typename Nt_traits::Integer& w1,
const int& deg1,
const typename Nt_traits::Integer& r2,
const typename Nt_traits::Integer& s2,
const typename Nt_traits::Integer& t2,
const typename Nt_traits::Integer& u2,
const typename Nt_traits::Integer& v2,
const typename Nt_traits::Integer& w2,
const int& deg2,
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
// curve always has the minimal degree.
return (_compute_resultant_roots (nt_traits,
r2, s2, t2, u2, v2, w2,
deg2,
r1, s1, t1, u1, v1, w1,
deg1,
xs));
return (compute_resultant_roots(nt_traits,
r2, s2, t2, u2, v2, w2,
deg2,
r1, s1, t1, u1, v1, w1,
deg1,
xs));
}
// Act according to the degree of the first conic curve.
const typename Nt_traits::Integer _two = 2;
typename Nt_traits::Integer c[5];
unsigned int degree = 4;
typename Nt_traits::Algebraic *xs_end;
const typename Nt_traits::Integer two = 2;
typename Nt_traits::Integer c[5];
unsigned int degree = 4;
typename Nt_traits::Algebraic* xs_end;
if (deg1 == 1)
{
if (deg1 == 1) {
// 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:
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.
if (deg2 == 1)
{
if (deg2 == 1) {
// The second curve is also a line. We therefore get the linear
// equation c[1]*x + c[0] = 0:
c[1] = v1*u2 - u1*v2;
c[0] = v1*w2 - w1*v2;
if (CGAL::sign (c[1]) == ZERO)
// The two lines are parallel:
return (0);
// Return if the two lines are parallel
if (CGAL::sign (c[1]) == ZERO) return 0;
xs[0] = nt_traits.convert(-c[0]) / nt_traits.convert(c[1]);
return (1);
xs[0] = nt_traits.convert(-c[0]) / nt_traits.convert(c[1]);
return 1;
}
// 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:
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;
xs_end = nt_traits.solve_quadratic_equation (c[2], c[1], c[0],
xs);
xs_end = nt_traits.solve_quadratic_equation(c[2], c[1], c[0], xs);
return static_cast<int>(xs_end - xs);
}
// At this stage, both curves have degree 2. We obtain a qaurtic polynomial
// 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:
// C1: (t1*x + v1)*y + (r1*x^2 + u1*x + w1) = 0
// C2: (t2*x + v2)*y + (r2*x^2 + u2*x + w2) = 0
@ -125,50 +116,47 @@ int
degree = 3;
}
else
{
else {
// We can write the two curves as:
// 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
// By writing the resultant of these two polynomials we get a quartic
// 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;
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*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;
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 +
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 +
_two*u2*v1*t1*s2 - u2*v1*t2*s1 + w2*t1*t1*s2 - _two*s1*s2*u1*u2 -
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 -
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*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;
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 -
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 +
_two*v2*w1*t2*s1 + _two*w1*u1*s2*s2 - v2*u1*v1*s2 - _two*s1*s2*u1*w2 -
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 -
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 -
_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;
}
// Compute the roots of the resultant polynomial.
typename Nt_traits::Polynomial poly =
nt_traits.construct_polynomial (c, degree);
typename Nt_traits::Polynomial poly =
nt_traits.construct_polynomial(c, degree);
xs_end = nt_traits.compute_polynomial_roots (poly,
xs);
xs_end = nt_traits.compute_polynomial_roots(poly, 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
* C2: A*x + B*y + C = 0
* \param deg1 The degree of the first curve.
@ -177,55 +165,50 @@ int
* \pre xs must be a vector of size 4.
* \return The number of distinct roots found.
*/
template <class Nt_traits>
int
_compute_resultant_roots (Nt_traits& nt_traits,
const typename Nt_traits::Algebraic& r,
const typename Nt_traits::Algebraic& s,
const typename Nt_traits::Algebraic& t,
const typename Nt_traits::Algebraic& u,
const typename Nt_traits::Algebraic& v,
const typename Nt_traits::Algebraic& w,
const int& deg1,
const typename Nt_traits::Algebraic& A,
const typename Nt_traits::Algebraic& B,
const typename Nt_traits::Algebraic& C,
typename Nt_traits::Algebraic *xs)
template <typename Nt_traits>
int compute_resultant_roots(const Nt_traits& nt_traits,
const typename Nt_traits::Algebraic& r,
const typename Nt_traits::Algebraic& s,
const typename Nt_traits::Algebraic& t,
const typename Nt_traits::Algebraic& u,
const typename Nt_traits::Algebraic& v,
const typename Nt_traits::Algebraic& w,
const int& deg1,
const typename Nt_traits::Algebraic& A,
const typename Nt_traits::Algebraic& B,
const typename Nt_traits::Algebraic& C,
typename Nt_traits::Algebraic* xs)
{
if (deg1 == 1)
{
if (deg1 == 1) {
// We should actually compute the intersection of two line:
// (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)
// The two lines are parallel and do not intersect.
return (0);
// Return if the two lines are parallel and do not intersect.
if (CGAL::sign(denom) == CGAL::ZERO) return 0;
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:
xs[0] = -C / A;
return (1);
return 1;
}
// We can write the first curve as: y = -(A*x + C) / B.
// 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:
const typename Nt_traits::Algebraic _two = 2;
typename Nt_traits::Algebraic c[3];
typename Nt_traits::Algebraic *xs_end;
const typename Nt_traits::Algebraic two = 2;
typename Nt_traits::Algebraic c[3];
typename Nt_traits::Algebraic* xs_end;
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;
xs_end = nt_traits.solve_quadratic_equation (c[2], c[1], c[0],
xs);
xs_end = nt_traits.solve_quadratic_equation(c[2], c[1], c[0], 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
//
//
// 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
#define CGAL_CONIC_POINT_2_H
#include <CGAL/license/Arrangement_on_surface_2.h>
/*! \file
* Header file for the _Conic_point_2<Alg_kernel> class.
* Header file for the Conic_point_2<Alg_kernel> class.
*/
#include <list>
#include <CGAL/assertions.h>
namespace CGAL {
/*!
* \class A class that stores additional information with the point's
/*! \class
* A class that stores additional information with the point's
* coordinates, namely the conic IDs of the generating curves.
*/
template <class Alg_kernel_>
class _Conic_point_2 : public Alg_kernel_::Point_2
{
template <typename AlgKernel>
class Conic_point_2 : public AlgKernel::Point_2 {
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::Point_2 Base;
typedef _Conic_point_2<Alg_kernel> Self;
typedef typename Alg_kernel::FT Algebraic;
typedef typename Alg_kernel::FT Algebraic;
/*! \class
* Representation of an ID of a conic arc.
*/
class Conic_id
{
class Conic_id {
private:
unsigned int index; // The index of the conic arc.
size_t index; // the index of the conic arc
public:
/*! Default constructor. */
Conic_id () :
index (0)
{}
Conic_id() : index(0) {}
/*! Constructor. */
Conic_id (unsigned int ind) :
index (ind)
{
CGAL_precondition (ind != 0);
}
Conic_id(size_t ind) : index(ind) { CGAL_precondition(ind != 0); }
/*! Check if the ID is valid. */
bool is_valid () const
{
return (index != 0);
}
bool is_valid() const { return (index != 0); }
/*! Equality operator. */
bool operator== (const Conic_id& id) const
{
return (index == id.index);
}
bool operator==(const Conic_id& id) const { return (index == id.index); }
/*! Inequality operator. */
bool operator!= (const Conic_id& id) const
{
return (index != id.index);
}
bool operator!=(const Conic_id& id) const { return (index != id.index); }
/*! Less-than operator. */
bool operator< (const Conic_id& id) const
{
return (index < id.index);
}
bool operator<(const Conic_id& id) const { return (index < id.index); }
/*! Greater-than operator. */
bool operator> (const Conic_id& id) const
{
return (index > id.index);
}
bool operator>(const Conic_id& id) const { return (index > id.index); }
};
private:
typedef std::list<Conic_id> Ids_container;
typedef typename std::list<Conic_id>::const_iterator Ids_iterator;
Ids_container conic_ids; // The IDs of the generating conics.
public:
Ids_container conic_ids; // the IDs of the generating conics.
public:
/// \name Constructors.
//@{
/*! Default constructors. */
_Conic_point_2 () :
Base()
{}
Conic_point_2() : Base() {}
/*! Constructor from the base class. */
_Conic_point_2 (const Base& p) :
Base (p)
{}
/*! Constrcutor from the base class. */
Conic_point_2(const Base& p) : Base(p) {}
/*! Constructor with homogeneous coordinates. */
_Conic_point_2 (const Algebraic& hx,
const Algebraic& hy,
const Algebraic& hz) :
Base (hx, hy, hz)
/*! Constructor with homegeneous coordinates. */
Conic_point_2(const Algebraic& hx, const Algebraic& hy, const Algebraic& hz) :
Base(hx, hy, hz)
{}
/*! Constructor with Cartesian coordinates. */
_Conic_point_2 (const Algebraic& x, const Algebraic& y) :
Base (x, y)
{}
Conic_point_2(const Algebraic& x, const Algebraic& y) : Base(x, y) {}
//@}
/// \name Maintaining the generating conic IDs.
//@{
/*! Add a generating conic ID. */
void set_generating_conic (const Conic_id& id)
{
if (id.is_valid())
conic_ids.push_back (id);
return;
}
void set_generating_conic(const Conic_id& id)
{ if (id.is_valid()) conic_ids.push_back(id); }
/*! Check if the given conic generates the point. */
bool is_generating_conic (const Conic_id& id) const
{
if (! id.is_valid())
return (false);
Ids_iterator it;
for (it = conic_ids.begin(); it != conic_ids.end(); ++it)
{
if (*it == id)
return (true);
}
return (false);
bool is_generating_conic(const Conic_id& id) const {
if (! id.is_valid()) return false;
for (auto 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.
*/
#include <CGAL/Cartesian.h>
#include <CGAL/Algebraic_structure_traits.h>
#include <CGAL/number_utils.h>
#include <CGAL/tags.h>
@ -230,37 +231,63 @@ public:
/// \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:
/*!
* Return an approximation of a point coordinate.
/*! Return 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
{
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()));
}
if (i == 0)
return (CGAL::to_double(p.x()));
else
return (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;
}
};
/*! Get an Approximate_2 functor object. */
Approximate_2 approximate_2_object () const
{
return Approximate_2();
}
Approximate_2 approximate_2_object () const { return Approximate_2(*this); }
typedef typename Kernel::Construct_segment_2 Construct_x_monotone_curve_2;

View File

@ -1088,59 +1088,66 @@ public:
// 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
// Approximate_2 and the member function approximate_2_object() based on the
// corresponding types and function definitions of the subcurve traits. If
// the subcurve traits does not provide these definitions, they are defined
// as dummies. Essentially, the polycurve traits becomes a practical model of
// the ArrangementLandmarkTraits concept only if the subcurve traits is a
// model of this concept.
// as dummies. Essentially, the polycurve traits becomes a model of the
// ArrangementLandmarkTraits concept only if the subcurve traits is a model
// of this concept.
//
// The following implementation is inspired by
// https://stackoverflow.com/a/11816999/1915421
template <typename T>
struct Void {
typedef void type;
};
template <typename... Ts> using void_t = void;
template <typename T, typename _ = void>
template <typename T, typename = void>
struct has_approximate_2 {
// Generic implementation
typedef void Approximate_number_type;
typedef void Approximate_2;
using Approximate_number_type = void;
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>
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
typedef typename T::Approximate_number_type
Approximate_number_type;
typedef typename T::Approximate_2 Approximate_2;
using Approximate_number_type = typename T::Approximate_number_type;
using Approximate_2 = typename T::Approximate_2;
using Approximate_point_2 = typename T::Approximate_point_2;
};
typedef typename has_approximate_2<Subcurve_traits_2>::Approximate_number_type
Approximate_number_type;
typedef typename has_approximate_2<Subcurve_traits_2>::Approximate_2
Approximate_2;
using Approximate_number_type =
typename has_approximate_2<Subcurve_traits_2>::Approximate_number_type;
using 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. */
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() const
{
typedef typename std::is_same<void, Approximate_2>::type Is_void;
Approximate_2 approximate_2_object() const {
using Is_void = typename std::is_same<void, Approximate_2>::type;
return approximate_2_object_impl(Is_void());
}
#endif
//
class Construct_x_monotone_curve_2 {
protected:
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::Compare_endpoints_xy_2 Compare_endpoints_xy_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_y_2 Parameter_space_in_y_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
{ 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!
* Obtain the segment traits.
* \return the segment traits.

View File

@ -28,6 +28,7 @@
#include <boost/variant.hpp>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Cartesian.h>
#include <CGAL/tags.h>
#include <CGAL/intersections.h>
#include <CGAL/Arr_tags.h>
@ -879,9 +880,24 @@ public:
/// \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_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:
/*! Obtain an approximation of a point coordinate.
* \param p the exact point.
@ -890,15 +906,37 @@ public:
* \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
{
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 {
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. */
Approximate_2 approximate_2_object() const { return Approximate_2(); }
Approximate_2 approximate_2_object() const { return Approximate_2(*this); }
//! Functor
class Construct_x_monotone_curve_2 {

View File

@ -64,11 +64,12 @@ public:
typedef typename Base::Point Point;
/*! 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 */
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 */
Point & point() { return Base::point(); }

View File

@ -154,7 +154,7 @@ protected:
// the right endpoint it its interior.
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).
bool m_found_intersect; // An intersection has been found.
// (or an overlap).

View File

@ -76,8 +76,7 @@ public:
typedef typename Curve_kernel_2::Curve_analysis_2 Curve_analysis_2;
//! default constructor
Point_2_rep() {
}
Point_2_rep() : _m_location(CGAL::ARR_INTERIOR) {}
//! constructs a "finite" point on curve,
//! 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_3
Filtered_kernel
GraphicsView
HalfedgeDS
Hash_map
Homogeneous_kernel

View File

@ -239,14 +239,15 @@ bool read_orientation_and_end_points(InputStream_& is,
}
/*! */
template <typename InputStream_, typename Curve>
bool read_general_arc(InputStream_& is, Curve& cv)
template <typename InputStream_, typename Traits>
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>.
Rational r, s, t, u, v, w; // The conic coefficients.
is >> r >> s >> t >> u >> v >> w;
// Read the orientation.
int i_orient = 0;
int i_orient(0);
is >> i_orient;
CGAL::Orientation orient = (i_orient > 0) ? CGAL::COUNTERCLOCKWISE :
(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>
// defines the 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;
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>
// defines the 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;
is >> r2 >> s2 >> t2 >> u2 >> v2 >> w2;
// 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_target, r2, s2, t2, u2, v2, w2);
return true;
}
/*! */
template <typename InputStream_, typename Curve>
bool read_general_conic(InputStream_& is, Curve& cv)
{
template <typename InputStream_, typename Traits>
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>.
Rational r, s, t, u, v, w;
is >> r >> s >> t >> u >> v >> w;
// 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;
}
/*! */
template <typename InputStream_, typename Curve>
bool read_general_curve(InputStream_& is, Curve& cv)
{
template <typename InputStream_, typename Traits>
bool read_general_curve(InputStream_& is, typename Traits::Curve_2& cv,
const Traits& traits) {
Rational r, s, t, u, v, w; // The conic coefficients.
// Read a general conic, given by its coefficients <r,s,t,u,v,w>.
is >> r >> s >> t >> u >> v >> w;
CGAL::Orientation orient;
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;
// 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;
}
@ -308,8 +312,7 @@ bool read_general_curve(InputStream_& is, Curve& cv)
template <>
template <typename InputStream_>
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
// (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;
//get number of x-monotone conic-arcs.
unsigned int number_of_curves;
size_t 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) {
if ((type == 'a') || (type == 'A')) {
if (!read_general_curve(is, tmp_cv)) return false;
X_monotone_subcurve_2 tmp_xcv(tmp_cv);
conic_x_monotone_segments.push_back(tmp_xcv);
if (! read_general_curve(is, tmp_cv, sub_traits)) return false;
conic_x_monotone_segments.push_back(ctr_xcv(tmp_cv));
}
else if ((type == 'c') || (type == 'C')) {
if (!read_general_conic(is, tmp_cv)) return false;
X_monotone_subcurve_2 tmp_xcv(tmp_cv);
conic_x_monotone_segments.push_back(tmp_xcv);
if (! read_general_conic(is, tmp_cv, sub_traits)) return false;
conic_x_monotone_segments.push_back(ctr_xcv(tmp_cv));
}
else if ((type == 'i') || (type == 'I')) {
if (!read_general_arc(is, tmp_cv)) return false;
X_monotone_subcurve_2 tmp_xcv(tmp_cv);
conic_x_monotone_segments.push_back(tmp_xcv);
if (! read_general_arc(is, tmp_cv, sub_traits)) return false;
conic_x_monotone_segments.push_back(ctr_xcv(tmp_cv));
}
else {
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 */
template <>
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
// (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;
//get number of xmonotone-conic arcs.
unsigned int number_of_curves;
size_t 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) {
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);
}
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);
}
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);
}
@ -422,12 +425,11 @@ template <typename InputStream_>
bool IO_base_test<Base_geom_traits>::read_segment(InputStream_& is,
Subcurve_2& seg)
{
Subcurve_2 tmp_seg;
char type;
is >> type;
if (!read_general_curve(is, tmp_seg)) return false;
seg = tmp_seg;
return true;
const auto& sub_traits = *(m_geom_traits.subcurve_traits_2());
if (! read_general_curve(is, seg, sub_traits)) return false;
return true;
}
template <>
@ -438,8 +440,10 @@ bool IO_base_test<Base_geom_traits>::read_xsegment(InputStream_& is,
char type;
is >> type;
Subcurve_2 tmp_seg;
if (!read_general_curve(is, tmp_seg)) return false;
xseg = X_monotone_subcurve_2(tmp_seg);
const auto& sub_traits = *(m_geom_traits.subcurve_traits_2());
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;
}
@ -1037,9 +1041,9 @@ bool read_ellipse(InputStream_& is, bool& is_circle, Rat_circle& circle,
}
/*! */
template <typename InputStream_, typename Curve>
bool read_partial_ellipse(InputStream_& is, Curve& cv)
{
template <typename InputStream_, typename Traits>
bool read_partial_ellipse(InputStream_& is, typename Traits::Curve_2& cv,
const Traits& traits) {
bool is_circle; // Is this a circle.
Rat_circle circle;
Rational r, s, t, u, v, w;
@ -1050,15 +1054,16 @@ bool read_partial_ellipse(InputStream_& is, Curve& cv)
return false;
// Create the conic (or circular) arc.
cv = (is_circle) ? Curve(circle, orient, source, target) :
Curve(r, s, t, u, v, w, orient, source, target);
auto ctr_cv = traits.construct_curve_2_object();
cv = (is_circle) ? ctr_cv(circle, orient, source, target) :
ctr_cv(r, s, t, u, v, w, orient, source, target);
return true;
}
/*! */
template <typename InputStream_, typename Curve>
bool read_full_ellipse(InputStream_& is, Curve& cv)
{
template <typename InputStream_, typename Traits>
bool read_full_ellipse(InputStream_& is, typename Traits::Curve_2& cv,
const Traits& traits) {
bool is_circle; // Is this a circle.
Rat_circle circle;
Rational r, s, t, u, v, w;
@ -1066,14 +1071,14 @@ bool read_full_ellipse(InputStream_& is, Curve& cv)
return false;
// 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;
}
/*! Read a hyperbola */
template <typename InputStream_, typename Curve>
bool read_hyperbola(InputStream_& is, Curve& cv)
{
template <typename InputStream_, typename Curve, typename Traits>
bool read_hyperbola(InputStream_& is, Curve& cv, const Traits& traits) {
// Read the hyperbola (using the format "a b x0 y0"):
// 2 2
// ( x - x0 ) ( y - y0 )
@ -1096,14 +1101,15 @@ bool read_hyperbola(InputStream_& is, Curve& cv)
return false;
// 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;
}
/*! Read a hyperbola */
template <typename InputStream_, typename Curve>
bool read_parabola(InputStream_& is, Curve& cv)
{
template <typename InputStream_, typename Traits>
bool read_parabola(InputStream_& is, typename Traits::Curve_2& cv,
const Traits& traits) {
// Read the parabola (using the format "c x0 y0"):
//
// 2
@ -1125,15 +1131,15 @@ bool read_parabola(InputStream_& is, Curve& cv)
return false;
// 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;
}
/*! */
template <typename InputStream_, typename Curve>
bool read_segment(InputStream_& is, Curve& cv)
{
template <typename InputStream_, typename Traits>
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);
Rational 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);
// Create the segment.
cv = Curve(segment);
auto ctr_cv = traits.construct_curve_2_object();
cv = ctr_cv(segment);
return true;
}
/*! */
template <typename InputStream_, typename Curve>
bool read_general_arc(InputStream_& is, Curve& cv)
{
template <typename InputStream_, typename Traits>
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>.
Rational r, s, t, u, v, w; // The conic coefficients.
is >> r >> s >> t >> u >> v >> w;
// Read the orientation.
int i_orient = 0;
int i_orient(0);
is >> i_orient;
CGAL::Orientation orient = (i_orient > 0) ? CGAL::COUNTERCLOCKWISE :
(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>
// defines the 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;
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>
// defines the 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;
is >> r2 >> s2 >> t2 >> u2 >> v2 >> w2;
// 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_target, r2, s2, t2, u2, v2, w2);
return true;
}
/*! */
template <typename InputStream_, typename Curve>
bool read_general_curve(InputStream_& is, Curve& cv)
{
template <typename InputStream_, typename Traits>
bool read_general_curve(InputStream_& is, typename Traits::Curve_2& cv,
const Traits& traits) {
Rational r, s, t, u, v, w; // The conic coefficients.
// Read a general conic, given by its coefficients <r,s,t,u,v,w>.
is >> r >> s >> t >> u >> v >> w;
CGAL::Orientation orient;
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;
// 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;
}
@ -1205,11 +1214,11 @@ bool read_general_curve(InputStream_& is, Curve& cv)
template <>
template <typename InputStream_>
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;
if (!read_curve(is, tmp_cv)) return false;
xcv = X_monotone_curve_2(tmp_cv);
if (! read_curve(is, tmp_cv)) return false;
auto ctr_xcv = m_geom_traits.construct_x_monotone_curve_2_object();
xcv = ctr_xcv(tmp_cv);
return true;
}
@ -1221,25 +1230,37 @@ bool IO_base_test<Base_geom_traits>::read_curve(InputStream_& is, Curve_2& cv)
// Get the arc type:
char type;
is >> type;
if ((type == 'f') || (type == 'F')) return read_full_ellipse(is, cv);
else if ((type == 's') || (type == 'S')) return read_segment(is, cv);
else if ((type == 'i') || (type == 'I')) return read_general_arc(is, cv);
else if ((type == 'c') || (type == 'C')) {
// 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).
cv = Curve_2(r, s, t, u, v, w);
return true;
switch (type) {
case 'f':
case 'F': return read_full_ellipse(is, cv, m_geom_traits);
case 's':
case 'S': return read_segment(is, cv, m_geom_traits);
case 'i':
case 'I': return read_general_arc(is, cv, m_geom_traits);
case 'c':
case 'C':
{
// Read a general conic, given by its coefficients <r,s,t,u,v,w>.
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;
}
@ -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:
std::cerr << "Illegal rational arc type specification: " << type << "."
<< std::endl;
return (false);
return false;
}
// Bezier

View File

@ -50,43 +50,41 @@ typedef Polycurve_conic_traits_2::Point_2 Pc_point_2;
// CGAL::CORE_algebraic_number_traits>
// >::Point_2 test_point_2;
void check_equal()
{
void check_equal() {
bool are_equal;
Polycurve_conic_traits_2 traits;
Polycurve_conic_traits_2::Equal_2 equal = traits.equal_2_object();
Polycurve_conic_traits_2::Construct_x_monotone_curve_2
construct_x_monotone_curve_2 = traits.construct_x_monotone_curve_2_object();
Conic_traits_2 sub_traits;
Polycurve_conic_traits_2 traits(&sub_traits);
auto equal = traits.equal_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
Conic_point_2 ps1(Rational(1,4), 4);
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 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 pmid3(Rational(3,2), 2);
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 pmid4(Rational(3,2), 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
Polycurve_conic_traits_2::X_monotone_curve_2 xmc1 =
construct_x_monotone_curve_2(c1);
Polycurve_conic_traits_2::X_monotone_curve_2 xmc2 =
construct_x_monotone_curve_2(c2);
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);
Polycurve_conic_traits_2::X_monotone_curve_2 xmc1 = ctr_xcv(c1);
Polycurve_conic_traits_2::X_monotone_curve_2 xmc2 = ctr_xcv(c2);
Polycurve_conic_traits_2::X_monotone_curve_2 xmc3 = ctr_xcv(c3);
Polycurve_conic_traits_2::X_monotone_curve_2 xmc4 = ctr_xcv(c4);
are_equal = equal(xmc1, xmc2);
std::cout << "Two equal conic arcs are computed as: "
@ -104,8 +102,7 @@ void check_equal()
template <typename Traits>
void check_intersect(typename Traits::X_monotone_curve_2& xcv1,
typename Traits::X_monotone_curve_2& xcv2,
const Traits& traits)
{
const Traits& traits) {
typedef typename Traits::Multiplicity Multiplicity;
typedef typename Traits::Point_2 Point_2;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
@ -114,8 +111,8 @@ void check_equal()
Intersection_result;
std::vector<Intersection_result> intersection_points;
traits.intersect_2_object()(xcv1, xcv2,
std::back_inserter(intersection_points));
auto intersect = traits.intersect_2_object();
intersect(xcv1, xcv2, std::back_inserter(intersection_points));
std::cout<< "Number of intersection Points: " << intersection_points.size()
<< std::endl;
@ -133,13 +130,12 @@ void check_equal()
// }
}
void check_compare_end_points_xy_2()
{
Polycurve_conic_traits_2 traits;
Polycurve_conic_traits_2::Construct_x_monotone_curve_2
construct_x_monotone_curve_2 = traits.construct_x_monotone_curve_2_object();
Polycurve_conic_traits_2::Compare_endpoints_xy_2 compare_endpoints_xy_2 =
traits.compare_endpoints_xy_2_object();
void check_compare_end_points_xy_2() {
Conic_traits_2 sub_traits;
Polycurve_conic_traits_2 traits(&sub_traits);
auto ctr_xcv = traits.construct_x_monotone_curve_2_object();
auto cmp_endpoints = traits.compare_endpoints_xy_2_object();
auto ctr_sub_cv = sub_traits.construct_curve_2_object();
//create some curves
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.
// Note that the arc is clockwise oriented.
Conic_curve_2
c2 = Conic_curve_2(1, 0, 0, 0, 1, 0, // The parabola.
CGAL::CLOCKWISE,
Conic_point_2(-1.73, -3), // Approximation of the source.
0, 0, 0, 0, 1, 3, // The line: y = -3.
Conic_point_2(1.41, -2), // Approximation of the target.
0, 0, 0, 0, 1, 2); // The line: y = -2.
c2 = ctr_sub_cv(1, 0, 0, 0, 1, 0, // The parabola.
CGAL::CLOCKWISE,
Conic_point_2(-1.73, -3), // Approximation of the source.
0, 0, 0, 0, 1, 3, // The line: y = -3.
Conic_point_2(1.41, -2), // Approximation of the target.
0, 0, 0, 0, 1, 2); // The line: y = -2.
assert(c2.is_valid());
//make polyline x-monotone curves
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc1 =
construct_x_monotone_curve_2(c1);
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc2 =
construct_x_monotone_curve_2(c2);
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc1 = ctr_xcv(c1);
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc2 = ctr_xcv(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: "
<< (res == CGAL::SMALLER ? "SMALLER":
(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: "
<< (res == CGAL::SMALLER ? "SMALLER":
(res == CGAL::LARGER ? "LARGER" : "EQUAL")) << std::endl;
}
template <typename Curve_type>
void check_split(Curve_type &xcv1, Curve_type &xcv2)
{
Polycurve_conic_traits_2 traits;
void check_split(Curve_type& xcv1, Curve_type& xcv2) {
Conic_traits_2 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();
//split x poly-curves
Conic_curve_2 c6(1,1,0,6,-26,162,CGAL::COUNTERCLOCKWISE,
Conic_point_2(Algebraic(-7), Algebraic(13)),
Conic_point_2(Algebraic(-3), Algebraic(9)));
Conic_curve_2 c7(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE,
Conic_point_2(Algebraic(-3), Algebraic(9)),
Conic_point_2(Algebraic(0), Algebraic(0)));
Conic_curve_2 c8(0,1,0,-1,0,0, CGAL::COUNTERCLOCKWISE,
Conic_point_2(Algebraic(0), Algebraic(0)),
Conic_point_2(Algebraic(4), Algebraic(-2)));
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(-3), Algebraic(9)));
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(0), Algebraic(0)));
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(4), Algebraic(-2)));
Conic_x_monotone_curve_2 xc6(c6);
Conic_x_monotone_curve_2 xc7(c7);
Conic_x_monotone_curve_2 xc8(c8);
Conic_x_monotone_curve_2 xc6 = ctr_sub_xcv(c6);
Conic_x_monotone_curve_2 xc7 = ctr_sub_xcv(c7);
Conic_x_monotone_curve_2 xc8 = ctr_sub_xcv(c8);
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(xc7);
Pc_x_monotone_curve_2 split_expected_1 =
traits.construct_x_monotone_curve_2_object()(xmono_conic_curves_2.begin(),
xmono_conic_curves_2.end());
ctr_xcv(xmono_conic_curves_2.begin(), xmono_conic_curves_2.end());
xmono_conic_curves_2.clear();
xmono_conic_curves_2.push_back(xc8);
Pc_x_monotone_curve_2 split_expected_2 =
traits.construct_x_monotone_curve_2_object()(xmono_conic_curves_2.begin(),
xmono_conic_curves_2.end());
ctr_xcv(xmono_conic_curves_2.begin(), xmono_conic_curves_2.end());
Polycurve_conic_traits_2::X_monotone_curve_2 split_curve_1, split_curve_2;
Polycurve_conic_traits_2::Point_2
point_of_split = Polycurve_conic_traits_2::Point_2(0,0);
Polycurve_conic_traits_2::Point_2 point_of_split =
Polycurve_conic_traits_2::Point_2(0,0);
//Split functor
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;
}
void check_is_vertical()
{
Polycurve_conic_traits_2 traits;
Polycurve_conic_traits_2::Construct_x_monotone_curve_2
construct_x_monotone_curve_2 = traits.construct_x_monotone_curve_2_object();
Polycurve_conic_traits_2::Is_vertical_2 is_vertical =
traits.is_vertical_2_object();
void check_is_vertical() {
Conic_traits_2 sub_traits;
Polycurve_conic_traits_2 traits(&sub_traits);
auto ctr_sub_cv = sub_traits.construct_curve_2_object();
auto ctr_xcv = traits.construct_x_monotone_curve_2_object();
auto is_vertical = traits.is_vertical_2_object();
//create a curve
Rat_point_2 ps1(1, 10);
Rat_point_2 pmid1(5, 4);
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
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc1 =
construct_x_monotone_curve_2(c1);
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc1 = ctr_xcv(c1);
bool result = is_vertical(polyline_xmc1);
std::cout << "Is_verticle:: Expected first result is not vertivle: Computed: "
@ -254,8 +248,7 @@ void check_is_vertical()
/*! */
template <typename stream>
bool read_orientation(stream& is, CGAL::Orientation& orient)
{
bool read_orientation(stream& is, CGAL::Orientation& orient) {
int i_orient;
is >> i_orient;
orient = (i_orient > 0) ? CGAL::COUNTERCLOCKWISE :
@ -265,8 +258,7 @@ bool read_orientation(stream& is, CGAL::Orientation& orient)
/*! */
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
double x, y;
is >> x >> y;
@ -290,18 +282,18 @@ bool read_orientation_and_end_points(stream& is, CGAL::Orientation& orient,
Conic_point_2& target)
{
// 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.
if (!read_app_point(is, source)) return false;
if (!read_app_point(is, target)) return false;
if (! read_app_point(is, source)) return false;
if (! read_app_point(is, target)) return false;
return true;
}
/*! */
template <typename stream, typename Curve>
bool read_general_arc(stream& is, Curve& cv)
{
template <typename stream, typename Traits>
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>.
Rational r, s, t, u, v, w; // The conic coefficients.
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>
// defines the 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;
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>
// defines the 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;
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;
// Create the conic arc.
cv = Curve(r, s, t, u, v, w, orient,
app_source, r1, s1, t1, u1, v1, w1,
app_target, r2, s2, t2, u2, v2, w2);
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_target, r2, s2, t2, u2, v2, w2);
return true;
}
/*! */
template <typename stream, typename Curve>
bool read_general_conic(stream& is, Curve& cv)
{
template <typename stream, typename Traits>
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>.
Rational r, s, t, u, v, w;
is >> r >> s >> t >> u >> v >> w;
// 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;
}
// /*! */
template <typename stream, typename Curve>
bool read_general_curve(stream& is, Curve& cv)
{
template <typename stream, typename Traits>
bool read_general_curve(stream& is, typename Traits::Curve_2& cv,
const Traits& traits) {
Rational r, s, t, u, v, w; // The conic coefficients.
// Read a general conic, given by its coefficients <r,s,t,u,v,w>.
is >> r >> s >> t >> u >> v >> w;
CGAL::Orientation orient;
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;
// Create the conic (or circular) arc.
@ -368,26 +362,25 @@ bool read_general_curve(stream& is, Curve& cv)
// << u << " " << v << " " << w << std::endl;
// std::cout << "Read Points : " << source.x() << " " << source.y() << " "
// << 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;
}
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))
if (!line.empty() && (line[0] != '#')) break;
return is;
}
bool check_compare_y_at_x_2()
{
Polycurve_conic_traits_2 traits;
Polycurve_conic_traits_2::Compare_y_at_x_2 cmp_y_at_x_2 =
traits.compare_y_at_x_2_object();
bool check_compare_y_at_x_2() {
Conic_traits_2 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();
auto cmp_y_at_x_2 = traits.compare_y_at_x_2_object();
//polycurve constructors
Polycurve_conic_traits_2::Construct_x_monotone_curve_2
construct_x_mono_polycurve = traits.construct_x_monotone_curve_2_object();
Polycurve_conic_traits_2::Construct_curve_2 construct_polycurve =
traits.construct_curve_2_object();
auto construct_x_mono_polycurve = traits.construct_x_monotone_curve_2_object();
auto ctr_cv = traits.construct_curve_2_object();
//create a curve
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 pmid2(15, 5);
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_point_2(Algebraic(0), Algebraic(0)),
Conic_point_2(Algebraic(3), Algebraic(9)));
Conic_curve_2 c4(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE,
Conic_point_2(Algebraic(3), Algebraic(9)),
Conic_point_2(Algebraic(5), Algebraic(25)));
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(3), Algebraic(9)));
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(5), Algebraic(25)));
std::vector<Conic_curve_2> conic_curves, conic_curves_2, Conic_curves_3;
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(c4);
Conic_x_monotone_curve_2 xc1(c1);
Conic_x_monotone_curve_2 xc2(c2);
Conic_x_monotone_curve_2 xc3(c3);
Conic_x_monotone_curve_2 xc4(c4);
Conic_x_monotone_curve_2 xc1 = ctr_sub_xcv(c1);
Conic_x_monotone_curve_2 xc2 = ctr_sub_xcv(c2);
Conic_x_monotone_curve_2 xc3 = ctr_sub_xcv(c3);
Conic_x_monotone_curve_2 xc4 = ctr_sub_xcv(c4);
std::vector<Conic_x_monotone_curve_2> xmono_conic_curves, xmono_conic_curves_2;
/* VERY IMPORTANT
@ -441,13 +434,13 @@ bool check_compare_y_at_x_2()
//construct poly-curve
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 =
// construct_polycurve(conic_curves_2.begin(), conic_curves_2.end());
// ctr_cv(conic_curves_2.begin(), conic_curves_2.end());
//make x-monotone curve
//Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc1 =
// construct_x_monotone_curve_2(c1);
// ctr_xcv(c1);
//create points
Polycurve_conic_traits_2::Point_2
@ -475,37 +468,33 @@ bool check_compare_y_at_x_2()
return true;
}
void check_are_mergable()
{
Polycurve_conic_traits_2 traits;
Polycurve_conic_traits_2::Construct_x_monotone_curve_2
construct_x_monotone_curve_2 = traits.construct_x_monotone_curve_2_object();
Polycurve_conic_traits_2::Are_mergeable_2 are_mergeable_2 =
traits.are_mergeable_2_object();
void check_are_mergable() {
Conic_traits_2 sub_traits;
Polycurve_conic_traits_2 traits(&sub_traits);
auto ctr_sub_cv = sub_traits.construct_curve_2_object();
auto ctr_xcv = traits.construct_x_monotone_curve_2_object();
auto are_mergeable_2 = traits.are_mergeable_2_object();
//create a curve
Rat_point_2 ps1(1, 10);
Rat_point_2 pmid1(5, 4);
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 pmid2(15, 14);
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 pmid3(Rational(3,2), 2);
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)
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc1 =
construct_x_monotone_curve_2(c1);
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc2 =
construct_x_monotone_curve_2(c2);
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc3 =
construct_x_monotone_curve_2(c3);
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc1 = ctr_xcv(c1);
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc2 = ctr_xcv(c2);
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc3 = ctr_xcv(c3);
bool result = are_mergeable_2(polyline_xmc1, polyline_xmc2);
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;
}
void check_merge_2()
{
Polycurve_conic_traits_2 traits;
Polycurve_conic_traits_2::Construct_x_monotone_curve_2
construct_x_monotone_curve_2 = traits.construct_x_monotone_curve_2_object();
Polycurve_conic_traits_2::Merge_2 merge_2 = traits.merge_2_object();
void check_merge_2() {
Conic_traits_2 sub_traits;
Polycurve_conic_traits_2 traits(&sub_traits);
auto ctr_sub_cv = sub_traits.construct_curve_2_object();
auto ctr_xcv = traits.construct_x_monotone_curve_2_object();
auto merge_2 = traits.merge_2_object();
//create a curve
Rat_point_2 ps1(1, 10);
Rat_point_2 pmid1(5, 4);
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 pmid2(15, 14);
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)
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc1 =
construct_x_monotone_curve_2(c1);
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc2 =
construct_x_monotone_curve_2(c2);
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc1 = ctr_xcv(c1);
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc2 = ctr_xcv(c2);
Polycurve_conic_traits_2::X_monotone_curve_2 merged_xmc;
@ -547,101 +534,93 @@ void check_merge_2()
<< std:: endl;
}
void check_construct_opposite()
{
Polycurve_conic_traits_2 traits;
Polycurve_conic_traits_2::Construct_x_monotone_curve_2
construct_x_monotone_curve_2 = traits.construct_x_monotone_curve_2_object();
Polycurve_conic_traits_2::Construct_opposite_2 construct_opposite_2 =
traits.construct_opposite_2_object();
void check_construct_opposite() {
Conic_traits_2 sub_traits;
Polycurve_conic_traits_2 traits(&sub_traits);
auto ctr_sub_cv = sub_traits.construct_curve_2_object();
auto ctr_xcv = traits.construct_x_monotone_curve_2_object();
auto ctr_opposite = traits.construct_opposite_2_object();
//create a curve
Rat_point_2 ps1(1, 10);
Rat_point_2 pmid1(5, 4);
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)
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 =
construct_opposite_2(polyline_xmc1);
ctr_opposite(polyline_xmc1);
std::cout<< "Construct_opposite_2:: Opposite curve created";
}
void check_compare_y_at_x_right()
{
Polycurve_conic_traits_2 traits;
Polycurve_conic_traits_2::Construct_x_monotone_curve_2
construct_x_monotone_curve_2 = traits.construct_x_monotone_curve_2_object();
Polycurve_conic_traits_2::Compare_y_at_x_right_2 cmp_y_at_x_right_2 =
traits.compare_y_at_x_right_2_object();
void check_compare_y_at_x_right() {
Conic_traits_2 sub_traits;
Polycurve_conic_traits_2 traits(&sub_traits);
auto ctr_sub_cv = sub_traits.construct_curve_2_object();
auto ctr_xcv = traits.construct_x_monotone_curve_2_object();
auto cmp_y_at_x_right = traits.compare_y_at_x_right_2_object();
//create constructing curves
Rat_point_2 ps2(1, 10);
Rat_point_2 pmid2(5, 4);
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 pmid3(5, 4);
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)
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc1 =
construct_x_monotone_curve_2(c1);
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc2 =
construct_x_monotone_curve_2(c2);
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc1 = ctr_xcv(c1);
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc2 = ctr_xcv(c2);
Polycurve_conic_traits_2::Point_2 intersection_point =
Polycurve_conic_traits_2::Point_2(5,4);
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: "
<< (result == CGAL::SMALLER ? "smaller":
(result == CGAL::LARGER ? "Larger" : "equal")) << std::endl;
}
void check_compare_y_at_x_left()
{
Polycurve_conic_traits_2 traits;
Polycurve_conic_traits_2::Construct_x_monotone_curve_2
construct_x_monotone_curve_2 = traits.construct_x_monotone_curve_2_object();
Polycurve_conic_traits_2::Compare_y_at_x_left_2 cmp_y_at_x_left_2 =
traits.compare_y_at_x_left_2_object();
void check_compare_y_at_x_left() {
Conic_traits_2 sub_traits;
Polycurve_conic_traits_2 traits(&sub_traits);
auto ctr_sub_cv = sub_traits.construct_curve_2_object();
auto ctr_xcv = traits.construct_x_monotone_curve_2_object();
auto cmp_y_at_x_left = traits.compare_y_at_x_left_2_object();
//create constructing curves
Rat_point_2 ps2(1, 10);
Rat_point_2 pmid2(5, 4);
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 pmid3(5, 4);
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)
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc1 =
construct_x_monotone_curve_2(c1);
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc2 =
construct_x_monotone_curve_2(c2);
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc1 = ctr_xcv(c1);
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc2 = ctr_xcv(c2);
Polycurve_conic_traits_2::Point_2 intersection_point =
Polycurve_conic_traits_2::Point_2(5,4);
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: "
<< (result == CGAL::SMALLER ? "smaller":
(result == CGAL::LARGER ? "Larger" : "equal")) << std::endl;
}
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::X_monotone_curve_2 X_monotone_curve_2;
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>
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;
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>
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;
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>
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;
CGAL::Comparison_result result;
@ -706,16 +682,14 @@ void check_compare_x_2(const Segment& seg1, const Segment& seg2)
}
template<typename Curve>
void check_compare_points(Curve& cv)
{
void check_compare_points(Curve& cv) {
Polycurve_conic_traits_2 traits;
CGAL::Arr_parameter_space result =
traits.parameter_space_in_x_2_object()(cv, CGAL::ARR_MAX_END);
}
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;
// 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[])
{
Polycurve_conic_traits_2 traits;
int main(int argc, char* argv[]) {
Conic_traits_2 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 constructors
auto construct_x_mono_polycurve = traits.construct_x_monotone_curve_2_object();
auto construct_polycurve = traits.construct_curve_2_object();
auto ctr_xcv = traits.construct_x_monotone_curve_2_object();
auto ctr_cv = traits.construct_curve_2_object();
//create a curve
Conic_curve_2 c3(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE,
Conic_point_2(Algebraic(0), Algebraic(0)),
Conic_point_2(Algebraic(3), Algebraic(9)));
Conic_curve_2 c4(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE,
Conic_point_2(Algebraic(3), Algebraic(9)),
Conic_point_2(Algebraic(5), Algebraic(25)));
Conic_curve_2 c5(0,1,0,1,0,0, CGAL::COUNTERCLOCKWISE,
Conic_point_2(Algebraic(-25), Algebraic(-5)),
Conic_point_2(Algebraic(0), Algebraic(0)));
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(3), Algebraic(9)));
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(5), Algebraic(25)));
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(0), Algebraic(0)));
Conic_curve_2 c6(1,1,0,6,-26,162,CGAL::COUNTERCLOCKWISE,
Conic_point_2(Algebraic(-7), Algebraic(13)),
Conic_point_2(Algebraic(-3), Algebraic(9)));
Conic_curve_2 c7(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE,
Conic_point_2(Algebraic(-3), Algebraic(9)),
Conic_point_2(Algebraic(0), Algebraic(0)));
Conic_curve_2 c8(0,1,0,-1,0,0, CGAL::COUNTERCLOCKWISE,
Conic_point_2(Algebraic(0), Algebraic(0)),
Conic_point_2(Algebraic(4), Algebraic(-2)));
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(-3), Algebraic(9)));
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(0), Algebraic(0)));
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(4), Algebraic(-2)));
Conic_curve_2 c9(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE,
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 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_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
std::vector<Conic_curve_2> conic_curves;
@ -771,21 +747,21 @@ int main(int argc, char* argv[])
//construct poly-curve
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_point_2(Algebraic(25), Algebraic(-5)),
Conic_point_2(Algebraic(0), Algebraic(0)));
Conic_curve_2 c12(1,0,0,0,-1,0,CGAL::COUNTERCLOCKWISE,
Conic_point_2(Algebraic(0), Algebraic(0)),
Conic_point_2(Algebraic(5), Algebraic(25)));
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(0), Algebraic(0)));
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(5), Algebraic(25)));
conic_curves.clear();
conic_curves.push_back(c11);
conic_curves.push_back(c12);
//construct poly-curve
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
* 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
* to x-monotone curves.
*/
Conic_x_monotone_curve_2 xc3(c3);
Conic_x_monotone_curve_2 xc4(c4);
Conic_x_monotone_curve_2 xc5(c5);
Conic_x_monotone_curve_2 xc6(c6);
Conic_x_monotone_curve_2 xc7(c7);
Conic_x_monotone_curve_2 xc8(c8);
Conic_x_monotone_curve_2 xc3 = ctr_sub_xcv(c3);
Conic_x_monotone_curve_2 xc4 = ctr_sub_xcv(c4);
Conic_x_monotone_curve_2 xc5 = ctr_sub_xcv(c5);
Conic_x_monotone_curve_2 xc6 = ctr_sub_xcv(c6);
Conic_x_monotone_curve_2 xc7 = ctr_sub_xcv(c7);
Conic_x_monotone_curve_2 xc8 = ctr_sub_xcv(c8);
//This vector is used to store curves that will be used to create
//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(xc4);
//construct x-monotone poly-curve
Pc_x_monotone_curve_2 conic_x_mono_polycurve_1 =
construct_x_mono_polycurve(xmono_conic_curves_2.begin(),
xmono_conic_curves_2.end());
ctr_xcv(xmono_conic_curves_2.begin(), xmono_conic_curves_2.end());
xmono_conic_curves_2.clear();
xmono_conic_curves_2.push_back(xc6);
@ -820,15 +793,13 @@ int main(int argc, char* argv[])
xmono_conic_curves_2.push_back(xc8);
//construct x-monotone poly-curve
Pc_x_monotone_curve_2 conic_x_mono_polycurve_2 =
construct_x_mono_polycurve(xmono_conic_curves_2.begin(),
xmono_conic_curves_2.end());
ctr_xcv(xmono_conic_curves_2.begin(), xmono_conic_curves_2.end());
xmono_conic_curves_2.clear();
xmono_conic_curves_2.push_back(xc5);
Pc_x_monotone_curve_2 x_polycurve_push =
construct_x_mono_polycurve(xmono_conic_curves_2.begin(),
xmono_conic_curves_2.end());
ctr_xcv(xmono_conic_curves_2.begin(), xmono_conic_curves_2.end());
Polycurve_conic_traits_2::X_monotone_subcurve_2 xcurve_push =
Polycurve_conic_traits_2::X_monotone_subcurve_2(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(xc4);
Pc_x_monotone_curve_2 base_curve =
construct_x_mono_polycurve(xmono_conic_curves_2.begin(),
xmono_conic_curves_2.end());
ctr_xcv(xmono_conic_curves_2.begin(), xmono_conic_curves_2.end());
//curves for push_back
Conic_curve_2 c13(1,1,0,-50,12,660,CGAL::COUNTERCLOCKWISE,
Conic_point_2(Algebraic(25), Algebraic(-7)),
Conic_point_2(Algebraic(25), Algebraic(-5)));
Conic_curve_2 c14(0,1,0,-1,0,0,CGAL::COUNTERCLOCKWISE,
Conic_point_2(Algebraic(25), Algebraic(-5)),
Conic_point_2(Algebraic(0), Algebraic(0)));
Conic_curve_2 c15(-1,0,0,0,1,0,CGAL::COUNTERCLOCKWISE,
Conic_point_2(Algebraic(0), Algebraic(0)),
Conic_point_2(Algebraic(5), Algebraic(25)));
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(-5)));
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(0), Algebraic(0)));
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(5), Algebraic(25)));
conic_curves.clear();
conic_curves.push_back(c13);
conic_curves.push_back(c14);
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);
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
// 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(xc21);
// 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());
// 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
// sub-arcs and append these sub-arcs as polygon edges.
void append_conic_arc (Polygon_2& polygon, const Curve_2& arc)
{
Conic_traits_2 traits;
std::list<CGAL::Object> objects;
std::list<CGAL::Object>::iterator it;
X_monotone_curve_2 xarc;
void append_conic_arc(Polygon_2& polygon, const Curve_2& arc) {
Conic_traits_2 traits;
std::list<CGAL::Object> objects;
X_monotone_curve_2 xarc;
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))
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,
// and whose endpoints lie on the line y = 0:
Curve_2 parabola1 = Curve_2 (1, 0, 0, 0, 2, -4, CGAL::COUNTERCLOCKWISE,
Point_2(2, 0), Point_2(-2, 0));
Curve_2 parabola1 = ctr_cv(1, 0, 0, 0, 2, -4, CGAL::COUNTERCLOCKWISE,
Point_2(2, 0), Point_2(-2, 0));
// Construct a parabolic arc supported by a parabola: x^2 - 2y - 4 = 0,
// and whose endpoints lie on the line y = 0:
Curve_2 parabola2 = Curve_2 (1, 0, 0, 0, -2, -4, CGAL::COUNTERCLOCKWISE,
Point_2(-2, 0), Point_2(2, 0));
Curve_2 parabola2 = ctr_cv(1, 0, 0, 0, -2, -4, CGAL::COUNTERCLOCKWISE,
Point_2(-2, 0), Point_2(2, 0));
// Construct a polygon from these two parabolic arcs.
Polygon_2 P;
append_conic_arc (P, parabola1);
append_conic_arc (P, parabola2);
append_conic_arc(P, parabola1);
append_conic_arc(P, parabola2);
// Construct a polygon that corresponds to the ellipse: x^2 + 9y^2 - 9 = 0:
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.
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::ostream_iterator<Polygon_with_holes_2>(std::cout, "\n"));
std::copy(res.begin(), res.end(), // export to standard output
std::ostream_iterator<Polygon_with_holes_2>(std::cout, "\n"));
std::cout << std::endl;
return (0);
return 0;
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1816,8 +1816,8 @@ protected:
namespace CGAL
{
template<class T>
void draw(const T&, const char* ="", bool=false)
template<class ... T>
void draw(T...)
{
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)
- 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)

View File

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

View File

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

View File

@ -773,7 +773,7 @@ void Surface_sweep_2<Vis>::_intersect(Subcurve* c1, Subcurve* c2,
//
template <typename Vis>
void Surface_sweep_2<Vis>::_create_intersection_point(const Point_2& xp,
unsigned int multiplicity,
Multiplicity multiplicity,
Subcurve*& c1,
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_>
struct Default_arr_traits<CGAL::_Conic_arc_2<Rat_kernel_, Alg_kernel_,
Nt_traits_> >
struct Default_arr_traits<CGAL::Conic_arc_2<Rat_kernel_, Alg_kernel_,
Nt_traits_> >
{
typedef CGAL::Arr_conic_traits_2<Rat_kernel_, Alg_kernel_, Nt_traits_>
Traits;

View File

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