Merge branch 'Triangulation_3-fix_simplex_traverser-GF-CGAL-5.6' into Triangulation_3-CDT_3-lrineau
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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++;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
<!-- ========================================================================= -->
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -52,6 +52,10 @@ namespace CGAL {
|
|||
|
||||
* \sa `PkgArrangementOnSurface2Read`
|
||||
* \sa `PkgArrangementOnSurface2Write`
|
||||
*
|
||||
* Drawing function
|
||||
*
|
||||
* \sa `PkgArrangementOnSurface2Draw`
|
||||
*/
|
||||
template <typename GeometryTraits, typename TopologyTraits>
|
||||
class Arrangement_on_surface_2 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
|
||||
/// @}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*/
|
||||
|
|
|
|||
|
After Width: | Height: | Size: 16 KiB |
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
//@{
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
//@}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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(); }
|
||||
|
|
|
|||
|
|
@ -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).
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -10,6 +10,7 @@ Circulator
|
|||
Distance_2
|
||||
Distance_3
|
||||
Filtered_kernel
|
||||
GraphicsView
|
||||
HalfedgeDS
|
||||
Hash_map
|
||||
Homogeneous_kernel
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)); };
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) -->
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 406 B |
|
Before Width: | Height: | Size: 390 B |
|
Before Width: | Height: | Size: 317 B |
|
|
@ -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"/>
|
||||
|
|
|
|||
|
|
@ -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"/>
|
||||
|
|
|
|||
|
|
@ -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  <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>
|
||||
|
Before Width: | Height: | Size: 406 B |
|
Before Width: | Height: | Size: 390 B |
|
Before Width: | Height: | Size: 317 B |