Merge branch 'Triangulation_3-fix_simplex_traverser-GF-CGAL-5.6' into Triangulation_3-CDT_3-lrineau

This commit is contained in:
Laurent Rineau 2023-06-22 15:28:48 +02:00
commit a85ce74720
668 changed files with 46633 additions and 38005 deletions

View File

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

1
.gitignore vendored
View File

@ -1212,6 +1212,7 @@ gmon.*
Polygonal_surface_reconstruction/examples/build*
Polygonal_surface_reconstruction/test/build*
Solver_interface/examples/build*
/Mesh_3/examples/Mesh_3/indicator_0.inr.gz
dump-*.xyz
dump-*.binary.cgal
dump_*.txt

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

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

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

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

View File

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

View File

@ -110,22 +110,75 @@ public:
typedef typename boost::property_traits<PMap>::value_type type;
};
template <typename PolygonMesh,
typename VPM_from_NP>
struct GetVertexPointMap_impl
{
typedef VPM_from_NP type;
typedef VPM_from_NP const_type;
template<class NamedParameters>
static const_type
get_const_map(const NamedParameters& np, const PolygonMesh&)
{
return parameters::get_parameter(np, internal_np::vertex_point);
}
template<class NamedParameters>
static type
get_map(const NamedParameters& np, PolygonMesh&)
{
return parameters::get_parameter(np, internal_np::vertex_point);
}
};
template <typename PolygonMesh>
struct GetVertexPointMap_impl<PolygonMesh, internal_np::Param_not_found>
{
typedef typename property_map_selector<PolygonMesh, boost::vertex_point_t>::const_type const_type;
typedef typename property_map_selector<PolygonMesh, boost::vertex_point_t>::type type;
template<class NamedParameters>
static const_type
get_const_map(const NamedParameters& /* np */, const PolygonMesh& pm)
{
return get_const_property_map(boost::vertex_point, pm);
}
template<class NamedParameters>
static type
get_map(const NamedParameters& /* np */, PolygonMesh& pm)
{
return get_property_map(boost::vertex_point, pm);
}
};
template <typename PolygonMesh,
typename NamedParameters = parameters::Default_named_parameters>
class GetVertexPointMap
{
typedef typename property_map_selector<PolygonMesh, boost::vertex_point_t>::const_type
DefaultVPMap_const;
typedef typename property_map_selector<PolygonMesh, boost::vertex_point_t>::type
DefaultVPMap;
typedef typename internal_np::Lookup_named_param_def<internal_np::vertex_point_t,
NamedParameters,
internal_np::Param_not_found>::type VPM_from_NP;
typedef GetVertexPointMap_impl<PolygonMesh, VPM_from_NP> Impl;
public:
typedef typename internal_np::Lookup_named_param_def<internal_np::vertex_point_t,
NamedParameters,
DefaultVPMap>::type type;
typedef typename internal_np::Lookup_named_param_def<internal_np::vertex_point_t,
NamedParameters,
DefaultVPMap_const>::type const_type;
typedef typename Impl::type type;
typedef typename Impl::const_type const_type;
static const_type
get_const_map(const NamedParameters& np, const PolygonMesh& pm)
{
return Impl::get_const_map(np, pm);
}
static type
get_map(const NamedParameters& np, PolygonMesh& pm)
{
return Impl::get_map(np, pm);
}
};
template<typename PolygonMesh, typename NamedParameters>
@ -138,10 +191,15 @@ public:
typedef typename CGAL::Kernel_traits<Point>::Kernel Kernel;
};
template <typename PolygonMesh,
typename NamedParametersGT = parameters::Default_named_parameters,
typename NamedParametersVPM = NamedParametersGT>
class GetGeomTraits
template<typename PolygonMesh, class GT, class NamedParametersVPM>
struct GetGeomTraits_impl
{
typedef GT type;
};
template<typename PolygonMesh, class NamedParametersVPM>
struct GetGeomTraits_impl<PolygonMesh, internal_np::Param_not_found, NamedParametersVPM>
{
typedef typename CGAL::graph_has_property<PolygonMesh, boost::vertex_point_t>::type Has_internal_pmap;
@ -154,12 +212,20 @@ class GetGeomTraits
typedef typename boost::mpl::if_c<Has_internal_pmap::value ||
!std::is_same<internal_np::Param_not_found, NP_vpm>::value,
typename GetK<PolygonMesh, NamedParametersVPM>::Kernel,
Fake_GT>::type DefaultKernel;
Fake_GT>::type type;
};
public:
template <typename PolygonMesh,
typename NamedParametersGT = parameters::Default_named_parameters,
typename NamedParametersVPM = NamedParametersGT>
struct GetGeomTraits
{
typedef typename internal_np::Lookup_named_param_def<internal_np::geom_traits_t,
NamedParametersGT,
DefaultKernel>::type type;
internal_np::Param_not_found>::type GT_from_NP;
typedef typename GetGeomTraits_impl<PolygonMesh,
GT_from_NP,
NamedParametersVPM>::type type;
};
// Define the following structs:
@ -278,6 +344,21 @@ public:
typedef typename CGAL::Identity_property_map<const Dummy_point> const_type;
};
template <typename PointRange, typename NamedParameters>
struct GetPolygonSoupGeomTraits
{
typedef typename internal_np::Lookup_named_param_def <
internal_np::geom_traits_t,
NamedParameters,
typename CGAL::Kernel_traits<
typename boost::property_traits<
typename GetPointMap<PointRange, NamedParameters>::type
>::value_type
>::type
> ::type type;
};
template <class PointRange, class NamedParameters, class PointMap = Default, class NormalMap = Default>
struct Point_set_processing_3_np_helper
{

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 406 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 390 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 317 B

View File

@ -1,6 +1,6 @@
<!-- HTML header for doxygen 1.8.13-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="https://www.w3.org/1999/xhtml">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link rel="icon" type="image/png" href="$relpath$../Manual/g-196x196-doc.png"/>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>

View File

@ -1,6 +1,6 @@
<!-- HTML header for doxygen 1.8.13-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="https://www.w3.org/1999/xhtml">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link rel="icon" type="image/png" href="$relpath$../Manual/g-196x196-doc.png" />
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 406 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 390 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 317 B

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

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