Merge remote-tracking branch 'cgal/master' into CGAL_IO-maxGimeno

This commit is contained in:
Mael Rouxel-Labbé 2020-10-09 18:36:17 +02:00
commit f55ef7dd50
343 changed files with 9511 additions and 6937 deletions

93
.github/workflows/build_doc.yml vendored Normal file
View File

@ -0,0 +1,93 @@
name: Documentation
on:
issue_comment:
types: [created]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v3
id: get_round
with:
result-encoding: string
script: |
const asso = context.payload.comment.author_association
if(asso == 'OWNER' || asso == 'MEMBER') {
const body = context.payload.comment.body
if(body.includes("build:")) {
return body.replace('build:','')
}
}
return 'stop'
- uses: actions/github-script@v3
if: steps.get_round.outputs.result != 'stop'
id: get_pr_number
with:
result-encoding: string
script: |
//get pullrequest url
const pr_number = context.payload.issue.number
return pr_number
- uses: actions/checkout@v2
name: "checkout branch"
if: steps.get_round.outputs.result != 'stop'
with:
repository: ${{ github.repository }}
ref: refs/pull/${{ steps.get_pr_number.outputs.result }}/merge
token: ${{ secrets.PUSH_TO_CGAL_GITHUB_IO_TOKEN }}
- name: install dependencies
if: steps.get_round.outputs.result != 'stop'
run: |
set -x
sudo apt-get install -y graphviz ssh
sudo pip install lxml pyquery
wget --no-verbose -O doxygen_exe https://cgal.geometryfactory.com/~mgimeno/doxygen/build_1_8_13/bin/doxygen
sudo mv doxygen_exe /usr/bin/doxygen
sudo chmod +x /usr/bin/doxygen
git config --global user.email "maxime.gimeno@geometryfactory.com"
git config --global user.name "Maxime Gimeno"
- name: configure all
if: steps.get_round.outputs.result != 'stop'
run: |
set -ex
git clone https://CGAL:${{ secrets.PUSH_TO_CGAL_GITHUB_IO_TOKEN }}@github.com/CGAL/cgal.github.io.git --depth=5
mkdir -p build_doc && cd build_doc && cmake ../Documentation/doc
- name: Upload Doc
if: steps.get_round.outputs.result != 'stop'
run: |
set -ex
PR_NUMBER=${{ steps.get_pr_number.outputs.result }}
ROUND=${{ steps.get_round.outputs.result }}
wget --no-verbose cgal.github.io -O tmp.html
if ! egrep -q "\/$PR_NUMBER\/$ROUND" tmp.html; then
mkdir -p cgal.github.io/${PR_NUMBER}/$ROUND
cd build_doc && make -j2 doc && make -j2 doc_with_postprocessing
cp -r ./doc_output/* ../cgal.github.io/${PR_NUMBER}/$ROUND
cd ../cgal.github.io
egrep -v " ${PR_NUMBER}\." index.html > tmp.html
echo "<li><a href=https://cgal.github.io/${PR_NUMBER}/$ROUND/Manual/index.html>Manual for PR ${PR_NUMBER} ($ROUND).</a></li>" >> ./tmp.html
mv tmp.html index.html
git add ${PR_NUMBER}/$ROUND && git commit -q -a -m "Add ${PR_NUMBER} $ROUND" && git push -q -u origin master
else
exit 1
fi
- name: Post address
uses: actions/github-script@v3
if: steps.get_round.outputs.result != 'stop'
with:
script: |
const address = "The documentation is built. You can find it here : https://cgal.github.io/${{ steps.get_pr_number.outputs.result }}/${{ steps.get_round.outputs.result }}/Manual/index.html"
github.issues.createComment({
owner: "CGAL",
repo: "cgal",
issue_number: ${{ github.event.issue.number }},
body: address
});

27
.github/workflows/delete_doc.yml vendored Normal file
View File

@ -0,0 +1,27 @@
name: Documentation Removal
on:
pull_request_target:
types: [closed, removed]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.0.0
- name: delete directory
run: |
set -x
git config --global user.email "maxime.gimeno@geometryfactory.com"
git config --global user.name "Maxime Gimeno"
git clone https://maxGimeno:${{ secrets.PUSH_TO_CGAL_GITHUB_IO_TOKEN }}@github.com/CGAL/cgal.github.io.git --depth=5
PR_NUMBER=$(python -c "import json; import os; y = json.load(open(os.environ['GITHUB_EVENT_PATH'])); print(y[\"number\"])")
cd cgal.github.io/
egrep -v " ${PR_NUMBER}\." index.html > tmp.html
if [ -n "$(diff -q ./index.html ./tmp.html)" ]; then
mv tmp.html index.html
#git rm -r ${PR_NUMBER} && git commit -a -m "Remove ${PR_NUMBER}" && git push -u origin master
git commit -a -m "Remove ${PR_NUMBER}" && git push -u origin master
fi

View File

@ -41,6 +41,7 @@ do
continue
fi
cd $ROOT
#install openmesh only if necessary
if [ "$ARG" = "CHECK" ] || [ "$ARG" = BGL ] || [ "$ARG" = Convex_hull_3 ] ||\
[ "$ARG" = Polygon_mesh_processing ] || [ "$ARG" = Property_map ] ||\
@ -92,28 +93,27 @@ cd $ROOT
exit 1
fi
echo "Matrix is up to date."
#check if non standard cgal installation works
cd $ROOT
mkdir build_test
cd build_test
mytime cmake -DCMAKE_INSTALL_PREFIX=install/ -DCGAL_BUILD_THREE_DOC=TRUE ..
mytime make install
# test install with minimal downstream example
mkdir installtest
cd installtest
touch main.cpp
mkdir build
echo 'project(Example)' >> CMakeLists.txt
echo 'set(PROJECT_SRCS ${PROJECT_SOURCE_DIR}/main.cpp)' >> CMakeLists.txt
echo 'find_package(CGAL REQUIRED)' >> CMakeLists.txt
echo 'add_executable(${PROJECT_NAME} ${PROJECT_SRCS})' >> CMakeLists.txt
echo 'target_link_libraries(${PROJECT_NAME} CGAL::CGAL)' >> CMakeLists.txt
echo '#include "CGAL/remove_outliers.h"' >> main.cpp
cd build
mytime cmake -DCMAKE_INSTALL_PREFIX=../../install -DCGAL_BUILD_THREE_DOC=TRUE ..
cd ..
exit 0
fi
if [ "$ARG" = "Installation" ]
then
mkdir build_dir
cd build_dir
cmake -DWITH_tests=ON -DBUILD_TESTING=ON ..
ctest -j2 -L CGAL_cmake_testsuite --output-on-failure
cd ..
rm -rf ./build_dir
#==-- configure all CGAL with -DWITH_examples=ON -DWITH_demos=ON -DWITH_tests=ON, and then launch CTest on a few labels. --==
mkdir config_dir
cd config_dir
cmake -DWITH_examples=ON -DWITH_demos=ON -DWITH_tests=ON -DBUILD_TESTING=ON ..
ctest -j2 -L AABB_tree --output-on-failure
cd ..
rm -rf ./config_dir
exit 0
fi
IFS=$old_IFS
if [ -n "$TRAVIS_PULL_REQUEST_BRANCH" ] && [ "$ARG" != Polyhedron_demo ]; then
@ -185,6 +185,7 @@ cd $ROOT
cd "$ROOT/$DEMO"
build_demo
fi
done
IFS=$old_IFS
# Local Variables:

View File

@ -578,7 +578,7 @@ public:
#ifdef CGAL_HAS_THREADS
mutable CGAL_MUTEX build_mutex; // mutex used to protect const calls inducing build() and build_kd_tree()
#endif
public:
const Node* root_node() const {
CGAL_assertion(size() > 1);
@ -596,7 +596,7 @@ public:
}
return m_p_root_node;
}
private:
const Primitive& singleton_data() const {
CGAL_assertion(size() == 1);
return *m_primitives.begin();

View File

@ -660,23 +660,33 @@ public:
return Equal_2(_traits);
}
/*! A functor that divides a curve into continues (x-monotone) curves. */
//! A functor for subdividing curves into x-monotone curves.
class Make_x_monotone_2
{
private:
Traits& _traits;
public:
Make_x_monotone_2(Traits& traits) : _traits(traits) {}
template<class OutputIterator>
OutputIterator operator() (const Curve_2& cv, OutputIterator oi) const
/*! Subdivide a given curve into x-monotone subcurves and insert them into
* a given output iterator.
* \param cv the curve.
* \param oi an output iterator for the result. Its value type is a variant
* that wraps Point_2 or an X_monotone_curve_2 objects.
* \return The past-the-end iterator.
*/
template <class OutputIterator>
OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const
{
Object_vector res (boost::apply_visitor(Make_x_monotone_2_visitor(_traits),cv.variant()));
re_cast_object_vector(res,oi);
return (oi);
}
private:
class Make_x_monotone_2_visitor
: public boost::static_visitor < Object_vector >
class Make_x_monotone_2_visitor :
public boost::static_visitor < Object_vector >
{
private:
typedef boost::static_visitor <Object_vector> Base;
@ -1787,4 +1797,3 @@ public:
#endif // CGAL_DONT_SUBMIT
#endif //CGAL_ARR_RATIONAL_ARC_TRAITS_D_1_H

View File

@ -80,7 +80,7 @@ public:
Arr_rational_arc_traits_2 ()
{}
/// \name Functor definitions.
/// \name Basic functor definitions.
//@{
/*! A functor that compares the x-coordinates of two points */
@ -381,19 +381,22 @@ public:
{
return Equal_2();
}
//@}
//! \name Intersections, subdivisions, and mergings
//@{
/*! A functor that divides a curve into continues (x-monotone) curves. */
class Make_x_monotone_2
{
public:
/*!
* Cut the given conic curve (or conic arc) into x-monotone subcurves
* and insert them to the given output iterator.
* \param cv The curve.
* \param oi The output iterator, whose value-type is Object. The returned
* objects is a wrapper for an X_monotone_curve_2 object.
* \return The past-the-end iterator.
/*! Subdivide a given rational arc into x-monotone subcurves and insert them
* into a given output iterator.
* \param cv the arc.
* \param oi an output iterator for the result. Its value type is a variant
* that wraps Point_2 or an X_monotone_curve_2 objects.
* \return the past-the-end iterator.
*/
template<class OutputIterator>
OutputIterator operator() (const Curve_2& cv, OutputIterator oi)

View File

@ -25,26 +25,26 @@ typedef CGAL::Curved_kernel_via_analysis_2< Algebraic_kernel_d_2 > CKvA_2;
Polynomial_2 makeParabola( )
{
Polynomial_2 x = CGAL::shift( Polynomial_2( 1 ), 1, 0 );
Polynomial_2 y = CGAL::shift( Polynomial_2( 1 ), 1, 1 );
Polynomial_2 parabola = y - x*x;
Polynomial_2 x = CGAL::shift( Polynomial_2( 1 ), 1, 0 );
Polynomial_2 y = CGAL::shift( Polynomial_2( 1 ), 1, 1 );
Polynomial_2 parabola = y - x*x;
return parabola;
return parabola;
}
X_monotone_curve_2 makeVerticalLine( Bound x )
{
Traits traits;
Traits::Construct_point_2 constructPoint =
traits.construct_point_2_object( );
Traits::Construct_x_monotone_segment_2 constructSegment =
traits.construct_x_monotone_segment_2_object( );
Traits traits;
Traits::Construct_point_2 constructPoint =
traits.construct_point_2_object( );
Traits::Construct_x_monotone_segment_2 constructSegment =
traits.construct_x_monotone_segment_2_object( );
std::vector< X_monotone_curve_2 > curves;
Point_2 p1 = constructPoint( Algebraic_real_1(x), Algebraic_real_1(Bound( -10000 )) );
Point_2 p2 = constructPoint( x, Bound( +10000 ) );
constructSegment( p1, p2, std::back_inserter( curves ) );
return curves[ 0 ];
std::vector< X_monotone_curve_2 > curves;
Point_2 p1 = constructPoint( Algebraic_real_1(x), Algebraic_real_1(Bound( -10000 )) );
Point_2 p2 = constructPoint( x, Bound( +10000 ) );
constructSegment( p1, p2, std::back_inserter( curves ) );
return curves[ 0 ];
}
typedef CGAL::Cartesian< Coefficient > Kernel;
@ -52,40 +52,38 @@ typedef Kernel::Point_2 Kernel_point_2;
int main( )
{
Algebraic_real_1 real( 1 );
//CGAL::Qt::Converter< Algebraic_kernel_d_2 > testConverter;
//CGAL::Qt::Converter< CKvA_2 > testConverter;
Algebraic_real_1 real( 1 );
//CGAL::Qt::Converter< Algebraic_kernel_d_2 > testConverter;
//CGAL::Qt::Converter< CKvA_2 > testConverter;
//CGAL::Qt::Converter< Cartesian > testConverter;
Kernel_point_2 testPt( 1, 2 );
Point_2 testPt2( testPt.x( ), testPt.y( ) );
Traits traits;
Construct_curve_2 constructCurve = traits.construct_curve_2_object( );
Curve_2 curve = constructCurve( makeParabola( ) );
Make_x_monotone_2 mm = traits.make_x_monotone_2_object( );
std::vector< CGAL::Object > curves;
mm( curve, std::back_inserter( curves ) );
std::cout << curves.size( ) << std::endl;
X_monotone_curve_2 c1;
CGAL::assign( c1, curves[ 0 ] );
double lb = -3;
double ub = 3;
double step = 6.0 / 1000;
//CGAL::Qt::Converter< Cartesian > testConverter;
Kernel_point_2 testPt( 1, 2 );
Point_2 testPt2( testPt.x( ), testPt.y( ) );
Traits traits;
Construct_curve_2 constructCurve = traits.construct_curve_2_object( );
Curve_2 curve = constructCurve( makeParabola( ) );
Make_x_monotone_2 mm = traits.make_x_monotone_2_object( );
std::vector< CGAL::Object > curves;
mm( curve, std::back_inserter( curves ) );
std::cout << curves.size( ) << std::endl;
X_monotone_curve_2 c1;
CGAL::assign( c1, curves[ 0 ] );
double lb = -3;
double ub = 3;
double step = 6.0 / 1000;
for ( int i = 0; i < 1000; ++i )
{
X_monotone_curve_2 c2 = makeVerticalLine( lb + step * i );
for ( int i = 0; i < 1000; ++i ) {
X_monotone_curve_2 c2 = makeVerticalLine( lb + step * i );
CGAL::Object o;
CGAL::Oneset_iterator< CGAL::Object > oi( o );
Intersect_2 intersect = traits.intersect_2_object( );
intersect( c1, c2, oi );
std::pair< Point_2, Multiplicity > res;
CGAL::assign( res, o );
std::pair< double, double > approx = res.first.to_double( );
std::cout << approx.first << " " << approx.second << std::endl;
}
CGAL::Object o;
CGAL::Oneset_iterator< CGAL::Object > oi( o );
Intersect_2 intersect = traits.intersect_2_object( );
intersect( c1, c2, oi );
std::pair< Point_2, Multiplicity > res;
CGAL::assign( res, o );
std::pair< double, double > approx = res.first.to_double( );
std::cout << approx.first << " " << approx.second << std::endl;
}
return 0;
return 0;
}

View File

@ -6,28 +6,29 @@
#include <CGAL/Arr_walk_along_line_point_location.h>
#include <CGAL/Object.h>
typedef CGAL::Gmpq NT;
typedef CGAL::Cartesian< NT > Kernel;
typedef CGAL::Arr_linear_traits_2< Kernel > Traits;
typedef CGAL::Arr_default_dcel< Traits > Dcel;
typedef CGAL::Arrangement_with_history_2< Traits, Dcel > Arrangement;
typedef CGAL::Arr_walk_along_line_point_location< Arrangement > WalkAlongLinePointLocationStrategy;
typedef Kernel::Point_2 Point_2;
typedef Kernel::Ray_2 Ray_2;
typedef Arrangement::Curve_2 Curve_2;
typedef CGAL::Gmpq NT;
typedef CGAL::Cartesian<NT> Kernel;
typedef CGAL::Arr_linear_traits_2<Kernel> Traits;
typedef CGAL::Arr_default_dcel<Traits> Dcel;
typedef CGAL::Arrangement_with_history_2< Traits, Dcel> Arrangement;
typedef CGAL::Arr_walk_along_line_point_location<Arrangement>
Walk_along_line_pl;
typedef Kernel::Point_2 Point_2;
typedef Kernel::Ray_2 Ray_2;
typedef Arrangement::Curve_2 Curve_2;
int main( )
{
Point_2 p1( 0, 0 );
Point_2 p2( 1, 0 );
Ray_2 ray( p1, p2 );
Curve_2 curve( ray );
Point_2 p1(0, 0);
Point_2 p2(1, 0);
Ray_2 ray(p1, p2);
Curve_2 curve(ray);
Arrangement arr;
CGAL::insert( arr, curve );
CGAL::insert(arr, curve);
WalkAlongLinePointLocationStrategy pl( arr );
CGAL::Object o = pl.locate( Point_2( 1, -1 ) );
Walk_along_line_pl pl(arr);
auto o = pl.locate(Point_2(1, -1));
return 0;
}

View File

@ -239,19 +239,17 @@ namespace CGAL {
const Point_2& tgt) const;
};
/*! Subdivide the given subcurve into x-monotone subcurves and insert them
* into the given output iterator. Since the subcurves that
* constitute a general polycurve are not necessarily
* \f$x\f$-monotone, this functor may break them.
/*! Subdivide a given subcurve into x-monotone subcurves and insert them
* into a given output iterator.
*/
class Make_x_monotone_2 {
public:
/*!
* \pre if `cv` is not empty then it must be continuous and well-oriented.
* \param cv The subcurve.
* \param oi The output iterator, whose value-type is Object. The output
* object is a wrapper of a X_monotone_curve_2 objects.
* \return The past-the-end iterator.
* \param cv the subcurve.
* \param oi an output iterator for the result. Its value type is a variant
* that wraps Point_2 or an X_monotone_curve_2 objects.
* \return the past-the-end iterator.
*/
template <typename OutputIterator>
OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const;

View File

@ -1,57 +1,52 @@
namespace CGAL {
/*!
\ingroup PkgArrangementOnSurface2Funcs
Produces the symbolic vertical decomposition of a
given arrangement, performing a batched vertical ray-shooting query from
all arrangement vertices, such that every vertex is associated with a pair
of objects, one corresponds to the arrangement feature that lies below it,
and the other corresponds to the feature that lies above it.
The output of this function can be readily used for inserting vertical walls
and physically decomposing the arrangement into pseudo-trapezoids. To do
this, it is convenient to process the vertices in an ascending
\f$ xy\f$-lexicographic order. The visible objects are therefore returned through
an output iterator, which pairs each finite arrangement vertex with the two
features it "sees", such that the vertices are given in ascending
\f$ xy\f$-lexicographic order.
Produces the symbolic vertical decomposition of the `arr` arrangement.
More precisely, it performs a batched vertical ray-shooting query from all
arrangement vertices, such that every vertex is associated with a pair of
objects, one corresponding to the arrangement feature that lies below it,
while the other corresponds to the feature that lies above it.
The query results are returned through the output iterator, which pairs
each finite arrangement vertex with a pair of `Object`s, the first
represents the feature below the vertex, and the second represents the
feature that lies above it. Each `Object` may be one of the following:
<UL>
<LI>`Halfedge_const_handle`, if the vertex is located above (or
below) an edge. The given halfedge is always directed from right to left.
In case there is no concrete edge below (or above) the vertex, and
the arrangement is unbounded, then the object returned is a
<I>fictitious</I> halfedge.
<LI>`Face_const_handle`, in case there is no edge below (or above)
the vertex, and the arrangement is bounded.
<LI>`Vertex_const_handle`, in case the vertex is located vertically
above (or below) another arrangement vertex.
<LI>An empty object, in case the vertex is the top end-vertex of
a vertical edge, we define there is no feature below it. Similarly, if
it is the bottom end-vertex of a vertical edge, we define that there
is no feature above it.
</UL>
The function returns a past-the-end iterator for its output sequence.
\cgalHeading{Requirements}
`OutputIterator::value_type` must be
`pair<Arrangement_2::Vertex_const_handle, pair<Object, Object> >`.
*/
/*! \ingroup PkgArrangementOnSurface2Funcs
*
* Produces the symbolic vertical decomposition of a given arrangement,
* performing a batched vertical ray-shooting query from all arrangement
* vertices, such that every vertex is associated with a pair of objects, one
* corresponds to the arrangement feature that lies below it, and the other
* corresponds to the feature that lies above it. The output of this function
* can be readily used for inserting vertical walls and physically decomposing
* the arrangement into pseudo-trapezoids. To do this, it is convenient to
* process the vertices in an ascending \f$ xy\f$-lexicographic order. The
* visible objects are therefore returned through an output iterator, which
* pairs each finite arrangement vertex with the two features it "sees", such
* that the vertices are given in ascending \f$ xy\f$-lexicographic order.
*
* Produces the symbolic vertical decomposition of the `arr` arrangement. More
* precisely, it performs a batched vertical ray-shooting query from all
* arrangement vertices, such that every vertex is associated with a pair of
* objects, one corresponding to the arrangement feature that lies below it,
* while the other corresponds to the feature that lies above it. The query
* results are returned through the output iterator, which pairs each finite
* arrangement vertex with a pair of objects, the first represents the feature
* below the vertex, and the second represents the feature that lies above
* it. Each object is an optional variant that wraps a handle to an arrangement
* feature. If the vertex is the top end-vertex of a vertical edge, we say that
* there is no feature below it; similarly, if it is the bottom end-vertex of a
* vertical edge, we say that there is no feature above it. In these cases the
* optional object is set to be empty; otherwise it is set as follows:
* <UL>
* <LI>`Halfedge_const_handle`, if the vertex is located above (or below) an
* edge. The given halfedge is always directed from right to left. In case
* there is no concrete edge below (or above) the vertex, and the arrangement
* is unbounded, then the object returned is a <I>fictitious</I> halfedge.
* <LI>`Face_const_handle`, in case there is no edge below (or above)
* the vertex, and the arrangement is bounded.
* <LI>`Vertex_const_handle`, in case the vertex is located vertically above
* (or below) another arrangement vertex.
* </UL> The function returns a past-the-end iterator for its output sequence.
*
* \cgalHeading{Requirements}
*
* `OutputIterator::value_type` must be
* `pair<Arrangement_2::Vertex_const_handle, pair<Object, Object> >`.
*
*/
template<typename Traits, typename Dcel,
typename OutputIterator>
OutputIterator decompose (const Arrangement_2<Traits,Dcel>& arr,
OutputIterator oi);
} /* namespace CGAL */

View File

@ -16,18 +16,16 @@ public:
/// A model of this concept must provide:
/// @{
/*!
subdivides the input curve `c` into \f$ x\f$-monotone subcurves and
isolated points, and inserts the results into a container through the
given output iterator. The value type of `OutputIterator` is
`CGAL::Object`, where each `Object` wraps either an
`ArrTraits::X_monotone_curve_2` object or a `ArrTraits::Point_2`
object. The operator returns a past-the-end iterator for the output
sequence.
*/
/*! subdivides the input curve `c` into \f$ x\f$-monotone subcurves and
* isolated points, and inserts the results into a range begining at the
* given output iterator `oi`. The type `OutputIterator` dereferences a
* `boost::variant` that wraps either an `ArrTraits::Point_2` object or an
* `ArrTraits::X_monotone_curve_2` object. The operator returns a past-the-end
* iterator for the output sequence.
*/
template <typename OutputIterator>
OutputIterator operator()( ArrTraits::Curve_2 c,
OutputIterator oi);
OutputIterator operator()(ArrTraits::Curve_2 c,
OutputIterator oi);
/// @}

View File

@ -25,106 +25,102 @@ typedef CORE::BigInt Integer;
typedef LEDA::integer Integer;
#endif
typedef CGAL::Arr_algebraic_segment_traits_2<Integer> Arr_traits_2;
typedef CGAL::Arrangement_2<Arr_traits_2> Arrangement_2;
typedef Arr_traits_2::Curve_2 Curve_2;
typedef Arr_traits_2::Polynomial_2 Polynomial_2;
typedef Arr_traits_2::Algebraic_real_1 Algebraic_real_1;
typedef Arr_traits_2::X_monotone_curve_2 X_monotone_curve_2;
typedef Arr_traits_2::Point_2 Point_2;
typedef CGAL::Arr_algebraic_segment_traits_2<Integer> Arr_traits_2;
typedef CGAL::Arrangement_2<Arr_traits_2> Arrangement_2;
typedef Arr_traits_2::Curve_2 Curve_2;
typedef Arr_traits_2::Polynomial_2 Polynomial_2;
typedef Arr_traits_2::Algebraic_real_1 Algebraic_real_1;
typedef Arr_traits_2::X_monotone_curve_2 X_monotone_curve_2;
typedef Arr_traits_2::Point_2 Point_2;
typedef boost::variant<Point_2, X_monotone_curve_2> Make_x_monotone_result;
int main() {
int main()
{
Arr_traits_2 arr_traits;
auto construct_curve = arr_traits.construct_curve_2_object();
auto construct_x_monotone_segment =
arr_traits.construct_x_monotone_segment_2_object();
auto construct_point = arr_traits.construct_point_2_object();
auto make_x_monotone = arr_traits.make_x_monotone_2_object();
Arr_traits_2 arr_traits;
Arrangement_2 arr(&arr_traits);
Arr_traits_2::Construct_curve_2 construct_curve
= arr_traits.construct_curve_2_object();
Arr_traits_2::Construct_x_monotone_segment_2 construct_x_monotone_segment
= arr_traits.construct_x_monotone_segment_2_object();
Arr_traits_2::Construct_point_2 construct_point
= arr_traits.construct_point_2_object();
Arr_traits_2::Make_x_monotone_2 make_x_monotone
= arr_traits.make_x_monotone_2_object();
std::vector<X_monotone_curve_2> segs;
Arrangement_2 arr(&arr_traits);
Polynomial_2 x = CGAL::shift(Polynomial_2(1),1,0);
Polynomial_2 y = CGAL::shift(Polynomial_2(1),1,1);
std::vector<X_monotone_curve_2> segs;
// Construct x^4+y^3-1
Curve_2 cv0 = construct_curve(CGAL::ipower(x,4)+CGAL::ipower(y,3)-1);
// Construct all x-monotone segments using the Make_x_mononotone functor
std::vector<Make_x_monotone_result> pre_segs;
make_x_monotone(cv0, std::back_inserter(pre_segs));
// Cast all CGAL::Objects into X_monotone_segment_2
// (the vector might also contain Point_2 objects for isolated points,
// but not for this instance
for(size_t i = 0; i < pre_segs.size(); ++i) {
auto* curr_p = boost::get<X_monotone_curve_2>(&pre_segs[i]);;
CGAL_assertion(curr_p);
segs.push_back(*curr_p);
}
// Construct an ellipse with equation 2*x^2+5*y^2-7=0
Curve_2 cv1 = construct_curve(2*CGAL::ipower(x,2)+5*CGAL::ipower(y,2)-7);
Polynomial_2 x = CGAL::shift(Polynomial_2(1),1,0);
Polynomial_2 y = CGAL::shift(Polynomial_2(1),1,1);
// Construct point on the upper arc (counting of arc numbers starts with 0!
Point_2 p11 = construct_point(Algebraic_real_1(0),cv1,1);
// Construct x^4+y^3-1
Curve_2 cv0 = construct_curve(CGAL::ipower(x,4)+CGAL::ipower(y,3)-1);
// Construct all x-monotone segments using the Make_x_mononotone functor
std::vector<CGAL::Object> pre_segs;
make_x_monotone(cv0,std::back_inserter(pre_segs));
// Cast all CGAL::Objects into X_monotone_segment_2
// (the vector might also contain Point_2 objects for isolated points,
// but not for this instance
for(size_t i = 0; i < pre_segs.size(); i++ ) {
X_monotone_curve_2 curr;
bool check = CGAL::assign(curr,pre_segs[i]);
assert(check); CGAL_USE(check);
segs.push_back(curr);
}
// Construct an ellipse with equation 2*x^2+5*y^2-7=0
Curve_2 cv1 = construct_curve(2*CGAL::ipower(x,2)+5*CGAL::ipower(y,2)-7);
construct_x_monotone_segment(cv1,p11,Arr_traits_2::POINT_IN_INTERIOR,
std::back_inserter(segs));
// Construct point on the upper arc (counting of arc numbers starts with 0!
Point_2 p11 = construct_point(Algebraic_real_1(0),cv1,1);
// Construct a vertical cusp x^2-y^3=0
Curve_2 cv2 = construct_curve(CGAL::ipower(x,2)-CGAL::ipower(y,3));
construct_x_monotone_segment(cv1,p11,Arr_traits_2::POINT_IN_INTERIOR,
// Construct a segment containing the cusp point.
// This adds to X_monotone_curve_2 objects to the vector,
// because the cusp is a critical point
Point_2 p21 = construct_point(Algebraic_real_1(-2),cv2,0);
Point_2 p22 = construct_point(Algebraic_real_1(2),cv2,0);
construct_x_monotone_segment(cv2,p21,p22,std::back_inserter(segs));
// Construct an unbounded curve, starting at x=3
Point_2 p23 = construct_point(Algebraic_real_1(3),cv2,0);
construct_x_monotone_segment(cv2,p23,Arr_traits_2::MIN_ENDPOINT,
std::back_inserter(segs));
// Construct a vertical cusp x^2-y^3=0
Curve_2 cv2 = construct_curve(CGAL::ipower(x,2)-CGAL::ipower(y,3));
// Construct another conic: y^2-x^2+1
Curve_2 cv3 = construct_curve(CGAL::ipower(y,2)-CGAL::ipower(x,2)+1);
// Construct a segment containing the cusp point.
// This adds to X_monotone_curve_2 objects to the vector,
// because the cusp is a critical point
Point_2 p21 = construct_point(Algebraic_real_1(-2),cv2,0);
Point_2 p22 = construct_point(Algebraic_real_1(2),cv2,0);
construct_x_monotone_segment(cv2,p21,p22,std::back_inserter(segs));
Point_2 p31 = construct_point(Algebraic_real_1(2),cv3,1);
construct_x_monotone_segment(cv3,p31,Arr_traits_2::MAX_ENDPOINT,
std::back_inserter(segs));
// Construct an unbounded curve, starting at x=3
Point_2 p23 = construct_point(Algebraic_real_1(3),cv2,0);
construct_x_monotone_segment(cv2,p23,Arr_traits_2::MIN_ENDPOINT,
std::back_inserter(segs));
// Construct a vertical segment
Point_2 v1 = construct_point(0,0);
Point_2 v2 = construct_point(Algebraic_real_1(0),cv1,1);
construct_x_monotone_segment(v1,v2,std::back_inserter(segs));
// Construct another conic: y^2-x^2+1
Curve_2 cv3 = construct_curve(CGAL::ipower(y,2)-CGAL::ipower(x,2)+1);
CGAL::insert(arr,segs.begin(),segs.end());
Point_2 p31 = construct_point(Algebraic_real_1(2),cv3,1);
construct_x_monotone_segment(cv3,p31,Arr_traits_2::MAX_ENDPOINT,
std::back_inserter(segs));
// Add some isolated points (must be wrapped into CGAL::Object)
std::vector<CGAL::Object> isolated_points;
isolated_points.push_back
(CGAL::make_object(construct_point(Algebraic_real_1(2),cv3,0)));
isolated_points.push_back
(CGAL::make_object(construct_point(Integer(1),Integer(5))));
isolated_points.push_back
(CGAL::make_object(construct_point(Algebraic_real_1(-1),
Algebraic_real_1(5))));
// Construct a vertical segment
Point_2 v1 = construct_point(0,0);
Point_2 v2 = construct_point(Algebraic_real_1(0),cv1,1);
construct_x_monotone_segment(v1,v2,std::back_inserter(segs));
CGAL::insert(arr,isolated_points.begin(), isolated_points.end());
CGAL::insert(arr,segs.begin(),segs.end());
// Print the arrangement size.
std::cout << "The arrangement size:" << std::endl
<< " V = " << arr.number_of_vertices()
<< ", E = " << arr.number_of_edges()
<< ", F = " << arr.number_of_faces() << std::endl;
// Add some isolated points (must be wrapped into CGAL::Object)
std::vector<CGAL::Object> isolated_points;
isolated_points.push_back
(CGAL::make_object(construct_point(Algebraic_real_1(2),cv3,0)));
isolated_points.push_back
(CGAL::make_object(construct_point(Integer(1),Integer(5))));
isolated_points.push_back
(CGAL::make_object(construct_point(Algebraic_real_1(-1),
Algebraic_real_1(5))));
CGAL::insert(arr,isolated_points.begin(), isolated_points.end());
// Print the arrangement size.
std::cout << "The arrangement size:" << std::endl
<< " V = " << arr.number_of_vertices()
<< ", E = " << arr.number_of_edges()
<< ", F = " << arr.number_of_faces() << std::endl;
return 0;
return 0;
}
#endif

View File

@ -8,16 +8,20 @@
#include <list>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef CGAL::Arr_segment_traits_2<Kernel> Traits_2;
typedef Traits_2::Point_2 Point_2;
typedef Traits_2::X_monotone_curve_2 Segment_2;
typedef CGAL::Arrangement_2<Traits_2> Arrangement_2;
typedef Arrangement_2::Vertex_const_handle Vertex_const_handle;
typedef Arrangement_2::Halfedge_const_handle Halfedge_const_handle;
typedef Arrangement_2::Face_const_handle Face_const_handle;
typedef std::pair<CGAL::Object, CGAL::Object> Object_pair;
typedef std::pair<Vertex_const_handle, Object_pair> Vert_decomp_entry;
typedef std::list<Vert_decomp_entry> Vert_decomp_list;
typedef CGAL::Arr_segment_traits_2<Kernel> Traits_2;
typedef Traits_2::Point_2 Point_2;
typedef Traits_2::X_monotone_curve_2 Segment_2;
typedef CGAL::Arrangement_2<Traits_2> Arrangement_2;
typedef Arrangement_2::Vertex_const_handle Vertex_const_handle;
typedef Arrangement_2::Halfedge_const_handle Halfedge_const_handle;
typedef Arrangement_2::Face_const_handle Face_const_handle;
typedef boost::variant<Vertex_const_handle, Halfedge_const_handle,
Face_const_handle> Cell_type;
typedef boost::optional<Cell_type> Vert_decomp_type;
typedef std::pair<Vert_decomp_type, Vert_decomp_type> Vert_decomp_pair;
typedef std::pair<Vertex_const_handle, Vert_decomp_pair> Vert_decomp_entry;
typedef std::list<Vert_decomp_entry> Vert_decomp_list;
int main()
{
@ -39,34 +43,41 @@ int main()
CGAL::decompose(arr, std::back_inserter(vd_list));
// Print the results.
Vert_decomp_list::const_iterator vd_iter;
for (vd_iter = vd_list.begin(); vd_iter != vd_list.end(); ++vd_iter) {
const Object_pair& curr = vd_iter->second;
for (auto vd_iter = vd_list.begin(); vd_iter != vd_list.end(); ++vd_iter) {
const Vert_decomp_pair& curr = vd_iter->second;
std::cout << "Vertex (" << vd_iter->first->point() << ") : ";
Vertex_const_handle vh;
Halfedge_const_handle hh;
Face_const_handle fh;
std::cout << " feature below: ";
if (CGAL::assign(hh, curr.first))
std::cout << '[' << hh->curve() << ']';
else if (CGAL::assign(vh, curr.first))
std::cout << '(' << vh->point() << ')';
else if (CGAL::assign(fh, curr.first))
std::cout << "NONE";
else
std::cout << "EMPTY";
if (! curr.first) std::cout << "EMPTY";
else {
auto* vh = boost::get<Vertex_const_handle>(&*(curr.first));
if (vh) std::cout << '(' << (*vh)->point() << ')';
else {
auto* hh = boost::get<Halfedge_const_handle>(&*(curr.first));
if (hh) std::cout << '[' << (*hh)->curve() << ']';
else {
auto* fh = boost::get<Face_const_handle>(&*(curr.first));
CGAL_assertion(fh);
std::cout << "NONE (" << (*fh)->is_unbounded() << ")";
}
}
}
std::cout << " feature above: ";
if (CGAL::assign(hh, curr.second))
std::cout << '[' << hh->curve() << ']' << std::endl;
else if (CGAL::assign(vh, curr.second))
std::cout << '(' << vh->point() << ')' << std::endl;
else if (CGAL::assign(fh, curr.second))
std::cout << "NONE" << std::endl;
else
std::cout << "EMPTY" << std::endl;
if (! curr.second) std::cout << "EMPTY" << std::endl;
else {
auto* vh = boost::get<Vertex_const_handle>(&*(curr.second));
if (vh) std::cout << '(' << (*vh)->point() << ')' << std::endl;
else {
auto* hh = boost::get<Halfedge_const_handle>(&*(curr.second));
if (hh) std::cout << '[' << (*hh)->curve() << ']' << std::endl;
else {
auto* fh = boost::get<Face_const_handle>(&*(curr.second));
CGAL_assertion(fh);
std::cout << "NONE (" << (*fh)->is_unbounded() << ")" << std::endl;
}
}
}
}
return 0;

View File

@ -33,16 +33,18 @@ typedef CGAL::Arr_Bezier_curve_traits_2<Rat_kernel, Alg_kernel, Nt_traits>
typedef Bezier_traits::Curve_2 Bezier_curve_2;
typedef Bezier_traits::X_monotone_curve_2 Bezier_x_curve_2;
typedef CGAL::Arr_polycurve_traits_2<Bezier_traits> Polycurve_bezier_traits_2;
typedef Polycurve_bezier_traits_2::Point_2 Point_2;
typedef Polycurve_bezier_traits_2::X_monotone_curve_2 X_mono_polycurve;
typedef CGAL::Arrangement_2<Polycurve_bezier_traits_2> Arrangement_2;
typedef boost::variant<Point_2, Bezier_x_curve_2> Make_x_monotone_result;
int main()
{
Polycurve_bezier_traits_2 pc_traits;
Bezier_traits bezier_traits;
Polycurve_bezier_traits_2::Construct_x_monotone_curve_2
construct_x_mono_polycurve =
auto construct_x_mono_polycurve =
pc_traits.construct_x_monotone_curve_2_object();
std::vector<Bezier_x_curve_2> x_bezier_curves;
@ -69,11 +71,11 @@ int main()
// Read the current curve (specified by its control points).
in_file >> B;
//convert it into x-monotone bezier curve.
std::vector<CGAL::Object> obj_vector;
std::vector<Make_x_monotone_result> obj_vector;
bezier_traits.make_x_monotone_2_object()(B, std::back_inserter(obj_vector));
Bezier_x_curve_2 x_seg =
CGAL::object_cast<Bezier_x_curve_2>((obj_vector[0]));
x_curves.push_back(x_seg);
auto* x_seg_p = boost::get<Bezier_x_curve_2>(&obj_vector[0]);
CGAL_assertion(x_seg_p);
x_curves.push_back(*x_seg_p);
}
X_mono_polycurve polycurve =

View File

@ -8,19 +8,22 @@
#include <CGAL/Arr_vertical_decomposition_2.h>
#include <list>
typedef CGAL::MP_Float Number_type;
typedef CGAL::Cartesian<Number_type> Kernel;
typedef CGAL::Arr_linear_traits_2<Kernel> Traits_2;
typedef Traits_2::Point_2 Point_2;
typedef Traits_2::X_monotone_curve_2 Segment_2;
typedef CGAL::Arrangement_2<Traits_2> Arrangement_2;
typedef Arrangement_2::Vertex_const_handle Vertex_const_handle;
typedef Arrangement_2::Halfedge_const_handle Halfedge_const_handle;
typedef Arrangement_2::Face_const_handle Face_const_handle;
typedef CGAL::MP_Float Number_type;
typedef CGAL::Cartesian<Number_type> Kernel;
typedef CGAL::Arr_linear_traits_2<Kernel> Traits_2;
typedef Traits_2::Point_2 Point_2;
typedef Traits_2::X_monotone_curve_2 Segment_2;
typedef CGAL::Arrangement_2<Traits_2> Arrangement_2;
typedef Arrangement_2::Vertex_const_handle Vertex_const_handle;
typedef Arrangement_2::Halfedge_const_handle Halfedge_const_handle;
typedef Arrangement_2::Face_const_handle Face_const_handle;
typedef std::pair<Vertex_const_handle, std::pair<CGAL::Object, CGAL::Object> >
Vert_decomp_entry;
typedef std::list<Vert_decomp_entry> Vert_decomp_list;
typedef boost::variant<Vertex_const_handle, Halfedge_const_handle,
Face_const_handle> Cell_type;
typedef boost::optional<Cell_type> Vert_decomp_type;
typedef std::pair<Vert_decomp_type, Vert_decomp_type> Vert_decomp_pair;
typedef std::pair<Vertex_const_handle, Vert_decomp_pair> Vert_decomp_entry;
typedef std::list<Vert_decomp_entry> Vert_decomp_list;
int main ()
{
@ -43,37 +46,37 @@ int main ()
CGAL::decompose (arr, std::back_inserter(vd_list));
// Print the results.
Vert_decomp_list::const_iterator vd_iter;
std::pair<CGAL::Object, CGAL::Object> curr;
Vertex_const_handle vh;
Halfedge_const_handle hh;
Face_const_handle fh;
for (vd_iter = vd_list.begin(); vd_iter != vd_list.end(); ++vd_iter) {
curr = vd_iter->second;
for (auto vd_iter = vd_list.begin(); vd_iter != vd_list.end(); ++vd_iter) {
const Vert_decomp_pair& curr = vd_iter->second;
std::cout << "Vertex (" << vd_iter->first->point() << ") : ";
std::cout << " feature below: ";
if (CGAL::assign (vh, curr.first))
std::cout << '(' << vh->point() << ')';
else if (CGAL::assign (hh, curr.first))
if (!hh->is_fictitious())
std::cout << '[' << hh->curve() << ']';
else
std::cout << "NONE";
else
std::cout << "EMPTY";
if (! curr.first) std::cout << "EMPTY";
else {
auto* vh = boost::get<Vertex_const_handle>(&*(curr.first));;
if (vh) std::cout << '(' << (*vh)->point() << ')';
else {
auto* hh = boost::get<Halfedge_const_handle>(&*(curr.first));
CGAL_assertion(hh);
if (! (*hh)->is_fictitious())
std::cout << '[' << (*hh)->curve() << ']';
else std::cout << "NONE";
}
}
std::cout << " feature above: ";
if (CGAL::assign (vh, curr.second))
std::cout << '(' << vh->point() << ')' << std::endl;
else if (CGAL::assign (hh, curr.second))
if (!hh->is_fictitious())
std::cout << '[' << hh->curve() << ']' << std::endl;
else
std::cout << "NONE" << std::endl;
else
std::cout << "EMPTY" << std::endl;
if (! curr.second) std::cout << "EMPTY" << std::endl;
else {
auto* vh = boost::get<Vertex_const_handle>(&*(curr.second));;
if (vh) std::cout << '(' << (*vh)->point() << ')' << std::endl;
else {
auto* hh = boost::get<Halfedge_const_handle>(&*(curr.second));
CGAL_assertion(hh);
if (! (*hh)->is_fictitious())
std::cout << '[' << (*hh)->curve() << ']' << std::endl;
else std::cout << "NONE" << std::endl;
}
}
}
return 0;

View File

@ -7,9 +7,9 @@
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s) : Ron Wein <wein@post.tau.ac.il>
// Iddo Hanniel <iddoh@cs.technion.ac.il>
// Waqar Khan <wkhan@mpi-inf.mpg.de>
// Author(s): Ron Wein <wein@post.tau.ac.il>
// Iddo Hanniel <iddoh@cs.technion.ac.il>
// Waqar Khan <wkhan@mpi-inf.mpg.de>
#ifndef CGAL_ARR_BEZIER_CURVE_TRAITS_2_H
#define CGAL_ARR_BEZIER_CURVE_TRAITS_2_H
@ -163,7 +163,7 @@ public:
}
//@}
/// \name Functor definitions for the arrangement traits.
/// \name Basic functor definitions for the arrangement traits
//@{
/*! \class Compare_x_2
@ -473,33 +473,34 @@ public:
{
return (Equal_2 (p_cache));
}
//@}
//! \name Intersections, subdivisions, and mergings
//@{
/*! \class Make_x_monotone_2
* The Make_x_monotone_2 functor.
* A functor for subdividing a curve into x-monotone curves.
*/
class Make_x_monotone_2
{
class Make_x_monotone_2 {
private:
Bezier_cache *p_cache;
Bezier_cache* p_cache;
public:
/*! Constructor. */
Make_x_monotone_2 (Bezier_cache *cache) :
p_cache (cache)
{}
Make_x_monotone_2(Bezier_cache* cache) : p_cache(cache) {}
/*!
* Cut the given Bezier curve into x-monotone subcurves and insert them
* into the given output iterator.
* \param cv The curve.
* \param oi The output iterator, whose value-type is Object. The returned
* objects is a wrapper for an X_monotone_curve_2 object.
* \return The past-the-end iterator.
/*! Subdivide a given Bezier curve into x-monotone subcurves and insert them
* into a given output iterator.
* \param cv the curve.
* \param oi an output iterator for the result. Its value type is a variant
* that wraps Point_2 or an X_monotone_curve_2 objects.
* \return the past-the-end iterator.
*/
template<class OutputIterator>
template <typename OutputIterator>
OutputIterator operator() (const Curve_2& B, OutputIterator oi) const
{
typedef boost::variant<Point_2, X_monotone_curve_2>
Make_x_monotone_result;
typedef typename Bounding_traits::Vertical_tangency_point
Vertical_tangency_point;
@ -512,20 +513,17 @@ public:
std::back_inserter(cpts));
bound_tr.compute_vertical_tangency_points
(cpts, std::back_inserter (vpt_bounds));
(cpts, std::back_inserter (vpt_bounds));
// Construct Point_2 from bounded tangency points.
std::list<Point_2> vpts;
bool app_ok = true;
typename std::list<Vertical_tangency_point>::const_iterator iter;
for (iter = vpt_bounds.begin(); iter != vpt_bounds.end(); ++iter)
{
for (auto iter = vpt_bounds.begin(); iter != vpt_bounds.end(); ++iter) {
const typename Bounding_traits::Bez_point_bound& bound = iter->bound;
const typename Bounding_traits::Bez_point_bbox& bbox = iter->bbox;
if (! bound.can_refine)
{
if (! bound.can_refine) {
// If we cannot refine the vertical-tangency bound anymore, then
// we failed to bound the vertical tangency point.
// \todo In the future, we might want to use the info.
@ -534,28 +532,25 @@ public:
}
// Construct an approximate vertical tangency point.
Point_2 pt;
Point_2 pt;
if (bound.type == Bounding_traits::Bez_point_bound::RATIONAL_PT)
{
if (bound.type == Bounding_traits::Bez_point_bound::RATIONAL_PT) {
CGAL_assertion (CGAL::compare (bound.t_min, bound.t_max) == EQUAL);
Rational t0 = bound.t_min;
Rational t0 = bound.t_min;
pt = Point_2 (B, t0);
}
else
{
pt.add_originator (typename Point_2::Originator(B, bound));
else {
pt.add_originator(typename Point_2::Originator(B, bound));
}
pt.set_bbox (bbox);
pt.set_bbox(bbox);
vpts.push_back(pt);
}
// If bounding the approximated vertical-tangency points went fine,
// use these points as endpoint for the x-monotone subcurves.
if (app_ok)
{
if (app_ok) {
// Create the x-monotone subcurves with approximate endpoints.
typename std::list<Point_2>::const_iterator pit;
unsigned int xid = 1; // Serial number of the subcurve.
@ -563,19 +558,16 @@ public:
// Note: xid is needed in ctr of p0 (and of p1 below),
// for handling end case of start point == end point.
for (pit = vpts.begin(); pit != vpts.end(); ++pit)
{
*oi++ = CGAL::make_object (X_monotone_curve_2 (B, xid,
p0, *pit,
*p_cache));
for (pit = vpts.begin(); pit != vpts.end(); ++pit) {
*oi++ = Make_x_monotone_result(X_monotone_curve_2(B, xid, p0, *pit,
*p_cache));
xid++;
p0 = *pit;
}
Point_2 p1(B, xid, Rational(1)); // A rational end point.
*oi++ = CGAL::make_object (X_monotone_curve_2 (B, xid,
p0, p1,
*p_cache));
*oi++ = Make_x_monotone_result(X_monotone_curve_2(B, xid, p0, p1,
*p_cache));
return (oi);
}
@ -583,41 +575,34 @@ public:
// points in an exact manner. We do this by considering all t-values
// on B(t) = (X(t), Y(t)), such that X'(t) = 0.
const typename Bezier_cache::Vertical_tangency_list&
vt_list = p_cache->get_vertical_tangencies (B.id(),
B.x_polynomial(),
B.x_norm());
vt_list = p_cache->get_vertical_tangencies(B.id(), B.x_polynomial(),
B.x_norm());
// Create the x-monotone subcurves.
Point_2 p1;
typename Bezier_cache::Vertical_tangency_iter it;
unsigned int xid = 1; // Serial number of the subcurve.
Point_2 p0 (B, xid, Rational(0));
Point_2 p1;
unsigned int xid = 1; // Serial number of the subcurve.
Point_2 p0(B, xid, Rational(0));
for (it = vt_list.begin(); it != vt_list.end(); ++it)
{
p1 = Point_2 (B, *it);
*oi++ = CGAL::make_object (X_monotone_curve_2 (B, xid,
p0, p1,
*p_cache));
for (auto it = vt_list.begin(); it != vt_list.end(); ++it) {
p1 = Point_2(B, *it);
*oi++ = Make_x_monotone_result(X_monotone_curve_2(B, xid, p0, p1,
*p_cache));
xid++;
p0 = p1;
}
// Create the final subcurve.
p1 = Point_2 (B, xid, Rational(1));
*oi++ = CGAL::make_object (X_monotone_curve_2 (B, xid,
p0, p1,
*p_cache));
return (oi);
p1 = Point_2(B, xid, Rational(1));
*oi++ = Make_x_monotone_result(X_monotone_curve_2(B, xid, p0, p1,
*p_cache));
return oi;
}
};
/*! Get a Make_x_monotone_2 functor object. */
Make_x_monotone_2 make_x_monotone_2_object () const
{
return (Make_x_monotone_2 (p_cache));
}
Make_x_monotone_2 make_x_monotone_2_object() const
{ return (Make_x_monotone_2 (p_cache)); }
/*! \class Split_2
* The Split_2 functor.
@ -756,7 +741,6 @@ public:
{
return Merge_2(this);
}
//@}
/// \name Functor definitions for the Boolean set-operation traits.

View File

@ -22,6 +22,7 @@
*/
#include <CGAL/Arrangement_2/Arr_traits_adaptor_2.h>
#include <CGAL/Arr_point_location_result.h>
namespace CGAL {
@ -60,6 +61,9 @@ private:
typedef typename Arrangement_2::DInner_ccb DInner_ccb;
typedef typename Arrangement_2::DIso_vertex DIso_vertex;
typedef Arr_point_location_result<Arrangement_2> Pl_result;
typedef typename Pl_result::Type Pl_result_type;
private:
Arrangement_2* p_arr; // The associated arrangement.
@ -99,33 +103,29 @@ public:
* This object may wrap a Face_const_handle (the general case),
* or a Halfedge_const_handle (in case of an overlap).
*/
CGAL::Object locate_curve_end(const X_monotone_curve_2& cv,
Arr_curve_end ind,
Arr_parameter_space ps_x,
Arr_parameter_space ps_y) const
Pl_result_type locate_curve_end(const X_monotone_curve_2& cv,
Arr_curve_end ind,
Arr_parameter_space ps_x,
Arr_parameter_space ps_y) const
{
CGAL_precondition((ps_x != ARR_INTERIOR) || (ps_y != ARR_INTERIOR));
// Use the topology traits to locate the unbounded curve end.
CGAL::Object obj =
p_arr->topology_traits()->locate_curve_end(cv, ind, ps_x, ps_y);
auto obj = p_arr->topology_traits()->locate_curve_end(cv, ind, ps_x, ps_y);
// Return a handle to the DCEL feature.
DFace* f;
if (CGAL::assign(f, obj))
return (CGAL::make_object(p_arr->_const_handle_for(f)));
DFace** f_p = boost::get<DFace*>(&obj);
if (f_p) return (Pl_result::make_result(p_arr->_const_handle_for(*f_p)));
DHalfedge* he;
if (CGAL::assign(he, obj))
return (CGAL::make_object(p_arr->_const_handle_for(he)));
DHalfedge** he_p = boost::get<DHalfedge*>(&obj);
if (he_p) return (Pl_result::make_result(p_arr->_const_handle_for(*he_p)));
DVertex* v;
if (CGAL::assign(v, obj))
return (CGAL::make_object(p_arr->_const_handle_for(v)));
DVertex** v_p = boost::get<DVertex*>(&obj);
if (v_p) return (Pl_result::make_result(p_arr->_const_handle_for(*v_p)));
// We should never reach here:
CGAL_error();
return Object();
return Pl_result::make_result(Vertex_const_handle());
}
/*!

View File

@ -8,7 +8,7 @@
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Michael Kerber <mkerber@mpi-inf.mpg.de>
// Author(s): Michael Kerber <mkerber@mpi-inf.mpg.de>
//
// ============================================================================
@ -264,138 +264,141 @@ public:
}
template<typename OutputIterator> OutputIterator
x_monotone_segment (Curve_2 cv,
Point_2 p,
boost::optional<Point_2> start,
boost::optional<Point_2> end,
OutputIterator out) const {
template <typename OutputIterator> OutputIterator
x_monotone_segment(Curve_2 cv,
Point_2 p,
boost::optional<Point_2> start,
boost::optional<Point_2> end,
OutputIterator out) const
{
typedef boost::variant<Point_2, X_monotone_curve_2>
Make_x_monotone_result;
//CGAL_assertion(is_one_one(cv,p));
//CGAL_assertion(is_one_one(cv,p));
std::list<X_monotone_curve_2> segs;
std::list<X_monotone_curve_2> segs;
Is_on_2 on_arc
= this->_ckva()->is_on_2_object();
Construct_min_vertex_2 left
= this->_ckva()->construct_min_vertex_2_object();
Construct_max_vertex_2 right
= this->_ckva()->construct_max_vertex_2_object();
Equal_2 equal = this->_ckva()->equal_2_object();
std::vector<CGAL::Object> arcs;
this->_ckva()->make_x_monotone_2_object()
(cv,std::back_inserter(arcs));
typename std::vector<CGAL::Object>::const_iterator
it = arcs.begin(),helper;
X_monotone_curve_2 it_seg;
CGAL::assign(it_seg,*it);
while(it!=arcs.end()) {
if( on_arc(p,it_seg) ) {
break;
}
CGAL_assertion(it!=arcs.end());
it++;
CGAL::assign(it_seg,*it);
}
bool left_on_arc = start && on_arc(start.get(),it_seg);
bool right_on_arc = end && on_arc(end.get(),it_seg);
if( left_on_arc && right_on_arc ) {
segs.push_back(it_seg.trim(start.get(),end.get()));
}
if(left_on_arc && (!right_on_arc)) {
if(!it_seg.is_finite(CGAL::ARR_MAX_END) ||
!equal(start.get(),right(it_seg))) {
if(it_seg.is_finite(CGAL::ARR_MIN_END) && equal(start.get(),left(it_seg))) {
segs.push_back(it_seg);
} else {
X_monotone_curve_2 split1,split2;
it_seg.split(start.get(),split1,split2);
segs.push_back(split2);
}
}
}
if((!left_on_arc) && right_on_arc) {
if(!it_seg.is_finite(CGAL::ARR_MIN_END) ||
! equal(left(it_seg),end.get())) {
if(it_seg.is_finite(CGAL::ARR_MAX_END) && equal(end.get(),right(it_seg))) {
segs.push_back(it_seg);
} else {
X_monotone_curve_2 split1,split2;
it_seg.split(end.get(),split1,split2);
segs.push_back(split1);
}
}
}
if( (!left_on_arc) && (!right_on_arc)) {
segs.push_back(it_seg);
}
helper=it; // for later usage
if(! left_on_arc) {
Point_2 point_it;
while(true) {
if(it_seg.is_finite(CGAL::ARR_MIN_END) &&
is_one_one(cv,left(it_seg) ) ) {
point_it=left(it_seg);
} else {
CGAL_assertion(! start);
break;
}
CGAL_assertion(it!=arcs.begin());
it--;
CGAL::assign(it_seg,*it);
while(! on_arc(point_it,it_seg)) {
CGAL_assertion(it!=arcs.begin());
it--;
CGAL::assign(it_seg,*it);
}
if(start && on_arc(start.get(),it_seg)) {
segs.push_front(it_seg.trim(start.get(),
right(it_seg)));
break;
} else {
segs.push_front(it_seg);
}
}
}
if(! right_on_arc) {
it=helper; // reset
CGAL::assign(it_seg,*it);
Point_2 point_it;
while(true) {
if(it_seg.is_finite(CGAL::ARR_MAX_END) &&
is_one_one(cv,right(it_seg) ) ) {
point_it=right(it_seg);
} else {
CGAL_assertion(! end);
break;
}
it++;
CGAL_assertion(it!=arcs.end());
CGAL::assign(it_seg,*it);
while(! on_arc(point_it,it_seg)) {
it++;
CGAL_assertion(it!=arcs.end());
CGAL::assign(it_seg,*it);
}
if(end && on_arc(end.get(),it_seg)) {
segs.push_back(it_seg.trim(left(it_seg),end.get()));
break;
} else {
segs.push_back(it_seg);
}
}
}
std::copy(segs.begin(),segs.end(),out);
return out;
Is_on_2 on_arc = this->_ckva()->is_on_2_object();
auto left = this->_ckva()->construct_min_vertex_2_object();
auto right = this->_ckva()->construct_max_vertex_2_object();
Equal_2 equal = this->_ckva()->equal_2_object();
std::vector<Make_x_monotone_result> arcs;
this->_ckva()->make_x_monotone_2_object()(cv, std::back_inserter(arcs));
auto it = arcs.begin();
auto helper = it;
const auto* it_seg_p = boost::get<X_monotone_curve_2>(&(*it));
while (it != arcs.end()) {
if ( on_arc(p, *it_seg_p) ) break;
it++;
it_seg_p = boost::get<X_monotone_curve_2>(&(*it));
}
bool left_on_arc = start && on_arc(start.get(), *it_seg_p);
bool right_on_arc = end && on_arc(end.get(), *it_seg_p);
if ( left_on_arc && right_on_arc ) {
segs.push_back(it_seg_p->trim(start.get(),end.get()));
}
if (left_on_arc && (!right_on_arc)) {
if (!it_seg_p->is_finite(CGAL::ARR_MAX_END) ||
!equal(start.get(),right(*it_seg_p))) {
if (it_seg_p->is_finite(CGAL::ARR_MIN_END) &&
equal(start.get(),left(*it_seg_p)))
{
segs.push_back(*it_seg_p);
}
else {
X_monotone_curve_2 split1,split2;
it_seg_p->split(start.get(),split1,split2);
segs.push_back(split2);
}
}
}
if ((!left_on_arc) && right_on_arc) {
if (!it_seg_p->is_finite(CGAL::ARR_MIN_END) ||
! equal(left(*it_seg_p), end.get()))
{
if (it_seg_p->is_finite(CGAL::ARR_MAX_END) &&
equal(end.get(), right(*it_seg_p)))
{
segs.push_back(*it_seg_p);
}
else {
X_monotone_curve_2 split1,split2;
it_seg_p->split(end.get(), split1, split2);
segs.push_back(split1);
}
}
}
if ( (!left_on_arc) && (!right_on_arc)) {
segs.push_back(*it_seg_p);
}
helper = it; // for later usage
if (! left_on_arc) {
Point_2 point_it;
while (true) {
if (it_seg_p->is_finite(CGAL::ARR_MIN_END) &&
is_one_one(cv, left(*it_seg_p) ) ) {
point_it = left(*it_seg_p);
} else {
CGAL_assertion(! start);
break;
}
CGAL_assertion(it != arcs.begin());
it--;
it_seg_p = boost::get<X_monotone_curve_2>(&(*it));
while (! on_arc(point_it, *it_seg_p)) {
CGAL_assertion(it != arcs.begin());
it--;
it_seg_p = boost::get<X_monotone_curve_2>(&(*it));
}
if (start && on_arc(start.get(),*it_seg_p)) {
segs.push_front(it_seg_p->trim(start.get(), right(*it_seg_p)));
break;
}
else {
segs.push_front(*it_seg_p);
}
}
}
if (! right_on_arc) {
it = helper; // reset
it_seg_p = boost::get<X_monotone_curve_2>(&(*it));
Point_2 point_it;
while (true) {
if (it_seg_p->is_finite(CGAL::ARR_MAX_END) &&
is_one_one(cv,right(*it_seg_p) ) )
{
point_it=right(*it_seg_p);
} else {
CGAL_assertion(! end);
break;
}
it++;
CGAL_assertion(it != arcs.end());
it_seg_p = boost::get<X_monotone_curve_2>(&(*it));
while(! on_arc(point_it, *it_seg_p)) {
it++;
CGAL_assertion(it != arcs.end());
it_seg_p = boost::get<X_monotone_curve_2>(&(*it));
}
if(end && on_arc(end.get(),*it_seg_p)) {
segs.push_back(it_seg_p->trim(left(*it_seg_p),end.get()));
break;
}
else {
segs.push_back(*it_seg_p);
}
}
}
std::copy(segs.begin(), segs.end(), out);
return out;
}
public:
template<typename OutputIterator> OutputIterator

View File

@ -41,11 +41,9 @@ namespace Ss2 = Surface_sweep_2;
* \param oi Output: An output iterator for the query results.
* \pre The value-type of PointsIterator is Arrangement::Point_2,
* and the value-type of OutputIterator is is pair<Point_2, Result>,
* where Result is either
* (i) Object or
* (ii) boost::optional<boost::variant<Vertex_const_handle,
* Halfedge_const_handle,
* Face_const_handle> >.
* where Result is boost::optional<boost::variant<Vertex_const_handle,
* Halfedge_const_handle,
* Face_const_handle> >.
* It represents the arrangement feature containing the point.
*/
template <typename GeometryTraits_2, typename TopologyTraits,

View File

@ -7,14 +7,15 @@
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// Eric Berberich <ericb@post.tau.ac.il>
// Author(s): Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// Eric Berberich <ericb@post.tau.ac.il>
#ifndef CGAL_ARR_BOUNDED_PLANAR_TOPOLOGY_TRAITS_2_H
#define CGAL_ARR_BOUNDED_PLANAR_TOPOLOGY_TRAITS_2_H
#include <boost/variant.hpp>
#include <CGAL/license/Arrangement_on_surface_2.h>
#include <CGAL/disable_warnings.h>
@ -306,17 +307,18 @@ public:
* \param ps_x The boundary condition of the curve end in x.
* \param ps_y The boundary condition of the curve end in y.
* \pre The curve has a boundary condition in either x or y.
* \return An object that contains the curve end.
* \return An object that wraps the curve end.
*/
CGAL::Object place_boundary_vertex(Face*,
const X_monotone_curve_2&,
Arr_curve_end,
Arr_parameter_space /* ps_x */,
Arr_parameter_space /* ps_y */)
boost::optional<boost::variant<Vertex*, Halfedge*> >
place_boundary_vertex(Face*,
const X_monotone_curve_2&,
Arr_curve_end,
Arr_parameter_space /* ps_x */,
Arr_parameter_space /* ps_y */)
{
// This function should never be called:
CGAL_error();
return Object();
return boost::none;
}
/*! Locate the predecessor halfedge for the given curve around a given
@ -349,14 +351,17 @@ public:
* \pre The curve end is incident to the boundary.
* \return An object that contains the curve end.
*/
CGAL::Object locate_curve_end(const X_monotone_curve_2&,
Arr_curve_end,
Arr_parameter_space /* ps_x */,
Arr_parameter_space /* ps_y */)
boost::variant<Vertex*, Halfedge*, Face*>
locate_curve_end(const X_monotone_curve_2&,
Arr_curve_end,
Arr_parameter_space /* ps_x */,
Arr_parameter_space /* ps_y */)
{
typedef boost::variant<Vertex*, Halfedge*, Face*> Result;
// This function should never be called:
CGAL_error();
return Object();
Vertex* v(nullptr);
return Result(v);
}
/*! Split a fictitious edge using the given vertex.

View File

@ -378,46 +378,47 @@ public:
}
//@}
/// \name Functor definitions for supporting intersections.
/// \name Intersections, subdivisions, and mergings
//@{
class Make_x_monotone_2
{
/*! \class
* A functor for subdividing a curve into x-monotone curves.
*/
class Make_x_monotone_2 {
private:
typedef Arr_circle_segment_traits_2<Kernel_, Filter> Self;
bool m_use_cache;
public:
Make_x_monotone_2(bool use_cache = false) : m_use_cache(use_cache) {}
Make_x_monotone_2(bool use_cache = false) : m_use_cache(use_cache)
{}
/*!
* Cut the given conic curve (ocv.is_in_x_range (p)r conic arc) into x-monotone subcurves
* and insert them to the given output iterator.
* \param cv The curve.
* \param oi The output iterator, whose value-type is Object. The returned
* objects are all wrcv.is_in_x_range (p)appers X_monotone_curve_2 objects.
* \return The past-the-end iterator.
/*! Subdivide a given circular arc or line segment into x-monotone subcurves
* and insert them to a given output iterator.
* \param cv the curve.
* \param oi the output iterator for the result. Its dereference type is a
* variant that wraps a \c Point_2 or an \c X_monotone_curve_2
* objects.
* \return the past-the-end iterator.
*/
template<class OutputIterator>
OutputIterator operator() (const Curve_2& cv, OutputIterator oi) const
template <typename OutputIterator>
OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const
{
typedef boost::variant<Point_2, X_monotone_curve_2>
Make_x_monotone_result;
// Increment the serial number of the curve cv, which will serve as its
// unique identifier.
unsigned int index = 0;
if(m_use_cache)
index = Self::get_index();
unsigned int index = 0;
if (m_use_cache) index = Self::get_index();
if (cv.orientation() == COLLINEAR)
{
if (cv.orientation() == COLLINEAR) {
// The curve is a line segment.
*oi = make_object (X_monotone_curve_2 (cv.supporting_line(),
cv.source(), cv.target(),
index));
++oi;
return (oi);
*oi++ = Make_x_monotone_result(X_monotone_curve_2(cv.supporting_line(),
cv.source(),
cv.target(),
index));
return oi;
}
// Check the case of a degenrate circle (a point).
@ -425,12 +426,11 @@ public:
CGAL::Sign sign_rad = CGAL::sign (circ.squared_radius());
CGAL_precondition (sign_rad != NEGATIVE);
if (sign_rad == ZERO)
{
if (sign_rad == ZERO) {
// Create an isolated point.
*oi = make_object (Point_2 (circ.center().x(), circ.center().y()));
++oi;
return (oi);
*oi++ = Make_x_monotone_result(Point_2(circ.center().x(),
circ.center().y()));
return oi;
}
// The curve is circular: compute the to vertical tangency points
@ -438,84 +438,73 @@ public:
Point_2 vpts[2];
unsigned int n_vpts = cv.vertical_tangency_points (vpts);
if (cv.is_full())
{
if (cv.is_full()) {
CGAL_assertion (n_vpts == 2);
// Subdivide the circle into two arcs (an upper and a lower half).
*oi = make_object (X_monotone_curve_2 (circ,
vpts[0], vpts[1],
cv.orientation(),
index));
++oi;
*oi++ = Make_x_monotone_result(X_monotone_curve_2(circ,
vpts[0], vpts[1],
cv.orientation(),
index));
*oi = make_object (X_monotone_curve_2 (circ,
vpts[1], vpts[0],
cv.orientation(),
index));
++oi;
*oi++ = Make_x_monotone_result(X_monotone_curve_2(circ,
vpts[1], vpts[0],
cv.orientation(),
index));
}
else
{
else {
// Act according to the number of vertical tangency points.
if (n_vpts == 2)
{
if (n_vpts == 2) {
// Subdivide the circular arc into three x-monotone arcs.
*oi = make_object (X_monotone_curve_2 (circ,
cv.source(), vpts[0],
cv.orientation(),
index));
++oi;
*oi++ = Make_x_monotone_result(X_monotone_curve_2(circ,
cv.source(), vpts[0],
cv.orientation(),
index));
*oi = make_object (X_monotone_curve_2 (circ,
vpts[0], vpts[1],
cv.orientation(),
index));
++oi;
*oi++ = Make_x_monotone_result(X_monotone_curve_2(circ,
vpts[0], vpts[1],
cv.orientation(),
index));
*oi = make_object (X_monotone_curve_2 (circ,
vpts[1], cv.target(),
cv.orientation(),
index));
++oi;
*oi++ = Make_x_monotone_result(X_monotone_curve_2(circ,
vpts[1],
cv.target(),
cv.orientation(),
index));
}
else if (n_vpts == 1)
{
else if (n_vpts == 1) {
// Subdivide the circular arc into two x-monotone arcs.
*oi = make_object (X_monotone_curve_2 (circ,
cv.source(), vpts[0],
cv.orientation(),
index));
++oi;
*oi++ = Make_x_monotone_result(X_monotone_curve_2(circ,
cv.source(),
vpts[0],
cv.orientation(),
index));
*oi = make_object (X_monotone_curve_2 (circ,
vpts[0], cv.target(),
cv.orientation(),
index));
++oi;
*oi++ = Make_x_monotone_result(X_monotone_curve_2(circ,
vpts[0],
cv.target(),
cv.orientation(),
index));
}
else
{
CGAL_assertion (n_vpts == 0);
else {
CGAL_assertion(n_vpts == 0);
// The arc is already x-monotone:
*oi = make_object (X_monotone_curve_2 (circ,
cv.source(), cv.target(),
cv.orientation(),
index));
++oi;
*oi++ = Make_x_monotone_result(X_monotone_curve_2(circ,
cv.source(),
cv.target(),
cv.orientation(),
index));
}
}
return (oi);
return oi;
}
};
/*! Get a Make_x_monotone_2 functor object. */
Make_x_monotone_2 make_x_monotone_2_object () const
{
return Make_x_monotone_2(m_use_cache);
}
Make_x_monotone_2 make_x_monotone_2_object() const
{ return Make_x_monotone_2(m_use_cache); }
class Split_2
{

View File

@ -27,6 +27,10 @@
* Arrangement_2 package, which it is now part of. It contains a traits
* class for the arrangement package that handles circular curves.
* It is based on the circular kernel.
*
* \todo Fix the circular-kernel make-x-monotone functor to use modern variant
* instead of the legacy CGAL::Object. Then, eliminate the special
* implementation here and directly use the kernel functor instead.
*/
#include <CGAL/basic.h>
@ -109,7 +113,7 @@ public:
typedef unsigned int Multiplicity;
typedef CGAL::Tag_false Has_left_category;
typedef CGAL::Tag_false Has_merge_category;
typedef CGAL::Tag_false Has_merge_category;
typedef CGAL::Tag_false Has_do_intersect_category;
typedef Arr_oblivious_side_tag Left_side_category;
@ -129,7 +133,7 @@ public:
typedef typename CircularKernel::Construct_circular_min_vertex_2
Construct_min_vertex_2;
typedef typename CircularKernel::Equal_2 Equal_2;
typedef typename CircularKernel::Make_x_monotone_2 Make_x_monotone_2;
// typedef typename CircularKernel::Make_x_monotone_2 Make_x_monotone_2;
typedef typename CircularKernel::Split_2 Split_2;
typedef typename CircularKernel::Intersect_2 Intersect_2;
typedef typename CircularKernel::Is_vertical_2 Is_vertical_2;
@ -149,8 +153,8 @@ public:
Equal_2 equal_2_object() const
{ return ck.equal_2_object(); }
Make_x_monotone_2 make_x_monotone_2_object() const
{ return ck.make_x_monotone_2_object(); }
// Make_x_monotone_2 make_x_monotone_2_object() const
// { return ck.make_x_monotone_2_object(); }
Split_2 split_2_object() const
{ return ck.split_2_object(); }
@ -168,6 +172,34 @@ public:
{ return ck.is_vertical_2_object(); }
//! A functor for subdividing curves into x-monotone curves.
class Make_x_monotone_2 {
public:
template <typename OutputIterator>
OutputIterator operator()(const Curve_2& arc, OutputIterator oi) const
{
typedef boost::variant<Point_2, X_monotone_curve_2>
Make_x_monotone_result;
std::vector<CGAL::Object> objs;
CircularKernel().make_x_monotone_2_object()(arc, std::back_inserter(objs));
for (const auto& obj : objs) {
if (const auto* p = CGAL::object_cast<Point_2>(&obj)) {
*oi++ = Make_x_monotone_result(*p);
continue;
}
if (const auto* xcv = CGAL::object_cast<X_monotone_curve_2>(&obj)) {
*oi++ = Make_x_monotone_result(*xcv);
continue;
}
CGAL_error();
}
return oi;
}
};
Make_x_monotone_2 make_x_monotone_2_object() const
{ return Make_x_monotone_2(); }
};
} // namespace CGAL

View File

@ -27,6 +27,10 @@
* Arrangement_2 package, which it is now part of. It contains a traits
* class for the arrangement package that handles circular and linear curves.
* It is based on the circular kernel.
*
* \todo Fix the circular-kernel make-x-monotone functor to use modern variant
* instead of the legacy CGAL::Object. Then, eliminate the special
* implementation here and directly use the kernel functor instead.
*/
#include <vector>
@ -39,53 +43,35 @@
namespace CGAL {
namespace VariantFunctors{
// Takes an iterator range of Object(Line/Circular_arc),
// returns an Object(Variant(Line/Circular_arc)).
// Do nothing for Object(Endpoint).
// Takes an iterator range of Object(Line/Circular_arc/Point),
// returns a variant of Line, Circular_arc, and Point_2.
template <class CK, class Arc1, class Arc2, class OutputIterator>
OutputIterator
object_to_object_variant(const std::vector<CGAL::Object>& res1,
OutputIterator res2)
{
for (std::vector<CGAL::Object>::const_iterator it = res1.begin();
it != res1.end(); ++it ) {
if (const Arc1 *arc = CGAL::object_cast< Arc1 >(&*it)){
boost::variant< Arc1, Arc2 > v = *arc;
*res2++ = make_object(v);
typedef typename CK::Circular_arc_point_2 Point_2;
typedef boost::variant<Arc1, Arc2> X_monotone_curve_2;
typedef boost::variant<Point_2, X_monotone_curve_2>
Make_x_monotone_result;
for (auto it = res1.begin(); it != res1.end(); ++it) {
if (const Arc1* arc = CGAL::object_cast<Arc1>(&*it)) {
boost::variant<Arc1, Arc2> v = *arc;
*res2++ = Make_x_monotone_result(v);
}
else if (const Arc2 *line = CGAL::object_cast< Arc2 >(&*it)){
boost::variant< Arc1, Arc2 > v = *line;
*res2++ = make_object(v);
else if (const Arc2* line = CGAL::object_cast<Arc2>(&*it)) {
boost::variant<Arc1, Arc2> v = *line;
*res2++ = Make_x_monotone_result(v);
}
else{
*res2++ = *it;
else if (const Point_2* p = CGAL::object_cast<Point_2>(&*it)) {
*res2++ = Make_x_monotone_result(*p);
}
else CGAL_error();
}
return res2;
}
template <class CK, class Arc,
class IntersectionPoint, class XMonotoneCurve,
class InternaType, class OutputIterator>
OutputIterator
object_to_object_variant1(const std::vector<InternaType>& res,
OutputIterator oi)
{
typedef IntersectionPoint Intersection_point;
typedef XMonotoneCurve X_monotone_curve_2;
typedef boost::variant<Intersection_point, X_monotone_curve_2>
Intersection_result;
for (auto it = res.begin(); it != res.end(); ++it) {
if (const Arc* arc = boost::get<Arc>(&*it)) {
X_monotone_curve_2 cv = *arc;
*oi++ = Intersection_result(cv);
}
else *oi++ = Intersection_result(*it);
}
return oi;
}
template <class CircularKernel, class Arc1, class Arc2>
class Compare_y_to_right_2
{
@ -147,17 +133,12 @@ namespace CGAL {
template <class CircularKernel, class Arc1, class Arc2>
class Equal_2
#ifndef CGAL_CFG_MATCHING_BUG_6
: public
CircularKernel::Equal_2
#endif
: public CircularKernel::Equal_2
{
public:
typedef boost::variant< Arc1, Arc2 > Curve_2;
typedef bool result_type;
#ifndef CGAL_CFG_MATCHING_BUG_6
using CircularKernel::Equal_2::operator();
#else
typedef typename CircularKernel::Circular_arc_point_2
Circular_arc_point_2;
typedef typename CircularKernel::Line_arc_2 Line_arc_2;
@ -185,8 +166,6 @@ namespace CGAL {
operator() ( const Circular_arc_2 &a0, const Line_arc_2 &a1) const
{ return false; }
#endif
result_type
operator()(const Curve_2 &a0, const Curve_2 &a1) const
{
@ -259,6 +238,7 @@ namespace CGAL {
};
//! A functor for subdividing curves into x-monotone curves.
template <class CircularKernel, class Arc1, class Arc2>
class Make_x_monotone_2
{
@ -268,20 +248,21 @@ namespace CGAL {
template < class OutputIterator,class Not_X_Monotone >
OutputIterator
operator()(const boost::variant<Arc1, Arc2, Not_X_Monotone> &A, OutputIterator res) const
operator()(const boost::variant<Arc1, Arc2, Not_X_Monotone> &A,
OutputIterator res) const
{
if ( const Arc1* arc1 = boost::get<Arc1>( &A ) ){
if ( const Arc1* arc1 = boost::get<Arc1>( &A ) ) {
std::vector<CGAL::Object> container;
CircularKernel()
.make_x_monotone_2_object()(*arc1,std::back_inserter(container));
CircularKernel().
make_x_monotone_2_object()(*arc1,std::back_inserter(container));
return object_to_object_variant<CircularKernel, Arc1, Arc2>
(container, res);
}
else {
const Arc2* arc2 = boost::get<Arc2>( &A );
std::vector<CGAL::Object> container;
CircularKernel()
.make_x_monotone_2_object()(*arc2,std::back_inserter(container));
CircularKernel().
make_x_monotone_2_object()(*arc2,std::back_inserter(container));
return object_to_object_variant<CircularKernel, Arc1, Arc2>
(container, res);
}

View File

@ -448,135 +448,127 @@ public:
}
//@}
/// \name Functor definitions for supporting intersections.
/// \name Intersections, subdivisions, and mergings
//@{
class Make_x_monotone_2
{
/*! \class Make_x_monotone_2
* A functor for subdividing curves into x-monotone curves.
*/
class Make_x_monotone_2 {
typedef Arr_conic_traits_2 <Rat_kernel_, Alg_kernel_, Nt_traits_> Self;
public:
/*!
* Cut the given conic curve (or conic arc) into x-monotone subcurves
* and insert them to the given output iterator.
* \param cv The curve.
* \param oi The output iterator, whose value-type is Object. The returned
* objects are all wrappers X_monotone_curve_2 objects.
* \return The past-the-end iterator.
public:
/*! Subdivide a given conic curve (or conic arc) into x-monotone subcurves
* and insert them to a given output iterator.
* \param cv the curve.
* \param oi the output iterator for the result. Its dereference type is a
* variant that wraps a \c Point_2 or an \c X_monotone_curve_2
* objects.
* \return the past-the-end iterator.
*/
template<class OutputIterator>
OutputIterator operator() (const Curve_2& cv, OutputIterator oi) const
template <typename OutputIterator>
OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const
{
typedef boost::variant<Point_2, X_monotone_curve_2>
Make_x_monotone_result;
// Increment the serial number of the curve cv, which will serve as its
// unique identifier.
unsigned int index = Self::get_index();
Conic_id conic_id (index);
auto index = Self::get_index();
Conic_id conic_id(index);
// Find the points of vertical tangency to cv and act accordingly.
typename Curve_2::Point_2 vtan_ps[2];
int n_vtan_ps;
typename Curve_2::Point_2 vtan_ps[2];
int n_vtan_ps;
n_vtan_ps = cv.vertical_tangency_points (vtan_ps);
n_vtan_ps = cv.vertical_tangency_points(vtan_ps);
if (n_vtan_ps == 0)
{
if (n_vtan_ps == 0) {
// In case the given curve is already x-monotone:
*oi = make_object (X_monotone_curve_2 (cv, conic_id));
++oi;
return (oi);
*oi++ = Make_x_monotone_result(X_monotone_curve_2(cv, conic_id));
return oi;
}
// Split the conic arc into x-monotone sub-curves.
if (cv.is_full_conic())
{
if (cv.is_full_conic()) {
// Make sure we have two vertical tangency points.
CGAL_assertion(n_vtan_ps == 2);
// In case the curve is a full conic, split it into two x-monotone
// arcs, one going from ps[0] to ps[1], and the other from ps[1] to
// ps[0].
*oi = make_object (X_monotone_curve_2 (cv, vtan_ps[0], vtan_ps[1],
conic_id));
++oi;
*oi = make_object (X_monotone_curve_2 (cv, vtan_ps[1], vtan_ps[0],
conic_id));
++oi;
*oi++ = Make_x_monotone_result(X_monotone_curve_2(cv, vtan_ps[0],
vtan_ps[1],
conic_id));
*oi++ = Make_x_monotone_result(X_monotone_curve_2(cv, vtan_ps[1],
vtan_ps[0],
conic_id));
}
else
{
if (n_vtan_ps == 1)
{
else {
if (n_vtan_ps == 1) {
// Split the arc into two x-monotone sub-curves: one going from the
// arc source to ps[0], and the other from ps[0] to the target.
*oi = make_object (X_monotone_curve_2 (cv, cv.source(), vtan_ps[0],
conic_id));
++oi;
*oi = make_object (X_monotone_curve_2 (cv, vtan_ps[0], cv.target(),
conic_id));
++oi;
*oi++ = Make_x_monotone_result(X_monotone_curve_2(cv, cv.source(),
vtan_ps[0],
conic_id));
*oi++ = Make_x_monotone_result(X_monotone_curve_2(cv, vtan_ps[0],
cv.target(),
conic_id));
}
else
{
CGAL_assertion (n_vtan_ps == 2);
else {
CGAL_assertion(n_vtan_ps == 2);
// Identify the first point we encounter when going from cv's source
// to its target, and the second point we encounter. Note that the
// two endpoints must both be below the line connecting the two
// tangnecy points (or both lies above it).
int ind_first = 0;
int ind_second = 1;
Alg_kernel_ ker;
typename Alg_kernel_::Line_2 line =
ker.construct_line_2_object() (vtan_ps[0], vtan_ps[1]);
const Comparison_result start_pos =
int ind_first = 0;
int ind_second = 1;
Alg_kernel_ ker;
typename Alg_kernel_::Line_2 line =
ker.construct_line_2_object()(vtan_ps[0], vtan_ps[1]);
const Comparison_result start_pos =
ker.compare_y_at_x_2_object() (cv.source(), line);
const Comparison_result order_vpts =
ker.compare_x_2_object() (vtan_ps[0], vtan_ps[1]);
const Comparison_result order_vpts =
ker.compare_x_2_object()(vtan_ps[0], vtan_ps[1]);
CGAL_assertion (start_pos != EQUAL &&
ker.compare_y_at_x_2_object() (cv.target(),
line) == start_pos);
CGAL_assertion (order_vpts != EQUAL);
CGAL_assertion(start_pos != EQUAL &&
ker.compare_y_at_x_2_object()(cv.target(),
line) == start_pos);
CGAL_assertion(order_vpts != EQUAL);
if ((cv.orientation() == COUNTERCLOCKWISE &&
start_pos == order_vpts) ||
(cv.orientation() == CLOCKWISE &&
start_pos != order_vpts))
if (((cv.orientation() == COUNTERCLOCKWISE) &&
(start_pos == order_vpts)) ||
((cv.orientation() == CLOCKWISE) && (start_pos != order_vpts)))
{
ind_first = 1;
ind_second = 0;
}
// Split the arc into three x-monotone sub-curves.
*oi = make_object (X_monotone_curve_2 (cv,
cv.source(),
vtan_ps[ind_first],
conic_id));
++oi;
*oi++ = Make_x_monotone_result(X_monotone_curve_2(cv, cv.source(),
vtan_ps[ind_first],
conic_id));
*oi = make_object (X_monotone_curve_2 (cv,
vtan_ps[ind_first],
vtan_ps[ind_second],
conic_id));
++oi;
*oi++ = Make_x_monotone_result(X_monotone_curve_2(cv,
vtan_ps[ind_first],
vtan_ps[ind_second],
conic_id));
*oi = make_object (X_monotone_curve_2 (cv,
vtan_ps[ind_second],
cv.target(),
conic_id));
++oi;
*oi++ = Make_x_monotone_result(X_monotone_curve_2(cv,
vtan_ps[ind_second],
cv.target(),
conic_id));
}
}
return (oi);
return oi;
}
};
/*! Get a Make_x_monotone_2 functor object. */
Make_x_monotone_2 make_x_monotone_2_object () const
{
return Make_x_monotone_2();
}
Make_x_monotone_2 make_x_monotone_2_object() const
{ return Make_x_monotone_2(); }
class Split_2
{

View File

@ -101,120 +101,120 @@ public:
}
/*! Obtain the counter of the given operation */
unsigned int count(Operation_id id) const
size_t count(Operation_id id) const
{ return m_counters[id]; }
unsigned int count_compare_x() const
size_t count_compare_x() const
{ return m_counters[COMPARE_X_OP]; }
unsigned int count_compare_xy() const
size_t count_compare_xy() const
{ return m_counters[COMPARE_XY_OP]; }
unsigned int count_construct_min_vertex() const
size_t count_construct_min_vertex() const
{ return m_counters[CONSTRUCT_MIN_VERTEX_OP]; }
unsigned int count_construct_max_vertex() const
size_t count_construct_max_vertex() const
{ return m_counters[CONSTRUCT_MAX_VERTEX_OP]; }
unsigned int count_is_vertical() const
size_t count_is_vertical() const
{ return m_counters[IS_VERTICAL_OP]; }
unsigned int count_compare_y_at_x() const
size_t count_compare_y_at_x() const
{ return m_counters[COMPARE_Y_AT_X_OP]; }
unsigned int count_equal_points() const
size_t count_equal_points() const
{ return m_counters[EQUAL_POINTS_OP]; }
unsigned int count_equal_curves() const
size_t count_equal_curves() const
{ return m_counters[EQUAL_CURVES_OP]; }
unsigned int count_compare_y_at_x_left() const
size_t count_compare_y_at_x_left() const
{ return m_counters[COMPARE_Y_AT_X_LEFT_OP]; }
unsigned int count_compare_y_at_x_right() const
size_t count_compare_y_at_x_right() const
{ return m_counters[COMPARE_Y_AT_X_RIGHT_OP]; }
unsigned int count_make_x_monotone() const
size_t count_make_x_monotone() const
{ return m_counters[MAKE_X_MONOTONE_OP]; }
unsigned int count_split() const
size_t count_split() const
{ return m_counters[SPLIT_OP]; }
unsigned int count_intersect() const
size_t count_intersect() const
{ return m_counters[INTERSECT_OP]; }
unsigned int count_are_mergeable() const
size_t count_are_mergeable() const
{ return m_counters[ARE_MERGEABLE_OP]; }
unsigned int count_merge() const
size_t count_merge() const
{ return m_counters[MERGE_OP]; }
unsigned int count_construct_opposite() const
size_t count_construct_opposite() const
{ return m_counters[CONSTRUCT_OPPOSITE_OP]; }
unsigned int count_compare_endpoints_xy() const
size_t count_compare_endpoints_xy() const
{ return m_counters[COMPARE_ENDPOINTS_XY_OP]; }
// left-right
unsigned int count_parameter_space_in_x_curve_end() const
size_t count_parameter_space_in_x_curve_end() const
{ return m_counters[PARAMETER_SPACE_IN_X_CURVE_END_OP]; }
unsigned int count_parameter_space_in_x_curve() const
size_t count_parameter_space_in_x_curve() const
{ return m_counters[PARAMETER_SPACE_IN_X_CURVE_OP]; }
unsigned int count_parameter_space_in_x_point() const
size_t count_parameter_space_in_x_point() const
{ return m_counters[PARAMETER_SPACE_IN_X_POINT_OP]; }
unsigned int count_is_on_x_identification_point() const
size_t count_is_on_x_identification_point() const
{ return m_counters[IS_ON_X_IDENTIFICATION_POINT_OP]; }
unsigned int count_is_on_x_identification_curve() const
size_t count_is_on_x_identification_curve() const
{ return m_counters[IS_ON_X_IDENTIFICATION_CURVE_OP]; }
unsigned int count_compare_y_on_boundary() const
size_t count_compare_y_on_boundary() const
{ return m_counters[COMPARE_Y_ON_BOUNDARY_OP]; }
unsigned int count_compare_y_near_boundary() const
size_t count_compare_y_near_boundary() const
{ return m_counters[COMPARE_Y_NEAR_BOUNDARY_OP]; }
// bottom-top
unsigned int count_parameter_space_in_y_curve_end() const
size_t count_parameter_space_in_y_curve_end() const
{ return m_counters[PARAMETER_SPACE_IN_Y_CURVE_END_OP]; }
unsigned int count_parameter_space_in_y_curve() const
size_t count_parameter_space_in_y_curve() const
{ return m_counters[PARAMETER_SPACE_IN_Y_CURVE_OP]; }
unsigned int count_parameter_space_in_y_point() const
size_t count_parameter_space_in_y_point() const
{ return m_counters[PARAMETER_SPACE_IN_Y_POINT_OP]; }
unsigned int count_is_on_y_identification_point() const
size_t count_is_on_y_identification_point() const
{ return m_counters[IS_ON_Y_IDENTIFICATION_POINT_OP]; }
unsigned int count_is_on_y_identification_curve() const
size_t count_is_on_y_identification_curve() const
{ return m_counters[IS_ON_Y_IDENTIFICATION_CURVE_OP]; }
unsigned int count_compare_x_at_limit_point_curve_end() const
size_t count_compare_x_at_limit_point_curve_end() const
{ return m_counters[COMPARE_X_AT_LIMIT_POINT_CURVE_END_OP]; }
unsigned int count_compare_x_at_limit_curve_ends() const
size_t count_compare_x_at_limit_curve_ends() const
{ return m_counters[COMPARE_X_AT_LIMIT_CURVE_ENDS_OP]; }
unsigned int count_compare_x_near_limit() const
size_t count_compare_x_near_limit() const
{ return m_counters[COMPARE_X_NEAR_LIMIT_OP]; }
unsigned int count_compare_x_on_boundary_points() const
size_t count_compare_x_on_boundary_points() const
{ return m_counters[COMPARE_X_ON_BOUNDARY_POINTS_OP]; }
unsigned int count_compare_x_on_boundary_point_curve_end() const
size_t count_compare_x_on_boundary_point_curve_end() const
{ return m_counters[COMPARE_X_ON_BOUNDARY_POINT_CURVE_END_OP]; }
unsigned int count_compare_x_on_boundary_curve_ends() const
size_t count_compare_x_on_boundary_curve_ends() const
{ return m_counters[COMPARE_X_ON_BOUNDARY_CURVE_ENDS_OP]; }
unsigned int count_compare_x_near_boundary() const
size_t count_compare_x_near_boundary() const
{ return m_counters[COMPARE_X_NEAR_BOUNDARY_OP]; }
/// \name Types and functors inherited from the base
@ -242,11 +242,11 @@ public:
class Compare_x_2 {
private:
typename Base::Compare_x_2 m_object;
unsigned int& m_counter;
size_t& m_counter;
public:
/*! Construct */
Compare_x_2(const Base* base, unsigned int& counter) :
Compare_x_2(const Base* base, size_t& counter) :
m_object(base->compare_x_2_object()), m_counter(counter) {}
/*! Operate */
@ -258,11 +258,11 @@ public:
class Compare_xy_2 {
private:
typename Base::Compare_xy_2 m_object;
unsigned int& m_counter;
size_t& m_counter;
public:
/*! Construct */
Compare_xy_2(const Base* base, unsigned int& counter) :
Compare_xy_2(const Base* base, size_t& counter) :
m_object(base->compare_xy_2_object()), m_counter(counter) {}
/*! Operate */
@ -274,11 +274,11 @@ public:
class Construct_min_vertex_2 {
private:
typename Base::Construct_min_vertex_2 m_object;
unsigned int& m_counter;
size_t& m_counter;
public:
/*! Construct */
Construct_min_vertex_2(const Base* base, unsigned int& counter) :
Construct_min_vertex_2(const Base* base, size_t& counter) :
m_object(base->construct_min_vertex_2_object()), m_counter(counter) {}
/*! Operate */
@ -290,11 +290,11 @@ public:
class Construct_max_vertex_2 {
private:
typename Base::Construct_max_vertex_2 m_object;
unsigned int& m_counter;
size_t& m_counter;
public:
/*! Construct */
Construct_max_vertex_2(const Base* base, unsigned int& counter) :
Construct_max_vertex_2(const Base* base, size_t& counter) :
m_object(base->construct_max_vertex_2_object()), m_counter(counter) {}
/*! Operate */
@ -306,11 +306,11 @@ public:
class Is_vertical_2 {
private:
typename Base::Is_vertical_2 m_object;
unsigned int& m_counter;
size_t& m_counter;
public:
/*! Construct */
Is_vertical_2(const Base* base, unsigned int& counter) :
Is_vertical_2(const Base* base, size_t& counter) :
m_object(base->is_vertical_2_object()), m_counter(counter) {}
/*! Operate */
@ -324,11 +324,11 @@ public:
class Compare_y_at_x_2 {
private:
typename Base::Compare_y_at_x_2 m_object;
unsigned int& m_counter;
size_t& m_counter;
public:
/*! Construct */
Compare_y_at_x_2(const Base* base, unsigned int& counter) :
Compare_y_at_x_2(const Base* base, size_t& counter) :
m_object(base->compare_y_at_x_2_object()), m_counter(counter) {}
/*! Operate */
@ -343,12 +343,12 @@ public:
class Equal_2 {
private:
typename Base::Equal_2 m_object;
unsigned int& m_counter1;
unsigned int& m_counter2;
size_t& m_counter1;
size_t& m_counter2;
public:
/*! Construct */
Equal_2(const Base* base, unsigned int& counter1, unsigned int& counter2) :
Equal_2(const Base* base, size_t& counter1, size_t& counter2) :
m_object(base->equal_2_object()),
m_counter1(counter1), m_counter2(counter2)
{}
@ -369,11 +369,11 @@ public:
class Compare_y_at_x_left_2 {
private:
typename Base::Compare_y_at_x_left_2 m_object;
unsigned int& m_counter;
size_t& m_counter;
public:
/*! Construct */
Compare_y_at_x_left_2(const Base* base, unsigned int& counter) :
Compare_y_at_x_left_2(const Base* base, size_t& counter) :
m_object(base->compare_y_at_x_left_2_object()), m_counter(counter) {}
/*! Operate */
@ -389,11 +389,11 @@ public:
class Compare_y_at_x_right_2 {
private:
typename Base::Compare_y_at_x_right_2 m_object;
unsigned int& m_counter;
size_t& m_counter;
public:
/*! Construct */
Compare_y_at_x_right_2(const Base* base, unsigned int& counter) :
Compare_y_at_x_right_2(const Base* base, size_t& counter) :
m_object(base->compare_y_at_x_right_2_object()), m_counter(counter) {}
/*! Operate */
@ -403,19 +403,27 @@ public:
{ ++m_counter; return m_object(xc1, xc2, p); }
};
/*! A functor that divides a curve into x-monotone curves. */
/*! \class Make_x_monotone_2
* A functor that subdivides a curve into x-monotone curves.
*/
class Make_x_monotone_2 {
private:
typename Base::Make_x_monotone_2 m_object;
unsigned int& m_counter;
size_t& m_counter;
public:
/*! Construct */
Make_x_monotone_2(const Base* base, unsigned int& counter) :
Make_x_monotone_2(const Base* base, size_t& counter) :
m_object(base->make_x_monotone_2_object()), m_counter(counter) {}
/*! Operate */
template<class OutputIterator>
/*! Subdivide a given curve into x-monotone subcurves and insert them into
* a given output iterator.
* \param cv the curve.
* \param oi the output iterator for the result. Its value type is a variant
* that wraps Point_2 or an X_monotone_curve_2 objects.
* \return The past-the-end iterator.
*/
template <typename OutputIterator>
OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const
{ ++m_counter; return m_object(cv, oi); }
};
@ -424,11 +432,11 @@ public:
class Split_2 {
private:
typename Base::Split_2 m_object;
unsigned int& m_counter;
size_t& m_counter;
public:
/*! Construct */
Split_2(const Base* base, unsigned int& counter) :
Split_2(const Base* base, size_t& counter) :
m_object(base->split_2_object()), m_counter(counter) {}
/*! Operate */
@ -441,11 +449,11 @@ public:
class Intersect_2 {
private:
typename Base::Intersect_2 m_object;
unsigned int& m_counter;
size_t& m_counter;
public:
/*! Construct */
Intersect_2(const Base* base, unsigned int& counter) :
Intersect_2(const Base* base, size_t& counter) :
m_object(base->intersect_2_object()), m_counter(counter) {}
/*! Operate */
@ -460,11 +468,11 @@ public:
class Are_mergeable_2 {
private:
typename Base::Are_mergeable_2 m_object;
unsigned int& m_counter;
size_t& m_counter;
public:
/*! Construct */
Are_mergeable_2(const Base* base, unsigned int& counter) :
Are_mergeable_2(const Base* base, size_t& counter) :
m_object(base->are_mergeable_2_object()), m_counter(counter) {}
/*! Operate */
@ -477,11 +485,11 @@ public:
class Merge_2 {
private:
typename Base::Merge_2 m_object;
unsigned int& m_counter;
size_t& m_counter;
public:
/*! Construct */
Merge_2(const Base* base, unsigned int& counter) :
Merge_2(const Base* base, size_t& counter) :
m_object(base->merge_2_object()), m_counter(counter) {}
/*! Operate */
@ -495,11 +503,11 @@ public:
class Construct_opposite_2 {
private:
typename Base::Construct_opposite_2 m_object;
unsigned int& m_counter;
size_t& m_counter;
public:
/*! Construct */
Construct_opposite_2(const Base* base, unsigned int& counter) :
Construct_opposite_2(const Base* base, size_t& counter) :
m_object(base->construct_opposite_2_object()), m_counter(counter) {}
/*! Operate */
@ -513,11 +521,11 @@ public:
class Compare_endpoints_xy_2 {
private:
typename Base::Compare_endpoints_xy_2 m_object;
unsigned int& m_counter;
size_t& m_counter;
public:
/*! Construct */
Compare_endpoints_xy_2(const Base* base, unsigned int& counter) :
Compare_endpoints_xy_2(const Base* base, size_t& counter) :
m_object(base->compare_endpoints_xy_2_object()), m_counter(counter) {}
/*! Operate */
@ -533,14 +541,14 @@ public:
class Parameter_space_in_x_2 {
private:
typename Base::Parameter_space_in_x_2 m_object;
unsigned int& m_counter1;
unsigned int& m_counter2;
unsigned int& m_counter3;
size_t& m_counter1;
size_t& m_counter2;
size_t& m_counter3;
public:
/*! Construct */
Parameter_space_in_x_2(const Base* base, unsigned int& counter1,
unsigned int& counter2, unsigned int& counter3) :
Parameter_space_in_x_2(const Base* base, size_t& counter1,
size_t& counter2, size_t& counter3) :
m_object(base->parameter_space_in_x_2_object()),
m_counter1(counter1),
m_counter2(counter2),
@ -569,13 +577,13 @@ public:
class Is_on_x_identification_2 {
private:
typename Base::Is_on_x_identificiation_2 m_object;
unsigned int& m_counter1;
unsigned int& m_counter2;
size_t& m_counter1;
size_t& m_counter2;
public:
/*! Construct */
Is_on_x_identification_2(const Base* base,
unsigned int& counter1, unsigned int& counter2) :
size_t& counter1, size_t& counter2) :
m_object(base->is_on_x_identificiation_2_object()),
m_counter1(counter1),
m_counter2(counter2) {}
@ -597,11 +605,11 @@ public:
class Compare_y_on_boundary_2 {
private:
typename Base::Compare_y_on_boundary_2 m_object;
unsigned int& m_counter;
size_t& m_counter;
public:
/*! Construct */
Compare_y_on_boundary_2(const Base* base, unsigned int& counter) :
Compare_y_on_boundary_2(const Base* base, size_t& counter) :
m_object(base->compare_y_on_boundary_2_object()),
m_counter(counter)
{}
@ -617,11 +625,11 @@ public:
class Compare_y_near_boundary_2 {
private:
typename Base::Compare_y_near_boundary_2 m_object;
unsigned int& m_counter;
size_t& m_counter;
public:
/*! Construct */
Compare_y_near_boundary_2(const Base* base, unsigned int& counter) :
Compare_y_near_boundary_2(const Base* base, size_t& counter) :
m_object(base->compare_y_near_boundary_2_object()), m_counter(counter) {}
/*! Operate */
@ -639,14 +647,14 @@ public:
class Parameter_space_in_y_2 {
private:
typename Base::Parameter_space_in_y_2 m_object;
unsigned int& m_counter1;
unsigned int& m_counter2;
unsigned int& m_counter3;
size_t& m_counter1;
size_t& m_counter2;
size_t& m_counter3;
public:
/*! Construct */
Parameter_space_in_y_2(const Base* base, unsigned int& counter1,
unsigned int& counter2, unsigned int& counter3) :
Parameter_space_in_y_2(const Base* base, size_t& counter1,
size_t& counter2, size_t& counter3) :
m_object(base->parameter_space_in_y_2_object()),
m_counter1(counter1),
m_counter2(counter2),
@ -673,13 +681,13 @@ public:
class Is_on_y_identification_2 {
private:
typename Base::Is_on_y_identificiation_2 m_object;
unsigned int& m_counter1;
unsigned int& m_counter2;
size_t& m_counter1;
size_t& m_counter2;
public:
/*! Construct */
Is_on_y_identification_2(const Base* base,
unsigned int& counter1, unsigned int& counter2) :
size_t& counter1, size_t& counter2) :
m_object(base->is_on_y_identificiation_2_object()),
m_counter1(counter1),
m_counter2(counter2) {}
@ -701,13 +709,13 @@ public:
class Compare_x_at_limit_2 {
private:
typename Base::Compare_x_at_limit_2 m_object;
unsigned int& m_counter1;
unsigned int& m_counter2;
size_t& m_counter1;
size_t& m_counter2;
public:
/*! Construct */
Compare_x_at_limit_2(const Base* base,
unsigned int& counter1, unsigned int& counter2) :
size_t& counter1, size_t& counter2) :
m_object(base->compare_x_at_limit_2_object()),
m_counter1(counter1),
m_counter2(counter2) {}
@ -733,11 +741,11 @@ public:
class Compare_x_near_limit_2 {
private:
typename Base::Compare_x_near_limit_2 m_object;
unsigned int& m_counter;
size_t& m_counter;
public:
/*! Construct */
Compare_x_near_limit_2(const Base* base, unsigned int& counter) :
Compare_x_near_limit_2(const Base* base, size_t& counter) :
m_object(base->compare_x_near_limit_2_object()),
m_counter(counter) {}
@ -755,14 +763,14 @@ public:
class Compare_x_on_boundary_2 {
private:
typename Base::Compare_x_on_boundary_2 m_object;
unsigned int& m_counter1;
unsigned int& m_counter2;
unsigned int& m_counter3;
size_t& m_counter1;
size_t& m_counter2;
size_t& m_counter3;
public:
/*! Construct */
Compare_x_on_boundary_2(const Base* base, unsigned int& counter1,
unsigned int& counter2, unsigned int& counter3 ) :
Compare_x_on_boundary_2(const Base* base, size_t& counter1,
size_t& counter2, size_t& counter3 ) :
m_object(base->compare_x_on_boundary_2_object()),
m_counter1(counter1),
m_counter2(counter2),
@ -794,12 +802,12 @@ public:
class Compare_x_near_boundary_2 {
private:
typename Base::Compare_x_near_boundary_2 m_object;
unsigned int& m_counter;
size_t& m_counter;
public:
/*! Construct */
Compare_x_near_boundary_2(const Base* base,
unsigned int& counter) :
size_t& counter) :
m_object(base->compare_x_near_boundary_2_object()),
m_counter(counter) {}
@ -945,12 +953,12 @@ public:
* \param doit indicates whethet to actually inceremnt the counter or not
* \return the counter at the end of the operation
*/
static unsigned int increment(bool doit = true)
static size_t increment(bool doit = true)
{
#ifdef CGAL_NO_ATOMIC
static unsigned int counter;
static size_t counter;
#else
static CGAL::cpp11::atomic<unsigned int> counter;
static CGAL::cpp11::atomic<size_t> counter;
#endif
if (doit) ++counter;
return counter;
@ -962,7 +970,7 @@ public:
private:
/*! The operation counters */
mutable unsigned int m_counters[NUMBER_OF_OPERATIONS];
mutable size_t m_counters[NUMBER_OF_OPERATIONS];
};
template <class Out_stream, class Base_traits>
@ -971,8 +979,8 @@ Out_stream& operator<<(Out_stream& os,
const Arr_counting_traits_2<Base_traits>& traits)
{
typedef Arr_counting_traits_2<Base_traits> Traits;
unsigned int sum = 0;
unsigned int i;
size_t sum = 0;
size_t i;
for (i = 0; i < Traits::NUMBER_OF_OPERATIONS; ++i)
sum += traits.count(static_cast<typename Traits::Operation_id>(i));
os << "# of COMPARE_X operation = "

View File

@ -27,8 +27,8 @@
#include <boost/utility/enable_if.hpp>
#include <boost/mpl/has_xxx.hpp>
#include <CGAL/Object.h>
#include <CGAL/tags.h>
#include <CGAL/assertions.h>
#include <CGAL/Arr_tags.h>
#include <CGAL/Arr_geometry_traits/Curve_data_aux.h>
@ -101,6 +101,12 @@ public:
/// \name Overriden functors.
//@{
//! \name Intersections & subdivisions
//@{
/*! \class Make_x_monotone_2
* A functor for subdividing a curve into x-monotone curves.
*/
class Make_x_monotone_2 {
private:
const Base_traits_2& m_base;
@ -109,36 +115,36 @@ public:
/*! Constructor. */
Make_x_monotone_2(const Base_traits_2& base) : m_base(base) {}
/*! Cut the given curve into x-monotone subcurves and insert them to the
* given output iterator. As segments are always x_monotone, only one
* x-monotone curve will be contained in the iterator.
* \param cv The curve.
* \param oi The output iterator, whose value-type is X_monotone_curve_2.
* \return The past-the-end iterator.
/*! Subdivide a given curve into x-monotone subcurves and insert them into
* a given output iterator.
* \param cv the curve.
* \param oi the output iterator for the result. Its value type is a variant
* that wraps Point_2 or an X_monotone_curve_2 objects.
* \return the past-the-end iterator.
*/
template<typename OutputIterator>
template <typename OutputIterator>
OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const
{
typedef boost::variant<Point_2, Base_x_monotone_curve_2>
Base_make_x_monotone_result;
typedef boost::variant<Point_2, X_monotone_curve_2>
Make_x_monotone_result;
// Make the original curve x-monotone.
std::list<CGAL::Object> base_objects;
std::list<Base_make_x_monotone_result> base_objects;
m_base.make_x_monotone_2_object()(cv, std::back_inserter(base_objects));
// Attach the data to each of the resulting x-monotone curves.
const Base_x_monotone_curve_2* base_x_curve;
X_monotone_curve_data xdata = Convert()(cv.data());
for (typename std::list<CGAL::Object>::const_iterator it =
base_objects.begin(); it != base_objects.end(); ++it)
{
base_x_curve = object_cast<Base_x_monotone_curve_2>(&(*it));
if (base_x_curve != nullptr) {
// Current object is an x-monotone curve: Attach data to it.
*oi++ = make_object(X_monotone_curve_2(*base_x_curve, xdata));
}
else {
// Current object is an isolated point: Leave it as is.
CGAL_assertion(object_cast<Point_2>(&(*it)) != nullptr);
*oi++ = *it;
for (const auto& base_obj : base_objects) {
if (const auto* bxcv = boost::get<Base_x_monotone_curve_2>(&base_obj)) {
*oi++ = Make_x_monotone_result(X_monotone_curve_2(*bxcv, xdata));
continue;
}
// Current object is an isolated point: Leave it as is.
const auto* bp = boost::get<Point_2>(&base_obj);
CGAL_assertion(bp);
*oi++ = Make_x_monotone_result(*bp);
}
return oi;
@ -359,6 +365,8 @@ public:
/*! Obtain a Merge_2 functor object. */
Merge_2 merge_2_object() const { return Merge_2(*this); }
//@}
class Construct_x_monotone_curve_2 {
private:
const Base_traits_2& m_base;

View File

@ -1358,8 +1358,9 @@ public:
/// \name Functor definitions for supporting intersections.
//@{
/*! A functor that divides an arc into x-monotone arcs. That are, arcs that
* do not cross the identification arc.
/*! \class Make_x_monotone_2
* A functor for subdividing arcs into x-monotone arcs that do not cross the
* identification arc.
*/
class Make_x_monotone_2 {
protected:
@ -1376,21 +1377,24 @@ public:
friend class Arr_geodesic_arc_on_sphere_traits_2<Kernel>;
public:
/*! Cut the given curve into x-monotone subcurves and insert them into the
* given output iterator. As spherical_arcs are always x_monotone, only one
* object will be contained in the iterator.
/*! Subdivide a given curve into x-monotone subcurves and insert them into
* a given output iterator. As spherical_arcs are always x_monotone, only
* one object will be contained in the iterator.
* \param xc the curve.
* \param oi the output iterator, whose value-type is Object. The output
* object is a wrapper of either an X_monotone_curve_2, or - in
* case the input spherical_arc is degenerate - a Point_2 object.
* \param oi the output iterator for the result. Its dereference type is a
* variant that wraps a \c Point_2 or an \c X_monotone_curve_2
* objects.
* \return the past-the-end iterator.
*/
template<typename OutputIterator>
template <typename OutputIterator>
OutputIterator operator()(const Curve_2& c, OutputIterator oi) const
{
typedef boost::variant<Point_2, X_monotone_curve_2>
Make_x_monotone_result;
if (c.is_degenerate()) {
// The spherical_arc is a degenerate point - wrap it with an object:
*oi++ = make_object(c.right());
*oi++ = Make_x_monotone_result(c.right());
return oi;
}
@ -1398,7 +1402,7 @@ public:
// The spherical arc is monotone - wrap it with an object:
// *oi++ = make_object(X_monotone_curve_2(c));
const X_monotone_curve_2* xc = &c;
*oi++ = make_object(*xc);
*oi++ = Make_x_monotone_result(*xc);
return oi;
}
@ -1410,14 +1414,14 @@ public:
const Direction_3& pp = m_traits->pos_pole();
X_monotone_curve_2 xc1(np, pp, c.normal(), true, true);
X_monotone_curve_2 xc2(pp, np, c.normal(), true, false);
*oi++ = make_object(xc1);
*oi++ = make_object(xc2);
*oi++ = Make_x_monotone_result(xc1);
*oi++ = Make_x_monotone_result(xc2);
return oi;
}
#if defined(CGAL_FULL_X_MONOTONE_GEODESIC_ARC_ON_SPHERE_IS_SUPPORTED)
// The arc is not vertical => break it at the discontinuity arc:
const X_monotone_curve_2 xc(c.normal());
*oi++ = make_object(xc);
*oi++ = Make_x_monotone_result(xc);
#else
// Full x-monotone arcs are not supported!
// Split the arc at the intersection point with the complement of the
@ -1428,8 +1432,8 @@ public:
Direction_3 d2(normal.dz(), 0, -(normal.dx()));
X_monotone_curve_2 xc1(d1, d2, normal, false, directed_right);
X_monotone_curve_2 xc2(d2, d1, normal, false, directed_right);
*oi++ = make_object(xc1);
*oi++ = make_object(xc2);
*oi++ = Make_x_monotone_result(xc1);
*oi++ = Make_x_monotone_result(xc2);
#endif
return oi;
}
@ -1447,16 +1451,16 @@ public:
if (source.is_min_boundary() || target.is_min_boundary()) {
X_monotone_curve_2 xc1(source, pp, normal, true, true);
X_monotone_curve_2 xc2(pp, target, normal, true, false);
*oi++ = make_object(xc1);
*oi++ = make_object(xc2);
*oi++ = Make_x_monotone_result(xc1);
*oi++ = Make_x_monotone_result(xc2);
return oi;
}
if (source.is_max_boundary() || target.is_max_boundary()) {
X_monotone_curve_2 xc1(source, np, normal, true, false);
X_monotone_curve_2 xc2(np, target, normal, true, true);
*oi++ = make_object(xc1);
*oi++ = make_object(xc2);
*oi++ = Make_x_monotone_result(xc1);
*oi++ = Make_x_monotone_result(xc2);
return oi;
}
@ -1476,19 +1480,19 @@ public:
(!plane_is_positive && !s_is_positive));
const Point_2& pole1 = (ccw) ? pp : np;
X_monotone_curve_2 xc1(source, pole1, normal, true, ccw);
*oi++ = make_object(xc1);
*oi++ = Make_x_monotone_result(xc1);
if (s_is_positive != t_is_positive) {
// Construct 1 more arc:
X_monotone_curve_2 xc2(pole1, target, normal, true, !ccw);
*oi++ = make_object(xc2);
*oi++ = Make_x_monotone_result(xc2);
return oi;
}
// Construct 2 more arcs:
const Point_2& pole2 = (ccw) ? np : pp;
X_monotone_curve_2 xc2(pole1, pole2, normal, true, !ccw);
*oi++ = make_object(xc2);
*oi++ = Make_x_monotone_result(xc2);
X_monotone_curve_2 xc3(pole2, target, normal, true, ccw);
*oi++ = make_object(xc3);
*oi++ = Make_x_monotone_result(xc3);
return oi;
}
@ -1514,8 +1518,8 @@ public:
X_monotone_curve_2 xc1(source, p, normal, false, directed_right);
X_monotone_curve_2 xc2(p, target, normal, false, directed_right);
*oi++ = make_object(xc1);
*oi++ = make_object(xc2);
*oi++ = Make_x_monotone_result(xc1);
*oi++ = Make_x_monotone_result(xc2);
return oi;
}
};

View File

@ -197,49 +197,51 @@ public:
/*! Intersect 2 planes
* \param plane1 the first plane
* \param plane2 the second plane
* \return a geometric object that represents the intersection. Could be
* the line of intersection, or a plane in case plane1 and plane2 coincide.
* \return a variant that represents the intersection. It wraps a line of
* intersection or a plane in case plane1 and plane2 coincide.
*/
template <class Kernel>
CGAL::Object intersect(const Arr_plane_3<Kernel> & plane1,
template <typname Kernel>
boost::variant<typename Kernel::Line_3, Arr_plane_3<Kernel> >
intersect(const Arr_plane_3<Kernel> & plane1,
const Arr_plane_3<Kernel> & plane2)
{
typedef typename Kernel::Point_3 Point_3;
typedef typename Kernel::Direction_3 Direction_3;
typedef typename Kernel::Line_3 Line_3;
typedef typename Kernel::FT FT;
typedef boost::variant<Line_3, Arr_plane_3<Kernel> > Intersection_result;
// We know that the plane goes throgh the origin
const FT & a1 = plane1.a();
const FT & b1 = plane1.b();
const FT & c1 = plane1.c();
const FT& a1 = plane1.a();
const FT& b1 = plane1.b();
const FT& c1 = plane1.c();
const FT & a2 = plane2.a();
const FT & b2 = plane2.b();
const FT & c2 = plane2.c();
const FT& a2 = plane2.a();
const FT& b2 = plane2.b();
const FT& c2 = plane2.c();
FT det = a1*b2 - a2*b1;
if (det != 0) {
Point_3 is_pt = Point_3(0, 0, 0, det);
Direction_3 is_dir = Direction_3(b1*c2 - c1*b2, a2*c1 - a1*c2, det);
return make_object(Line_3(is_pt, is_dir));
return Intersection_result(Line_3(is_pt, is_dir));
}
det = a1*c2 - a2*c1;
if (det != 0) {
Point_3 is_pt = Point_3(0, 0, 0, det);
Direction_3 is_dir = Direction_3(c1*b2 - b1*c2, det, a2*b1 - a1*b2);
return make_object(Line_3(is_pt, is_dir));
return Intersection_result(Line_3(is_pt, is_dir));
}
det = b1*c2 - c1*b2;
if (det != 0) {
Point_3 is_pt = Point_3(0, 0, 0, det);
Direction_3 is_dir = Direction_3(det, c1*a2 - a1*c2, a1*b2 - b1*a2);
return make_object(Line_3(is_pt, is_dir));
return Intersection_result(Line_3(is_pt, is_dir));
}
// degenerate case
return make_object(plane1);
return Intersection_result(plane1);
}
/*! Compute the image point of the projection of p under an affine

View File

@ -1262,36 +1262,26 @@ private:
// the intersection of the two skewed bounding boxes.
Bez_point_bbox ipt_bbox;
Control_points aux_vec;
CGAL::Object res;
Point_2 p;
res = f_intersect (skew1a, skew2a);
if (! assign (p, res))
{
CGAL_error();
}
aux_vec.push_back(p);
auto res1 = f_intersect(skew1a, skew2a);
const Point_2* p1 = boost::get<Point_2>(&*res1);
if (! p1) CGAL_error();
aux_vec.push_back(*p1);
res = f_intersect (skew1a, skew2b);
if (! assign(p, res))
{
CGAL_error();
}
aux_vec.push_back(p);
auto res2 = f_intersect(skew1a, skew2b);
const Point_2* p2 = boost::get<Point_2>(&*res2);
if (! p2) CGAL_error();
aux_vec.push_back(*p2);
res = f_intersect (skew1b, skew2a);
if (! assign(p, res))
{
CGAL_error();
}
aux_vec.push_back(p);
auto res3 = f_intersect(skew1b, skew2a);
const Point_2* p3 = boost::get<Point_2>(&*res3);
if (! p3) CGAL_error();
aux_vec.push_back(*p3);
res = f_intersect (skew1b, skew2b);
if (!assign(p, res))
{
CGAL_error();
}
aux_vec.push_back(p);
auto res4 = f_intersect (skew1b, skew2b);
const Point_2* p4 = boost::get<Point_2>(&*res4);
if (! p4) CGAL_error();
aux_vec.push_back(*p4);
construct_bbox (aux_vec, ipt_bbox);

View File

@ -27,6 +27,10 @@
* Arrangement_2 package, which it is now part of. It contains a traits
* class for the arrangement package that handles linear curves.
* It is based on the circular kernel.
*
* \todo Fix the circular-kernel make-x-monotone functor to use modern variant
* instead of the legacy CGAL::Object. Then, eliminate the special
* implementation here and directly use the kernel functor instead.
*/
#include <CGAL/basic.h>
@ -73,7 +77,7 @@ public:
typedef typename CircularKernel::Compare_y_at_x_2 Compare_y_at_x_2;
typedef typename CircularKernel::Compare_y_to_right_2 Compare_y_at_x_right_2;
typedef typename CircularKernel::Equal_2 Equal_2;
typedef typename CircularKernel::Make_x_monotone_2 Make_x_monotone_2;
// typedef typename CircularKernel::Make_x_monotone_2 Make_x_monotone_2;
typedef typename CircularKernel::Split_2 Split_2;
typedef typename CircularKernel::Construct_circular_min_vertex_2
Construct_min_vertex_2;
@ -97,8 +101,8 @@ public:
Equal_2 equal_2_object() const
{ return ck.equal_2_object(); }
Make_x_monotone_2 make_x_monotone_2_object() const
{ return ck.make_x_monotone_2_object(); }
// Make_x_monotone_2 make_x_monotone_2_object() const
// { return ck.make_x_monotone_2_object(); }
Split_2 split_2_object() const
{ return ck.split_2_object(); }
@ -115,7 +119,20 @@ public:
Is_vertical_2 is_vertical_2_object() const
{ return ck.is_vertical_2_object();}
//! A functor for subdividing curves into x-monotone curves.
class Make_x_monotone_2 {
public:
template <typename OutputIterator>
OutputIterator operator()(const Curve_2& line, OutputIterator oi) const
{
typedef boost::variant<Point_2, X_monotone_curve_2> Make_x_monotone_result;
*oi++ = Make_x_monotone_result(line);
return oi;
}
};
Make_x_monotone_2 make_x_monotone_2_object() const
{ return Make_x_monotone_2(); }
};
} // namespace CGAL

View File

@ -1239,16 +1239,18 @@ public:
* given output iterator. As segments are always x_monotone, only one
* object will be contained in the iterator.
* \param cv The curve.
* \param oi The output iterator, whose value-type is Object. The output
* object is a wrapper of an X_monotone_curve_2 which is
* essentially the same as the input curve.
* \param oi an output iterator for the result. Its dereference type is a
* variant that wraps a \c Point_2 or an \c X_monotone_curve_2
* objects.
* \return The past-the-end iterator.
*/
template <typename OutputIterator>
OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const
{
// Wrap the curve with an object.
*oi++ = make_object(cv);
// Wrap the segment with a variant.
typedef boost::variant<Point_2, X_monotone_curve_2>
Make_x_monotone_result;
*oi++ = Make_x_monotone_result(cv);
return oi;
}
};

View File

@ -7,14 +7,14 @@
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s) : Efi Fogel <efif@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
// (based on old version by: Iddo Hanniel,
// Eyal Flato,
// Oren Nechushtan,
// Ester Ezra,
// Shai Hirsch,
// and Eugene Lipovetsky)
// Author(s): Efi Fogel <efif@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
// (based on old version by: Iddo Hanniel,
// Eyal Flato,
// Oren Nechushtan,
// Ester Ezra,
// Shai Hirsch,
// and Eugene Lipovetsky)
#ifndef CGAL_ARR_NON_CACHING_SEGMENT_BASIC_TRAITS_2_H
#define CGAL_ARR_NON_CACHING_SEGMENT_BASIC_TRAITS_2_H

View File

@ -113,24 +113,27 @@ public:
// Traits types:
typedef X_monotone_curve_2 Curve_2;
/*! \class
* A functor for splitting curves into x-monotone pieces.
/*! \class Make_x_monotone_2
* A functor for subdividing a curve into x-monotone curves.
*/
class Make_x_monotone_2 {
public:
/*! Cut the given segment into x-monotone subcurves and insert them into
* the given output iterator. As segments are always x_monotone, only one
/*! Subdivide a given curve into x-monotone subcurves and insert them into
* a given output iterator. As segments are always x_monotone, only one
* x-monotone curve is inserted into the output iterator.
* \param cv The segment.
* \param oi The output iterator, whose value-type is Object. The output
* object is a wrapper of an X_monotone_curve_2 object.
* \return The past-the-end iterator.
* \param cv the segment.
* \param oi the output iterator for the result. Its dereference type is a
* variant that wraps a \c Point_2 or an \c X_monotone_curve_2
* objects.
* \return the past-the-end iterator.
*/
template <typename OutputIterator>
OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const
{
*oi++ = make_object(cv);
// Wrap the segment with a variant.
typedef boost::variant<Point_2, X_monotone_curve_2>
Make_x_monotone_result;
*oi++ = Make_x_monotone_result(cv);
return oi;
}
};

View File

@ -42,6 +42,7 @@ public:
typedef typename Base_traits_2::X_monotone_curve_2 Base_x_monotone_curve_2;
typedef typename Base_traits_2::Point_2 Base_point_2;
typedef typename Base_traits_2::Multiplicity Multiplicity;
typedef typename Base_traits_2::Construct_min_vertex_2
Base_construct_min_vertex_2;

View File

@ -56,15 +56,15 @@ Arr_landmarks_point_location<Arr, Gen>::locate(const Point_2& p) const
const Vertex_const_handle* vh;
const Halfedge_const_handle* hh;
const Face_const_handle* fh;
if ( ( vh = Result().template assign<Vertex_const_handle>(lm_location_obj) ) )
if ( ( vh = Result().template assign<Vertex_const_handle>(&lm_location_obj) ) )
out_obj = _walk_from_vertex(*vh, p, crossed_edges);
else if ( ( hh = Result().template assign<Halfedge_const_handle>(lm_location_obj) ) )
else if ( ( hh = Result().template assign<Halfedge_const_handle>(&lm_location_obj) ) )
out_obj = _walk_from_edge(*hh, landmark_point, p, crossed_edges);
else if ( ( fh = Result().template assign<Face_const_handle>(lm_location_obj) ) )
else if ( ( fh = Result().template assign<Face_const_handle>(&lm_location_obj) ) )
out_obj = _walk_from_face(*fh, landmark_point, p, crossed_edges);
else CGAL_error_msg("lm_location_obj of an unknown type.");
if ( ( fh = Result().template assign<Face_const_handle>(out_obj) ) ) {
if ( ( fh = Result().template assign<Face_const_handle>(&out_obj) ) ) {
// If we reached here, we did not locate the query point in any of the
// holes inside the current face, so we conclude it is contained in this
// face.
@ -159,7 +159,7 @@ _walk_from_vertex(Vertex_const_handle nearest_vertex,
if (new_vertex) {
// We found a vertex closer to p; Continue using this vertex.
const Vertex_const_handle* p_vh =
Result().template assign<Vertex_const_handle>(obj);
Result().template assign<Vertex_const_handle>(&obj);
CGAL_assertion(p_vh != nullptr);
vh = *p_vh;
continue;
@ -167,11 +167,12 @@ _walk_from_vertex(Vertex_const_handle nearest_vertex,
// If p is located on an edge or on a vertex, return the object
// that wraps this arrangement feature.
if (Result().template assign<Halfedge_const_handle>(obj) ||
Result().template assign<Vertex_const_handle>(obj))
if (Result().template assign<Halfedge_const_handle>(&obj) ||
Result().template assign<Vertex_const_handle>(&obj))
return obj;
const Face_const_handle* p_fh = Result().template assign<Face_const_handle>(obj);
const Face_const_handle* p_fh =
Result().template assign<Face_const_handle>(&obj);
if (p_fh)
// Walk to p from the face we have located:
return _walk_from_face(*p_fh, vh->point(), p, crossed_edges);

View File

@ -44,10 +44,8 @@ Arr_simple_point_location<Arrangement>::locate(const Point_2& p) const
// Go over arrangement halfedges and check whether one of them contains
// the query point in its interior.
typename Traits_adaptor_2::Is_in_x_range_2 is_in_x_range =
m_geom_traits->is_in_x_range_2_object();
typename Traits_adaptor_2::Compare_y_at_x_2 cmp_y_at_x =
m_geom_traits->compare_y_at_x_2_object();
auto is_in_x_range = m_geom_traits->is_in_x_range_2_object();
auto cmp_y_at_x = m_geom_traits->compare_y_at_x_2_object();
typename Arrangement::Edge_const_iterator eit;
for (eit = m_arr->edges_begin(); eit != m_arr->edges_end(); ++eit) {
@ -71,14 +69,14 @@ Arr_simple_point_location<Arrangement>::locate(const Point_2& p) const
// In case the ray-shooting returned a vertex, we have to locate the first
// halfedge whose source vertex is v, rotating clockwise around the vertex
// from "6 o'clock", and to return its incident face.
const Vertex_const_handle* vh = Result().template assign<Vertex_const_handle>(obj);
const auto* vh = Result::template assign<Vertex_const_handle>(&obj);
if (vh) {
Halfedge_const_handle hh = _first_around_vertex(*vh);
Face_const_handle fh = hh->face();
return make_result(fh);
}
const Halfedge_const_handle* hh = Result().template assign<Halfedge_const_handle>(obj);
const auto* hh = Result::template assign<Halfedge_const_handle>(&obj);
if (hh) {
// Make sure that the edge is directed from right to left, so that p
// (which lies below it) is contained in its incident face. If necessary,
@ -288,14 +286,13 @@ Arr_simple_point_location<Arrangement>::_vertical_ray_shoot(const Point_2& p,
if (! optional_empty(optional_obj)) {
const Result_type& obj = optional_assign(optional_obj);
const Vertex_const_handle* p_vh = Result().template assign<Vertex_const_handle>(obj);
const auto* p_vh = Result::template assign<Vertex_const_handle>(&obj);
if (p_vh) {
found_vertex = true;
closest_v = *p_vh;
}
else {
const Halfedge_const_handle* p_hh =
Result().template assign<Halfedge_const_handle>(obj);
const auto* p_hh = Result::template assign<Halfedge_const_handle>(&obj);
CGAL_assertion(p_hh != nullptr);
found_halfedge = true;
closest_he = *p_hh;

View File

@ -618,7 +618,8 @@ _is_in_connected_component (const Point_2& p,
// The current curve is not vertical. Check the query point is in the
// semi-open x-range (source, target] of this curve and lies below it.
if (source_res != EQUAL) {
if (closest_he == invalid_he || (closest_he->twin() == curr)) {
if ((closest_he == invalid_he) ||
(closest_he->twin() == Halfedge_const_handle(curr))) {
// 1. If we have no closests halfedge, we have just found one.
// 2. If the closest halfedge is the twin of our current halfedge,
// we can take our halfedge to be the closest one. This covers the
@ -701,7 +702,7 @@ _is_in_connected_component (const Point_2& p,
do {
next_non_vert = next_non_vert->next();
CGAL_assertion (next_non_vert != curr);
CGAL_assertion(next_non_vert != Halfedge_const_handle(curr));
}
while ((! next_non_vert->is_fictitious() &&
is_vertical(next_non_vert->curve())) ||

View File

@ -78,32 +78,34 @@ struct Arr_point_location_result {
// lead to conversion overhead, and so we rather go for the real type.
// Overloads for empty returns are also provided.
#if CGAL_ARR_POINT_LOCATION_VERSION < 2
template<typename T>
template <typename T>
static
inline CGAL::Object make_result(T t) { return CGAL::make_object(t); }
inline Type make_result(T t) { return CGAL::make_object(t); }
static
inline CGAL::Object empty_optional_result() { return CGAL::Object(); }
template<typename T>
const T* assign(CGAL::Object obj) const { return CGAL::object_cast<T>(&obj); }
template <typename T>
static
inline const T* assign(const Type* obj) { return CGAL::object_cast<T>(obj); }
#else
template<typename T>
template <typename T>
static
inline Type make_result(T t) { return Type(t); }
inline
static
boost::optional<Type> empty_optional_result() { return boost::optional<Type>(); }
inline boost::optional<Type> empty_optional_result()
{ return boost::optional<Type>(); }
template<typename T>
const T* assign(const Type& obj) const { return boost::get<T>(&obj); }
template <typename T>
static
inline const T* assign(const Type* obj) { return boost::get<T>(obj); }
#endif // CGAL_ARR_POINT_LOCATION_VERSION < 2
//this one is only to remove warnings in functions
static
inline Type default_result(){
CGAL_error_msg("This functions should never have been called!");
CGAL_error_msg("This functions should have never been called!");
return Type();
}
};

View File

@ -63,6 +63,7 @@ public:
typedef typename Subcurve_traits_2::Point_2 Point_2;
typedef typename Subcurve_traits_2::X_monotone_curve_2 X_monotone_subcurve_2;
typedef typename Subcurve_traits_2::Multiplicity Multiplicity;
//@}

View File

@ -7,10 +7,10 @@
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s) : Efi Fogel <efif@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
// Dror Atariah <dror.atariah@fu-berlin.de>
// Waqar Khan <wkhan@mpi-inf.mpg.de>
// Author(s): Efi Fogel <efif@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
// Dror Atariah <dror.atariah@fu-berlin.de>
// Waqar Khan <wkhan@mpi-inf.mpg.de>
#ifndef CGAL_ARR_POLYCURVE_TRAITS_2_H
#define CGAL_ARR_POLYCURVE_TRAITS_2_H
@ -160,10 +160,8 @@ public:
#ifndef DOXYGEN_RUNNING
class Push_back_2;
#endif
/*! \class
* A functor that divides an arc into x-monotone arcs. That are, arcs that
* do not cross the identification arc.
*/
//! A functor for subdividing curves into x-monotone curves.
class Make_x_monotone_2 {
protected:
typedef Arr_polycurve_traits_2<Subcurve_traits_2> Polycurve_traits_2;
@ -176,21 +174,24 @@ public:
m_poly_traits(traits)
{}
/*! Cut the given curve into x-monotone sub-curves and insert them into the
* given output iterator.
/*! Subdivide a given curve into x-monotone sub-curves and insert them into
* a given output iterator.
*
* \pre if `cv` is not empty then it must be continuous and well-oriented.
* \param cv The curve.
* \param oi The output iterator, whose value-type is Object. The output
* object is a wrapper of a X_monotone_curve_2.
* \return The past-the-end iterator.
* \param cv the curve.
* \param oi an output iterator for the result. Its value type is a variant
* that wraps Point_2 or an X_monotone_curve_2 objects.
* \return the past-the-end iterator.
*/
private:
template <typename OutputIterator>
OutputIterator operator_impl(const Curve_2& cv, OutputIterator oi,
Arr_all_sides_oblivious_tag) const
{
typedef typename Curve_2::Subcurve_const_iterator const_seg_iterator;
typedef boost::variant<Point_2, X_monotone_subcurve_2>
Make_x_monotone_subresult;
typedef boost::variant<Point_2, X_monotone_curve_2>
Make_x_monotone_result;
// If the polycurve is empty, return.
if (cv.number_of_subcurves() == 0) return oi;
@ -204,33 +205,29 @@ public:
m_poly_traits.subcurve_traits_2()->compare_endpoints_xy_2_object();
#ifdef CGAL_ALWAYS_LEFT_TO_RIGHT
typename Subcurve_traits_2::Construct_opposite_2 ctr_seg_opposite =
auto ctr_seg_opposite =
m_poly_traits.subcurve_traits_2()->construct_opposite_2_object();
#endif
// Convert the input polycurve to a sequence of CGAL objects, such
// that each Object wraps an x-monotone subcurve.
std::vector<Object> x_seg_objects;
const_seg_iterator it_segs;
for (it_segs = cv.subcurves_begin(); it_segs != cv.subcurves_end();
++it_segs)
make_seg_x_monotone(*it_segs, std::back_inserter(x_seg_objects));
typename std::vector<Object>::iterator it = x_seg_objects.begin();
X_monotone_subcurve_2 x_seg;
#if defined (CGAL_NO_ASSERTIONS)
CGAL::assign(x_seg, *it);
#else
bool assign_res = CGAL::assign(x_seg, *it);
CGAL_assertion(assign_res);
// Convert the input polycurve to a sequence of variant objects, such
// that each object wraps an x-monotone subcurve.
std::vector<Make_x_monotone_subresult> x_seg_objects;
for (auto its = cv.subcurves_begin(); its != cv.subcurves_end(); ++its)
make_seg_x_monotone(*its, std::back_inserter(x_seg_objects));
auto it = x_seg_objects.begin();
const auto* x_seg_p = boost::get<X_monotone_subcurve_2>(&(*it));
#if ! defined (CGAL_NO_ASSERTIONS)
CGAL_assertion(x_seg_p != nullptr);
#endif
// If the polycurve consists of a single x-monotone subcurve, return.
if (x_seg_objects.size() == 1) {
#ifdef CGAL_ALWAYS_LEFT_TO_RIGHT
if (cmp_seg_endpts(x_seg) == LARGER)
x_seg = ctr_seg_opposite(x_seg);
*oi++ = Make_x_monotone_result(ctr_x_curve(ctr_seg_opposite(*x_seg_p))); else *oi++ = Make_x_monotone_result(ctr_x_curve(*x_seg_p));
#else
*oi++ = Make_x_monotone_result(ctr_x_curve(*x_seg_p));
#endif
*oi++ = make_object(ctr_x_curve(x_seg));
x_seg_objects.clear();
return oi;
}
@ -244,39 +241,38 @@ public:
auto max_seg_v =
m_poly_traits.subcurve_traits_2()->construct_max_vertex_2_object();
auto equal = m_poly_traits.subcurve_traits_2()->equal_2_object();
Point_2 last_target = (cmp_seg_endpts(x_seg) == SMALLER) ?
max_seg_v(x_seg) : min_seg_v(x_seg);
Point_2 last_target = (cmp_seg_endpts(*x_seg_p) == SMALLER) ?
max_seg_v(*x_seg_p) : min_seg_v(*x_seg_p);
Point_2 next_src;
);
// The polycurve consists of at least 2 x-monotone subcurves:
Push_back_2 push_back = m_poly_traits.push_back_2_object();
typename Subcurve_traits_2::Is_vertical_2 is_seg_vertical =
auto is_seg_vertical =
m_poly_traits.subcurve_traits_2()->is_vertical_2_object();
bool is_start_vertical = is_seg_vertical(x_seg);
Comparison_result start_dir = cmp_seg_endpts(x_seg);
bool is_start_vertical = is_seg_vertical(*x_seg_p);
Comparison_result start_dir = cmp_seg_endpts(*x_seg_p);
#ifdef CGAL_ALWAYS_LEFT_TO_RIGHT
Push_front_2 push_front = m_poly_traits.push_front_2_object();
if (cmp_seg_endpts(x_seg) == LARGER) x_seg = ctr_seg_opposite(x_seg);
#endif
X_monotone_curve_2 x_polycurve = ctr_x_curve(x_seg);
for (++it; it != x_seg_objects.end(); ++it){
X_monotone_subcurve_2 x_seg;
#if defined (CGAL_NO_ASSERTIONS)
CGAL::assign(x_seg, *it);
X_monotone_curve_2 x_polycurve = (cmp_seg_endpts(x_seg) == LARGER) ?
ctr_x_curve(ctr_seg_opposite(*x_seg_p)) : ctr_x_curve(*x_seg_p);
#else
bool assign_res = CGAL::assign(x_seg, *it);
CGAL_assertion(assign_res);
X_monotone_curve_2 x_polycurve = ctr_x_curve(*x_seg_p);
#endif
for (++it; it != x_seg_objects.end(); ++it) {
const auto* x_seg_p = boost::get<X_monotone_subcurve_2>(&(*it));
#if ! defined (CGAL_NO_ASSERTIONS)
CGAL_assertion(x_seg_p != nullptr);
#endif
// Test that cv is continuous and well-oriented.
CGAL_precondition_code
(
next_src = (cmp_seg_endpts(x_seg) == SMALLER) ?
min_seg_v(x_seg) : max_seg_v(x_seg);
next_src = (cmp_seg_endpts(*x_seg_p) == SMALLER) ?
min_seg_v(*x_seg_p) : max_seg_v(*x_seg_p);
);
CGAL_precondition_msg
(
@ -285,46 +281,50 @@ public:
);
CGAL_precondition_code
(
last_target = (cmp_seg_endpts(x_seg) == SMALLER) ?
max_seg_v(x_seg) : min_seg_v(x_seg);
last_target = (cmp_seg_endpts(*x_seg_p) == SMALLER) ?
max_seg_v(*x_seg_p) : min_seg_v(*x_seg_p);
);
if ((cmp_seg_endpts(x_seg) != start_dir) ||
(is_seg_vertical(x_seg) != is_start_vertical))
if ((cmp_seg_endpts(*x_seg_p) != start_dir) ||
(is_seg_vertical(*x_seg_p) != is_start_vertical))
{
// Construct an x-monotone curve from the sub-range which was found
*oi++ = make_object(x_polycurve);
is_start_vertical = is_seg_vertical(x_seg);
start_dir = cmp_seg_endpts(x_seg);
*oi++ = Make_x_monotone_result(x_polycurve);
is_start_vertical = is_seg_vertical(*x_seg_p);
start_dir = cmp_seg_endpts(*x_seg_p);
#ifdef CGAL_ALWAYS_LEFT_TO_RIGHT
if (cmp_seg_endpts(x_seg) == LARGER) x_seg = ctr_seg_opposite(x_seg);
x_polycurve = (cmp_seg_endpts(*x_seg_p) == LARGER) ?
ctr_x_curve(ctr_seg_opposite(*x_seg_p)) : ctr_x_curve(*x_seg_p);
#else
x_polycurve = ctr_x_curve(*x_seg_p);
#endif
x_polycurve = ctr_x_curve(x_seg);
}
else {
#ifdef CGAL_ALWAYS_LEFT_TO_RIGHT
if (cmp_seg_endpts(x_seg) == LARGER) {
x_seg = ctr_seg_opposite(x_seg);
push_front(x_polycurve, x_seg);
}
if (cmp_seg_endpts(*x_seg_p) == LARGER)
push_front(x_polycurve, ctr_seg_opposite(*x_seg_p));
else
push_back(x_polycurve, x_seg);
push_back(x_polycurve, *x_seg_p);
#else
push_back(x_polycurve, x_seg);
push_back(x_polycurve, *x_seg_p);
#endif
}
} // for loop
if (x_polycurve.number_of_subcurves() != 0)
*oi++ = make_object(x_polycurve);
*oi++ = Make_x_monotone_result(x_polycurve);
x_seg_objects.clear();
return oi;
}
template <typename OutputIterator>
OutputIterator operator_impl(const Curve_2& cv, OutputIterator oi,
Arr_not_all_sides_oblivious_tag) const
{
typedef typename Curve_2::Subcurve_const_iterator const_seg_iterator;
typedef boost::variant<Point_2, X_monotone_subcurve_2>
Make_x_monotone_subresult;
typedef boost::variant<Point_2, X_monotone_curve_2>
Make_x_monotone_result;
// If the polycurve is empty, return.
if (cv.number_of_subcurves() == 0) return oi;
@ -347,29 +347,25 @@ public:
m_poly_traits.subcurve_traits_2()->construct_opposite_2_object();
#endif
// Convert the input polycurve to a sequence of CGAL objects, such
// that each Object wraps an x-monotone subcurve.
std::vector<Object> x_seg_objects;
const_seg_iterator it_segs;
for (it_segs = cv.subcurves_begin(); it_segs != cv.subcurves_end();
++it_segs)
make_seg_x_monotone(*it_segs, std::back_inserter(x_seg_objects));
typename std::vector<Object>::iterator it = x_seg_objects.begin();
X_monotone_subcurve_2 x_seg;
#if defined (CGAL_NO_ASSERTIONS)
CGAL::assign(x_seg, *it);
#else
bool assign_res = CGAL::assign(x_seg, *it);
CGAL_assertion(assign_res);
// Convert the input polycurve to a sequence of objects, such that
// each object wraps an x-monotone subcurve.
std::vector<Make_x_monotone_subresult> x_seg_objects;
for (auto its = cv.subcurves_begin(); its != cv.subcurves_end(); ++its)
make_seg_x_monotone(*its, std::back_inserter(x_seg_objects));
auto it = x_seg_objects.begin();
const auto* x_seg_p = boost::get<X_monotone_subcurve_2>(&(*it));
#if ! defined (CGAL_NO_ASSERTIONS)
CGAL_assertion(x_seg_p != nullptr);
#endif
// If the polycurve consists of a single x-monotone subcurve, return.
if (x_seg_objects.size() == 1) {
#ifdef CGAL_ALWAYS_LEFT_TO_RIGHT
if (cmp_seg_endpts(x_seg) == LARGER)
x_seg = ctr_seg_opposite(x_seg);
*oi++ = Make_x_monotone_result(ctr_x_curve(ctr_seg_opposite(*x_seg_p))); else *oi++ = Make_x_monotone_result(ctr_x_curve(*x_seg_p));
#else
*oi++ = Make_x_monotone_result(ctr_x_curve(*x_seg_p));
#endif
*oi++ = make_object(ctr_x_curve(x_seg));
x_seg_objects.clear();
return oi;
}
@ -383,39 +379,38 @@ public:
auto max_seg_v =
m_poly_traits.subcurve_traits_2()->construct_max_vertex_2_object();
auto equal = m_poly_traits.subcurve_traits_2()->equal_2_object();
Point_2 last_target = (cmp_seg_endpts(x_seg) == SMALLER) ?
max_seg_v(x_seg) : min_seg_v(x_seg);
Point_2 last_target = (cmp_seg_endpts(*x_seg_p) == SMALLER) ?
max_seg_v(*x_seg_p) : min_seg_v(*x_seg_p);
Point_2 next_src;
);
// The polycurve consists of at least 2 x-monotone subcurves:
Push_back_2 push_back = m_poly_traits.push_back_2_object();
typename Subcurve_traits_2::Is_vertical_2 is_seg_vertical =
auto is_seg_vertical =
m_poly_traits.subcurve_traits_2()->is_vertical_2_object();
bool is_start_vertical = is_seg_vertical(x_seg);
Comparison_result start_dir = cmp_seg_endpts(x_seg);
bool is_start_vertical = is_seg_vertical(*x_seg_p);
Comparison_result start_dir = cmp_seg_endpts(*x_seg_p);
#ifdef CGAL_ALWAYS_LEFT_TO_RIGHT
Push_front_2 push_front = m_poly_traits.push_front_2_object();
if (cmp_seg_endpts(x_seg) == LARGER) x_seg = ctr_seg_opposite(x_seg);
#endif
X_monotone_curve_2 x_polycurve = ctr_x_curve(x_seg);
for (++it; it != x_seg_objects.end(); ++it){
X_monotone_subcurve_2 x_seg;
#if defined (CGAL_NO_ASSERTIONS)
CGAL::assign(x_seg, *it);
X_monotone_curve_2 x_polycurve = (cmp_seg_endpts(x_seg) == LARGER) ?
ctr_x_curve(ctr_seg_opposite(*x_seg_p)) : ctr_x_curve(*x_seg_p);
#else
bool assign_res = CGAL::assign(x_seg, *it);
CGAL_assertion(assign_res);
X_monotone_curve_2 x_polycurve = ctr_x_curve(*x_seg_p);
#endif
for (++it; it != x_seg_objects.end(); ++it) {
const auto* x_seg_p = boost::get<X_monotone_subcurve_2>(&(*it));
#if ! defined (CGAL_NO_ASSERTIONS)
CGAL_assertion(x_seg_p != nullptr);
#endif
// Test that cv is continuous and well-oriented.
CGAL_precondition_code
(
next_src = (cmp_seg_endpts(x_seg) == SMALLER) ?
min_seg_v(x_seg) : max_seg_v(x_seg);
next_src = (cmp_seg_endpts(*x_seg_p) == SMALLER) ?
min_seg_v(*x_seg_p) : max_seg_v(*x_seg_p);
);
CGAL_precondition_msg
(
@ -424,59 +419,61 @@ public:
);
CGAL_precondition_code
(
last_target = (cmp_seg_endpts(x_seg) == SMALLER) ?
max_seg_v(x_seg) : min_seg_v(x_seg);
last_target = (cmp_seg_endpts(*x_seg_p) == SMALLER) ?
max_seg_v(*x_seg_p) : min_seg_v(*x_seg_p);
);
Arr_curve_end polycurve_target =
(cmp_seg_endpts(x_polycurve[0]) == SMALLER) ?
ARR_MAX_END : ARR_MIN_END;
Arr_curve_end seg_source = (cmp_seg_endpts(x_seg) == SMALLER) ?
ARR_MIN_END : ARR_MAX_END;
unsigned int num_segs = x_polycurve.number_of_subcurves();
Arr_curve_end polycurve_target =
(cmp_seg_endpts(x_polycurve[0]) == SMALLER) ?
ARR_MAX_END : ARR_MIN_END;
Arr_curve_end seg_source = (cmp_seg_endpts(*x_seg_p) == SMALLER) ?
ARR_MIN_END : ARR_MAX_END;
auto num_segs = x_polycurve.number_of_subcurves();
if ((cmp_seg_endpts(x_seg) != start_dir) ||
(is_seg_vertical(x_seg) != is_start_vertical))
if ((cmp_seg_endpts(*x_seg_p) != start_dir) ||
(is_seg_vertical(*x_seg_p) != is_start_vertical))
{
// Construct an x-monotone curve from the sub-range which was found
*oi++ = make_object(x_polycurve);
is_start_vertical = is_seg_vertical(x_seg);
start_dir = cmp_seg_endpts(x_seg);
*oi++ = Make_x_monotone_result(x_polycurve);
is_start_vertical = is_seg_vertical(*x_seg_p);
start_dir = cmp_seg_endpts(*x_seg_p);
#ifdef CGAL_ALWAYS_LEFT_TO_RIGHT
if (cmp_seg_endpts(x_seg) == LARGER) x_seg = ctr_seg_opposite(x_seg);
x_polycurve (cmp_seg_endpts(*x_seg_p) == LARGER) ?
ctr_x_curve(ctr_seg_opposite(*x_seg_p)) : ctr_x_curve(*x_seg_p);
#else
x_polycurve = ctr_x_curve(*x_seg_p);
#endif
x_polycurve = ctr_x_curve(x_seg);
}
else if (ps_x(x_polycurve[num_segs-1], polycurve_target) !=
ARR_INTERIOR ||
ps_x(x_seg, seg_source) != ARR_INTERIOR)
(ps_x(*x_seg_p, seg_source) != ARR_INTERIOR))
{
*oi++ = make_object(x_polycurve);
*oi++ = Make_x_monotone_result(x_polycurve);
#ifdef CGAL_ALWAYS_LEFT_TO_RIGHT
if (cmp_seg_endpts(x_seg) == LARGER) x_seg = ctr_seg_opposite(x_seg);
x_polycurve = (cmp_seg_endpts(*x_seg_p) == LARGER) ?
ctr_seg_opposite(*x_seg_p) : ctr_x_curve(*x_seg_p);
#endif
x_polycurve = ctr_x_curve(x_seg);
x_polycurve = ctr_x_curve(*x_seg_p);
}
else {
#ifdef CGAL_ALWAYS_LEFT_TO_RIGHT
if (cmp_seg_endpts(x_seg) == LARGER) {
x_seg = ctr_seg_opposite(x_seg);
push_front(x_polycurve, x_seg);
}
if (cmp_seg_endpts(*x_seg_p) == LARGER)
push_front(x_polycurve, ctr_seg_opposite(*x_seg_p));
else
push_back(x_polycurve, x_seg);
push_back(x_polycurve, *x_seg_p);
#else
push_back(x_polycurve, x_seg);
push_back(x_polycurve, *x_seg_p);
#endif
}
} // for loop
if (x_polycurve.number_of_subcurves() != 0)
*oi++ = make_object(x_polycurve);
*oi++ = Make_x_monotone_result(x_polycurve);
x_seg_objects.clear();
return oi;
}
public:
public:
template <typename OutputIterator>
OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const
{ return operator_impl(cv, oi, Are_all_sides_oblivious_tag()); }

View File

@ -808,45 +808,41 @@ public:
return Equal_2(this);
}
/*! A functor that divides a curve into continues (x-monotone) curves. */
class Make_x_monotone_2
{
public:
//! \name Intersections & subdivisions
//@{
/*!
* Cut the given conic curve (or conic arc) into x-monotone subcurves
* and insert them to the given output iterator.
* \param cv The curve.
* \param oi The output iterator, whose value-type is Object. The returned
* objects is a wrapper for an X_monotone_curve_2 object.
* \return The past-the-end iterator.
/*! \class Make_x_monotone_2
* A functor for subdividing a curve into continues x-monotone curves.
*/
class Make_x_monotone_2 {
public:
/*! Subdivide a given rational-function curve into x-monotone subcurves
* and insert them to a given output iterator.
* \param cv the curve.
* \param oi the output iterator for the result. Its dereference type is a
* variant that wraps a \c Point_2 or an \c X_monotone_curve_2
* objects.
* \return the past-the-end iterator.
*/
template<typename OutputIterator>
template <typename OutputIterator>
OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const
{
// Make the rational arc continuous.
std::list<X_monotone_curve_2> arcs;
typedef boost::variant<Point_2, X_monotone_curve_2>
Make_x_monotone_result;
// Make the rational arc continuous.
std::list<X_monotone_curve_2> arcs;
cv.make_continuous(std::back_inserter(arcs));
// Create objects.
typename std::list<X_monotone_curve_2>::const_iterator iter;
for (iter = arcs.begin(); iter != arcs.end(); ++iter)
{
*oi = make_object (*iter);
++oi;
}
return (oi);
for (const auto& arc : arcs) *oi++ = Make_x_monotone_result(arc);
return oi;
}
};
/*! Obtain a Make_x_monotone_2 functor object. */
Make_x_monotone_2 make_x_monotone_2_object() const
{
return Make_x_monotone_2();
}
{ return Make_x_monotone_2(); }
/*! A functor that splits a curve at a point. */
class Split_2
@ -975,6 +971,8 @@ public:
return Merge_2(this);
}
//@}
/// \name Functor definitions to handle boundaries
//@{

View File

@ -543,23 +543,30 @@ public:
//@}
/// \name Functor definitions for supporting intersections.
//! \name Intersections, subdivisions, and mergings
//@{
/*! \class Make_x_monotone_2
* A functor for subdividing a curve into x-monotone curves.
*/
class Make_x_monotone_2 {
public:
/*! Cut the given curve into x-monotone subcurves and insert them into the
* given output iterator. As segments are always x_monotone, only one
* object will be contained in the iterator.
/*! Subdivide a given curve into x-monotone subcurves and insert them into
* a given output iterator. As segments are always x_monotone a single
* object is inserted.
* \param cv the curve.
* \param oi the output iterator, whose value-type is variant<....
* \return the past-the-end iterator.
* \param oi the output iterator for the result. Its dereference type is a
* variant that wraps a \c Point_2 or an \c X_monotone_curve_2
* objects.
* \return the past-the-end output iterator.
*/
template <typename OutputIterator>
OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const
{
// Wrap the segment with an object.
*oi++ = make_object(cv);
// Wrap the segment with a variant.
typedef boost::variant<Point_2, X_monotone_curve_2>
Make_x_monotone_result;
*oi++ = Make_x_monotone_result(cv);
return oi;
}
};
@ -1161,6 +1168,7 @@ public:
//! \brief constructs default.
template <typename Kernel>
Arr_segment_traits_2<Kernel>::_Segment_cached_2::_Segment_cached_2() :
m_is_directed_right(false),
m_is_vert(false),
m_is_degen(true)
{}

View File

@ -151,23 +151,25 @@ public:
OutputIterator insert(const Vector_3 & normal1, const Vector_3 & normal2,
OutputIterator oi)
{
std::list<CGAL::Object> x_objects;
typedef boost::variant<Point_2, X_monotone_curve_2>
Make_x_monotone_result;
std::list<Make_x_monotone_result> x_objects;
make_x_monotone(normal1, normal2, std::back_inserter(x_objects));
typename std::list<CGAL::Object>::iterator it = x_objects.begin();
const X_monotone_curve_2 * xc = object_cast<X_monotone_curve_2>(&(*it));
auto it = x_objects.begin();
const auto* xc = boost::get<X_monotone_curve_2>(&(*it));
#if CGAL_ARR_SPHERICAL_GAUSSIAN_MAP_3_DEBUG==1
std::cout << "1.a. insert_in_face_interior(" << *xc << ")" << std::endl;
#endif
Halfedge_handle he =
m_sgm.insert_in_face_interior(*xc, m_sgm.faces_begin());
if (!xc->is_directed_right()) he = he->twin();
Halfedge_handle he = m_sgm.insert_in_face_interior(*xc, m_sgm.faces_begin());
if (! xc->is_directed_right()) he = he->twin();
*oi++ = he;
++it;
if (it == x_objects.end()) return oi;
xc = object_cast<X_monotone_curve_2>(&(*it));
xc = boost::get<X_monotone_curve_2>(&(*it));
#if CGAL_ARR_SPHERICAL_GAUSSIAN_MAP_3_DEBUG==1
std::cout << "1.b. insert_from_vertex(" << *xc << ")" << std::endl;
#endif
@ -190,11 +192,14 @@ public:
const Vector_3 & normal2,
OutputIterator oi)
{
std::list<CGAL::Object> x_objects;
typedef boost::variant<Point_2, X_monotone_curve_2>
Make_x_monotone_result;
std::list<Make_x_monotone_result> x_objects;
make_x_monotone(normal1, normal2, std::back_inserter(x_objects));
typename std::list<CGAL::Object>::iterator it = x_objects.begin();
const X_monotone_curve_2 * xc = object_cast<X_monotone_curve_2>(&(*it));
auto it = x_objects.begin();
const auto* xc = boost::get<X_monotone_curve_2>(&(*it));
#if CGAL_ARR_SPHERICAL_GAUSSIAN_MAP_3_DEBUG==1
std::cout << "2.a. insert_from_vertex(" << *xc << ", "
<< vertex1->point() << ")" << std::endl;
@ -208,7 +213,7 @@ public:
++it;
if (it == x_objects.end()) return oi;
xc = object_cast<X_monotone_curve_2>(&(*it));
xc = boost::get<X_monotone_curve_2>(&(*it));
#if CGAL_ARR_SPHERICAL_GAUSSIAN_MAP_3_DEBUG==1
std::cout << "2.b. insert_from_vertex(" << *xc << ")" << std::endl;
#endif
@ -231,12 +236,15 @@ public:
const Vector_3 & normal2, Vertex_handle vertex2,
OutputIterator oi)
{
std::list<CGAL::Object> x_objects;
typedef boost::variant<Point_2, X_monotone_curve_2>
Make_x_monotone_result;
std::list<Make_x_monotone_result> x_objects;
make_x_monotone(normal1, normal2, std::back_inserter(x_objects));
typename std::list<CGAL::Object>::iterator it = x_objects.begin();
auto it = x_objects.begin();
if (x_objects.size() == 1) {
const X_monotone_curve_2 * xc = object_cast<X_monotone_curve_2>(&(*it));
const auto* xc = boost::get<X_monotone_curve_2>(&(*it));
#if CGAL_ARR_SPHERICAL_GAUSSIAN_MAP_3_DEBUG==1
std::cout << "3. insert_from_vertex(" << *xc << ")" << std::endl;
#endif
@ -247,8 +255,8 @@ public:
return oi;
}
const X_monotone_curve_2 * xc1 = object_cast<X_monotone_curve_2>(&(*it++));
const X_monotone_curve_2 * xc2 = object_cast<X_monotone_curve_2>(&(*it));
const X_monotone_curve_2* xc1 = boost::get<X_monotone_curve_2>(&(*it++));
const X_monotone_curve_2* xc2 = boost::get<X_monotone_curve_2>(&(*it));
#if CGAL_ARR_SPHERICAL_GAUSSIAN_MAP_3_DEBUG==1
std::cout << "3.a. insert_from_vertex(" << *xc2 << ")" << std::endl;
@ -283,11 +291,13 @@ public:
const Vector_3 & normal2, Vertex_handle vertex2,
OutputIterator oi)
{
std::list<CGAL::Object> x_objects;
typedef boost::variant<Point_2, X_monotone_curve_2>
Make_x_monotone_result;
std::list<Make_x_monotone_result> x_objects;
make_x_monotone(normal1, normal2, std::back_inserter(x_objects));
typename std::list<CGAL::Object>::iterator it = x_objects.begin();
auto it = x_objects.begin();
if (x_objects.size() == 1) {
const X_monotone_curve_2 * xc = object_cast<X_monotone_curve_2>(&(*it));
const auto* xc = boost::get<X_monotone_curve_2>(&(*it));
#if CGAL_ARR_SPHERICAL_GAUSSIAN_MAP_3_DEBUG==1
std::cout << "4. insert_at_vertices(" << *xc << ")" << std::endl;
#endif
@ -295,8 +305,8 @@ public:
return oi;
}
const X_monotone_curve_2 * xc1 = object_cast<X_monotone_curve_2>(&(*it++));
const X_monotone_curve_2 * xc2 = object_cast<X_monotone_curve_2>(&(*it));
const X_monotone_curve_2 * xc1 = boost::get<X_monotone_curve_2>(&(*it++));
const X_monotone_curve_2 * xc2 = boost::get<X_monotone_curve_2>(&(*it));
#if CGAL_ARR_SPHERICAL_GAUSSIAN_MAP_3_DEBUG==1
std::cout << "4.a. insert_from_vertex(" << *xc1

View File

@ -35,6 +35,7 @@ void Arr_transform_on_sphere(Arrangement & arr,
typedef typename Arrangement::Geometry_traits_2 Geometry_traits_2;
typedef typename Arrangement::Topology_traits Topology_traits;
typedef typename Geometry_traits_2::Point_2 Point_2;
typedef typename Geometry_traits_2::Curve_2 Curve_2;
typedef typename Geometry_traits_2::X_monotone_curve_2 X_monotone_curve_2;
@ -45,6 +46,8 @@ void Arr_transform_on_sphere(Arrangement & arr,
typedef typename Arrangement::Halfedge_around_vertex_circulator
Halfedge_around_vertex_circulator;
typedef boost::variant<Point_2, X_monotone_curve_2> Make_x_monotone_result;
const Geometry_traits_2 * geom_traits = arr.geometry_traits();
Topology_traits * topol_traits = arr.topology_traits();
@ -53,8 +56,7 @@ void Arr_transform_on_sphere(Arrangement & arr,
// Preprocessing loop - merge all the edges that were splited
// (meaning have a common endpoint that lies on the boundary and their degree
// is 2) on the identification curve.
for (Vertex_handle vi1 = arr.vertices_begin() ; vi1 != arr.vertices_end() ;)
{
for (auto vi1 = arr.vertices_begin(); vi1 != arr.vertices_end(); ) {
Vertex_handle v_temp = vi1;
++vi1;
@ -63,9 +65,9 @@ void Arr_transform_on_sphere(Arrangement & arr,
Arr_parameter_space by =
geom_traits->parameter_space_in_y_2_object()(v_temp->point());
// use vertex->parameter_space_in_x() != interior || vertex->parameter_space_in_y() != interior)
if ((bx != ARR_INTERIOR || by != ARR_INTERIOR) && (v_temp->degree() == 2))
{
// use vertex->parameter_space_in_x() != interior ||
// vertex->parameter_space_in_y() != interior)
if ((bx != ARR_INTERIOR || by != ARR_INTERIOR) && (v_temp->degree() == 2)) {
Curve_2 merged_cv;
Halfedge_around_vertex_circulator havc = v_temp->incident_halfedges();
Halfedge_around_vertex_circulator havc_next = havc;
@ -80,16 +82,13 @@ void Arr_transform_on_sphere(Arrangement & arr,
// Compare the direction of the edges.
bool eq_direction = havc->direction() == havc_next->twin()->direction();
if (point_eq1 && normal_eq1 && eq_direction)
{
if (havc->source()->point() == havc->curve().source())
{
if (point_eq1 && normal_eq1 && eq_direction) {
if (havc->source()->point() == havc->curve().source()) {
merged_cv = Curve_2(havc->source()->point(),
havc_next->twin()->target()->point(),
havc->curve().normal());
}
else if (havc->source()->point() == havc->curve().target())
{
else if (havc->source()->point() == havc->curve().target()) {
merged_cv = Curve_2(havc_next->twin()->target()->point(),
havc->source()->point(),
havc->curve().normal());
@ -111,20 +110,17 @@ void Arr_transform_on_sphere(Arrangement & arr,
}
//Rotate all the vertices.
for (Vertex_handle vi1 = arr.vertices_begin(); vi1 != arr.vertices_end() ;
++vi1)
{
for (auto vi1 = arr.vertices_begin(); vi1 != arr.vertices_end(); ++vi1) {
m_arr_access.modify_vertex_ex(vi1, aff.transform(vi1->point()));
}
unsigned int num_of_edges = arr.number_of_edges();
size_t num_of_edges = arr.number_of_edges();
Edge_iterator ei1 = arr.edges_begin();
// Rotate all the halfedges.
// The loop is over the initial edges , since new edges are created and
// added to the edges list.
for (unsigned int i=0 ; i < num_of_edges ; ++i)
{
for (size_t i = 0; i < num_of_edges; ++i) {
Curve_2 new_cv;
Halfedge_handle hei1 = ei1;
@ -133,8 +129,7 @@ void Arr_transform_on_sphere(Arrangement & arr,
// Take only the halfedge that its source is equal to the source of
// the curve.
bool eq1 = hei1->source()->point() == aff.transform(hei1->curve().source());
if (!eq1)
{
if (!eq1) {
hei1 = hei1->twin();
eq1 = hei1->source()->point() == aff.transform(hei1->curve().source());
}
@ -150,31 +145,28 @@ void Arr_transform_on_sphere(Arrangement & arr,
// Modify the edge with the new curve.
m_arr_access.modify_edge_ex(hei1, new_cv);
std::list<CGAL::Object> objects;
std::list<Make_x_monotone_result> objects;
// Try to split the curve into x_monotone pieces.
geom_traits->make_x_monotone_2_object()(new_cv , std::back_inserter(objects));
// If the curve is not x-monotone - split it into 2 x_monotone parts.
// Since the curves were x_monotone before , can assume that it will be
// splited into 2 parts max.
if (objects.size() == 2)
{
typename std::list<CGAL::Object>::iterator it = objects.begin();
if (objects.size() == 2) {
auto it = objects.begin();
// The curve that its left vertex lies on the identification curve
const X_monotone_curve_2 * sub_cv1 =
object_cast<X_monotone_curve_2>(&(*it));
const auto* sub_cv1 = boost::get<X_monotone_curve_2>(&(*it));
++it;
//The curve that its rigth vertex lies on the identification curve
const X_monotone_curve_2 * sub_cv2 =
object_cast<X_monotone_curve_2>(&(*it));
const auto* sub_cv2 = boost::get<X_monotone_curve_2>(&(*it));
bool eq1 = (*sub_cv1).source() == hei1->source()->point();
bool eq2 = (*sub_cv2).target() == hei1->target()->point();
if (eq1 && eq2)
m_arr_access.split_edge_ex (hei1, (*sub_cv1).target(), *sub_cv1,
*sub_cv2);
m_arr_access.split_edge_ex(hei1, (*sub_cv1).target(), *sub_cv1,
*sub_cv2);
else
CGAL_error_msg
("The new curve endpoints should be equal to the original ones");
@ -183,25 +175,20 @@ void Arr_transform_on_sphere(Arrangement & arr,
// Update all the vertices that located on the boundary after the rotation
// with boundary conditions
for (Vertex_handle vi = arr.vertices_begin() ; vi != arr.vertices_end() ;
++vi)
{
for (auto vi = arr.vertices_begin(); vi != arr.vertices_end(); ++vi) {
Arr_parameter_space bx =
geom_traits->parameter_space_in_x_2_object()(vi->point());
Arr_parameter_space by =
geom_traits->parameter_space_in_y_2_object()(vi->point());
if (bx != ARR_INTERIOR || by != ARR_INTERIOR)
{
if (bx != ARR_INTERIOR || by != ARR_INTERIOR) {
// The target of the Halfedge_around_vertex_circulator is the relevant
// point.
Halfedge_around_vertex_circulator havc = vi->incident_halfedges();
Arr_curve_end ind;
if (geom_traits->construct_min_vertex_2_object()(havc->curve()) == vi->point())
ind = ARR_MIN_END;
else
ind = ARR_MAX_END;
Arr_curve_end ind =
(geom_traits->construct_min_vertex_2_object()(havc->curve()) ==
vi->point()) ? ARR_MIN_END : ARR_MAX_END;
// Check if it was already added.
if (topol_traits->discontinuity_vertex(havc->curve(), ind)== nullptr &&
@ -219,7 +206,7 @@ void Arr_transform_on_sphere(Arrangement & arr,
}
// Transform the faces with the suitable transformation traits.
for(Face_handle f1 = arr.faces_begin() ; f1 != arr.faces_end() ; ++f1)
for (auto f1 = arr.faces_begin(); f1 != arr.faces_end(); ++f1)
tran_tr.rotate_face(f1, aff);
}

View File

@ -7,8 +7,8 @@
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s) : Efi Fogel <efif@post.tau.ac.il>
// Eric Berberich <ericb@post.tau.ac.il>
// Author(s): Efi Fogel <efif@post.tau.ac.il>
// Eric Berberich <ericb@post.tau.ac.il>
#ifndef CGAL_ARR_SPHERICAL_TOPOLOGY_TRAITS_2_H
#define CGAL_ARR_SPHERICAL_TOPOLOGY_TRAITS_2_H
@ -491,11 +491,12 @@ public:
* \pre The curve has a boundary condition in either x or y.
* \return An object that contains the curve end.
*/
CGAL::Object place_boundary_vertex(Face* f,
const X_monotone_curve_2& xc,
Arr_curve_end ind,
Arr_parameter_space ps_x,
Arr_parameter_space ps_y);
boost::optional<boost::variant<Vertex*, Halfedge*> >
place_boundary_vertex(Face* f,
const X_monotone_curve_2& xc,
Arr_curve_end ind,
Arr_parameter_space ps_x,
Arr_parameter_space ps_y);
/*! Locate the predecessor halfedge for the given curve around a given
* vertex with boundary conditions.
@ -522,9 +523,10 @@ public:
* \pre The curve end is incident to the boundary.
* \return An object that contains the curve end.
*/
CGAL::Object locate_curve_end(const X_monotone_curve_2& xc, Arr_curve_end ce,
Arr_parameter_space ps_x,
Arr_parameter_space ps_y);
boost::variant<Vertex*, Halfedge*, Face*>
locate_curve_end(const X_monotone_curve_2& xc, Arr_curve_end ce,
Arr_parameter_space ps_x,
Arr_parameter_space ps_y);
/*! Split a fictitious edge using the given vertex.
* \param e The edge to split (one of the pair of halfedges).

View File

@ -7,9 +7,8 @@
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// Author(s): Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
#ifndef CGAL_ARR_BOUNDED_PLANAR_VERT_DEOCMP_HELPER_H
#define CGAL_ARR_BOUNDED_PLANAR_VERT_DEOCMP_HELPER_H
@ -43,9 +42,15 @@ private:
typedef Geometry_traits_2 Gt2;
public:
typedef typename Arrangement_2::Vertex_const_handle Vertex_const_handle;
typedef typename Arrangement_2::Halfedge_const_handle Halfedge_const_handle;
typedef typename Arrangement_2::Face_const_handle Face_const_handle;
typedef typename Arrangement_2::Topology_traits Topology_traits;
typedef boost::variant<Vertex_const_handle, Halfedge_const_handle,
Face_const_handle> Cell_type;
typedef boost::optional<Cell_type> Vert_type;
protected:
// Data members:
const Topology_traits* m_top_traits; // The topology-traits class.
@ -76,10 +81,10 @@ public:
//@}
/*! Get the current top object. */
CGAL::Object top_object() const { return CGAL::make_object(m_unb_face); }
Vert_type top_object() const { return Vert_type(m_unb_face); }
/*! Get the current bottom object. */
CGAL::Object bottom_object() const { return CGAL::make_object(m_unb_face); }
Vert_type bottom_object() const { return Vert_type(m_unb_face); }
};
} // namespace CGAL

View File

@ -7,8 +7,8 @@
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s) : Efi Fogel <efif@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
// Author(s): Efi Fogel <efif@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
#ifndef CGAL_ARR_SPHERICAL_TOPOLOGY_TRAITS_2_IMPL_H
#define CGAL_ARR_SPHERICAL_TOPOLOGY_TRAITS_2_IMPL_H
@ -514,7 +514,10 @@ let_me_decide_the_outer_ccb(std::pair< CGAL::Sign, CGAL::Sign> signs1,
* the interior of the curve, find a place for a boundary vertex that will
* represent the curve end along the face boundary */
template <typename GeomTraits, typename Dcel>
CGAL::Object
boost::optional
<boost::variant
<typename Arr_spherical_topology_traits_2<GeomTraits, Dcel>::Vertex*,
typename Arr_spherical_topology_traits_2<GeomTraits, Dcel>::Halfedge*> >
Arr_spherical_topology_traits_2<GeomTraits, Dcel>::
place_boundary_vertex(Face* /* f */,
const X_monotone_curve_2& xc, Arr_curve_end ind,
@ -525,15 +528,18 @@ place_boundary_vertex(Face* /* f */,
,
Arr_parameter_space ps_y)
{
typedef boost::variant<Vertex*, Halfedge*> Non_optional_result;
typedef boost::optional<Non_optional_result> Result;
// std::cout << "place_boundary_vertex()" << std::endl;
if (ps_y == ARR_BOTTOM_BOUNDARY) {
if (m_south_pole == nullptr) return Object();
return CGAL::make_object(m_south_pole);
if (m_south_pole == nullptr) return boost::none;
return Result(Non_optional_result(m_south_pole));
}
if (ps_y == ARR_TOP_BOUNDARY) {
if (m_north_pole == nullptr) return Object();
return CGAL::make_object(m_north_pole);
if (m_north_pole == nullptr) return boost::none;
return Result(Non_optional_result(m_north_pole));
}
CGAL_assertion((ps_x == ARR_LEFT_BOUNDARY) || (ps_x == ARR_RIGHT_BOUNDARY));
@ -541,15 +547,14 @@ place_boundary_vertex(Face* /* f */,
const Point_2& key = (ind == ARR_MIN_END) ?
m_geom_traits->construct_min_vertex_2_object()(xc) :
m_geom_traits->construct_max_vertex_2_object()(xc);
typename Vertex_map::iterator it = m_boundary_vertices.find(key);
auto it = m_boundary_vertices.find(key);
if (it != m_boundary_vertices.end()) {
Vertex* v = it->second;
return CGAL::make_object(v);
return Result(Non_optional_result(v));
}
// The vertex hasn't been created yet, return a null object:
return Object();
return boost::none;
}
/*! \brief locate the predecessor halfedge for the given curve around a given
@ -585,7 +590,11 @@ locate_around_boundary_vertex(Vertex* v,
/*! \brief locates a DCEL feature that contains a given curve end. */
template <typename GeomTraits, typename Dcel>
CGAL::Object Arr_spherical_topology_traits_2<GeomTraits, Dcel>::
boost::variant
<typename Arr_spherical_topology_traits_2<GeomTraits, Dcel>::Vertex*,
typename Arr_spherical_topology_traits_2<GeomTraits, Dcel>::Halfedge*,
typename Arr_spherical_topology_traits_2<GeomTraits, Dcel>::Face*>
Arr_spherical_topology_traits_2<GeomTraits, Dcel>::
locate_curve_end(const X_monotone_curve_2& xc, Arr_curve_end ind,
Arr_parameter_space
#if !defined(CGAL_NO_ASSERTIONS)
@ -594,13 +603,14 @@ locate_curve_end(const X_monotone_curve_2& xc, Arr_curve_end ind,
,
Arr_parameter_space ps_y)
{
typedef boost::variant<Vertex*, Halfedge*, Face*> Result;
// Act according to the boundary conditions.
if (ps_y == ARR_TOP_BOUNDARY) {
// In case the curve end coincides with the north pole, return the vertex
// representing the north pole, if one exists. Otherwise, return the face
// containing this pole (the spherical face).
if (m_north_pole != nullptr) return CGAL::make_object(m_north_pole);
return CGAL::make_object(m_spherical_face);
if (m_north_pole != nullptr) return Result(m_north_pole);
return Result(m_spherical_face);
}
typename Vertex_map::iterator it;
@ -610,7 +620,7 @@ locate_curve_end(const X_monotone_curve_2& xc, Arr_curve_end ind,
// In case the curve end coincides with the south pole, return the vertex
// representing the south pole, if one exists. Otherwise, search for the
// face containing this pole.
if (m_south_pole != nullptr) return CGAL::make_object(m_south_pole);
if (m_south_pole != nullptr) return Result(m_south_pole);
it = m_boundary_vertices.begin();
}
else {
@ -625,7 +635,7 @@ locate_curve_end(const X_monotone_curve_2& xc, Arr_curve_end ind,
it = m_boundary_vertices.find(key);
if (it != m_boundary_vertices.end()) {
v = it->second;
return CGAL::make_object(v);
return Result(v);
}
it = m_boundary_vertices.lower_bound(key);
@ -635,11 +645,10 @@ locate_curve_end(const X_monotone_curve_2& xc, Arr_curve_end ind,
// discontinuity that is strictly above the curve end. If there is none,
// we know the curve end is contained in the spherical face. Otherwise,
// we return the face that lies below the vertex v.
if (it == m_boundary_vertices.end())
return CGAL::make_object(m_spherical_face);
if (it == m_boundary_vertices.end()) return Result(m_spherical_face);
v = it->second;
return CGAL::make_object(_face_below_vertex_on_discontinuity(v));
return Result(_face_below_vertex_on_discontinuity(v));
}
/*! \brief determines whether a given boundary vertex is redundant */

View File

@ -7,8 +7,8 @@
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s) : Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// Author(s): Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
#ifndef CGAL_ARR_SPHERICAL_VERT_DECOMP_HELPER_H
#define CGAL_ARR_SPHERICAL_VERT_DECOMP_HELPER_H
@ -44,8 +44,13 @@ private:
public:
typedef typename Gt2::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Arrangement_2::Face_const_handle Face_const_handle;
typedef typename Arrangement_2::Vertex_const_handle Vertex_const_handle;
typedef typename Arrangement_2::Halfedge_const_handle Halfedge_const_handle;
typedef typename Arrangement_2::Face_const_handle Face_const_handle;
typedef boost::variant<Vertex_const_handle, Halfedge_const_handle,
Face_const_handle> Cell_type;
typedef boost::optional<Cell_type> Vert_type;
protected:
typedef typename Arrangement_2::Topology_traits Topology_traits;
@ -80,17 +85,17 @@ public:
//@}
/*! Get the current top object. */
CGAL::Object top_object () const
Vert_type top_object () const
{
return (m_valid_north_pole) ?
CGAL::make_object (m_north_pole) : CGAL::make_object (m_north_face);
Vert_type(m_north_pole) : Vert_type(m_north_face);
}
/*! Get the current bottom object. */
CGAL::Object bottom_object () const
Vert_type bottom_object () const
{
return (m_valid_south_pole) ?
CGAL::make_object(m_south_pole) : CGAL::make_object(m_south_face);
Vert_type(m_south_pole) : Vert_type(m_south_face);
}
};

View File

@ -8,8 +8,8 @@
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// Author(s): Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
#ifndef CGAL_ARR_UNB_PLANAR_TOPOLOGY_TRAITS_2_IMPL_H
#define CGAL_ARR_UNB_PLANAR_TOPOLOGY_TRAITS_2_IMPL_H
@ -296,27 +296,31 @@ are_equal(const Vertex *v,
// represent the curve end along the face boundary.
//
template <typename GeomTraits, typename Dcel_>
CGAL::Object
boost::optional
<boost::variant
<typename Arr_unb_planar_topology_traits_2<GeomTraits, Dcel_>::Vertex*,
typename Arr_unb_planar_topology_traits_2<GeomTraits, Dcel_>::Halfedge*> >
Arr_unb_planar_topology_traits_2<GeomTraits, Dcel_>::
place_boundary_vertex(Face *f,
place_boundary_vertex(Face* f,
const X_monotone_curve_2& cv, Arr_curve_end ind,
Arr_parameter_space ps_x, Arr_parameter_space ps_y)
{
// Get a halfedge on the outer CCB of f and start traversing the CCB.
Halfedge *first = *(f->outer_ccbs_begin());
Halfedge *curr = first;
bool eq_source, eq_target;
typedef boost::variant<Vertex*, Halfedge*> Non_optional_result;
typedef boost::optional<Non_optional_result> Result;
do
{
// Get a halfedge on the outer CCB of f and start traversing the CCB.
Halfedge* first = *(f->outer_ccbs_begin());
Halfedge* curr = first;
bool eq_source, eq_target;
do {
// Note we consider only fictitious halfedges and check whether they
// contain the relevant curve end.
if (curr->has_null_curve() &&
_is_on_fictitious_edge (cv, ind, ps_x, ps_y, curr,
eq_source, eq_target))
_is_on_fictitious_edge(cv, ind, ps_x, ps_y, curr, eq_source, eq_target))
{
CGAL_assertion (! eq_source && ! eq_target);
return (CGAL::make_object (curr));
CGAL_assertion(! eq_source && ! eq_target);
return Result(curr);
}
// Move to the next halfegde along the CCB.
@ -327,59 +331,58 @@ place_boundary_vertex(Face *f,
// If we reached here, we did not find a suitable halfegde, which should
// never happen.
CGAL_error();
return CGAL::Object();
return boost::none;
}
//-----------------------------------------------------------------------------
// Locate a DCEL feature that contains the given unbounded curve end.
//
template <typename GeomTraits, typename Dcel_>
CGAL::Object Arr_unb_planar_topology_traits_2<GeomTraits, Dcel_>::
boost::variant
<typename Arr_unb_planar_topology_traits_2<GeomTraits, Dcel_>::Vertex*,
typename Arr_unb_planar_topology_traits_2<GeomTraits, Dcel_>::Halfedge*,
typename Arr_unb_planar_topology_traits_2<GeomTraits, Dcel_>::Face*>
Arr_unb_planar_topology_traits_2<GeomTraits, Dcel_>::
locate_curve_end (const X_monotone_curve_2& cv, Arr_curve_end ind,
Arr_parameter_space ps_x, Arr_parameter_space ps_y)
{
typedef boost::variant<Vertex*, Halfedge*, Face*> Result;
// Start traversing the inner CCB of the fictitious face and try to locate
// a feature that contains the curve end.
Halfedge *first = *(fict_face->inner_ccbs_begin());
Halfedge *curr = first;
bool eq_source, eq_target;
Halfedge* first = *(fict_face->inner_ccbs_begin());
Halfedge* curr = first;
bool eq_source, eq_target;
do
{
if (_is_on_fictitious_edge (cv, ind, ps_x, ps_y, curr,
eq_source, eq_target))
do {
if (_is_on_fictitious_edge(cv, ind, ps_x, ps_y, curr, eq_source, eq_target))
{
if (eq_source)
{
if (eq_source) {
// cv's end coincides with the source vertex of the current
// fictitious halfedge. This means that cv overlaps the curve that
// is associated with the only non-fictitious halfedge incident to
// this vertex. We therefore return a pointer to this halfedge.
Halfedge *he = curr->opposite()->next();
CGAL_assertion (! he->has_null_curve());
return (CGAL::make_object (he));
Halfedge* he = curr->opposite()->next();
CGAL_assertion(! he->has_null_curve());
return Result(he);
}
else if (eq_target)
{
else if (eq_target) {
// cv's end coincides with the target vertex of the current
// fictitious halfedge. This means that cv overlaps the curve that
// is associated with the only non-fictitious halfedge incident to
// this vertex. We therefore return a pointer to this halfedge.
Halfedge *he = curr->opposite()->prev();
CGAL_assertion (! he->has_null_curve());
return (CGAL::make_object (he));
Halfedge* he = curr->opposite()->prev();
CGAL_assertion(! he->has_null_curve());
return Result(he);
}
// The current ficitious edge contains cv's end in its interior.
// Note we use curr's twin, whose incident face is a valid
// unbounded face (whereas the incident face of curr is the fictitious
// face).
Face *uf = curr->opposite()->outer_ccb()->face();
Face* uf = curr->opposite()->outer_ccb()->face();
CGAL_assertion (uf->is_unbounded() && ! uf->is_fictitious());
return (CGAL::make_object (uf));
return Result(uf);
}
curr = curr->next();
@ -388,7 +391,8 @@ locate_curve_end (const X_monotone_curve_2& cv, Arr_curve_end ind,
// We should never reach here.
CGAL_error();
return Object();
Vertex* v(nullptr);
return Result(v);
}
//-----------------------------------------------------------------------------

View File

@ -7,9 +7,8 @@
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// Author(s): Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
#ifndef CGAL_ARR_UNB_PLANAR_VERT_DECOMP_HELPER_H
#define CGAL_ARR_UNB_PLANAR_VERT_DECOMP_HELPER_H
@ -43,12 +42,16 @@ private:
typedef Geometry_traits_2 Gt2;
public:
typedef typename Arrangement_2::Vertex_const_handle Vertex_const_handle;
typedef typename Arrangement_2::Halfedge_const_handle Halfedge_const_handle;
typedef typename Arrangement_2::Face_const_handle Face_const_handle;
typedef boost::variant<Vertex_const_handle, Halfedge_const_handle,
Face_const_handle> Cell_type;
typedef boost::optional<Cell_type> Vert_type;
protected:
typedef typename Arrangement_2::Topology_traits Topology_traits;
typedef typename Arrangement_2::Halfedge_const_handle Halfedge_const_handle;
typedef typename Arrangement_2::Vertex_const_handle Vertex_const_handle;
// Data members:
const Topology_traits* m_top_traits; // The topology-traits class.
@ -77,10 +80,10 @@ public:
//@}
/*! Get the current top object. */
CGAL::Object top_object() const { return CGAL::make_object(m_top_fict); }
Vert_type top_object() const { return Vert_type(m_top_fict); }
/*! Get the current bottom object. */
CGAL::Object bottom_object() const { return CGAL::make_object(m_bottom_fict); }
Vert_type bottom_object() const { return Vert_type(m_bottom_fict); }
};
//-----------------------------------------------------------------------------

View File

@ -504,7 +504,12 @@ public:
}
};
/*! A functor that divides a curve into x-monotone curves. */
//! \name Intersections & subdivisions
//@{
/*! \class Make_x_monotone_2
* A functor for subdividing curves into x-monotone curves.
*/
class Make_x_monotone_2 {
private:
typename Base::Make_x_monotone_2 m_object;
@ -515,39 +520,43 @@ public:
Make_x_monotone_2(const Base * base, bool enabled = true) :
m_object(base->make_x_monotone_2_object()), m_enabled(enabled) {}
/*! Operate
* \param cv the curve
* \param oi an output iterator that contains the result. It's value
* type is CGAL::Object, which wraps either an x-monotone curve or a point
* \return the output iterator
/*! Subdivide a given curve into x-monotone subcurves and insert them into
* a given output iterator.
* \param cv the curve.
* \param oi an output iterator for the result. Its value type is a variant
* that wraps Point_2 or X_monotone_curve_2 objects.
* \return the output iterator.
*/
template<typename OutputIterator>
template <typename OutputIterator>
OutputIterator operator()(const Curve_2 & cv, OutputIterator oi) const
{
if (!m_enabled) return m_object(cv, oi);
if (! m_enabled) return m_object(cv, oi);
std::cout << "make_x_monotone" << std::endl
<< " cv: " << cv << std::endl;
std::list<CGAL::Object> container;
typedef boost::variant<Point_2, X_monotone_curve_2>
Make_x_monotone_result;
std::list<Make_x_monotone_result> container;
m_object(cv, std::back_inserter(container));
if (container.empty()) return oi;
std::list<CGAL::Object>::iterator it;
unsigned int i = 0;
for (it = container.begin(); it != container.end(); ++it) {
X_monotone_curve_2 xcv;
if (assign (xcv, *it)) {
std::cout << " result[" << i++ << "]: xcv: " << xcv << std::endl;
size_t i = 0;
for (auto it = container.begin(); it != container.end(); ++it) {
if (const auto* xcv = boost::get<X_monotone_curve_2>(*it)) {
std::cout << " result[" << i++ << "]: xcv: " << *xcv << std::endl;
continue;
}
Point_2 p;
if (assign (p, *it)) {
std::cout << " result[" << i++ << "]: p: " << p << std::endl;
if (const Point_2* p = boost::get<Point_2>(*it)) {
std::cout << " result[" << i++ << "]: p: " << *p << std::endl;
continue;
}
CGAL_error();
}
for (it = container.begin(); it != container.end(); ++it) *oi++ = *it;
for (auto it = container.begin(); it != container.end(); ++it) *oi++ = *it;
container.clear();
return oi;
}
@ -597,14 +606,14 @@ public:
Intersect_2(const Base* base, bool enabled = true) :
m_object(base->intersect_2_object()), m_enabled(enabled) {}
/*! Operate
/*! Compute the intersections of the two given curves and insert them into
* a given output iterator.
* \param xcv1 the first curve
* \param xcv2 the ssecond curve
* \param oi an output iterator that contains the result. It's value
* type is CGAL::Object, which wraps either an x-monotone overlapping
* curve or pair that consists of an intersection point and its
* multiplicity
* \return the output iterator
* \param oi the output iterator for the result. It value type is a variant
* that wraps an x-monotone overlapping curve or a pair that
* consists of the intersection point and its multiplicity
* \return the past-the-end output iterator.
*/
template <typename OutputIterator>
OutputIterator operator()(const X_monotone_curve_2 & xcv1,

View File

@ -7,9 +7,8 @@
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// Author(s): Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
#ifndef CGAL_ARR_UNB_PLANAR_TOPOLOGY_TRAITS_2_H
#define CGAL_ARR_UNB_PLANAR_TOPOLOGY_TRAITS_2_H
@ -308,11 +307,12 @@ public:
* \return An object that contains the curve end.
* In our case this object always wraps a fictitious edge.
*/
CGAL::Object place_boundary_vertex(Face* f,
const X_monotone_curve_2& cv,
Arr_curve_end ind,
Arr_parameter_space ps_x,
Arr_parameter_space ps_y);
boost::optional<boost::variant<Vertex*, Halfedge*> >
place_boundary_vertex(Face* f,
const X_monotone_curve_2& cv,
Arr_curve_end ind,
Arr_parameter_space ps_x,
Arr_parameter_space ps_y);
/*! Locate the predecessor halfedge for the given curve around a given
* vertex with boundary conditions.
@ -346,10 +346,11 @@ public:
* In our case this object may either wrap an unbounded face,
* or an edge with an end-vertex at infinity (in case of an overlap).
*/
CGAL::Object locate_curve_end(const X_monotone_curve_2& cv,
Arr_curve_end ind,
Arr_parameter_space ps_x,
Arr_parameter_space ps_y);
boost::variant<Vertex*, Halfedge*, Face*>
locate_curve_end(const X_monotone_curve_2& cv,
Arr_curve_end ind,
Arr_parameter_space ps_x,
Arr_parameter_space ps_y);
/*! Split a fictitious edge using the given vertex.
* \param e The edge to split (one of the pair of halfedges).

View File

@ -7,7 +7,7 @@
// $Id$
// 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_ARR_VERTICAL_DECOMPOSITION_2_H
#define CGAL_ARR_VERTICAL_DECOMPOSITION_2_H
@ -34,14 +34,13 @@ namespace Ss2 = Surface_sweep_2;
/*! Perform a vertical decomposition of an arrangement, by performing a
* "batched vertical ray-shooting" query from all arrangement vertices.
* \param arr The arrangement.
* \param oi Output: An output iterator of the vertices, each paired with
* a pair of arrangement features that lie below and above
* it, respectively.
* The vertices are sorted by increasing xy-order.
* \param oi An output iterator of the vertices, each paired with a pair of
* arrangement features that lie below and above it, respectively.
* The vertices are sorted by increasing xy-order.
* The OutputIterator dereferences the type \c
* pair<Vertex_const_handle, pair<Vert_type, Vert_type> >, where
* \c Vert_type is an optional handle to an arrangement feature.
* \return A past-the-end iterator for the ordered arrangement vertices.
* \pre The value-type of OutputIterator is
* pair<Vertex_const_handle, pair<Object, Object> >, where
* the Object represents a handle to an arrangement feature.
*/
template <typename GeometryTraits_2, typename TopologyTraits,
typename OutputIterator>

View File

@ -8,27 +8,29 @@
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Ophir Setter <ophirset@post.tau.ac.il>
// Author(s) : Ophir Setter <ophirset@post.tau.ac.il>
// Efi Fogel <efifogel@gmail.com>
//
#ifndef CGAL_ARR_COMPUTE_ZONE_VISITOR_H
#define CGAL_ARR_COMPUTE_ZONE_VISITOR_H
#include <CGAL/license/Arrangement_on_surface_2.h>
/*! \file
* Definition of the Arr_compute_zone_visitor class.
*/
#include <boost/variant.hpp>
namespace CGAL {
/*! \class
* A visitor class for Arrangement_zone_2, which outputs the
* zone of an x-monotone curve. Meaning, it output the arrangment's
* vertices, edges and faces that the x-monotone curve intersects.
* A visitor class for Arrangement_zone_2 that outputs the zone of an
* x-monotone curve. Specifically, it outputs handles to the the arrangment
* cells that the x-monotone curve intersects.
* The class should be templated by an Arrangement_2 class, and by an
* output iterator of CGAL Objects, where we store all arrangement
* features the x-monotone curve intersects.
* output iterator of a variant of types of handles to the arrangement cells
* that appear in the zone, namely, vertex, halfedge, and face handles.
*/
template <class Arrangement_, class OutputIterator_>
class Arr_compute_zone_visitor
@ -53,7 +55,7 @@ private:
const Vertex_handle invalid_v; // Invalid vertex.
OutputIterator& out_iter; // for outputing the zone objects.
// Its value type is CGAL::Object.
// Its value type is boost::variant.
bool output_left; // Determines wheter we should
// output the left end point of a
// subcurve (to avoid outputing
@ -65,8 +67,8 @@ public:
Arr_compute_zone_visitor (OutputIterator& oi) :
invalid_he(),
invalid_v(),
out_iter (oi),
output_left (true)
out_iter(oi),
output_left(true)
{}
/*! Initialize the visitor. */
@ -90,50 +92,35 @@ public:
* \return A handle to the halfedge obtained from the insertion of the
* subcurve into the arrangement.
*/
Result found_subcurve (const X_monotone_curve_2&,
Face_handle face,
Vertex_handle left_v, Halfedge_handle left_he,
Vertex_handle right_v, Halfedge_handle right_he)
Result found_subcurve(const X_monotone_curve_2&,
Face_handle face,
Vertex_handle left_v, Halfedge_handle left_he,
Vertex_handle right_v, Halfedge_handle right_he)
{
if (output_left)
{
typedef boost::variant<Vertex_handle, Halfedge_handle, Face_handle>
Zone_result;
if (output_left) {
// Only the first subcurve should output the arrangement feature incident
// to its left endpoint. This way we avoid reporting the same feature
// twice.
if (left_v != invalid_v)
{
*out_iter = CGAL::make_object (left_v);
++out_iter;
}
else if (left_he != invalid_he)
{
*out_iter = CGAL::make_object (left_he);
++out_iter;
}
if (left_v != invalid_v) *out_iter++ = Zone_result(left_v);
else if (left_he != invalid_he) *out_iter++ = Zone_result(left_he);
output_left = false;
}
// Report the face that contains the interior of the subcurve.
*out_iter = CGAL::make_object (face);
++out_iter;
*out_iter++ = Zone_result(face);
// If the right endpoint of the subcurve is incident to an arrangement
// vertex or an arrangement edge, report this feature.
if (right_v != invalid_v)
{
*out_iter = CGAL::make_object(right_v);
++out_iter;
}
else if (right_he != invalid_he)
{
*out_iter = CGAL::make_object(right_he);
++out_iter;
}
if (right_v != invalid_v) *out_iter++ = Zone_result(right_v);
else if (right_he != invalid_he) *out_iter++ = Zone_result(right_he);
// We did not modify the arrangement, so we return an invalid handle
// and a flag indicating that the zone-computation process should continue.
return (Result (invalid_he, false));
return Result(invalid_he, false);
}
/*!
@ -151,35 +138,28 @@ public:
Halfedge_handle he,
Vertex_handle left_v, Vertex_handle right_v)
{
if (output_left)
{
typedef boost::variant<Vertex_handle, Halfedge_handle, Face_handle>
Zone_result;
if (output_left) {
// Only the first subcurve should output the arrangement feature incident
// to its left endpoint. This way we avoid reporting the same feature
// twice.
if (left_v != invalid_v)
{
*out_iter = CGAL::make_object (left_v);
++out_iter;
}
if (left_v != invalid_v) *out_iter++ = Zone_result(left_v);
output_left = false;
}
// Report the arrangement edge the curve currently overlaps.
*out_iter = CGAL::make_object(he);
++out_iter;
*out_iter++ = Zone_result(he);
// If the right endpoint of the overlapping subcurve is incident to an
// arrangement vertex, report this vertex as well.
if (right_v != invalid_v)
{
*out_iter = CGAL::make_object (right_v);
++out_iter;
}
if (right_v != invalid_v) *out_iter++ = Zone_result(right_v);
// We did not modify the arrangement, so we return an invalid handle
// and a flag indicating that the zone-computation process should continue.
return (Result (invalid_he, false));
return Result(invalid_he, false);
}
};

View File

@ -8,7 +8,6 @@
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
// $Date$
//
//
// Author(s): Ron Wein <wein@post.tau.ac.il>s
// Efi Fogel <efif@post.tau.ac.il>
// Eric Berberich <eric@mpi-inf.mpg.de>
@ -24,7 +23,6 @@
#include <CGAL/license/Arrangement_on_surface_2.h>
/*! \file
* Definitions of the adaptor classes for the arrangement traits class.
*/
@ -50,6 +48,7 @@ public:
typedef Arr_traits_basic_adaptor_2<Base> Self;
typedef typename Base::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Base::Point_2 Point_2;
typedef typename Base::Multiplicity Multiplicity;
// Categories
typedef typename Base::Has_left_category Has_left_category;
@ -320,9 +319,12 @@ public:
const X_monotone_curve_2& xcv2,
Tag_false) const
{
std::list<CGAL::Object> intersections;
typedef std::pair<Point_2, Multiplicity> Intersection_point;
typedef boost::variant<Intersection_point, X_monotone_curve_2>
Intersection_result;
std::list<Intersection_result> intersections;
m_self->intersect_2_object()(xcv1, xcv2, back_inserter(intersections));
return !intersections.empty();
return ! intersections.empty();
}
};
@ -665,7 +667,7 @@ public:
return parameter_space_in_y(xcv, ind, Psy_2_curve_end_tag());
}
/*!
/*!
* Obtain the location of the given curve end in y.
* \param xcv The curve.
* \return The location of the curve end in y direction.
@ -2276,6 +2278,7 @@ public:
typedef typename Base_traits_2::Curve_2 Curve_2;
typedef typename Base::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Base::Point_2 Point_2;
typedef typename Base::Multiplicity Multiplicity;
// Categories.
typedef typename Base::Has_left_category Has_left_category;
@ -2324,6 +2327,10 @@ public:
* endpoint, then by the graphs, and finally by their right-most endpoint.
*/
class Compare_xy_2 {
typedef std::pair<Point_2, Multiplicity> Intersection_point;
typedef boost::variant<Intersection_point, X_monotone_curve_2>
Intersection_result;
public:
/*! Compare two points lexigoraphically: by x, then by y.
* \param p1 the first point.
@ -2360,7 +2367,7 @@ public:
Comparison_result operator()(const X_monotone_curve_2& c1,
const X_monotone_curve_2& c2) const
{
std::list<CGAL::Object> intersections;
std::list<Intersection_result> intersections;
return operator()(c1, c2, intersections,
Are_all_sides_oblivious_category());
}
@ -2586,7 +2593,7 @@ public:
Comparison_result
compare_remainder(const X_monotone_curve_2& c1,
const X_monotone_curve_2& c2,
std::list<CGAL::Object>& intersections) const
std::list<Intersection_result>& intersections) const
{
// Right-most sections are equal.
// Advance to the next respective sections:
@ -2597,9 +2604,9 @@ public:
}
// Verify the first intersection is an overlap, remove it, and
// recursively call.
CGAL::Object first = intersections.front();
X_monotone_curve_2 xcv;
if (!assign(xcv, first)) {
const X_monotone_curve_2* xcv =
boost::get<X_monotone_curve_2>(&(intersections.front()));
if (! xcv) {
CGAL_error_msg("The first intersection is not an overlap!");
return SMALLER;
}
@ -2611,10 +2618,9 @@ public:
typedef typename Self::Split_2 Split_2;
Split_2 split = m_self.split_2_object();
X_monotone_curve_2 c11, c12, c21, c22;
Construct_max_vertex_2 ctr_max =
m_self.construct_max_vertex_2_object();
const Point_2& p1 = ctr_max(xcv);
const Point_2& p2 = ctr_max(xcv);
Construct_max_vertex_2 ctr_max = m_self.construct_max_vertex_2_object();
const Point_2& p1 = ctr_max(*xcv);
const Point_2& p2 = ctr_max(*xcv);
split(c1, p1, c11, c12);
split(c2, p2, c21, c22);
return operator()(c12, c22, intersections,
@ -2625,7 +2631,7 @@ public:
*/
Comparison_result operator()(const X_monotone_curve_2& c1,
const X_monotone_curve_2& c2,
std::list<CGAL::Object>& intersections,
std::list<Intersection_result>& intersections,
Arr_all_sides_oblivious_tag) const
{
const Point_2& c1_min = m_self.construct_min_vertex_2_object()(c1);
@ -2646,7 +2652,7 @@ public:
*/
Comparison_result operator()(const X_monotone_curve_2& c1,
const X_monotone_curve_2& c2,
std::list<CGAL::Object>& intersections,
std::list<Intersection_result>& intersections,
Arr_not_all_sides_oblivious_tag) const
{
typedef typename Base::Parameter_space_in_x_2 Parameter_space_in_x_2;

View File

@ -8,9 +8,9 @@
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Ron Wein <wein@post.tau.ac.il>
// Baruch Zukerman <baruchzu@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// Author(s): Ron Wein <wein@post.tau.ac.il>
// Baruch Zukerman <baruchzu@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
//
#ifndef CGAL_ARRANGEMENT_ON_SURFACE_2_GLOBAL_H
#define CGAL_ARRANGEMENT_ON_SURFACE_2_GLOBAL_H
@ -32,6 +32,7 @@
#include <CGAL/Arrangement_2/Arr_compute_zone_visitor.h>
#include <CGAL/Arrangement_2/Arr_do_intersect_zone_visitor.h>
#include <CGAL/Arrangement_2/Arr_traits_adaptor_2.h>
#include <CGAL/Arr_point_location_result.h>
#include <CGAL/No_intersection_surface_sweep_2.h>
#include <CGAL/Surface_sweep_2/Arr_insertion_ss_visitor.h>
#include <CGAL/Surface_sweep_2/Arr_no_intersection_insertion_ss_visitor.h>
@ -80,6 +81,10 @@ void insert(Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits>& arr,
typedef Arrangement_on_surface_2<Gt2, Tt> Arr;
typedef ZoneVisitor Zone_visitor;
typedef typename Gt2::Point_2 Point_2;
typedef typename Gt2::X_monotone_curve_2 X_monotone_curve_2;
typedef boost::variant<Point_2, X_monotone_curve_2> Make_x_monotone_result;
// Obtain an arrangement accessor.
Arr_accessor<Arr> arr_access(arr);
@ -88,19 +93,14 @@ void insert(Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits>& arr,
Arrangement_zone_2<Arr, Zone_visitor> arr_zone(arr, &visitor);
// Break the input curve into x-monotone subcurves and isolated points.
std::list<CGAL::Object> x_objects;
std::list<CGAL::Object>::const_iterator obj_iter;
const typename Gt2::X_monotone_curve_2* x_curve;
const typename Gt2::Point_2* iso_p;
arr.geometry_traits()->
make_x_monotone_2_object()(c, std::back_inserter(x_objects));
std::list<Make_x_monotone_result> x_objects;
const auto* traits = arr.geometry_traits();
traits->make_x_monotone_2_object()(c, std::back_inserter(x_objects));
// Insert each x-monotone curve into the arrangement.
for (obj_iter = x_objects.begin(); obj_iter != x_objects.end(); ++obj_iter) {
for (const auto& x_obj : x_objects) {
// Act according to the type of the current object.
x_curve = object_cast<typename Gt2::X_monotone_curve_2>(&(*obj_iter));
const auto* x_curve = boost::get<X_monotone_curve_2>(&x_obj);
if (x_curve != nullptr) {
// Inserting an x-monotone curve:
// Initialize the zone-computation object with the given curve.
@ -116,14 +116,13 @@ void insert(Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits>& arr,
// Notify the arrangement observers that the global operation has been
// completed.
arr_access.notify_after_global_change();
continue;
}
else {
iso_p = object_cast<typename Gt2::Point_2>(&(*obj_iter));
CGAL_assertion(iso_p != nullptr);
const auto* iso_p = boost::get<Point_2>(&x_obj);
CGAL_assertion(iso_p != nullptr);
// Inserting a point into the arrangement:
insert_point(arr, *iso_p, pl);
}
// Inserting a point into the arrangement:
insert_point(arr, *iso_p, pl);
}
}
@ -529,7 +528,9 @@ void insert(Arrangement_on_surface_2<GeometryTraits_2,TopologyTraits>& arr,
template <typename GeometryTraits_2, typename TopologyTraits>
void insert(Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits>& arr,
const typename GeometryTraits_2::X_monotone_curve_2& c,
const Object& obj)
typename Arr_point_location_result<
Arrangement_on_surface_2<GeometryTraits_2,
TopologyTraits> >::type obj)
{
typedef GeometryTraits_2 Gt2;
typedef TopologyTraits Tt;
@ -597,7 +598,8 @@ template <typename GeometryTraits_2, typename TopologyTraits>
CGAL_DEPRECATED void insert_x_monotone_curve
(Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits>& arr,
const typename GeometryTraits_2::X_monotone_curve_2& c,
const Object& obj)
typename Arr_point_location_result<
Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits> >::type obj)
{
insert(arr, c, obj);
}
@ -658,6 +660,7 @@ insert_non_intersecting_curve
Traits_adaptor_2;
typedef typename Arr::Vertex_const_handle Vertex_const_handle;
typedef typename Arr::Halfedge_const_handle Halfedge_const_handle;
typedef typename Arr::Face_const_handle Face_const_handle;
CGAL_USE_TYPE(Halfedge_const_handle);
const Traits_adaptor_2* geom_traits =
@ -666,13 +669,13 @@ insert_non_intersecting_curve
// Check whether the left end has boundary conditions, and locate it in the
// arrangement accordingly.
const Arr_parameter_space bx1 =
geom_traits->parameter_space_in_x_2_object()(c, ARR_MIN_END);
const Arr_parameter_space by1 =
geom_traits->parameter_space_in_y_2_object()(c, ARR_MIN_END);
CGAL::Object obj1;
auto bx1 = geom_traits->parameter_space_in_x_2_object()(c, ARR_MIN_END);
auto by1 = geom_traits->parameter_space_in_y_2_object()(c, ARR_MIN_END);
const Vertex_const_handle* vh1 = nullptr;
typedef Arr_point_location_result<Arr> Pl_result;
typename Pl_result::type obj1;
if ((bx1 == ARR_INTERIOR) && (by1 == ARR_INTERIOR)) {
// We have a normal left endpoint with no boundary conditions:
// use a point-location query.
@ -680,33 +683,26 @@ insert_non_intersecting_curve
// The endpoint must not lie on an existing edge, but may coincide with
// and existing vertex vh1.
CGAL_precondition_msg
(object_cast<Halfedge_const_handle>(&obj1) == nullptr,
"The curve must not intersect an existing edge.");
CGAL_precondition_msg(boost::get<Halfedge_const_handle>(&obj1) == nullptr,
"The curve must not intersect an existing edge.");
vh1 = object_cast<Vertex_const_handle>(&obj1);
}
else {
// We have a left end with boundary conditions. Use the accessor to locate
// the feature that contains it.
obj1 = arr_access.locate_curve_end(c, ARR_MIN_END, bx1, by1);
CGAL_precondition_msg
(object_cast<Halfedge_const_handle>(&obj1) == nullptr,
"The curve must not overlap an existing edge.");
vh1 = object_cast<Vertex_const_handle>(&obj1);
CGAL_precondition_msg(boost::get<Halfedge_const_handle>(&obj1) == nullptr,
"The curve must not overlap an existing edge.");
}
vh1 = Pl_result::template assign<Vertex_const_handle>(&obj1);
// Check whether the right end has boundary conditions, and locate it in the
// arrangement accordingly.
const Arr_parameter_space bx2 =
geom_traits->parameter_space_in_x_2_object()(c, ARR_MAX_END);
const Arr_parameter_space by2 =
geom_traits->parameter_space_in_y_2_object()(c, ARR_MAX_END);
CGAL::Object obj2;
auto bx2 = geom_traits->parameter_space_in_x_2_object()(c, ARR_MAX_END);
auto by2 = geom_traits->parameter_space_in_y_2_object()(c, ARR_MAX_END);
const Vertex_const_handle* vh2 = nullptr;
typename Pl_result::type obj2;
if ((bx2 == ARR_INTERIOR) && (by2 == ARR_INTERIOR)) {
// We have a normal right endpoint with no boundary conditions:
// use a point-location query.
@ -714,11 +710,8 @@ insert_non_intersecting_curve
// The endpoint must not lie on an existing edge, but may coincide with
// and existing vertex vh2.
CGAL_precondition_msg
(object_cast<Halfedge_const_handle>(&obj2) == nullptr,
"The curve must not intersect an existing edge.");
vh2 = object_cast<Vertex_const_handle>(&obj2);
CGAL_precondition_msg(boost::get<Halfedge_const_handle>(&obj2) == nullptr,
"The curve must not intersect an existing edge.");
}
else {
// We have a right end with boundary conditions. Use the accessor to locate
@ -728,13 +721,10 @@ insert_non_intersecting_curve
// << ", by2: " << by2
// << std::endl;
obj2 = arr_access.locate_curve_end(c, ARR_MAX_END, bx2, by2);
CGAL_precondition_msg
(object_cast<Halfedge_const_handle>(&obj2) == nullptr,
"The curve must not overlap an existing edge.");
vh2 = object_cast<Vertex_const_handle>(&obj2);
CGAL_precondition_msg(boost::get<Halfedge_const_handle>(&obj2) == nullptr,
"The curve must not overlap an existing edge.");
}
vh2 = Pl_result::template assign<Vertex_const_handle>(&obj2);
// Notify the arrangement observers that a global operation is about to
// take place.
@ -776,10 +766,8 @@ insert_non_intersecting_curve
// we must insert the curve in the interior of a face.
// In this case insert_in_face_interior() already returns a halfedge
// directed from left to right.
const typename Arr::Face_const_handle* fh1 =
object_cast<typename Arr::Face_const_handle>(&obj1);
const typename Arr::Face_const_handle* fh2 =
object_cast<typename Arr::Face_const_handle>(&obj2);
const Face_const_handle* fh1 = boost::get<Face_const_handle>(&obj1);
const Face_const_handle* fh2 = boost::get<Face_const_handle>(&obj2);
// std::cout << arr << std::endl;
// std::cout << "(*fh1)->number_of_outer_ccbs(): "
@ -1140,49 +1128,49 @@ insert_point(Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits>& arr,
typedef Arrangement_on_surface_2<Gt2, Tt> Arr;
typedef typename Arr::Vertex_const_handle Vertex_const_handle;
typedef typename Arr::Halfedge_const_handle Halfedge_const_handle;
typedef typename Arr::Face_const_handle Face_const_handle;
// Act according to the type of arrangement feature that contains the point.
const typename Arr::Face_const_handle* fh;
const typename Arr::Halfedge_const_handle* hh;
const typename Arr::Vertex_const_handle* vh;
typename Arr::Vertex_handle vh_for_p;
// Locate the given point in the arrangement.
CGAL::Object obj = pl.locate (p);
auto obj = pl.locate(p);
// Notify the arrangement observers that a global operation is about to
// take place.
Arr_accessor<Arr> arr_access (arr);
Arr_accessor<Arr> arr_access(arr);
arr_access.notify_before_global_change();
if ((fh = object_cast<typename Arr::Face_const_handle>(&obj)) != nullptr) {
const Face_const_handle* fh = boost::get<Face_const_handle>(&obj);
if (fh != nullptr) {
// p lies inside a face: Insert it as an isolated vertex it the interior of
// this face.
vh_for_p = arr.insert_in_face_interior(p, arr.non_const_handle (*fh));
}
else if ((hh = object_cast<typename Arr::Halfedge_const_handle>(&obj)) !=
nullptr)
{
// p lies in the interior of an edge: Split this edge to create a new
// vertex associated with p.
typename Gt2::X_monotone_curve_2 sub_cv1, sub_cv2;
typename Arr::Halfedge_handle split_he;
arr.geometry_traits()->split_2_object()((*hh)->curve(), p,
sub_cv1, sub_cv2);
split_he = arr.split_edge(arr.non_const_handle(*hh), sub_cv1, sub_cv2);
// The new vertex is the target of the returned halfedge.
vh_for_p = split_he->target();
}
else {
// In this case p lies on an existing vertex, so we just update this
// vertex.
vh = object_cast<typename Arr::Vertex_const_handle>(&obj);
CGAL_assertion (vh != nullptr);
const Halfedge_const_handle* hh = boost::get<Halfedge_const_handle>(&obj);
if (hh != nullptr) {
// p lies in the interior of an edge: Split this edge to create a new
// vertex associated with p.
typename Gt2::X_monotone_curve_2 sub_cv1, sub_cv2;
typename Arr::Halfedge_handle split_he;
vh_for_p = arr.modify_vertex (arr.non_const_handle (*vh), p);
const auto* gt = arr.geometry_traits();
gt->split_2_object()((*hh)->curve(), p, sub_cv1, sub_cv2);
split_he = arr.split_edge(arr.non_const_handle(*hh), sub_cv1, sub_cv2);
// The new vertex is the target of the returned halfedge.
vh_for_p = split_he->target();
}
else {
// p lies on an existing vertex, so we just update this vertex.
const Vertex_const_handle* vh = boost::get<Vertex_const_handle>(&obj);
CGAL_assertion(vh != nullptr);
vh_for_p = arr.modify_vertex (arr.non_const_handle (*vh), p);
}
}
// Notify the arrangement observers that the global operation has been
@ -1381,60 +1369,47 @@ is_valid(const Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits>& arr)
// Shoot a vertical ray from each vertex we have collected downward, and
// check that this vertex is really contained in the proper face.
typename Gt2::Compare_y_at_x_right_2 comp_y_at_x_right =
traits->compare_y_at_x_right_2_object();
typename Gt2::Compare_y_at_x_left_2 comp_y_at_x_left =
traits->compare_y_at_x_left_2_object();
auto comp_y_at_x_right = traits->compare_y_at_x_right_2_object();
auto comp_y_at_x_left = traits->compare_y_at_x_left_2_object();
typename std::list<std::pair<Vertex_const_handle,
Face_const_handle> >::iterator vf_iter;
typename Tt::Default_point_location_strategy def_pl(arr);
Vertex_const_handle curr_v;
Object obj;
Halfedge_const_handle he_below;
Vertex_const_handle v_below;
Face_const_handle in_face;
Halfedge_around_vertex_const_circulator first, circ;
bool assign_ok;
const Halfedge_const_handle invalid_he;
for (vf_iter = vf_list.begin(); vf_iter != vf_list.end(); ++vf_iter) {
Face_const_handle in_face;
for (auto vf_iter = vf_list.begin(); vf_iter != vf_list.end(); ++vf_iter) {
// Perform ray-shooting from the current vertex.
curr_v = vf_iter->first;
obj = def_pl.ray_shoot_down(curr_v->point());
Vertex_const_handle curr_v = vf_iter->first;
auto obj = def_pl.ray_shoot_down(curr_v->point());
if (CGAL::assign(he_below, obj)) {
// Hit an edge - take the incident face of the halfedge directed to the
// if (CGAL::assign(he_below, obj)) {
if (auto* he_below_p = boost::get<Halfedge_const_handle>(&obj)) {
// Hit an edge; take the incident face of the halfedge directed to the
// right.
if (he_below->direction() == ARR_RIGHT_TO_LEFT)
he_below = he_below->twin();
in_face = he_below->face();
auto he_below = *he_below_p;
in_face = (he_below->direction() == ARR_RIGHT_TO_LEFT) ?
he_below->twin()->face() : he_below->face();
}
else if (CGAL::assign(v_below, obj)) {
else if (auto* v_below_p = boost::get<Vertex_const_handle>(&obj)) {
auto v_below = *v_below_p;
// Hit a vertex.
if (v_below->is_isolated()) in_face = v_below->face();
else {
// Get the first halfedge around v_below that is directed from left to
// right and the first halfedge that is directed from right to left.
first = circ = v_below->incident_halfedges();
Halfedge_around_vertex_const_circulator circ =
v_below->incident_halfedges();
Halfedge_around_vertex_const_circulator first = circ;
Halfedge_const_handle he_left; // A halfedge to the left of v_below.
Halfedge_const_handle he_right; // A halfedge to the right of v_below.
do {
if (circ->direction() == ARR_LEFT_TO_RIGHT) {
he_left = circ;
}
if (circ->direction() == ARR_LEFT_TO_RIGHT) he_left = circ;
else {
he_right = circ;
if (he_left != invalid_he && he_right != invalid_he)
break;
if ((he_left != invalid_he) && (he_right != invalid_he)) break;
}
++circ;
} while(++circ != first);
} while(circ != first);
CGAL_assertion (he_left != invalid_he || he_right != invalid_he);
CGAL_assertion((he_left != invalid_he) || (he_right != invalid_he));
if (he_left != invalid_he && he_right != invalid_he) {
while (he_left->direction() == ARR_LEFT_TO_RIGHT)
@ -1460,26 +1435,24 @@ is_valid(const Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits>& arr)
else {
Comparison_result res;
Halfedge_const_handle he_curr = he_right;
do // as long as we have he_right halfedge which is below
{
do {
// as long as we have he_right halfedge which is below
he_right = he_curr;
he_curr = he_right->next()->twin();
res = comp_y_at_x_right (he_curr->curve(),
he_right->curve(),
v_below->point());
res = comp_y_at_x_right(he_curr->curve(),
he_right->curve(),
v_below->point());
} while(res == SMALLER);
in_face = he_right->face();
}
}
}
else {
auto* in_face_p = boost::get<Face_const_handle>(&obj);
CGAL_assertion(in_face_p);
in_face = *in_face_p;
// Hit nothing (an unbounded face is returned).
assign_ok = CGAL::assign(in_face, obj);
CGAL_assertion (assign_ok && in_face->is_unbounded());
if (! assign_ok) return false;
CGAL_assertion(in_face->is_unbounded());
}
if (vf_iter->second != in_face) {
@ -1611,35 +1584,34 @@ do_intersect(Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits>& arr,
// Break the input curve into x-monotone subcurves and isolated points.
typedef Arr_traits_adaptor_2<Gt2> Traits_adaptor_2;
typedef typename Gt2::Point_2 Point_2;
typedef typename Gt2::X_monotone_curve_2 X_monotone_curve_2;
typedef boost::variant<Point_2, X_monotone_curve_2> Make_x_monotone_result;
typedef typename Arr::Face_const_handle Face_const_handle;
const Traits_adaptor_2* traits =
static_cast<const Traits_adaptor_2*>(arr.geometry_traits());
std::list<CGAL::Object> x_objects;
std::list<CGAL::Object>::const_iterator obj_iter;
const typename Gt2::X_monotone_curve_2* x_curve;
const typename Gt2::Point_2* iso_p;
std::list<Make_x_monotone_result> x_objects;
traits->make_x_monotone_2_object()(c, std::back_inserter(x_objects));
// Insert each x-monotone curve into the arrangement.
for (obj_iter = x_objects.begin(); obj_iter != x_objects.end(); ++obj_iter) {
for (const auto& x_obj : x_objects) {
// Act according to the type of the current object.
x_curve = object_cast<typename Gt2::X_monotone_curve_2>(&(*obj_iter));
const X_monotone_curve_2* x_curve = boost::get<X_monotone_curve_2>(&x_obj);
if (x_curve != nullptr) {
// Check if the x-monotone subcurve intersects the arrangement.
if (do_intersect(arr, *x_curve, pl) == true)
return true;
if (do_intersect(arr, *x_curve, pl) == true) return true;
continue;
}
else {
iso_p = object_cast<typename Gt2::Point_2>(&(*obj_iter));
CGAL_assertion(iso_p != nullptr);
// Check whether the isolated point lies inside a face (otherwise,
// it conincides with a vertex or an edge).
CGAL::Object obj = pl.locate (*iso_p);
const Point_2* iso_p = boost::get<Point_2>(&x_obj);
CGAL_assertion(iso_p != nullptr);
return (object_cast<typename Arr::Face_const_handle>(&obj) != nullptr);
}
// Check whether the isolated point lies inside a face (otherwise,
// it conincides with a vertex or an edge).
auto obj = pl.locate(*iso_p);
if (boost::get<Face_const_handle>(&x_obj) != nullptr) return true;
}
// If we reached here, the curve does not intersect the arrangement.
@ -1651,8 +1623,8 @@ do_intersect(Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits>& arr,
template <typename GeometryTraits_2, typename TopologyTraits, typename Curve,
typename PointLocation>
bool
do_intersect (Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits>& arr,
const Curve& c, const PointLocation& pl)
do_intersect(Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits>& arr,
const Curve& c, const PointLocation& pl)
{
typedef GeometryTraits_2 Gt2;

View File

@ -7,16 +7,15 @@
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// Eric Berberich <eric.berberich@cgal.org>
// (based on old version by: Iddo Hanniel,
// Eyal Flato,
// Oren Nechushtan,
// Ester Ezra,
// Shai Hirsch,
// and Eugene Lipovetsky)
// Author(s): Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// Eric Berberich <eric.berberich@cgal.org>
// (based on old version by: Iddo Hanniel,
// Eyal Flato,
// Oren Nechushtan,
// Ester Ezra,
// Shai Hirsch,
// and Eugene Lipovetsky)
#ifndef CGAL_ARRANGEMENT_ON_SURFACE_2_IMPL_H
#define CGAL_ARRANGEMENT_ON_SURFACE_2_IMPL_H
@ -32,6 +31,8 @@
* class-template.
*/
#include <boost/variant.hpp>
#include <CGAL/function_objects.h>
#include <CGAL/use.h>
@ -2195,16 +2196,30 @@ _place_and_set_curve_end(DFace* f,
{
// Use the topology traits to locate the DCEL feature that contains the
// given curve end.
CGAL::Object obj =
m_topol_traits.place_boundary_vertex(f, cv, ind, ps_x, ps_y);
DVertex* v;
DHalfedge* fict_he;
auto obj = m_topol_traits.place_boundary_vertex(f, cv, ind, ps_x, ps_y);
// Act according to the result type.
if (CGAL::assign(fict_he, obj)) {
if (! obj) {
// We have to create a new vertex that reprsents the given curve end.
DVertex* v = _create_boundary_vertex(cv, ind, ps_x, ps_y);
// Notify the topology traits on the creation of the boundary vertex.
m_topol_traits.notify_on_boundary_vertex_creation(v, cv, ind, ps_x, ps_y);
// There are no edges incident to v, therefore no predecessor halfedge.
*p_pred = nullptr;
// Return the vertex that represents the curve end.
return v;
}
DHalfedge** fict_he_p = boost::get<DHalfedge*>(&*obj);
if (fict_he_p != nullptr) {
DHalfedge* fict_he = *fict_he_p;
CGAL_assertion(fict_he != nullptr);
// The curve end is located on a fictitious edge. We first create a new
// vertex that corresponds to the curve end.
v = _create_boundary_vertex(cv, ind, ps_x, ps_y);
DVertex* v = _create_boundary_vertex(cv, ind, ps_x, ps_y);
// Split the fictitious halfedge at the newly created vertex.
// The returned halfedge is the predecessor for the insertion of the curve
@ -2216,29 +2231,16 @@ _place_and_set_curve_end(DFace* f,
_notify_after_split_fictitious_edge(Halfedge_handle(*p_pred),
Halfedge_handle((*p_pred)->next()));
return v;
}
else if (CGAL::assign(v, obj)) {
// In this case we are given an existing vertex that represents the curve
// end. We now have to locate the predecessor edge for the insertion of cv
// around this vertex.
*p_pred =
m_topol_traits.locate_around_boundary_vertex(v, cv, ind, ps_x, ps_y);
}
else {
CGAL_assertion(obj.is_empty());
// In this case we have to create a new vertex that reprsents the given
// curve end.
v = _create_boundary_vertex(cv, ind, ps_x, ps_y);
// Notify the topology traits on the creation of the boundary vertex.
m_topol_traits.notify_on_boundary_vertex_creation(v, cv, ind, ps_x, ps_y);
// There are no edges incident to v, therefore no predecessor halfedge.
*p_pred = nullptr;
}
// Return the vertex that represents the curve end.
DVertex** v_p = boost::get<DVertex*>(&*obj);
CGAL_assertion(v_p != nullptr);
DVertex* v = *v_p;
CGAL_assertion(v != nullptr);
// In this case we are given an existing vertex that represents the curve
// end. We now have to locate the predecessor edge for the insertion of cv
// around this vertex.
*p_pred = m_topol_traits.locate_around_boundary_vertex(v, cv, ind, ps_x, ps_y);
return v;
}

View File

@ -29,7 +29,7 @@ namespace CGAL {
//
template <typename Arrangement, typename ZoneVisitor>
void Arrangement_zone_2<Arrangement, ZoneVisitor>::
init_with_hint(const X_monotone_curve_2& cv, const Object& obj)
init_with_hint(const X_monotone_curve_2& cv, Pl_result_type obj)
{
// Set the curve and check whether its ends are bounded, therefore
// associated with valid endpoints.
@ -95,9 +95,8 @@ void Arrangement_zone_2<Arrangement, ZoneVisitor>::compute_zone()
// curve (currently m_obj stores the object containing it).
const Vertex_const_handle* vh;
const Halfedge_const_handle* hh;
const Face_const_handle* fh;
if ((vh = object_cast<Vertex_const_handle>(&m_obj)) != nullptr) {
if ((vh = boost::get<Vertex_const_handle>(&m_obj)) != nullptr) {
CGAL_assertion(m_has_left_pt);
// The left endpoint coincides with an existing vertex:
@ -119,7 +118,7 @@ void Arrangement_zone_2<Arrangement, ZoneVisitor>::compute_zone()
#endif
}
else if ((hh = object_cast<Halfedge_const_handle>(&m_obj)) != nullptr) {
else if ((hh = boost::get<Halfedge_const_handle>(&m_obj)) != nullptr) {
if (m_has_left_pt) {
// Obtain the right halfedge from the halfedge-pair containing m_left_pt
// in their interior.
@ -160,7 +159,7 @@ void Arrangement_zone_2<Arrangement, ZoneVisitor>::compute_zone()
}
else {
// The left endpoint lies inside a face.
fh = object_cast<Face_const_handle>(&m_obj);
const Face_const_handle* fh = boost::get<Face_const_handle>(&m_obj);
CGAL_assertion_msg(fh != nullptr,
"Invalid object returned by the point-location query.");

View File

@ -2832,7 +2832,8 @@ void insert(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
template <typename GeomTraits, typename TopTraits>
void insert(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
const typename GeomTraits::X_monotone_curve_2& c,
const Object& obj);
typename Arr_point_location_result<
Arrangement_on_surface_2<GeomTraits, TopTraits> >::type obj);
/*!
* Insert an x-monotone curve into the arrangement, such that the curve
@ -2948,16 +2949,16 @@ remove_vertex(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
template <typename GeomTraits, typename TopTraits>
bool is_valid(const Arrangement_on_surface_2<GeomTraits, TopTraits>& arr);
/*!
* Compute the zone of the given x-monotone curve in the existing arrangement.
/*! Compute the zone of the given x-monotone curve in the existing arrangement.
* Meaning, it output the arrangment's vertices, edges and faces that the
* x-monotone curve intersects.
* \param arr The arrangement.
* \param c The x-monotone curve that its zone was computed.
* \param oi Output iterator of CGAL::Object to insert the zone elements to.
* \param pi The point location strategy that is used to locate the starting
* point.
* \return The output iterator that the curves were inserted to.
* \param c the x-monotone curve that its zone is computed.
* \param oi the output iterator for the resulting zone elements. Its
* dereference type is a variant that wraps a \c Vertex_handle, a
* \c Halfedge_handle, or a \c Face_handle.
* \param pl the point location strategy used to locate the starting point.
* \return the past-the-end output iterator.
*/
template <typename GeomTraits, typename TopTraits,
typename OutputIterator, typename PointLocation>
@ -2971,9 +2972,11 @@ OutputIterator zone(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
* Overloaded version with no point location object - the walk point-location
* strategy is used as default.
* \param arr The arrangement.
* \param c The x-monotone curve that its zone was computed.
* \param oi Output iterator of CGAL::Object to insert the zone elements to.
* \return The output iterator that the curves were inserted to.
* \param c the x-monotone curve that its zone was computed.
* \param oi the output iterator for the resulting zone elements. Its
* dereference type is a variant that wraps a \c Vertex_handle, a
* \c Halfedge_handle, or a \c Face_handle.
* \return the past-the-end output iterator.
*/
template <typename GeomTraits, typename TopTraits, typename OutputIterator>
OutputIterator zone(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,

View File

@ -28,6 +28,7 @@
#include <CGAL/Arr_tags.h>
#include <CGAL/Arr_accessor.h>
#include <CGAL/Arrangement_2/Arr_traits_adaptor_2.h>
#include <CGAL/Arr_point_location_result.h>
#include <list>
#include <map>
@ -113,6 +114,9 @@ protected:
typedef std::set<const X_monotone_curve_2*> Curves_set;
typedef typename Curves_set::iterator Curves_set_iterator;
typedef Arr_point_location_result<Arrangement_2> Pl_result;
typedef typename Pl_result::Type Pl_result_type;
// Data members:
Arrangement_2& m_arr; // The associated arrangement.
const Traits_adaptor_2* m_geom_traits; // Its associated geometry traits.
@ -127,7 +131,7 @@ protected:
X_monotone_curve_2 m_cv; // The current portion of the
// inserted curve.
CGAL::Object m_obj; // The location of the left endpoint.
Pl_result_type m_obj; // The location of the left endpoint.
bool m_has_left_pt; // Is the left end of the curve bounded.
bool m_left_on_boundary; // Is the left point on the boundary.
Point_2 m_left_pt; // Its current left endpoint.
@ -247,7 +251,7 @@ public:
* \param obj An object that represents the location of the left end of the
* curve.
*/
void init_with_hint(const X_monotone_curve_2& cv, const Object& obj);
void init_with_hint(const X_monotone_curve_2& cv, Pl_result_type obj);
/*! Compute the zone of the given curve and issue the apporpriate
* notifications for the visitor.

View File

@ -1410,9 +1410,9 @@ public:
* Functor that computes the intersections of two arcs
*/
template < class CurvedKernelViaAnalysis_2 >
class Intersect_2 : public
Curved_kernel_via_analysis_2_functor_base< CurvedKernelViaAnalysis_2 > {
class Intersect_2 :
public Curved_kernel_via_analysis_2_functor_base<CurvedKernelViaAnalysis_2>
{
public:
//! this instance' first template parameter
typedef CurvedKernelViaAnalysis_2 Curved_kernel_via_analysis_2;
@ -1420,13 +1420,17 @@ public:
//! the base type
typedef
Curved_kernel_via_analysis_2_functor_base< Curved_kernel_via_analysis_2 >
Base;
Base;
CGAL_CKvA_2_GRAB_BASE_FUNCTOR_TYPES
typedef unsigned int Multiplicity;
typedef std::pair<Point_2, Multiplicity> Intersection_point;
typedef boost::variant<Intersection_point, Arc_2> Intersection_result;
//! the result type
typedef CGAL::cpp98::iterator< std::output_iterator_tag, CGAL::Object >
result_type;
typedef CGAL::cpp98::iterator<std::output_iterator_tag, Intersection_result>
result_type;
//! the arity of the functor
@ -1458,11 +1462,6 @@ public:
template < class OutputIterator >
OutputIterator operator()(const Arc_2& cv1, const Arc_2& cv2,
OutputIterator oi) const {
typedef unsigned int Multiplicity;
typedef std::pair<Point_2, Multiplicity> Intersection_point;
typedef boost::variant<Intersection_point, Arc_2> Intersection_result;
CERR("\nintersect; cv1: " << cv1
<< ";\n cv2:" << cv2 << "");
@ -1860,100 +1859,110 @@ public:
/*!\brief
* Functor that decomposes curve into x-monotone arcs and isolated points
*/
template < class CurvedKernelViaAnalysis_2 >
template <class CurvedKernelViaAnalysis_2>
class Make_x_monotone_2 : public
Curved_kernel_via_analysis_2_functor_base< CurvedKernelViaAnalysis_2 > {
Curved_kernel_via_analysis_2_functor_base<CurvedKernelViaAnalysis_2> {
public:
//! this instance' first template parameter
typedef CurvedKernelViaAnalysis_2 Curved_kernel_via_analysis_2;
//! this instance' first template parameter
typedef CurvedKernelViaAnalysis_2 Curved_kernel_via_analysis_2;
//! the base type
typedef
Curved_kernel_via_analysis_2_functor_base< Curved_kernel_via_analysis_2 >
//! the base type
typedef
Curved_kernel_via_analysis_2_functor_base< Curved_kernel_via_analysis_2>
Base;
CGAL_CKvA_2_GRAB_BASE_FUNCTOR_TYPES
CGAL_CKvA_2_GRAB_BASE_FUNCTOR_TYPES
//! the result type
typedef CGAL::cpp98::iterator< std::output_iterator_tag, CGAL::Object >
//! the result type
typedef CGAL::cpp98::iterator< std::output_iterator_tag, CGAL::Object>
result_type;
//! the arity of the functor
//! the arity of the functor
/*!\brief
* Standard constructor
*
* \param kernel The kernel
*/
Make_x_monotone_2(Curved_kernel_via_analysis_2 *kernel) :
Base(kernel) {
}
/*!\brief
* Standard constructor
*
* \param kernel The kernel
*/
Make_x_monotone_2(Curved_kernel_via_analysis_2* kernel) :
Base(kernel)
{}
/*!\brief
* Decomposes a given arc into list of x-monotone arcs
* (subcurves) and insert them to the output iterator. Since \c Arc_2
* is by definition x-monotone, an input arc is passed to the
* output iterator directly.
*
* \param cv The arc
* \param oi The output iterator, whose value-type is Object
* The returned objects are all wrappers Arc_2 objects
* \return The past-the-end iterator
*/
template < class OutputIterator >
OutputIterator operator()(const Arc_2& cv, OutputIterator oi) const {
/*!\brief
* Decomposes a given arc into list of x-monotone arcs
* (subcurves) and insert them to the output iterator. Since \c Arc_2
* is by definition x-monotone, an input arc is passed to the
* output iterator directly.
*
* \param cv The arc
* \param oi The output iterator, whose value-type is Object
* The returned objects are all wrappers Arc_2 objects
* \return The past-the-end iterator
*/
template <class OutputIterator>
OutputIterator operator()(const Arc_2& cv, OutputIterator oi) const
{
typedef typename Curved_kernel_via_analysis_2::Point_2 Point_2;
typedef typename Curved_kernel_via_analysis_2::Arc_2 Arc_2;
typedef boost::variant<Point_2, Arc_2> Make_x_monotone_result;
*oi++ = Make_x_monotone_result(cv);
return oi;
}
*oi++ = CGAL::make_object(cv);
return oi;
}
/*!\brief
* Decomposes a given curve into list of x-monotone arcs
* (subcurves) and isolated points and insert them to the output iterator.
*
* \param cv The curve
* \param oi The output iterator, whose value-type is Object.
* The returned objects either wrapper Arc_2 or Point_2 objects
* \return The past-the-end iterator
*/
template <class OutputIterator>
OutputIterator operator()(const Curve_analysis_2& cv, OutputIterator oi)
const
{
CGAL::internal::Make_x_monotone_2< Curved_kernel_via_analysis_2 >
make_x_monotone(Base::_ckva());
/*!\brief
* Decomposes a given curve into list of x-monotone arcs
* (subcurves) and isolated points and insert them to the output iterator.
*
* \param cv The curve
* \param oi The output iterator, whose value-type is Object.
* The returned objects either wrapper Arc_2 or Point_2 objects
* \return The past-the-end iterator
*/
template < class OutputIterator >
OutputIterator operator()(const Curve_analysis_2& cv, OutputIterator oi)
const {
return make_x_monotone(cv, oi);
}
CGAL::internal::Make_x_monotone_2< Curved_kernel_via_analysis_2 >
make_x_monotone(Base::_ckva());
/*!\brief
* Splits an input object \c obj into x-monotone arcs and isolated points
*
* \param obj the polymorph input object: can represet \c Point_2,
* \c Arc_2, \c Non_x_monotone_arc_2 or \c Curve_analysis_2
* \param oi Output iterator that stores CGAL::Object, which either
* encapsulates \c Point_2 or \c Arc_2
* \return Past-the-end iterator of \c oi
*/
template <class OutputIterator>
OutputIterator operator()(CGAL::Object obj, OutputIterator oi)
{
typedef typename Curved_kernel_via_analysis_2::Point_2 Point_2;
typedef typename Curved_kernel_via_analysis_2::Arc_2 Arc_2;
typedef typename Curved_kernel_via_analysis_2::Non_x_monotone_arc_2
Non_x_monotone_arc_2;
typedef boost::variant<Point_2, Arc_2>
Make_x_monotone_result;
return make_x_monotone(cv, oi);
}
Curve_analysis_2 curve;
Point_2 p;
Arc_2 xcv;
Non_x_monotone_arc_2 nxarc;
/*!\brief
* Splits an input object \c obj into x-monotone arcs and isolated points
*
* \param obj the polymorph input object: can represet \c Point_2,
* \c Arc_2, \c Non_x_monotone_arc_2 or \c Curve_analysis_2
* \param oi Output iterator that stores CGAL::Object, which either
* encapsulates \c Point_2 or \c Arc_2
* \return Past-the-end iterator of \c oi
*/
template <class OutputIterator>
OutputIterator operator()(CGAL::Object obj, OutputIterator oi) {
typedef typename Curved_kernel_via_analysis_2::Non_x_monotone_arc_2
Non_x_monotone_arc_2;
Curve_analysis_2 curve;
Non_x_monotone_arc_2 nxarc;
if(CGAL::assign(curve, obj))
oi = (*this)(curve, oi);
else if(CGAL::assign(nxarc, obj))
std::cerr << "AU BACKE" << std::endl;
//oi = std::transform(nxarc.begin(), nxarc.end(), oi,
// std::ptr_fun(CGAL::make_object<Arc_2>));
else // allow the remaining objects to pass through
*oi++ = obj;
return oi;
}
if (CGAL::assign(curve, obj)) oi = (*this)(curve, oi);
else if (CGAL::assign(nxarc, obj))
std::cerr << "AU BACKE" << std::endl;
//oi = std::transform(nxarc.begin(), nxarc.end(), oi,
// std::ptr_fun(CGAL::make_object<Arc_2>));
else if (CGAL::assign(xcv, obj)) *oi++ = Make_x_monotone_result(xcv);
else if (CGAL::assign(p, obj)) *oi++ = Make_x_monotone_result(p);
else CGAL_error();
return oi;
}
};

View File

@ -169,12 +169,10 @@ public:
Coordinate_1 asym_info1, asym_info2;
CGAL::Arr_parameter_space ps1, ps2;
obj1 = cv1.curve().asymptotic_value_of_arc(
cv1.location(ce), cv1.arcno()
);
obj2 = cv2.curve().asymptotic_value_of_arc(
cv2.location(ce), cv2.arcno()
);
obj1 =
cv1.curve().asymptotic_value_of_arc(cv1.location(ce), cv1.arcno());
obj2 =
cv2.curve().asymptotic_value_of_arc(cv2.location(ce), cv2.arcno());
CGAL::Comparison_result filter_res = CGAL::EQUAL;

View File

@ -42,15 +42,26 @@ namespace internal {
* Isolated points are stored as \c CurvedKernelViaAnalysis_2::Point_2 objects.
*
* The resulting arcs and points are written to the output iterator as
* polymorphic \c CGAL::Object. Past-the-end value of the iterator is returned.
* polymorphic \c variant. Past-the-end value of the iterator is returned.
*
* EF: I believe that the inheritance from binary_function is not exploited,
* and thus redundant, but I keep it anyway.
*/
template < class CurvedKernelViaAnalysis_2,
class ConstructArc_2 =
typename CurvedKernelViaAnalysis_2::Construct_arc_2 >
struct Make_x_monotone_2 :
public CGAL::cpp98::binary_function< typename CurvedKernelViaAnalysis_2::Curve_2,
CGAL::cpp98::iterator<std::output_iterator_tag, CGAL::Object>,
CGAL::cpp98::iterator<std::output_iterator_tag, CGAL::Object> > {
public CGAL::cpp98::binary_function<
typename CurvedKernelViaAnalysis_2::Curve_2,
CGAL::cpp98::iterator<std::output_iterator_tag,
boost::variant<
typename CurvedKernelViaAnalysis_2::Point_2,
typename CurvedKernelViaAnalysis_2::Arc_2> >,
CGAL::cpp98::iterator<std::output_iterator_tag,
boost::variant<
typename CurvedKernelViaAnalysis_2::Point_2,
typename CurvedKernelViaAnalysis_2::Arc_2> > >
{
//!\name Public types
//!@{
@ -87,242 +98,250 @@ struct Make_x_monotone_2 :
typedef typename Curved_kernel_via_analysis_2::Non_x_monotone_arc_2
Non_x_monotone_arc_2;
//!@}
//!@}
//!\name Constructors
//!@{
//!\name Constructors
//!@{
/*!\brief
* Standard constructor
*
* \param kernel The kernel instance to use
*/
Make_x_monotone_2(Curved_kernel_via_analysis_2 *kernel) :
_m_curved_kernel(kernel) {
CGAL_assertion(kernel != nullptr);
/*!\brief
* Standard constructor
*
* \param kernel The kernel instance to use
*/
Make_x_monotone_2(Curved_kernel_via_analysis_2 *kernel) :
_m_curved_kernel(kernel)
{
CGAL_assertion(kernel != nullptr);
}
//!@}
//!\name Functor invokation
//!@{
// TODO add operator for non-x-monotone arc
/*!\brief
* Splits a curve into x-monotone arcs and isolated points
*
* \param curve The input curve
* \param oi the output iterator for the result. Its dereference type is a
* variant that wraps a Point_2 or an X_monotone_curve_2 objects.
* \return Past-the-end iterator of \c oi
*/
template <typename OutputIterator>
OutputIterator operator()(Curve_analysis_2 curve, OutputIterator oi)
{
typedef boost::variant<Point_2, Arc_2> Make_x_monotone_result;
Construct_arc_2 construct_arc_2 =
_m_curved_kernel->construct_arc_2_object();
// use CGAL::Total_degree ?
if (typename CGAL::Polynomial_traits_d<
typename Curve_analysis_2::Polynomial_2 >::
Total_degree()(curve.polynomial_2()) < 1)
{
return oi;
}
//!@}
Status_line_1 evt_line1, evt_line2,
int_line = curve.status_line_of_interval(0);
int total_events = curve.number_of_status_lines_with_event();
// handle special case of a curve without any events
if(total_events == 0) {
for (int k = 0; k < int_line.number_of_events(); k++)
*oi++ = Make_x_monotone_result(construct_arc_2(curve, k));
return oi;
}
_m_curve = curve;
typedef typename Curved_kernel_via_analysis_2::
Curve_interval_arcno_cache CIA_cache;
const CIA_cache& map_interval_arcno =
_m_curved_kernel->interval_arcno_cache();
//!\name Functor invokation
//!@{
typename Curved_kernel_via_analysis_2::Construct_point_2
construct_point =
_m_curved_kernel->construct_point_2_object();
// TODO add operator for non-x-monotone arc
typename CIA_cache::result_type info1, info2;
std::vector<Point_2> min_pts, max_pts;
Coordinate_1 min_x, max_x;
int i, k, n;
Arc_2 arc;
// first handle segments before first event
evt_line1 = curve.status_line_at_event(0);
max_x = evt_line1.x();
/*!\brief
* Splits a curve into x-monotone arcs and isolated points
*
* \param curve The input curve
* \param oi Output iterator that stores CGAL::Object, which either
* encapsulates Point_2 or Arc_2
* \return Past-the-end iterator of \c oi
*/
template <class OutputIterator>
OutputIterator operator()(Curve_analysis_2 curve, OutputIterator oi) {
for (k = 0; k < evt_line1.number_of_events(); k++)
max_pts.push_back(construct_point(max_x, curve, k));
Construct_arc_2 construct_arc_2 =
_m_curved_kernel->construct_arc_2_object();
// use CGAL::Total_degree ?
if (typename CGAL::Polynomial_traits_d<
typename Curve_analysis_2::Polynomial_2 >::
Total_degree()(curve.polynomial_2()) < 1) {
return oi;
}
//std::cout << "handling events over the 1st interval\n";
for (k = 0; k < int_line.number_of_events(); k++) {
Status_line_1 evt_line1, evt_line2,
int_line = curve.status_line_of_interval(0);
int total_events = curve.number_of_status_lines_with_event();
// handle special case of a curve without any events
if(total_events == 0) {
for(int k = 0; k < int_line.number_of_events(); k++)
*oi++ = CGAL::make_object(construct_arc_2(curve, k));
return oi;
}
_m_curve = curve;
typedef typename Curved_kernel_via_analysis_2::
Curve_interval_arcno_cache CIA_cache;
const CIA_cache& map_interval_arcno =
_m_curved_kernel->interval_arcno_cache();
info1 = map_interval_arcno(evt_line1, 1, k);
if (info1.second != CGAL::ARR_INTERIOR) {
arc = construct_arc_2(CGAL::ARR_MIN_END, max_x,
(info1.second ==
CGAL::ARR_BOTTOM_BOUNDARY ?
CGAL::ARR_MIN_END : CGAL::ARR_MAX_END),
curve, k);
}
else {
arc = construct_arc_2(max_pts[info1.first], CGAL::ARR_MIN_END,
curve, k, info1.first);
}
*oi++ = Make_x_monotone_result(arc);
}
min_pts = max_pts;
max_pts.clear();
min_x = max_x;
typename Curved_kernel_via_analysis_2::Construct_point_2
construct_point =
_m_curved_kernel->construct_point_2_object();
// next handle arcs between events, including isolated points
for (i = 0; i < total_events-1; i++) {
evt_line1 = curve.status_line_at_event(i);
evt_line2 = curve.status_line_at_event(i+1);
max_x = evt_line2.x();
oi = _handle_vertical_and_isolated(evt_line1, min_x, min_pts, oi);
typename CIA_cache::result_type info1, info2;
std::vector<Point_2> min_pts, max_pts;
Coordinate_1 min_x, max_x;
int i, k, n;
Arc_2 arc;
// first handle segments before first event
evt_line1 = curve.status_line_at_event(0);
max_x = evt_line1.x();
n = evt_line2.number_of_events();
for (k = 0; k < n; k++)
max_pts.push_back(construct_point(max_x, curve, k));
for(k = 0; k < evt_line1.number_of_events(); k++)
max_pts.push_back(construct_point(max_x, curve, k));
//std::cout << "handling events over the 1st interval\n";
for(k = 0; k < int_line.number_of_events(); k++) {
info1 = map_interval_arcno(evt_line1, 1, k);
if (info1.second != CGAL::ARR_INTERIOR) {
arc = construct_arc_2(CGAL::ARR_MIN_END, max_x,
(info1.second ==
CGAL::ARR_BOTTOM_BOUNDARY ?
CGAL::ARR_MIN_END : CGAL::ARR_MAX_END),
curve, k);
} else {
arc = construct_arc_2(max_pts[info1.first], CGAL::ARR_MIN_END,
curve, k, info1.first
);
}
*oi++ = CGAL::make_object(arc);
}
min_pts = max_pts;
max_pts.clear();
min_x = max_x;
// next handle arcs between events, including isolated points
for (i = 0; i < total_events-1; i++) {
evt_line1 = curve.status_line_at_event(i);
evt_line2 = curve.status_line_at_event(i+1);
max_x = evt_line2.x();
oi = _handle_vertical_and_isolated(evt_line1, min_x, min_pts, oi);
n = evt_line2.number_of_events();
for(k = 0; k < n; k++)
max_pts.push_back(construct_point(max_x, curve, k));
n = curve.status_line_of_interval(i+1).number_of_events();
CGAL::Arr_curve_end inf1_end, inf2_end;
for (k = 0; k < n; k++) {
info1 = map_interval_arcno(evt_line1, 0, k);
info2 = map_interval_arcno(evt_line2, 1, k);
inf2_end = (info2.second == CGAL::ARR_BOTTOM_BOUNDARY ?
n = curve.status_line_of_interval(i+1).number_of_events();
CGAL::Arr_curve_end inf1_end, inf2_end;
for (k = 0; k < n; k++) {
info1 = map_interval_arcno(evt_line1, 0, k);
info2 = map_interval_arcno(evt_line2, 1, k);
inf2_end = (info2.second == CGAL::ARR_BOTTOM_BOUNDARY ?
CGAL::ARR_MIN_END : CGAL::ARR_MAX_END);
if (info1.second != CGAL::ARR_INTERIOR) {
inf1_end = (info1.second == CGAL::ARR_BOTTOM_BOUNDARY ?
CGAL::ARR_MIN_END : CGAL::ARR_MAX_END);
if (info2.second != CGAL::ARR_INTERIOR) {
arc = construct_arc_2(min_x, inf1_end, max_x, inf2_end,
curve, k);
} else {
arc = construct_arc_2(max_pts[info2.first], min_x,
inf1_end, curve, k, info2.first);
}
} else if (info2.second != CGAL::ARR_INTERIOR) {
arc = construct_arc_2(min_pts[info1.first], max_x,
inf2_end, curve, k, info1.first);
} else {
arc = construct_arc_2(min_pts[info1.first],
max_pts[info2.first],
curve, k, info1.first, info2.first);
}
*oi++ = CGAL::make_object(arc);
}
min_pts = max_pts;
max_pts.clear();
min_x = max_x;
if (info1.second != CGAL::ARR_INTERIOR) {
inf1_end = (info1.second == CGAL::ARR_BOTTOM_BOUNDARY ?
CGAL::ARR_MIN_END : CGAL::ARR_MAX_END);
if (info2.second != CGAL::ARR_INTERIOR) {
arc = construct_arc_2(min_x, inf1_end, max_x, inf2_end,
curve, k);
}
else {
arc = construct_arc_2(max_pts[info2.first], min_x,
inf1_end, curve, k, info2.first);
}
}
// here: min_x/min_pts hold information about the last event line
// event_line2 - points to the last event line
// vertical line or isolated points at last event?
evt_line2 = curve.status_line_at_event(total_events-1);
min_x = evt_line2.x();
oi = _handle_vertical_and_isolated(evt_line2, min_x, min_pts, oi);
n = curve.status_line_of_interval(total_events).number_of_events();
for (k = 0; k < n; k++) {
info1 = map_interval_arcno(evt_line2, 0, k);
if (info1.second != CGAL::ARR_INTERIOR) {
arc = construct_arc_2(
CGAL::ARR_MAX_END, min_x,
(info1.second == CGAL::ARR_BOTTOM_BOUNDARY ?
CGAL::ARR_MIN_END : CGAL::ARR_MAX_END), curve, k
);
} else {
arc = construct_arc_2(min_pts[info1.first],
CGAL::ARR_MAX_END, curve, k,
info1.first);
}
*oi++ = CGAL::make_object(arc);
else if (info2.second != CGAL::ARR_INTERIOR) {
arc = construct_arc_2(min_pts[info1.first], max_x,
inf2_end, curve, k, info1.first);
}
return oi;
else {
arc = construct_arc_2(min_pts[info1.first],
max_pts[info2.first],
curve, k, info1.first, info2.first);
}
*oi++ = Make_x_monotone_result(arc);
}
min_pts = max_pts;
max_pts.clear();
min_x = max_x;
}
//!@}
// here: min_x/min_pts hold information about the last event line
// event_line2 - points to the last event line
// vertical line or isolated points at last event?
evt_line2 = curve.status_line_at_event(total_events-1);
min_x = evt_line2.x();
oi = _handle_vertical_and_isolated(evt_line2, min_x, min_pts, oi);
n = curve.status_line_of_interval(total_events).number_of_events();
for (k = 0; k < n; k++) {
info1 = map_interval_arcno(evt_line2, 0, k);
if (info1.second != CGAL::ARR_INTERIOR) {
arc = construct_arc_2(CGAL::ARR_MAX_END, min_x,
(info1.second == CGAL::ARR_BOTTOM_BOUNDARY ?
CGAL::ARR_MIN_END : CGAL::ARR_MAX_END), curve, k
);
}
else {
arc = construct_arc_2(min_pts[info1.first],
CGAL::ARR_MAX_END, curve, k,
info1.first);
}
*oi++ = Make_x_monotone_result(arc);
}
return oi;
}
//!@}
private:
//!\name Private members
//!@{
//!\name Private members
//!@{
/*!\brief
* Constructs vertical arcs and isolated points at event line
*
* \param cv_line The event line in focus
* \param x x-coordinate of event
* \param pts Points at event line
* \param oi Output iterator that stores CGAL::Object, which either
* encapsulates Point_2 or Arc_2
* \return Past-the-end iterator of \c oi
*/
template <class OutputIterator>
OutputIterator _handle_vertical_and_isolated(
Status_line_1 cv_line,
Coordinate_1 x, std::vector<Point_2> pts,
OutputIterator oi) const {
/*!\brief
* Constructs vertical arcs and isolated points at event line
*
* \param cv_line The event line in focus
* \param x x-coordinate of event
* \param pts Points at event line
* \param oi the output iterator for the result. Its dereference type is a
* variant that wraps a Point_2 or an X_monotone_curve_2 objects.
* \return Past-the-end iterator of \c oi
*/
template <class OutputIterator>
OutputIterator
_handle_vertical_and_isolated(Status_line_1 cv_line,
Coordinate_1 x, std::vector<Point_2> pts,
OutputIterator oi) const
{
typedef boost::variant<Point_2, Arc_2> Make_x_monotone_result;
Construct_arc_2 construct_arc_2 =
_m_curved_kernel->construct_arc_2_object();
Construct_arc_2 construct_arc_2 =
_m_curved_kernel->construct_arc_2_object();
int n = cv_line.number_of_events(), j;
if(cv_line.covers_line()) { // look for vertical arcs
if(n > 0) {
// the first vertical ray
*oi++ = CGAL::make_object(
construct_arc_2(pts[0], CGAL::ARR_MIN_END, _m_curve)
);
for(j = 0; j < n-1; j++) // interior bounded arcs
*oi++ = CGAL::make_object(construct_arc_2(pts[j], pts[j+1],
_m_curve));
// the last vertical ray
*oi++ = CGAL::make_object(construct_arc_2(pts[n-1],
CGAL::ARR_MAX_END, _m_curve));
} else // unbounded vertical line
*oi++ = CGAL::make_object(construct_arc_2(x, _m_curve));
return oi;
}
// look for isolated points
std::pair<int, int> ipair;
for(j = 0; j < n; j++) {
ipair = cv_line.number_of_incident_branches(j);
if(ipair.first == 0&&ipair.second == 0) {
//std::cout << "isolated point found\n";
typename Curved_kernel_via_analysis_2::Construct_point_2
construct_point =
_m_curved_kernel->construct_point_2_object();
*oi++ = CGAL::make_object(construct_point(x, _m_curve, j));
}
}
return oi;
int n = cv_line.number_of_events(), j;
if (cv_line.covers_line()) { // look for vertical arcs
if (n > 0) {
// the first vertical ray
*oi++ =
Make_x_monotone_result(construct_arc_2(pts[0], CGAL::ARR_MIN_END,
_m_curve));
for (j = 0; j < n-1; j++) // interior bounded arcs
*oi++ = Make_x_monotone_result(construct_arc_2(pts[j], pts[j+1],
_m_curve));
// the last vertical ray
*oi++ =
Make_x_monotone_result(construct_arc_2(pts[n-1], CGAL::ARR_MAX_END,
_m_curve));
}
else // unbounded vertical line
*oi++ = Make_x_monotone_result(construct_arc_2(x, _m_curve));
return oi;
}
// look for isolated points
std::pair<int, int> ipair;
for (j = 0; j < n; j++) {
ipair = cv_line.number_of_incident_branches(j);
if (ipair.first == 0&&ipair.second == 0) {
//std::cout << "isolated point found\n";
typename Curved_kernel_via_analysis_2::Construct_point_2
construct_point = _m_curved_kernel->construct_point_2_object();
//!@}
*oi++ = Make_x_monotone_result(construct_point(x, _m_curve, j));
}
}
return oi;
}
//!\name Private data
//!@{
//!@}
//! pointer to \c Curved_kernel_via_analysis_2
Curved_kernel_via_analysis_2 *_m_curved_kernel;
//!\name Private data
//!@{
//! to avoid passing curve as a parameter
Curve_analysis_2 _m_curve;
//! pointer to \c Curved_kernel_via_analysis_2
Curved_kernel_via_analysis_2 *_m_curved_kernel;
//!@}
}; // struct Make_x_monotone
//! to avoid passing curve as a parameter
Curve_analysis_2 _m_curve;
//!@}
}; // struct Make_x_monotone
} // namespace internal

View File

@ -699,13 +699,14 @@ public:
* is by definition x-monotone, an input arc is passed to the
* output iterator directly.
* \param cv The curve.
* \param oi The output iterator, whose value-type is Object.
* The returned objects are all wrappers X_monotone_curve_2 objects.
* \return The past-the-end iterator.
* \param oi The output iteratorfor the result. Its dereference type is a
* variant that wraps a \c Point_2 or an \c X_monotone_curve_2
* objects..
* \return The past-the-end output iterator.
*/
template<class OutputIterator>
OutputIterator operator()(const Generic_arc_2& cv,
OutputIterator oi) const {
OutputIterator operator()(const Generic_arc_2& cv, OutputIterator oi) const
{
*oi++ = cv;
return oi;
}
@ -714,32 +715,32 @@ public:
* decompose a given curve into list of x-monotone pieces
* (subcurves) and insert them to the output iterator.
* \param cv The curve.
* \param oi The output iterator, whose value-type is Object.
* The returned objects are all wrappers X_monotone_curve_2 objects.
* \return The past-the-end iterator.
* \param oi the output iterator for the result. Its dereference type is a
* variant that wraps a \c Point_2 or an \c X_monotone_curve_2
* objects.
* \return The past-the-end output iterator.
*/
template<class OutputIterator>
OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const {
typedef typename SweepCurvesAdapter_2::Native_arc_2 Native_arc_2;
typedef typename SweepCurvesAdapter_2::Native_point_2 Native_point_2;
typedef typename SweepCurvesAdapter_2::Generic_point_2 Generic_point_2;
typedef typename SweepCurvesAdapter_2::Native_arc_2 Native_arc_2;
typedef typename SweepCurvesAdapter_2::Native_point_2 Native_point_2;
typedef typename SweepCurvesAdapter_2::Generic_point_2 Generic_point_2;
typedef boost::variant<Native_arc_2, Native_point_2>
Make_x_monotone_result;
typedef std::vector<CGAL::Object> Objects;
Objects objs;
_m_adapter->kernel().make_x_monotone_2_object()(cv,
std::back_inserter(objs));
std::vector<Make_x_monotone_result> objs;
auto make_x_monotone = _m_adapter->kernel().make_x_monotone_2_object();
make_x_monotone(cv, std::back_inserter(objs));
// sort out normal and degenerate arcs
for(typename Objects::const_iterator it = objs.begin();
it != objs.end(); it++) {
Native_arc_2 arc;
Native_point_2 pt;
if(CGAL::assign(arc, *it))
*oi++ = Generic_arc_2(arc);
else if(CGAL::assign(pt, *it))
*oi++ = Generic_arc_2(Generic_point_2(pt));
else
CGAL_error_msg("Bogus object..\n");
for (auto& obj : objs) {
if (auto* arc = boost::get<Native_arc_2>(&obj)) {
*oi++ = Generic_arc_2(*arc);
continue;
}
auto* pt = boost::get<Native_point_2>(&obj);
CGAL_assertion(pt);
*oi++ = Generic_arc_2(Generic_point_2(*pt));
}
return oi;
}

View File

@ -23,7 +23,6 @@
* Defintion of the Arr_basic_insertion_traits_2<Traits,Arrangement> class.
*/
#include <CGAL/Object.h>
#include <CGAL/Arr_tags.h>
#include <list>

View File

@ -23,7 +23,6 @@
*/
#include <CGAL/Arr_point_location_result.h>
#include <CGAL/Object.h>
#include <CGAL/Surface_sweep_2/Default_visitor_base.h>
#include <CGAL/Default.h>

View File

@ -8,9 +8,9 @@
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// Author(s): Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
#ifndef CGAL_ARR_NO_INTERSECTION_INSERTION_SS_VISITOR_H
#define CGAL_ARR_NO_INTERSECTION_INSERTION_SS_VISITOR_H

View File

@ -26,7 +26,6 @@
#include <boost/optional.hpp>
#include <CGAL/Arr_tags.h>
#include <CGAL/Object.h>
namespace CGAL {

View File

@ -7,9 +7,8 @@
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efifogel@gmail.com>
// Author(s): Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efifogel@gmail.com>
#ifndef CGAL_ARR_VERT_DECOMP_SS_VISITOR_H
#define CGAL_ARR_VERT_DECOMP_SS_VISITOR_H
@ -21,10 +20,11 @@
* Definition of the Arr_vert_decomp_ss_visitor class-template.
*/
#include <boost/variant.hpp>
namespace CGAL {
#include <CGAL/Surface_sweep_2/Default_visitor_base.h>
#include <CGAL/Object.h>
#include <CGAL/Default.h>
/*! \class Arr_vert_decomp_ss_visitor
@ -63,13 +63,18 @@ private:
public:
typedef typename Helper::Arrangement_2 Arrangement_2;
typedef typename Arrangement_2::Vertex_const_handle Vertex_const_handle;
typedef typename Arrangement_2::Halfedge_const_handle Halfedge_const_handle;
typedef typename Arrangement_2::Face_const_handle Face_const_handle;
typedef std::pair<CGAL::Object, CGAL::Object> Vert_pair;
typedef boost::variant<Vertex_const_handle, Halfedge_const_handle,
Face_const_handle>
Cell_type;
typedef boost::optional<Cell_type> Vert_type;
typedef std::pair<Vert_type, Vert_type> Vert_pair;
typedef std::pair<Vertex_const_handle, Vert_pair> Vert_entry;
protected:
typedef typename Base::Status_line_iterator Status_line_iterator;
typedef typename Arrangement_2::Halfedge_const_handle Halfedge_const_handle;
//typedef typename Arrangement_2::Vertex_const_handle Vertex_const_handle;
typedef typename Arrangement_2::Halfedge_around_vertex_const_circulator
Halfedge_around_vertex_const_circulator;
@ -84,8 +89,8 @@ protected:
// An invalid vertex handle.
Vertex_const_handle m_prev_vh; // The previous vertex.
CGAL::Object m_prev_obj_below; // The object this vertex sees below it.
CGAL::Object m_prev_obj_above; // The object this vertex sees above it.
Vert_type m_prev_obj_below; // The object this vertex sees below it.
Vert_type m_prev_obj_above; // The object this vertex sees above it.
Output_iterator* m_out; // An output iterator for the result.
@ -155,7 +160,7 @@ after_handle_event(Event* event,
// Get the vertex handle associated with the current event (stored with
// the point).
Vertex_const_handle vh = event->point().vertex_handle();
CGAL::Object obj_above, obj_below;
Vert_type obj_above, obj_below;
// Check the feature from above.
if (above == this->status_line_end()) {
@ -166,8 +171,7 @@ after_handle_event(Event* event,
else {
// We have a valid subcurve above the event: get its halfedge handle
// and associate it with the vertex.
obj_above =
CGAL::make_object((*above)->last_curve().halfedge_handle());
obj_above = Vert_type((*above)->last_curve().halfedge_handle());
}
// Check if the previous vertex we handled has the same x-coordinate
@ -206,12 +210,12 @@ after_handle_event(Event* event,
}
if (! vert_connected) {
obj_below = CGAL::make_object(m_prev_vh);
m_prev_obj_above = CGAL::make_object(vh);
obj_below = Vert_type(m_prev_vh);
m_prev_obj_above = Vert_type(vh);
}
else {
obj_below = CGAL::Object();
m_prev_obj_above = CGAL::Object();
obj_below = Vert_type();
m_prev_obj_above = Vert_type();
}
}
else {
@ -260,19 +264,18 @@ after_handle_event(Event* event,
}
if (! vert_connected) {
obj_below = CGAL::make_object(m_prev_vh);
m_prev_obj_above = CGAL::make_object(vh);
obj_below = Vert_type(m_prev_vh);
m_prev_obj_above = Vert_type(vh);
}
else {
obj_below = CGAL::Object();
m_prev_obj_above = CGAL::Object();
obj_below = Vert_type();
m_prev_obj_above = Vert_type();
}
}
else {
// Get the halfedge handle of the subcurve below the current event and
// associate it with its vertex.
obj_below =
CGAL::make_object((*below)->last_curve().halfedge_handle());
obj_below = Vert_type((*below)->last_curve().halfedge_handle());
}
}

View File

@ -208,8 +208,7 @@ verify(InputIterator begin, InputIterator end)
typename TopolTraits::Default_point_location_strategy pl(m_arr);
for (InputIterator it = begin; it != end; ++it) {
if (m_verbose_level > 1)
print(*it);
if (m_verbose_level > 1) print(*it);
// Perform (single) point location.
Result_type obj = pl.locate(it->first);

View File

@ -71,10 +71,10 @@ read_xcurve(InputStream_& is, typename GeomTraits_::X_monotone_curve_2& xcv)
typedef GeomTraits_ Geom_traits;
Basic_number_type x1, y1, x2, y2;
is >> x1 >> y1 >> x2 >> y2;
CGAL_assertion(!is.fail());
assert(!is.fail());
Point_2 p1(x1, y1);
Point_2 p2(x2, y2);
CGAL_assertion(p1 != p2);
assert(p1 != p2);
xcv = typename Geom_traits::X_monotone_curve_2(p1, p2);
return true;
}
@ -89,7 +89,7 @@ read_curve(InputStream_& is, typename GeomTraits_::Curve_2& cv)
is >> x1 >> y1 >> x2 >> y2;
Point_2 p1(x1, y1);
Point_2 p2(x2, y2);
CGAL_assertion(p1 != p2);
assert(p1 != p2);
cv = typename Geom_traits::Curve_2(p1, p2);
return true;
}
@ -690,21 +690,20 @@ bool IO_base_test<Base_geom_traits>::read_xsegment(InputStream_& is,
point_vector.push_back(Control_point_2(point_x, point_y));
}
//get the non x-monotone bezier segment
Subcurve_2 seg (point_vector.begin(), point_vector.end());
Subcurve_2 seg(point_vector.begin(), point_vector.end());
//convert it into x-monotone bezier segment.
std::vector<CGAL::Object> obj_vector;
bezier_traits.make_x_monotone_2_object()(seg,
std::back_inserter(obj_vector));
X_monotone_subcurve_2 x_segment =
CGAL::object_cast<X_monotone_subcurve_2>((obj_vector[0]));
xseg = x_segment;
typedef boost::variant<Point_2, X_monotone_subcurve_2> Make_x_monotone_result;
std::vector<Make_x_monotone_result> objs;
bezier_traits.make_x_monotone_2_object()(seg, std::back_inserter(objs));
assert(! objs.empty());
const auto* x_seg_p = boost::get<X_monotone_subcurve_2>(&(objs[0]));
assert(x_seg_p);
xseg = *x_seg_p;
return true;
}
template <>
template <typename InputStream_>
bool IO_base_test<Base_geom_traits>::read_xcurve(InputStream_& is,
@ -721,6 +720,8 @@ bool IO_base_test<Base_geom_traits>::read_xcurve(InputStream_& is,
unsigned int number_of_segments;
is >> number_of_segments;
typedef boost::variant<Point_2, X_monotone_subcurve_2> Make_x_monotone_result;
auto make_x_monotone = bezier_traits.make_x_monotone_2_object();
if ((type == 'x') || (type == 'X')) {
for (unsigned int i=0; i<number_of_segments; ++i) {
unsigned int num_control_points;
@ -737,13 +738,12 @@ bool IO_base_test<Base_geom_traits>::read_xcurve(InputStream_& is,
Subcurve_2 seg(point_vector.begin(), point_vector.end());
//convert it into x-monotone bezier segment.
std::vector<CGAL::Object> obj_vector;
bezier_traits.make_x_monotone_2_object()(seg,
std::back_inserter(obj_vector));
X_monotone_subcurve_2 x_seg =
CGAL::object_cast<X_monotone_subcurve_2>((obj_vector[0]));
x_segments.push_back(x_seg);
std::vector<Make_x_monotone_result> objs;
make_x_monotone(seg, std::back_inserter(objs));
assert(! objs.empty());
const auto* x_seg_p = boost::get<X_monotone_subcurve_2>(&(objs[0]));
assert(x_seg_p);
x_segments.push_back(*x_seg_p);
} //for loop (number of segments)
}
@ -1470,8 +1470,8 @@ bool IO_base_test<Base_geom_traits>::read_xcurve(InputStream_& is,
X_monotone_curve_2& xcv)
{
std::cout << std::endl;
std::list<CGAL::Object> x_objs;
std::list<CGAL::Object>::const_iterator xoit;
typedef boost::variant<Point_2, X_monotone_curve_2> Make_x_monotone_result;
std::list<Make_x_monotone_result> x_objs;
Curve_2 tmp_cv;
is >> tmp_cv;
Rational B_psx = Rational(tmp_cv.control_point(0).x());
@ -1482,15 +1482,15 @@ bool IO_base_test<Base_geom_traits>::read_xcurve(InputStream_& is,
Rational(tmp_cv.control_point(tmp_cv.number_of_control_points()-1).y());
Point_2 B_ps(B_psx, B_psy);
Point_2 B_pt(B_ptx, B_pty);
Base_geom_traits::Make_x_monotone_2 make_x_monotone =
this->m_geom_traits.make_x_monotone_2_object();
make_x_monotone(tmp_cv, std::front_inserter (x_objs));
xoit = x_objs.begin();
auto make_x_monotone = this->m_geom_traits.make_x_monotone_2_object();
make_x_monotone(tmp_cv, std::front_inserter(x_objs));
auto xoit = x_objs.begin();
size_t id(0);
if (!is.eof()) is >> id;
if (! is.eof()) is >> id;
std::advance(xoit, id);
if (CGAL::assign(xcv, *xoit))
return true;
const auto* xcv_p = boost::get<X_monotone_curve_2>(&*xoit);
assert(xcv_p);
xcv = *xcv_p;
return false;
}
@ -1546,9 +1546,8 @@ bool IO_base_test<Base_geom_traits>::read_point(InputStream_& is, Point_2& p) {
is >> x;
Base_geom_traits::X_monotone_curve_2 xcv;
CGAL::swallow(is, '(');
CGAL_assertion_code(bool check = )
read_xcurve(is, xcv);
CGAL_assertion(check);
bool check = read_xcurve(is, xcv);
assert(check);
CGAL::swallow(is, ')');
p = construct_point_2(x, xcv);
@ -1558,9 +1557,8 @@ bool IO_base_test<Base_geom_traits>::read_point(InputStream_& is, Point_2& p) {
Base_geom_traits::Algebraic_real_1 x;
is >> x;
Base_geom_traits::Curve_2 c;
CGAL_assertion_code(bool check = )
read_curve(is, c);
CGAL_assertion(check);
bool check = read_curve(is, c);
assert(check);
int arcno = 0;
is >> arcno;
p = construct_point_2(x, c, arcno);
@ -1589,36 +1587,31 @@ bool IO_base_test<Base_geom_traits>::read_xcurve(InputStream_& is,
switch (type) {
case '1': {
Curve_2 cv;
Point_2 end_left,end_right;
CGAL_assertion_code(bool check = )
read_curve(is,cv);
CGAL_assertion(check);
Point_2 end_left, end_right;
bool check = read_curve(is,cv);
assert(check);
CGAL::swallow(is, '(');
CGAL_assertion_code(check = )
read_point(is,end_left);
CGAL_assertion(check);
check = read_point(is,end_left);
assert(check);
CGAL::swallow(is, ')');
CGAL::swallow(is, '(');
CGAL_assertion_code(check = )
read_point(is,end_right);
CGAL_assertion(check);
check = read_point(is,end_right);
assert(check);
CGAL::swallow(is, ')');
std::vector<Base_geom_traits::X_monotone_curve_2> xcvs;
construct_segment_2(cv, end_left, end_right, std::back_inserter(xcvs));
CGAL_assertion(xcvs.size() == 1);
assert(xcvs.size() == 1);
xcv = xcvs[0];
break;
}
case '2': {
Curve_2 cv;
Point_2 p;
CGAL_assertion_code(bool check = )
read_curve(is, cv);
CGAL_assertion(check);
bool check = read_curve(is, cv);
assert(check);
CGAL::swallow(is, '(');
CGAL_assertion_code(check = )
read_point(is, p);
CGAL_assertion(check);
check = read_point(is, p);
assert(check);
CGAL::swallow(is, ')');
std::string site_of_p_string;
Base_geom_traits::Site_of_point site_of_p;
@ -1630,12 +1623,12 @@ bool IO_base_test<Base_geom_traits>::read_xcurve(InputStream_& is,
site_of_p = Base_geom_traits::MAX_ENDPOINT;
}
else {
CGAL_assertion(site_of_p_string == "POINT_IN_INTERIOR");
assert(site_of_p_string == "POINT_IN_INTERIOR");
site_of_p = Base_geom_traits::POINT_IN_INTERIOR;
}
std::vector<Base_geom_traits::X_monotone_curve_2> xcvs;
construct_segment_2(cv, p, site_of_p, std::back_inserter(xcvs));
CGAL_assertion(xcvs.size() == 1);
assert(xcvs.size() == 1);
xcv = xcvs[0];
break;
}
@ -1685,7 +1678,7 @@ bool IO_base_test<Base_geom_traits>::read_xcurve(InputStream_& is,
Point_2 p1, p2;
read_point(is, p1);
read_point(is, p2);
CGAL_assertion(p1 != p2);
assert(p1 != p2);
unsigned int flag;
is >> flag;
@ -1707,7 +1700,7 @@ bool IO_base_test<Base_geom_traits>::read_curve(InputStream_& is, Curve_2& cv)
Point_2 p1, p2;
read_point(is, p1);
read_point(is, p2);
CGAL_assertion(p1 != p2);
assert(p1 != p2);
unsigned int flag;
is >> flag;
if (flag == 1) {

View File

@ -262,7 +262,7 @@ private:
void allocate_pl()
{
Strategy* locator = new Strategy();
CGAL_assertion(locator);
assert(locator);
m_locators[id].m_variant = locator;
}

View File

@ -13,7 +13,6 @@
#include <boost/lexical_cast.hpp>
#include <CGAL/exceptions.h>
#include <CGAL/Object.h>
#include <CGAL/Arr_tags.h>
#include <CGAL/Arr_enums.h>
#include <CGAL/use.h>

View File

@ -13,7 +13,6 @@
#include <boost/lexical_cast.hpp>
#include <CGAL/exceptions.h>
#include <CGAL/Object.h>
#include <CGAL/Arr_tags.h>
#include <CGAL/Arrangement_2/Arr_traits_adaptor_2_dispatching.h>
#include <CGAL/use.h>
@ -931,22 +930,22 @@ template <typename Geom_traits_T>
bool Traits_test<Geom_traits_T>::
make_x_monotone_wrapper(std::istringstream& str_stream)
{
typedef Geom_traits_T Traits;
typedef typename Traits::Point_2 Point_2;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
typedef Geom_traits_T Traits;
typedef typename Traits::Point_2 Point_2;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
typedef boost::variant<Point_2, X_monotone_curve_2> Make_x_monotone_result;
CGAL_USE_TYPE(typename Traits::Curve_2);
unsigned int id;
str_stream >> id;
std::cout << "Test: make_x_monotone( " << this->m_curves[id]
<< " ) ? ";
std::vector<CGAL::Object> object_vec;
std::cout << "Test: make_x_monotone( " << this->m_curves[id] << " ) ? ";
std::vector<Make_x_monotone_result> objs;
this->m_geom_traits.make_x_monotone_2_object()(this->m_curves[id],
std::back_inserter(object_vec));
std::back_inserter(objs));
size_t num;
str_stream >> num;
if (!this->compare(num, object_vec.size(), "size")) return false;
if (!this->compare(num, objs.size(), "size")) return false;
for (size_t i = 0; i < num; ++i) {
unsigned int type; // 0 - point, 1 - x-monotone curve
@ -955,20 +954,19 @@ make_x_monotone_wrapper(std::istringstream& str_stream)
unsigned int id; // The id of the point or x-monotone
str_stream >> id; // ... curve respectively
const X_monotone_curve_2 * xcv_ptr =
CGAL::object_cast<X_monotone_curve_2> (&(object_vec[i]));
if (xcv_ptr != NULL) {
const auto* xcv_ptr = boost::get<X_monotone_curve_2>(&(objs[i]));
if (xcv_ptr != nullptr) {
if (!this->compare(type, 1u, "type")) return false;
if (!this->compare_curves(this->m_xcurves[id], *xcv_ptr)) return false;
continue;
}
const Point_2 * pt_ptr = CGAL::object_cast<Point_2> (&(object_vec[i]));
assert (pt_ptr != NULL);
const auto* pt_ptr = boost::get<Point_2>(&(objs[i]));
assert(pt_ptr != nullptr);
if (!this->compare(type, 0u, "type")) return false;
if (!this->compare_points(this->m_points[id], *pt_ptr)) return false;
}
object_vec.clear();
objs.clear();
return true;
}

View File

@ -12,11 +12,11 @@
#include "IO_test.h"
/*! Point location test */
template <typename GeomTraits_T, typename TopolTraits_T>
class Vertical_decomposition_test : public IO_test<GeomTraits_T> {
template <typename GeomTraits_2, typename TopolTraits>
class Vertical_decomposition_test : public IO_test<GeomTraits_2> {
public:
typedef GeomTraits_T Geom_traits;
typedef TopolTraits_T Topol_traits;
typedef GeomTraits_2 Geom_traits;
typedef TopolTraits Topol_traits;
private:
typedef IO_test<Geom_traits> Base;
@ -44,8 +44,11 @@ public:
typedef typename Arrangement::Edge_const_iterator Edge_const_iterator;
typedef typename Arrangement::Vertex_const_iterator Vertex_const_iterator;
typedef typename std::pair<CGAL::Object, CGAL::Object> Object_pair;
typedef typename std::pair<Vertex_const_handle, Object_pair>
typedef boost::variant<Vertex_const_handle, Halfedge_const_handle,
Face_const_handle> Cell_type;
typedef boost::optional<Cell_type> Vert_type;
typedef typename std::pair<Vert_type, Vert_type> Vert_pair;
typedef typename std::pair<Vertex_const_handle, Vert_pair>
Vert_decomp_entry;
typedef typename std::list<Vert_decomp_entry> Vert_decomp_list;
@ -69,7 +72,7 @@ protected:
/*! Compare the results.
*/
bool compare(const Result_type& expected, const CGAL::Object& actual);
bool compare(const Result_type& expected, Vert_type actual);
/*! print the results.
*/
@ -104,8 +107,8 @@ public:
/*!
* Constructor from a geometry traits object.
*/
template <typename GeomTraits_T, typename TopolTraits_T>
Vertical_decomposition_test<GeomTraits_T, TopolTraits_T>::
template <typename GeomTraits_2, typename TopolTraits>
Vertical_decomposition_test<GeomTraits_2, TopolTraits>::
Vertical_decomposition_test(const Geom_traits& geom_traits) :
Base(geom_traits),
m_geom_traits(geom_traits),
@ -113,24 +116,24 @@ Vertical_decomposition_test(const Geom_traits& geom_traits) :
{}
//! \brief sets the verbosity level.
template <typename GeomTraits_T, typename TopolTraits_T>
void Vertical_decomposition_test<GeomTraits_T, TopolTraits_T>::
template <typename GeomTraits_2, typename TopolTraits>
void Vertical_decomposition_test<GeomTraits_2, TopolTraits>::
set_verbose_level(size_t verbose_level)
{ m_verbose_level = verbose_level; }
/*! Clear the data structures */
template <typename GeomTraits_T, typename TopolTraits_T>
void Vertical_decomposition_test<GeomTraits_T, TopolTraits_T>::clear()
template <typename GeomTraits_2, typename TopolTraits>
void Vertical_decomposition_test<GeomTraits_2, TopolTraits>::clear()
{
m_arr.clear();
Base::clear();
}
template <typename GeomTraits_T, typename TopolTraits_T>
bool Vertical_decomposition_test<GeomTraits_T, TopolTraits_T>::init()
template <typename GeomTraits_2, typename TopolTraits>
bool Vertical_decomposition_test<GeomTraits_2, TopolTraits>::init()
{
// Initialize the input.
if (!Base::init()) return false;
if (! Base::init()) return false;
// Insert all into the arrangement
CGAL::insert(m_arr, this->m_xcurves.begin(), this->m_xcurves.end());
@ -147,8 +150,8 @@ bool Vertical_decomposition_test<GeomTraits_T, TopolTraits_T>::init()
}
//! \brief performs the test.
template <typename GeomTraits_T, typename TopolTraits_T>
bool Vertical_decomposition_test<GeomTraits_T, TopolTraits_T>::perform()
template <typename GeomTraits_2, typename TopolTraits>
bool Vertical_decomposition_test<GeomTraits_2, TopolTraits>::perform()
{
// Apply vertical decomposition.
Vert_decomp_list results;
@ -159,51 +162,48 @@ bool Vertical_decomposition_test<GeomTraits_T, TopolTraits_T>::perform()
}
//! \brief verifies the results.
template <typename GeomTraits_T, typename TopolTraits_T>
template <typename GeomTraits_2, typename TopolTraits>
template <typename InputIterator>
bool Vertical_decomposition_test<GeomTraits_T, TopolTraits_T>::
bool Vertical_decomposition_test<GeomTraits_2, TopolTraits>::
verify(InputIterator begin, InputIterator end)
{
typedef TopolTraits_T TopolTraits;
InputIterator it;
if (m_verbose_level > 1) for (it = begin; it != end; ++it) print(*it);
if (m_verbose_level > 1) for (auto it = begin; it != end; ++it) print(*it);
// Compare the results.
typename TopolTraits::Default_vertical_ray_shooting_strategy vs(m_arr);
for (it = begin; it != end; ++it) {
for (auto it = begin; it != end; ++it) {
Vertex_const_handle vh = it->first;
const Object_pair& res = it->second;
const CGAL::Object& obj_below_actual = res.first;
const CGAL::Object& obj_above_actual = res.second;
const auto& res = it->second;
auto obj_below_actual = res.first;
auto obj_above_actual = res.second;
Result_type obj_below_expected = vs.ray_shoot_down(vh->point());
Result_type obj_above_expected = vs.ray_shoot_up(vh->point());
if (!compare(obj_below_expected, obj_below_actual)) return false;
if (!compare(obj_above_expected, obj_above_actual)) return false;
if (! compare(obj_below_expected, obj_below_actual)) return false;
if (! compare(obj_above_expected, obj_above_actual)) return false;
}
return true;
}
template <typename GeomTraits_T, typename TopolTraits_T>
bool Vertical_decomposition_test<GeomTraits_T, TopolTraits_T>::
compare(const Result_type& expected, const CGAL::Object& actual)
template <typename GeomTraits_2, typename TopolTraits>
bool Vertical_decomposition_test<GeomTraits_2, TopolTraits>::
compare(const Result_type& expected, Vert_type actual)
{
// This test does not test the case where the result is empty!
if (! actual) return false;
auto obj = *actual;
// Assign object to a fase.
const Face_const_handle* fh_expected =
boost::get<Face_const_handle>(&(expected));
if (fh_expected) {
Vertex_const_handle vh_actual;
if (CGAL::assign(vh_actual, actual)) {
if (const auto* fh_expected = boost::get<Face_const_handle>(&(expected))) {
if (boost::get<Vertex_const_handle>(&obj)) {
std::cout << "Error: vertical decomposition!" << std::endl;
std::cout << "Expected: a face." << std::endl;
std::cout << "Actual: a vertex." << std::endl;
return false;
}
Halfedge_const_handle hh_actual;
if (CGAL::assign(hh_actual, actual)) {
if (boost::get<Halfedge_const_handle>(&obj)) {
std::cout << "Error: vertical decomposition!" << std::endl;
std::cout << "Expected: a face." << std::endl;
std::cout << "Actual: a halfedge." << std::endl;
@ -213,17 +213,15 @@ compare(const Result_type& expected, const CGAL::Object& actual)
}
// Assign object to a halfedge.
const Halfedge_const_handle* hh_expected =
boost::get<Halfedge_const_handle>(&(expected));
const auto* hh_expected = boost::get<Halfedge_const_handle>(&(expected));
if (hh_expected) {
Halfedge_const_handle hh_actual;
if (CGAL::assign(hh_actual, actual)) {
if (*hh_expected == hh_actual) return true;
if (const auto* hh_actual = boost::get<Halfedge_const_handle>(&obj)) {
if (*hh_expected == *hh_actual) return true;
std::cout << "Error: vertical decomposition!" << std::endl;
std::cout << "Expected: a halfedge, " << (*hh_expected)->curve()
<< std::endl;
std::cout << "Actual: a different halfedge." << hh_actual->curve()
std::cout << "Actual: a different halfedge." << (*hh_actual)->curve()
<< std::endl;
return false;
}
@ -232,14 +230,13 @@ compare(const Result_type& expected, const CGAL::Object& actual)
std::cout << "Expected: a halfedge, " << (*hh_expected)->curve()
<< std::endl;
Vertex_const_handle vh_actual;
if (CGAL::assign(vh_actual, actual)) {
std::cout << "Actual: a vertex, " << vh_actual->point() << std::endl;
if (const auto* vh_actual = boost::get<Vertex_const_handle>(&obj)) {
std::cout << "Actual: a vertex, " << (*vh_actual)->point() << std::endl;
return false;
}
Face_const_handle fh_actual;
if (CGAL::assign(fh_actual, actual)) {
if (boost::get<Face_const_handle>(&obj)) {
std::cout << "Actual: a face." << std::endl;
return false;
}
@ -248,17 +245,15 @@ compare(const Result_type& expected, const CGAL::Object& actual)
}
// Assign object to a vertex.
const Vertex_const_handle* vh_expected =
boost::get<Vertex_const_handle>(&(expected));
const auto* vh_expected = boost::get<Vertex_const_handle>(&(expected));
if (vh_expected) {
Vertex_const_handle vh_actual;
if (CGAL::assign(vh_actual, actual)) {
if (*vh_expected == vh_actual) return true;
if (const auto* vh_actual = boost::get<Vertex_const_handle>(&obj)) {
if (*vh_expected == *vh_actual) return true;
std::cout << "Error: vertical decomposition!" << std::endl;
std::cout << "Expected: a vertex, " << (*vh_expected)->point()
<< std::endl;
std::cout << "Actual: a different vertex, " << vh_actual->point()
std::cout << "Actual: a different vertex, " << (*vh_actual)->point()
<< std::endl;
return false;
}
@ -266,14 +261,12 @@ compare(const Result_type& expected, const CGAL::Object& actual)
std::cout << "Error: vertical decomposition!" << std::endl;
std::cout << "Expected: a vertex, " << (*vh_expected)->point() << std::endl;
Halfedge_const_handle hh_actual;
if (CGAL::assign(hh_actual, actual)) {
std::cout << "Actual: a halfedge, " << hh_actual->curve() << std::endl;
if (const auto* hh_actual = boost::get<Halfedge_const_handle>(&obj)) {
std::cout << "Actual: a halfedge, " << (*hh_actual)->curve() << std::endl;
return false;
}
Face_const_handle fh_actual;
if (CGAL::assign(fh_actual, actual)) {
if (boost::get<Face_const_handle>(&obj)) {
std::cout << "Actual: a face." << std::endl;
return false;
}
@ -285,28 +278,36 @@ compare(const Result_type& expected, const CGAL::Object& actual)
}
//! \brief prints the results.
template <typename GeomTraits_T, typename TopolTraits_T>
void Vertical_decomposition_test<GeomTraits_T, TopolTraits_T>::
template <typename GeomTraits_2, typename TopolTraits>
void Vertical_decomposition_test<GeomTraits_2, TopolTraits>::
print(const Vert_decomp_entry& result)
{
// Print the result.
Vertex_const_handle vh;
Halfedge_const_handle hh;
Face_const_handle fh;
const auto& res = result.second;
auto obj_below = res.first;
auto obj_above = res.second;
const Object_pair& res = result.second;
std::cout << "Vertex (" << result.first->point() << ") : ";
assert(obj_below);
auto obj = *obj_below;
std::cout << " feature below: ";
if (CGAL::assign(hh, res.first)) std::cout << '[' << hh->curve() << ']';
else if (CGAL::assign(vh, res.first)) std::cout << '(' << vh->point() << ')';
else if (CGAL::assign(fh, res.first)) std::cout << "NONE";
if (const auto* hh = boost::get<Halfedge_const_handle>(&obj))
std::cout << '[' << (*hh)->curve() << ']';
else if (const auto* vh = boost::get<Vertex_const_handle>(&obj))
std::cout << '(' << (*vh)->point() << ')';
else if (const auto* fh = boost::get<Face_const_handle>(&obj))
std::cout << "NONE";
else std::cout << "EMPTY";
assert(obj_above);
obj = *obj_above;
std::cout << " feature above: ";
if (CGAL::assign(hh, res.second)) std::cout << '[' << hh->curve() << ']';
else if (CGAL::assign(vh, res.second)) std::cout << '(' << vh->point() << ')';
else if (CGAL::assign(fh, res.second)) std::cout << "NONE";
if (const auto* hh = boost::get<Halfedge_const_handle>(&obj))
std::cout << '[' << (*hh)->curve() << ']';
else if (const auto* vh = boost::get<Vertex_const_handle>(&obj))
std::cout << '(' << (*vh)->point() << ')';
else if (const auto* vh = boost::get<Face_const_handle>(&obj))
std::cout << "NONE";
else std::cout << "EMPTY";
std::cout << std::endl;

View File

@ -1,64 +1,48 @@
// Constructing an arrangement of polycurves.
#include <CGAL/config.h>
#ifndef CGAL_USE_CORE
#include <iostream>
int main()
{
std::cout << "Sorry, this example needs CORE ..." << std::endl;
return 0;
}
#else
#include <CGAL/Cartesian.h>
#include <CGAL/Quotient.h>
#include <CGAL/MP_Float.h>
#include <CGAL/CORE_algebraic_number_traits.h>
#include <vector>
#include <list>
#include <CGAL/config.h>
#include <CGAL/Cartesian.h>
#include <CGAL/Quotient.h>
#include <CGAL/MP_Float.h>
#include <CGAL/Arr_polyline_traits_2.h>
#include <CGAL/Arr_circle_segment_traits_2.h>
#include <CGAL/Arrangement_2.h>
///////////////
//circle segment traits
//////////////
typedef CGAL::Quotient<CGAL::MP_Float> Number_type;
typedef CGAL::Cartesian<Number_type> Kernel;
typedef CGAL::Arr_circle_segment_traits_2<Kernel> Arc_traits_2;
typedef CGAL::Arr_polyline_traits_2<Arc_traits_2> Polycurve_arc_traits_2;
typedef Arc_traits_2::CoordNT CoordNT;
typedef Arc_traits_2::Point_2 Arc_point_2;
typedef Arc_traits_2::Curve_2 Arc_section_2;
typedef Arc_traits_2::X_monotone_curve_2 Arc_section_x_monotone_2;
typedef CGAL::Arrangement_2<Polycurve_arc_traits_2> Arc_arrangment_2;
typedef CGAL::Arr_circle_segment_traits_2<Kernel> Sub_traits_2;
typedef CGAL::Arr_polyline_traits_2<Sub_traits_2> Traits_2;
typedef Sub_traits_2::CoordNT CoordNT;
typedef Sub_traits_2::Point_2 Point_2;
typedef Sub_traits_2::Curve_2 Subcurve_2;
typedef Sub_traits_2::X_monotone_curve_2 Subcurve_x_monotone_2;
typedef boost::variant<Point_2, Subcurve_x_monotone_2>
Make_sub_x_monotone_result;
void check_equal()
{
Polycurve_arc_traits_2 Polycurve_traits_2;
Polycurve_arc_traits_2::Equal_2 equal_2 = Polycurve_traits_2.equal_2_object();
Polycurve_arc_traits_2::Construct_x_monotone_curve_2
construct_x_monotone_curve_2 =
Traits_2 Polycurve_traits_2;
auto equal_2 = Polycurve_traits_2.equal_2_object();
auto construct_x_monotone_curve_2 =
Polycurve_traits_2.construct_x_monotone_curve_2_object();
Arc_section_2 curve1, curve2, curve3;
Subcurve_2 curve1, curve2, curve3;
Kernel::Point_2 p1 = Kernel::Point_2(-5, 0);
Kernel::Point_2 mid = Kernel::Point_2(0, 5);
Kernel::Point_2 p2 = Kernel::Point_2(5, 0);
curve1= Arc_section_2(p1, mid, p2);
curve2= Arc_section_2(p1, mid, p2);
curve1= Subcurve_2(p1, mid, p2);
curve2= Subcurve_2(p1, mid, p2);
// //make x_monotone
// Polycurve_arc_traits_2::X_monotone_curve_2 xmc1 =
// Traits_2::X_monotone_curve_2 xmc1 =
// construct_x_monotone_curve_2(curve1);
// Polycurve_arc_traits_2::X_monotone_curve_2 xmc2 =
// Traits_2::X_monotone_curve_2 xmc2 =
// construct_x_monotone_curve_2(curve2);
// Polycurve_arc_traits_2::X_monotone_curve_2 xmc3 =
// Traits_2::X_monotone_curve_2 xmc3 =
// construct_x_monotone_curve_2(curve3);
// //simple equal
@ -71,11 +55,11 @@ void check_equal()
// << ((Are_equal) ? "Equal" : "Not equal") << std::endl;
}
void check_intersect(Polycurve_arc_traits_2::Make_x_monotone_2
void check_intersect(Traits_2::Make_x_monotone_2
make_x_monotone_2,
Polycurve_arc_traits_2::Intersect_2 intersect_2)
Traits_2::Intersect_2 intersect_2)
{
Arc_section_2 curve1, curve2, curve3;
Subcurve_2 curve1, curve2, curve3;
// Create a circular arc that correspond to the upper half of the
// circle centered at (1,1) with squared radius 3. We create the
@ -85,24 +69,22 @@ void check_intersect(Polycurve_arc_traits_2::Make_x_monotone_2
Kernel::Circle_2 circ1 = Kernel::Circle_2(c1, 3, CGAL::CLOCKWISE);
CoordNT one_minus_sqrt_3 = CoordNT(1, -1, 3);
CoordNT one_plus_sqrt_3 = CoordNT(1, 1, 3);
Arc_point_2 s1 = Arc_point_2(one_minus_sqrt_3, CoordNT(1));
Arc_point_2 t1 = Arc_point_2(one_plus_sqrt_3, CoordNT(1));
curve1 = Arc_section_2(circ1, s1, t1);
curve2 = Arc_section_2(circ1, s1, t1);
Point_2 s1 = Point_2(one_minus_sqrt_3, CoordNT(1));
Point_2 t1 = Point_2(one_plus_sqrt_3, CoordNT(1));
curve1 = Subcurve_2(circ1, s1, t1);
curve2 = Subcurve_2(circ1, s1, t1);
//push the same semi circle again
//curves.push_back(Arc_section_2(circ1, s1, t1));
//curves.push_back(Subcurve_2(circ1, s1, t1));
//make x_monotone
std::vector<CGAL::Object> X_monotone_curves;
make_x_monotone_2(curve1, std::back_inserter(X_monotone_curves));
make_x_monotone_2(curve2, std::back_inserter(X_monotone_curves));
std::vector<Make_sub_x_monotone_result> x_monotone_curves;
make_x_monotone_2(curve1, std::back_inserter(x_monotone_curves));
make_x_monotone_2(curve2, std::back_inserter(x_monotone_curves));
Arc_section_x_monotone_2 X_monotone_curve1, X_monotone_curve2,
X_monotone_curve3 ;
CGAL::assign(X_monotone_curve1, X_monotone_curves[0]);
CGAL::assign(X_monotone_curve2, X_monotone_curves[1]);
const auto* x_curve1 = boost::get<Subcurve_x_monotone_2>(curves[0]);
const auto* x_curve2 = boost::get<Subcurve_x_monotone_2>(curves[1]);
std::vector<CGAL::Object> Points_of_intersection;
std::vector<Intersection_result> Points_of_intersection;
//intersect_2(X_monotone_curve1, X_monotone_curve2,
// std::back_inserter(Points_of_intersection));
@ -113,12 +95,12 @@ void check_intersect(Polycurve_arc_traits_2::Make_x_monotone_2
Kernel::Point_2 c6 = Kernel::Point_2(0, 0);
CoordNT sqrt_3_div_2 =
CoordNT(Number_type(0), Number_type(1,2), Number_type(3));
Arc_point_2 s6 = Arc_point_2(Number_type(-1, 2), sqrt_3_div_2);
Arc_point_2 t6 = Arc_point_2(Number_type(1, 2), sqrt_3_div_2);
Point_2 s6 = Point_2(Number_type(-1, 2), sqrt_3_div_2);
Point_2 t6 = Point_2(Number_type(1, 2), sqrt_3_div_2);
curve3 = Arc_section_2(c6, 1, CGAL::CLOCKWISE, s6, t6);
make_x_monotone_2(curve3, std::back_inserter(X_monotone_curves));
CGAL::assign(X_monotone_curve2, X_monotone_curves[2]);
curve3 = Subcurve_2(c6, 1, CGAL::CLOCKWISE, s6, t6);
make_x_monotone_2(curve3, std::back_inserter(x_curves));
const auto* x_curve2 = boost::get<>(&x_curves[2]);
Points_of_intersection.clear();
//intersect_2(X_monotone_curve1, X_monotone_curve2,
@ -126,12 +108,12 @@ void check_intersect(Polycurve_arc_traits_2::Make_x_monotone_2
}
void
check_compare_end_points_xy_2(Polycurve_arc_traits_2::Compare_endpoints_xy_2
check_compare_end_points_xy_2(Traits_2::Compare_endpoints_xy_2
compare_endpoints_xy_2,
Polycurve_arc_traits_2::Make_x_monotone_2
Traits_2::Make_x_monotone_2
make_x_monotone_2)
{
Arc_section_2 curve1, curve2;
Subcurve_2 curve1, curve2;
// Create a circular arc that correspond to the upper half of the
// circle centered at (1,1) with squared radius 3. We create the
@ -141,39 +123,37 @@ check_compare_end_points_xy_2(Polycurve_arc_traits_2::Compare_endpoints_xy_2
Kernel::Circle_2 circ1 = Kernel::Circle_2(c1, 3, CGAL::CLOCKWISE);
CoordNT one_minus_sqrt_3 = CoordNT(1, -1, 3);
CoordNT one_plus_sqrt_3 = CoordNT(1, 1, 3);
Arc_point_2 s1 = Arc_point_2(one_minus_sqrt_3, CoordNT(1));
Arc_point_2 t1 = Arc_point_2(one_plus_sqrt_3, CoordNT(1));
curve1= Arc_section_2(circ1, s1, t1);
Point_2 s1 = Point_2(one_minus_sqrt_3, CoordNT(1));
Point_2 t1 = Point_2(one_plus_sqrt_3, CoordNT(1));
curve1= Subcurve_2(circ1, s1, t1);
//make x_monotone
std::vector<CGAL::Object> X_monotone_curves;
make_x_monotone_2(curve1, std::back_inserter(X_monotone_curves));
std::vector<Make_sub_x_monotone_result> x_curves;
make_x_monotone_2(curve1, std::back_inserter(x_curves));
Arc_section_x_monotone_2 X_monotone_curve1, X_monotone_curve2 ;
CGAL::assign(X_monotone_curve1, X_monotone_curves[ 0 ]);
int res = compare_endpoints_xy_2(X_monotone_curve1);
const auto* x_curve1 = boost::get<Subcurve_x_monotone_2>(&x_curves[0]);
const auto* x_curve2 = boost::get<Subcurve_x_monotone_2>(&x_curves[1]);
auto res = compare_endpoints_xy_2(x_curve1);
std::cout<< "The first result is: " << res << std::endl;
Kernel::Point_2 c2 = Kernel::Point_2(1, 1);
Kernel::Circle_2 circ2 = Kernel::Circle_2(c2, 3, CGAL::COUNTERCLOCKWISE);
Arc_point_2 t2 = Arc_point_2(one_minus_sqrt_3, CoordNT(1));
Arc_point_2 s2 = Arc_point_2(one_plus_sqrt_3, CoordNT(1));
curve2= Arc_section_2(circ2, s1, t1);
Point_2 t2 = Point_2(one_minus_sqrt_3, CoordNT(1));
Point_2 s2 = Point_2(one_plus_sqrt_3, CoordNT(1));
curve2 = Subcurve_2(circ2, s1, t1);
make_x_monotone_2(curve2, std::back_inserter(x_curves));
const auto* x_curve2 = boost::get<Subcurve_x_monotone_2>(&x_curves[1]);
make_x_monotone_2(curve2, std::back_inserter(X_monotone_curves));
CGAL::assign(X_monotone_curve2, X_monotone_curves[ 1 ]);
res = compare_endpoints_xy_2(X_monotone_curve2);
res = compare_endpoints_xy_2(x_curve2);
std::cout<< "The second result is: " << res << std::endl;
}
void check_split(Polycurve_arc_traits_2::Split_2 split_2,
Polycurve_arc_traits_2::Make_x_monotone_2 make_x_monotone_2)
void check_split(Traits_2::Split_2 split_2,
Traits_2::Make_x_monotone_2 make_x_monotone_2)
{
Arc_section_2 curve;
Subcurve_2 curve;
// Create a circular arc that correspond to the upper half of the
// circle centered at (1,1) with squared radius 3. We create the
@ -183,64 +163,59 @@ void check_split(Polycurve_arc_traits_2::Split_2 split_2,
Kernel::Circle_2 circ1 = Kernel::Circle_2(c1, 3, CGAL::CLOCKWISE);
CoordNT one_minus_sqrt_3 = CoordNT(1, -1, 3);
CoordNT one_plus_sqrt_3 = CoordNT(1, 1, 3);
Arc_point_2 s1 = Arc_point_2(one_minus_sqrt_3, CoordNT(1));
Arc_point_2 t1 = Arc_point_2(one_plus_sqrt_3, CoordNT(1));
curve= Arc_section_2(circ1, s1, t1);
Point_2 s1 = Point_2(one_minus_sqrt_3, CoordNT(1));
Point_2 t1 = Point_2(one_plus_sqrt_3, CoordNT(1));
curve= Subcurve_2(circ1, s1, t1);
//make x_monotone
std::vector<CGAL::Object> X_monotone_curves;
make_x_monotone_2(curve, std::back_inserter(X_monotone_curves));
Arc_section_x_monotone_2 X_monotone_curve, split_x_monotone_curve1,
split_x_monotone_curve2 ;
CGAL::assign(X_monotone_curve, X_monotone_curves[0]);
std::vector<Make_sub_x_monotone_result> x_curves;
make_x_monotone_2(curve, std::back_inserter(x_curves));
const auto* x_curve1 = boost::get<Subcurve_x_monotone_2>(&x_curves[0]);
// Subcurve_x_monotone_2 split_x_monotone_curve1, split_x_monotone_curve2 ;
//split_2(X_monotone_curve, Kernel::Point_2::Kernel::Point_2(1, 4),
// split_x_monotone_curve1, split_x_monotone_curve2);
}
void check_is_vertical(Polycurve_arc_traits_2::Make_x_monotone_2
void check_is_vertical(Traits_2::Make_x_monotone_2
make_x_monotone_2,
Polycurve_arc_traits_2::Is_vertical_2 is_vertical)
Traits_2::Is_vertical_2 is_vertical)
{
std::vector<Arc_section_2> curves;
std::vector<Subcurve_2> curves;
// Create a circular arc defined by two endpoints and a midpoint,
// all having rational coordinates. This arc is the upper-right
// quarter of a circle centered at the origin with radius 5.
Kernel::Point_2 p1 = Kernel::Point_2(0, 5);
Kernel::Point_2 mid = Kernel::Point_2(3, 4);
Kernel::Point_2 p2 = Kernel::Point_2(5, 0);
Kernel::Point_2 p3 = Kernel::Point_2(0, -5);
curves.push_back(Arc_section_2(p1, mid, p2)); //quarter of a circle
curves.push_back(Arc_section_2(p1, mid, p3)); //semi-circle
Kernel::Point_2 p1 = Kernel::Point_2(0, 5);
Kernel::Point_2 mid = Kernel::Point_2(3, 4);
Kernel::Point_2 p2 = Kernel::Point_2(5, 0);
Kernel::Point_2 p3 = Kernel::Point_2(0, -5);
curves.push_back(Subcurve_2(p1, mid, p2)); //quarter of a circle
curves.push_back(Subcurve_2(p1, mid, p3)); //semi-circle
//convert all curves to x-monotone curves
std::vector<CGAL::Object> X_monotone_curves;
for(int i = 0; i < curves.size(); ++i)
make_x_monotone_2(curves[i], std::back_inserter(X_monotone_curves));
std::vector<Make_sub_x_monotone_result> x_curves;
for (const auto& cv : curves)
make_x_monotone_2(cv, std::back_inserter(x_curves));
//std::vector<Arc_section_x_monotone_2> x_monotone_polycurves;
//std::vector<Subcurve_x_monotone_2> x_monotone_polycurves;
Arc_section_x_monotone_2 x_monotone_polycurve1, x_monotone_polycurve2;
CGAL::assign(x_monotone_polycurve1, X_monotone_curves[0]);
CGAL::assign(x_monotone_polycurve2, X_monotone_curves[1]);
const auto* x_polycurve1 = boost::get<Subcurve_x_monotone_2>(&x_curves[0]);
const auto* x_polycurve2 = boost::get<Subcurve_x_monotone_2>(&x_curves[1]);
bool res = is_vertical(x_monotone_polycurve1);
bool res = is_vertical(x_polycurve1);
std::cout << "Is_verticle:: The xmonotone curve (quarter circle) is : "
<< ((res)? "vertical" : "not vertical") << std::endl;
res = is_vertical(x_monotone_polycurve2);
res = is_vertical(x_polycurve2);
std::cout << "Is_verticle:: The xmonotone curve (Smi-circle) is : "
<< ((res)? "vertical" : "not vertical") << std::endl;
}
void check_compare_y_at_x_2(Polycurve_arc_traits_2::Make_x_monotone_2
make_x_monotone_2,
Polycurve_arc_traits_2::Compare_y_at_x_2
cmp_y_at_x_2)
void check_compare_y_at_x_2(Traits_2::Make_x_monotone_2 make_x_monotone_2,
Traits_2::Compare_y_at_x_2 cmp_y_at_x_2)
{
std::vector<Arc_section_2> curves;
std::vector<Subcurve_2> curves;
// Create a circular arc defined by two endpoints and a midpoint,
// all having rational coordinates. This arc is the upper-right
@ -249,30 +224,29 @@ void check_compare_y_at_x_2(Polycurve_arc_traits_2::Make_x_monotone_2
Kernel::Point_2 mid = Kernel::Point_2(4, 4);
Kernel::Point_2 p2 = Kernel::Point_2(7, 1);
Kernel::Point_2 p3 = Kernel::Point_2(1, 4);
curves.push_back(Arc_section_2(p1, mid, p2)); //quarter of a circle
curves.push_back(Arc_section_2(p1, mid, p3)); //semi-circle
curves.push_back(Subcurve_2(p1, mid, p2)); //quarter of a circle
curves.push_back(Subcurve_2(p1, mid, p3)); //semi-circle
//convert all curves to x-monotone curves
std::vector<CGAL::Object> X_monotone_curves;
for (int i = 0; i < curves.size(); ++i)
make_x_monotone_2(curves[i], std::back_inserter(X_monotone_curves));
std::vector<Make_sub_x_monotone_result> x_curves;
for (const auto& cv : curves)
make_x_monotone_2(cv, std::back_inserter(x_curves));
Arc_section_x_monotone_2 x_monotone_polycurve1, x_monotone_polycurve2;
CGAL::assign(x_monotone_polycurve1, X_monotone_curves[ 0 ]);
CGAL::assign(x_monotone_polycurve2, X_monotone_curves[ 1 ]);
const auto* x_polycurve1 = boost::get<Subcurve_x_monotone_2>(&x_curves[0]);
const auto* x_polycurve2 = boost::get<Subcurve_x_monotone_2>(&x_curves[1]);
Kernel::Point_2 p_test = Kernel::Point_2(3, 1);
Kernel::Point_2 p_test = Kernel::Point_2(3, 1);
// int res = cmp_y_at_x_2(p_test, x_monotone_polycurve1);
// cmp_y_at_x_2(x_monotone_polycurve1, CGAL::ARR_MIN_END,
// x_monotone_polycurve2);
}
void check_push_back(Polycurve_arc_traits_2::Make_x_monotone_2
void check_push_back(Traits_2::Make_x_monotone_2
make_x_monotone_2,
Polycurve_arc_traits_2::Push_back_2 push_back_2)
Traits_2::Push_back_2 push_back_2)
{
std::vector<Arc_section_2> curves;
std::vector<Subcurve_2> curves;
//check if segment is pushed in empty curve.
Kernel::Point_2 p1 = Kernel::Point_2(1, 1);
@ -282,10 +256,10 @@ void check_push_back(Polycurve_arc_traits_2::Make_x_monotone_2
Kernel::Point_2 mid2 = Kernel::Point_2(10, 3);
Kernel::Point_2 p3 = Kernel::Point_2(7, 7);
curves.push_back(Arc_section_2(p1, mid, p2));
curves.push_back(Arc_section_2(p2, mid2, p3));
curves.push_back(Subcurve_2(p1, mid, p2));
curves.push_back(Subcurve_2(p2, mid2, p3));
CGAL::internal::Polycurve_2<Arc_section_2, Arc_point_2> polycurve;
CGAL::internal::Polycurve_2<Subcurve_2, Point_2> polycurve;
////pushing segments in polycurve
push_back_2(polycurve, curves[0]);
@ -300,87 +274,70 @@ void check_push_back(Polycurve_arc_traits_2::Make_x_monotone_2
int main()
{
Polycurve_arc_traits_2 Polycurve_traits_2;
Traits_2 Polycurve_traits_2;
// Compare_x_2
// Polycurve_arc_traits_2::Compare_x_2 compare_x_2 =
// Traits_2::Compare_x_2 compare_x_2 =
// Polycurve_traits_2.compare_xy_2_object();
// number of points
// Polycurve_arc_traits_2::Number_of_points_2 num_of_points =
// Traits_2::Number_of_points_2 num_of_points =
// Polycurve_traits_2.number_of_points_2_object();
//construct min vertex
Polycurve_arc_traits_2::Construct_min_vertex_2 cnst_min_vertex =
Polycurve_traits_2.construct_min_vertex_2_object();
auto cnst_min_vertex = Polycurve_traits_2.construct_min_vertex_2_object();
//construct max vertex
Polycurve_arc_traits_2::Construct_max_vertex_2 cnst_max_vertex_2 =
Polycurve_traits_2.construct_max_vertex_2_object();
auto cnst_max_vertex_2 = Polycurve_traits_2.construct_max_vertex_2_object();
//is vertical (return bool)
Polycurve_arc_traits_2::Is_vertical_2 is_vertical =
Polycurve_traits_2.is_vertical_2_object();
auto is_vertical = Polycurve_traits_2.is_vertical_2_object();
//Compare y at x 2 (return comparison_result)
Polycurve_arc_traits_2::Compare_y_at_x_2 cmp_y_at_x_2 =
Polycurve_traits_2.compare_y_at_x_2_object();
auto cmp_y_at_x_2 = Polycurve_traits_2.compare_y_at_x_2_object();
//compare y at x left
Polycurve_arc_traits_2::Compare_y_at_x_left_2 cmp_y_at_x_left_2 =
Polycurve_traits_2.compare_y_at_x_left_2_object();
auto cmp_y_at_x_left_2 = Polycurve_traits_2.compare_y_at_x_left_2_object();
//compare y at x right
Polycurve_arc_traits_2::Compare_y_at_x_right_2 cmp_y_at_x_right_2 =
Polycurve_traits_2.compare_y_at_x_right_2_object();
auto cmp_y_at_x_right_2 = Polycurve_traits_2.compare_y_at_x_right_2_object();
//equal_2
Polycurve_arc_traits_2::Equal_2 equal_2 =
Polycurve_traits_2.equal_2_object();
auto equal_2 = Polycurve_traits_2.equal_2_object();
//compare end points xy_2
Polycurve_arc_traits_2::Compare_endpoints_xy_2 compare_endpoints_xy_2 =
auto compare_endpoints_xy_2 =
Polycurve_traits_2.compare_endpoints_xy_2_object();
//construct opposite
Polycurve_arc_traits_2::Construct_opposite_2 construct_opposite_2 =
Polycurve_traits_2.construct_opposite_2_object();
auto construct_opposite_2 = Polycurve_traits_2.construct_opposite_2_object();
//make x_monotone
Polycurve_arc_traits_2::Make_x_monotone_2 make_x_monotone_2 =
Polycurve_traits_2.make_x_monotone_2_object();
auto make_x_monotone_2 = Polycurve_traits_2.make_x_monotone_2_object();
//push back
Polycurve_arc_traits_2::Push_back_2 push_back_2 =
Polycurve_traits_2.push_back_2_object();
auto push_back_2 = Polycurve_traits_2.push_back_2_object();
//push front
Polycurve_arc_traits_2::Push_front_2 push_front_2 =
Polycurve_traits_2.push_front_2_object();
auto push_front_2 = Polycurve_traits_2.push_front_2_object();
//split_2
Polycurve_arc_traits_2::Split_2 split_2 =
Polycurve_traits_2.split_2_object();
auto split_2 = Polycurve_traits_2.split_2_object();
//Intersect_2
Polycurve_arc_traits_2::Intersect_2 intersect_2 =
Polycurve_traits_2.intersect_2_object();
auto intersect_2 = Polycurve_traits_2.intersect_2_object();
//Are_mergable
Polycurve_arc_traits_2::Are_mergeable_2 are_mergeable_2 =
Polycurve_traits_2.are_mergeable_2_object();
auto are_mergeable_2 = Polycurve_traits_2.are_mergeable_2_object();
//Merge_2
Polycurve_arc_traits_2::Merge_2 merge_2 =
Polycurve_traits_2.merge_2_object();
auto merge_2 = Polycurve_traits_2.merge_2_object();
//construct_curve_2
Polycurve_arc_traits_2::Construct_curve_2 construct_curve_2 =
Polycurve_traits_2.construct_curve_2_object();
auto construct_curve_2 = Polycurve_traits_2.construct_curve_2_object();
//construct x_monotone curve_2
Polycurve_arc_traits_2::Construct_x_monotone_curve_2
construct_x_monotone_curve_2 =
auto construct_x_monotone_curve_2 =
Polycurve_traits_2.construct_x_monotone_curve_2_object();
//check_equal();
@ -393,4 +350,3 @@ int main()
return 0;
}
#endif

View File

@ -23,15 +23,19 @@ typedef CGAL::Cartesian<Algebraic> Alg_kernel;
typedef Rat_kernel::Point_2 Rat_point_2;
//bezier traits
typedef CGAL::Arr_Bezier_curve_traits_2<Rat_kernel, Alg_kernel, Nt_traits> Bezier_traits_2;
typedef Bezier_traits_2::Curve_2 Bezier_curve;
typedef Bezier_traits_2::X_monotone_curve_2 Bezier_x_monotone_curve;
typedef CGAL::Arr_Bezier_curve_traits_2<Rat_kernel, Alg_kernel, Nt_traits>
Bezier_traits_2;
typedef Bezier_traits_2::Point_2 Bezier_point;
typedef Bezier_traits_2::Curve_2 Bezier_curve;
typedef Bezier_traits_2::X_monotone_curve_2 Bezier_x_monotone_curve;
//polyline traits
typedef CGAL::Arr_polyline_traits_2<Bezier_traits_2> Bezier_polycurve_traits;
typedef Bezier_polycurve_traits::Curve_2 Polycurve_bezier;
typedef Bezier_polycurve_traits::X_monotone_curve_2 X_polycurve_bezier;
typedef CGAL::Arr_polyline_traits_2<Bezier_traits_2> Bezier_polycurve_traits;
typedef Bezier_polycurve_traits::Curve_2 Polycurve_bezier;
typedef Bezier_polycurve_traits::X_monotone_curve_2 X_polycurve_bezier;
typedef boost::variant<Bezier_point, Bezier_x_monotone_curve>
Make_x_monotone_result;
int main (int argc, char *argv[])
{
@ -51,35 +55,40 @@ int main (int argc, char *argv[])
points_vector.push_back( Rat_point_2(900,0) );
Bezier_curve curve_1 (points_vector.begin(), points_vector.end());
std::vector<CGAL::Object> obj_vector;
std::vector<Make_x_monotone_result> objs;
//creating x-mono bezier
bezier_traits.make_x_monotone_2_object()( curve_1, std::back_inserter(obj_vector));
bezier_traits.make_x_monotone_2_object()(curve_1, std::back_inserter(objs));
//std::cout << "number of x_curves: " << obj_vector.size() << std::endl;
Bezier_x_monotone_curve x_curve_1 = CGAL::object_cast<Bezier_x_monotone_curve>( (obj_vector[0]) );
const auto* x_curve_1 = boost::get<Bezier_x_monotone_curve>(&(obj_vector[0]));
assert(x_curve_1);
//std::cout << x_curve << std::endl;
points_vector.clear();
points_vector.push_back( Rat_point_2(900,0) );
points_vector.push_back( Rat_point_2(1000,400) );
points_vector.push_back( Rat_point_2(1500,200) );
points_vector.push_back( Rat_point_2(2000,0) );
Bezier_curve curve_2 (points_vector.begin(), points_vector.end());
points_vector.push_back(Rat_point_2(900,0));
points_vector.push_back(Rat_point_2(1000,400));
points_vector.push_back(Rat_point_2(1500,200));
points_vector.push_back(Rat_point_2(2000,0));
Bezier_curve curve_2(points_vector.begin(), points_vector.end());
//creating x-monotne
obj_vector.clear();
bezier_traits.make_x_monotone_2_object()( curve_2, std::back_inserter(obj_vector));
Bezier_x_monotone_curve x_curve_2 = CGAL::object_cast<Bezier_x_monotone_curve>( (obj_vector[0]) );
bezier_traits.make_x_monotone_2_object()( curve_2, std::back_inserter(objs));
const auto* x_curve_2 = boost::get<Bezier_x_monotone_curve>(&(obj_vector[0]));
//push curves into polyline vectors
curves_vector.push_back(curve_1);
curves_vector.push_back(curve_2);
x_curves_vector.push_back(x_curve_1);
x_curves_vector.push_back(x_curve_2);
x_curves_vector.push_back(*x_curve_1);
x_curves_vector.push_back(*x_curve_2);
//create polycurves
Polycurve_bezier polycurve_1 = poly_traits.construct_curve_2_object()(curves_vector.begin(), curves_vector.end());
X_polycurve_bezier x_polycurve_1 = poly_traits.construct_x_monotone_curve_2_object()(x_curves_vector.begin(), x_curves_vector.end());
auto ctr_curve = poly_traits.construct_curve_2_object();
Polycurve_bezier
polycurve_1 = ctr_curve(curves_vector.begin(), curves_vector.end());
auto ctr_x_monotone_curve = poly_traits.construct_x_monotone_curve_2_object();
X_polycurve_bezier x_polycurve_1 =
ctr_x_monotone_curve(x_curves_vector.begin(), x_curves_vector.end());
std::cout << "polycurve : " << polycurve_1 << std::endl;
std::cout << "x_polycurve : " << x_polycurve_1 << std::endl;

View File

@ -73,25 +73,31 @@ bool check_compare_y_at_x_2(Curve& cv)
return true;
}
template<typename Curve>
void check_intersect(const Curve& cv1, const Curve& cv2)
template <typename GeometryTraits_2>
void check_intersect(const typename GeometryTraits_2::X_monotone_curve_2& cv1,
const typename GeometryTraits_2::X_monotone_curve_2& cv2,
const GeometryTraits_2& traits)
{
// Polycurve_arc_traits_2 traits;
// std::vector<CGAL::Object> object_vec;
// traits.intersect_2_object()(cv1, cv2, object_vec);
// std::cout<< "number of intersections is: " << object_vec.size();
// std::vector<Intersection_result> objs;
// traits.intersect_2_object()(cv1, cv2, std::back_inserter(objs));
// std::cout<< "number of intersections is: " << objs.size();
}
template<typename Curve>
void check_make_x_monotone(Curve cv)
template <typename GeometryTraits_2>
void check_make_x_monotone(typename GeometryTraits::Curve_2 cv,
const GeometryTraits_2& traits)
{
Polycurve_arc_traits_2 traits;
std::vector<CGAL::Object> object_vec;
typedef GeometryTraits_2 Geometry_traits_2;
typedef typename Geometry_traits_2::Point_2 Point_2;
typedef typename Geometry_traits_2::X_monotone_traits_2 X_monotone_traits_2;
traits.make_x_monotone_2_object()(cv, std::back_inserter(object_vec));
std::cout << "Number of x-monotone curves: "
<< object_vec.size() << std::endl;
typedef boost::variant<Point_2, X_monotone_traits_2>
Make_x_monotone_result;
std::vector<Make_x_monotone_result> objs;
traits.make_x_monotone_2_object()(cv, std::back_inserter(objs));
std::cout << "Number of x-monotone curves: " << objs.size() << std::endl;
}
template<typename Curve>
@ -198,8 +204,8 @@ int main(int argc, char* argv[])
//////////////////////
// check_compare_y_at_x_2(x_polycurve_1);
// check_intersect(x_polycurve_1, x_polycurve_2);
//check_make_x_monotone(curve_1);
// check_intersect(x_polycurve_1, x_polycurve_2, traits);
//check_make_x_monotone<Polycurve_arc_traits_2>(curve_1, traits);
//checking if the cgal_assertion for curve construction for two points work
//or not.

View File

@ -11,19 +11,19 @@ int main()
#else
#include <vector>
#include <list>
#include <boost/type_traits/is_same.hpp>
#include <CGAL/Cartesian.h>
#include <CGAL/Quotient.h>
#include <CGAL/MP_Float.h>
#include <CGAL/CORE_algebraic_number_traits.h>
#include <vector>
#include <list>
#include <CGAL/Arr_polyline_traits_2.h>
#include <CGAL/Arr_conic_traits_2.h>
#include <CGAL/Arrangement_2.h>
#include <CGAL/tags.h>
#include <CGAL/Arr_tags.h>
#include <boost/type_traits/is_same.hpp>
////////////////////
//conic traits
@ -43,7 +43,7 @@ typedef Conic_traits_2::Curve_2 Conic_curve_2;
typedef Conic_traits_2::X_monotone_curve_2 Conic_x_monotone_curve_2;
typedef CGAL::Arr_polyline_traits_2<Conic_traits_2> Polycurve_conic_traits_2;
typedef Polycurve_conic_traits_2::X_monotone_curve_2 Pc_x_monotone_curve_2;
// typedef Polycurve_conic_traits_2::Point_2 polypoint;
typedef Polycurve_conic_traits_2::Point_2 Pc_point_2;
// typedef CGAL::Arr_polyline_traits_2<
// CGAL::Arr_conic_traits_2<CGAL::Cartesian<BigRat>,
@ -102,27 +102,36 @@ void check_equal()
<< ((are_equal) ? "equal" : "Not equal") << std::endl;
}
template <typename curve_type>
void check_intersect(curve_type &xcv1, curve_type &xcv2)
template <typename Traits>
void check_intersect(typename Traits::X_monotone_curve_2& xcv1,
typename Traits::X_monotone_curve_2& xcv2,
const Traits& traits)
{
Polycurve_conic_traits_2 traits;
std::vector<CGAL::Object> intersection_points;
traits.intersect_2_object()(xcv1, xcv2, std::back_inserter(intersection_points));
std::cout<< "Number of intersection Points: " << intersection_points.size()
<< std::endl;
typedef typename Traits::Multiplicity Multiplicity;
typedef typename Traits::Point_2 Point_2;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
typedef std::pair<Multiplicity, Point_2> Intersection_point;
typedef boost::variant<Intersection_point, X_monotone_curve_2>
Intersection_result;
//dynamic cast the cgal_objects
// std::vector< std::pair<Polycurve_conic_traits_2::Point_2,
// Polycurve_conic_traits_2::Multiplicity> > pm_vector;
// for(int i=0; i<intersection_points.size(); i++)
// {
// std::pair<Polycurve_conic_traits_2::Point_2,
// Polycurve_conic_traits_2::Multiplicity> pm =
// CGAL::object_cast<std::pair<Polycurve_conic_traits_2::Point_2,
// Polycurve_conic_traits_2::Multiplicity> >
// (&(intersection_points[i]));
// pm_vector.push_back(pm);
// }
std::vector<Intersection_result> intersection_points;
traits.intersect_2_object()(xcv1, xcv2,
std::back_inserter(intersection_points));
std::cout<< "Number of intersection Points: " << intersection_points.size()
<< std::endl;
//dynamic cast the cgal_objects
// std::vector< std::pair<Polycurve_conic_traits_2::Point_2,
// Polycurve_conic_traits_2::Multiplicity> > pm_vector;
// for(int i=0; i<intersection_points.size(); i++)
// {
// std::pair<Polycurve_conic_traits_2::Point_2,
// Polycurve_conic_traits_2::Multiplicity> pm =
// CGAL::object_cast<std::pair<Polycurve_conic_traits_2::Point_2,
// Polycurve_conic_traits_2::Multiplicity> >
// (&(intersection_points[i]));
// pm_vector.push_back(pm);
// }
}
void check_compare_end_points_xy_2()
@ -151,7 +160,7 @@ void check_compare_end_points_xy_2()
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.
CGAL_assertion(c2.is_valid());
assert(c2.is_valid());
//make polyline x-monotone curves
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc1 =
@ -631,22 +640,23 @@ void check_compare_y_at_x_left()
(result == CGAL::LARGER ? "Larger" : "equal")) << std::endl;
}
template <typename Curve_type>
void check_make_x_monotne_curve(Curve_type c1)
template <typename GeometryTraits>
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;
Polycurve_conic_traits_2 traits;
std::vector<CGAL::Object> obj_vec;
traits.make_x_monotone_2_object()(c1, std::back_inserter(obj_vec));
std::vector<Make_x_monotone_result> objs;
traits.make_x_monotone_2_object()(c1, std::back_inserter(objs));
std::cout << "The polycurve is: " << c1 << std::endl;
std::cout<< "The poly curve have been split into " << obj_vec.size()
std::cout<< "The poly curve have been split into " << objs.size()
<< " polycurves" << std::endl;
//const Pc_x_monotone_curve_2 *split_curve_1 =
// CGAL::object_cast<Pc_x_monotone_curve_2> (&(obj_vec[0]));
// CGAL::object_cast<Pc_x_monotone_curve_2> (&(objs[0]));
//const Pc_x_monotone_curve_2 *split_curve_2 =
// CGAL::object_cast<Pc_x_monotone_curve_2> (&(obj_vec[1]));
// CGAL::object_cast<Pc_x_monotone_curve_2> (&(objs[1]));
//std::cout << "The split curve 1 is: " << *split_curve_1 << std::endl;
//std::cout << "The split curve 2 is: " << *split_curve_2 << std::endl;
@ -726,10 +736,8 @@ int main(int argc, char* argv[])
{
Polycurve_conic_traits_2 traits;
//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 construct_polycurve = traits.construct_curve_2_object();
//create a curve
@ -886,7 +894,7 @@ int main(int argc, char* argv[])
//check_split(conic_x_mono_polycurve_1, conic_x_mono_polycurve_2);
// std::cout<< std::endl;
//check_make_x_monotne_curve(conic_polycurve_2);
//check_make_x_monotne_curve<Point_2, Curve_2>(conic_polycurve_2);
//std::cout<< std::endl;
// check_is_vertical();

View File

@ -1,146 +1,131 @@
#include <CGAL/Cartesian.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Arr_segment_traits_2.h>
#include <CGAL/Arrangement_2.h>
#include <CGAL/Arr_simple_point_location.h>
#include <CGAL/Arr_walk_along_line_point_location.h>
#include <CGAL/Arr_trapezoid_ric_point_location.h>
template <class VerticalRayShoot>
template <typename VerticalRayShoot>
void vertical_ray_shooting_query
(const VerticalRayShoot& vrs, bool shoot_up,
const typename VerticalRayShoot::Arrangement_2::Point_2& q)
(const VerticalRayShoot& vrs, bool shoot_up,
const typename VerticalRayShoot::Arrangement_2::Point_2& q)
{
// Perform the point-location query.
CGAL::Object obj = (shoot_up) ? vrs.ray_shoot_up (q) :
vrs.ray_shoot_down (q);
auto obj = (shoot_up) ? vrs.ray_shoot_up(q) : vrs.ray_shoot_down(q);
// Print the result.
typedef typename VerticalRayShoot::Arrangement_2 Arrangement_2;
typedef typename VerticalRayShoot::Arrangement_2 Arrangement_2;
typedef typename Arrangement_2::Vertex_const_handle Vertex_const_handle;
typedef typename Arrangement_2::Halfedge_const_handle Halfedge_const_handle;
typedef typename Arrangement_2::Face_const_handle Face_const_handle;
typename Arrangement_2::Vertex_const_handle v;
typename Arrangement_2::Halfedge_const_handle e;
typename Arrangement_2::Face_const_handle f;
if (shoot_up) std::cout << " Shooting up from (" << q << ") : ";
else std::cout << " Shooting down from (" << q << ") : ";
if (shoot_up)
std::cout << " Shooting up from (" << q << ") : ";
else
std::cout << " Shooting down from (" << q << ") : ";
if (CGAL::assign (e, obj))
{
if (auto* e_p = boost::get<Halfedge_const_handle>(&obj)) {
// We hit an edge:
std::cout << "hit an edge: " << e->curve() << std::endl;
std::cout << "hit an edge: " << (*e_p)->curve() << std::endl;
}
else if (CGAL::assign (v, obj))
{
else if (auto* v_p = boost::get<Vertex_const_handle>(&obj)) {
// We hit a vertex:
if (v->is_isolated())
std::cout << "hit an isolated vertex: " << v->point() << std::endl;
else
std::cout << "hit a vertex: " << v->point() << std::endl;
if ((*v_p)->is_isolated())
std::cout << "hit an isolated vertex: " << (*v_p)->point() << std::endl;
else std::cout << "hit a vertex: " << (*v_p)->point() << std::endl;
}
else if (CGAL::assign (f, obj))
{
else if (auto* f_p = boost::get<Face_const_handle>(&obj)) {
// We did not hit anything:
assert (f->is_unbounded());
assert((*f_p)->is_unbounded());
std::cout << "hit nothing." << std::endl;
}
else
{
CGAL_error_msg( "Invalid object.");
}
return;
else CGAL_error_msg( "Invalid object.");
}
typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
typedef Kernel::FT Number_type;
typedef CGAL::Arr_segment_traits_2<Kernel> Traits_2;
typedef Traits_2::Point_2 Point_2;
typedef Traits_2::X_monotone_curve_2 Segment_2;
typedef CGAL::Arrangement_2<Traits_2> Arrangement_2;
typedef CGAL::Arr_simple_point_location<Arrangement_2> Simple_pl;
typedef CGAL::Arr_walk_along_line_point_location<Arrangement_2> Walk_pl;
typedef CGAL::Arr_trapezoid_ric_point_location<Arrangement_2> RIC_pl;
typedef int Number_type;
typedef CGAL::Cartesian<Number_type> Kernel;
typedef CGAL::Arr_segment_traits_2<Kernel> Traits_2;
typedef Traits_2::Point_2 Point_2;
typedef Traits_2::X_monotone_curve_2 Segment_2;
typedef CGAL::Arrangement_2<Traits_2> Arrangement_2;
typedef CGAL::Arr_simple_point_location<Arrangement_2> Simple_pl;
typedef CGAL::Arr_walk_along_line_point_location<Arrangement_2> Walk_pl;
typedef CGAL::Arr_trapezoid_ric_point_location<Arrangement_2> RIC_pl;
int main ()
int main()
{
// Construct the arrangement.
Arrangement_2 arr;
Simple_pl simple_pl (arr);
Walk_pl walk_pl (arr);
RIC_pl ric_pl (arr);
Arrangement_2 arr;
Simple_pl simple_pl(arr);
Walk_pl walk_pl(arr);
RIC_pl ric_pl(arr);
insert (arr, Segment_2 (Point_2 (0, 0), Point_2 (0, 1)));
insert (arr, Segment_2 (Point_2 (0, 3), Point_2 (0, 4)));
insert (arr, Segment_2 (Point_2 (-1, -1), Point_2 (1, -1)));
insert (arr, Segment_2 (Point_2 (-1, 5), Point_2 (1, 5)));
insert(arr, Segment_2(Point_2(0, 0), Point_2(0, 1)));
insert(arr, Segment_2(Point_2(0, 3), Point_2(0, 4)));
insert(arr, Segment_2(Point_2(-1, -1), Point_2(1, -1)));
insert(arr, Segment_2(Point_2(-1, 5), Point_2(1, 5)));
// Perform the vertical ray-shooting queries.
std::cout << "First round of queries: " << std::endl;
Point_2 q1 (0, 2);
Point_2 q1(0, 2);
vertical_ray_shooting_query (simple_pl, true, q1);
vertical_ray_shooting_query (walk_pl, true, q1);
vertical_ray_shooting_query (ric_pl, true, q1);
vertical_ray_shooting_query(simple_pl, true, q1);
vertical_ray_shooting_query(walk_pl, true, q1);
vertical_ray_shooting_query(ric_pl, true, q1);
vertical_ray_shooting_query (simple_pl, false, q1);
vertical_ray_shooting_query (walk_pl, false, q1);
vertical_ray_shooting_query (ric_pl, false, q1);
vertical_ray_shooting_query(simple_pl, false, q1);
vertical_ray_shooting_query(walk_pl, false, q1);
vertical_ray_shooting_query(ric_pl, false, q1);
Point_2 q2 (0, 1);
Point_2 q2(0, 1);
vertical_ray_shooting_query (simple_pl, true, q2);
vertical_ray_shooting_query (walk_pl, true, q2);
vertical_ray_shooting_query (ric_pl, true, q2);
vertical_ray_shooting_query(simple_pl, true, q2);
vertical_ray_shooting_query(walk_pl, true, q2);
vertical_ray_shooting_query(ric_pl, true, q2);
vertical_ray_shooting_query (simple_pl, false, q2);
vertical_ray_shooting_query (walk_pl, false, q2);
vertical_ray_shooting_query (ric_pl, false, q2);
vertical_ray_shooting_query(simple_pl, false, q2);
vertical_ray_shooting_query(walk_pl, false, q2);
vertical_ray_shooting_query(ric_pl, false, q2);
Point_2 q3 (0, 3);
Point_2 q3(0, 3);
vertical_ray_shooting_query (simple_pl, true, q3);
vertical_ray_shooting_query (walk_pl, true, q3);
vertical_ray_shooting_query (ric_pl, true, q3);
vertical_ray_shooting_query(simple_pl, true, q3);
vertical_ray_shooting_query(walk_pl, true, q3);
vertical_ray_shooting_query(ric_pl, true, q3);
vertical_ray_shooting_query (simple_pl, false, q3);
vertical_ray_shooting_query (walk_pl, false, q3);
vertical_ray_shooting_query (ric_pl, false, q3);
vertical_ray_shooting_query(simple_pl, false, q3);
vertical_ray_shooting_query(walk_pl, false, q3);
vertical_ray_shooting_query(ric_pl, false, q3);
// Insert additional curves and perform the ray-shooting queries again.
insert (arr, Segment_2 (Point_2 (-1, 0), Point_2 (1, 0)));
insert (arr, Segment_2 (Point_2 (-1, 4), Point_2 (1, 4)));
insert (arr, Segment_2(Point_2(-1, 0), Point_2(1, 0)));
insert (arr, Segment_2(Point_2(-1, 4), Point_2(1, 4)));
std::cout << "Second round of queries: " << std::endl;
vertical_ray_shooting_query (simple_pl, true, q1);
vertical_ray_shooting_query (walk_pl, true, q1);
vertical_ray_shooting_query (ric_pl, true, q1);
vertical_ray_shooting_query(simple_pl, true, q1);
vertical_ray_shooting_query(walk_pl, true, q1);
vertical_ray_shooting_query(ric_pl, true, q1);
vertical_ray_shooting_query (simple_pl, false, q1);
vertical_ray_shooting_query (walk_pl, false, q1);
vertical_ray_shooting_query (ric_pl, false, q1);
vertical_ray_shooting_query(simple_pl, false, q1);
vertical_ray_shooting_query(walk_pl, false, q1);
vertical_ray_shooting_query(ric_pl, false, q1);
vertical_ray_shooting_query (simple_pl, true, q2);
vertical_ray_shooting_query (walk_pl, true, q2);
vertical_ray_shooting_query (ric_pl, true, q2);
vertical_ray_shooting_query(simple_pl, true, q2);
vertical_ray_shooting_query(walk_pl, true, q2);
vertical_ray_shooting_query(ric_pl, true, q2);
vertical_ray_shooting_query (simple_pl, false, q2);
vertical_ray_shooting_query (walk_pl, false, q2);
vertical_ray_shooting_query (ric_pl, false, q2);
vertical_ray_shooting_query(simple_pl, false, q2);
vertical_ray_shooting_query(walk_pl, false, q2);
vertical_ray_shooting_query(ric_pl, false, q2);
vertical_ray_shooting_query (simple_pl, true, q3);
vertical_ray_shooting_query (walk_pl, true, q3);
vertical_ray_shooting_query (ric_pl, true, q3);
vertical_ray_shooting_query(simple_pl, true, q3);
vertical_ray_shooting_query(walk_pl, true, q3);
vertical_ray_shooting_query(ric_pl, true, q3);
vertical_ray_shooting_query (simple_pl, false, q3);
vertical_ray_shooting_query (walk_pl, false, q3);
vertical_ray_shooting_query (ric_pl, false, q3);
vertical_ray_shooting_query(simple_pl, false, q3);
vertical_ray_shooting_query(walk_pl, false, q3);
vertical_ray_shooting_query(ric_pl, false, q3);
return (0);
}

View File

@ -8,13 +8,17 @@
#include <CGAL/Arr_segment_traits_2.h>
#include <CGAL/Arrangement_2.h>
typedef CGAL::Quotient<int> Number_type;
typedef CGAL::Simple_cartesian<Number_type> Kernel;
typedef CGAL::Arr_segment_traits_2<Kernel> Traits_2;
typedef Traits_2::Point_2 Point_2;
typedef Traits_2::X_monotone_curve_2 Segment_2;
typedef CGAL::Arrangement_2<Traits_2> Arrangement_2;
typedef Arrangement_2::Halfedge_handle Halfedge_handle;
typedef CGAL::Quotient<int> Number_type;
typedef CGAL::Simple_cartesian<Number_type> Kernel;
typedef CGAL::Arr_segment_traits_2<Kernel> Traits_2;
typedef Traits_2::Point_2 Point_2;
typedef Traits_2::X_monotone_curve_2 Segment_2;
typedef CGAL::Arrangement_2<Traits_2> Arrangement_2;
typedef Arrangement_2::Vertex_handle Vertex_handle;
typedef Arrangement_2::Halfedge_handle Halfedge_handle;
typedef Arrangement_2::Face_handle Face_handle;
typedef boost::variant<Vertex_handle, Halfedge_handle, Face_handle>
Zone_result;
#define N_SEGMENTS 3
@ -40,7 +44,7 @@ int main ()
for (k = 0; k < N_SEGMENTS; k++)
{
std::list<CGAL::Object> zone_elems;
std::list<Zone_result> zone_elems;
zone(arr, segs[k], std::back_inserter(zone_elems));
std::size_t zone_actual_comp = zone_elems.size();

View File

@ -38,8 +38,9 @@ CGAL::copy_face_graph(g1, g2);
// specifying named parameters for the second graph
CGAL::copy_face_graph(g1, g2,
CGAL::parameters::all_default(),
CGAL::parameters::vertex_point_map(vpm_2));
CGAL::parameters::vertex_point_map(vpm) //parameter for g1
.vertex_to_vertex_map(v2v), //other parameter for g1
CGAL::parameters::all_default()); //parameter for g2
\endcode
*/
˛

View File

@ -443,7 +443,7 @@ the requirement for traversal of all faces in a graph.
/// \defgroup PkgBGLPropertiesDynamic Dynamic Properties
/// \ingroup PkgBGLRef
/// \defgroup PkgBGLGraphExternalIndices External Indices
/// \defgroup BGLGraphExternalIndices External Indices
/// \ingroup PkgBGLRef
/// \defgroup PkgBGLHelperFct Helper Functions

View File

@ -77,7 +77,7 @@ int main(int argc, char** argv)
// http://www.boost.org/libs/property_map/doc/vector_property_map.html
// for details.
boost::vector_property_map<Vector, Face_index_map>
normals(get(CGAL::face_index, lcc));
normals(static_cast<unsigned>(num_faces(lcc)), get(CGAL::face_index, lcc));
calculate_face_normals(
lcc // Graph

View File

@ -82,7 +82,7 @@ int main(int argc, char** argv)
// http://www.boost.org/libs/property_map/doc/vector_property_map.html
// for details.
boost::vector_property_map<Vector, Face_index_map>
normals(get(CGAL::face_index, P));
normals(static_cast<unsigned>(num_faces(P)), get(CGAL::face_index, P));
calculate_face_normals(
P // Graph

View File

@ -13,6 +13,8 @@
#define CGAL_EULER_OPERATIONS_H
#include <stdexcept>
#include <algorithm>
#include <vector>
#include <boost/graph/graph_traits.hpp>
#include <CGAL/boost/graph/properties.h>
@ -558,6 +560,127 @@ add_edge(typename boost::graph_traits<Graph>::vertex_descriptor s,
return e;
}
/**
* checks whether a new face defined by a range of vertices (identified by their descriptors,
* `boost::graph_traits<Graph>::%vertex_descriptor`) can be added.
*/
template <typename VertexRange,typename PMesh>
bool can_add_face(const VertexRange& vrange, const PMesh& sm)
{
typedef typename boost::graph_traits<PMesh>::vertex_descriptor vertex_descriptor;
typedef typename boost::graph_traits<PMesh>::halfedge_descriptor halfedge_descriptor;
std::vector<typename boost::graph_traits<PMesh>::vertex_descriptor> face(vrange.begin(), vrange.end());
std::size_t N = face.size();
std::vector<vertex_descriptor> f2(face);
std::sort(f2.begin(), f2.end());
typename std::vector<vertex_descriptor>::iterator it = std::unique(f2.begin(),f2.end());
if((N > 0) && (it != f2.end())){
return false;
}
if(N < 3){
return false;
}
face.push_back(face.front());
for(std::size_t i=0; i < N; ++i){
halfedge_descriptor hd;
bool found;
boost::tie(hd,found) = halfedge(face[i],face[i+1],sm);
if(found && (! is_border(hd,sm))){
return false;
}
}
for(std::size_t i=0; i < N; ++i){
if(halfedge(face[i],sm) == boost::graph_traits<PMesh>::null_halfedge()){
continue;
}
if(! is_border(face[i],sm)){
return false;
}
}
//Test if all halfedges of the new face
//are possibly consecutive border halfedges in the HDS.
//Possibly because it may be not directly encoded in the HDS
//(using next() function ). This situation can occur when one or
//more facets share only a vertex: For example, the new facet we try to add
//would make the vertex indices[i] a manifold but this should be forbidden
//if a facet only incident to that vertex has already been inserted.
//We check this for each vertex of the sequence.
for(std::size_t i = 0; i < N; ++i) {
std::size_t prev_index= (i-1+N)%N;
std::size_t next_index= (i+1)%N;
vertex_descriptor previous_vertex = face[ prev_index ];
vertex_descriptor next_vertex = face[ next_index ];
halfedge_descriptor halfedge_around_vertex = halfedge(face[i],sm);
if ( halfedge_around_vertex == boost::graph_traits<PMesh>::null_halfedge() ||
halfedge(previous_vertex,sm) == boost::graph_traits<PMesh>::null_halfedge()||
halfedge(next_vertex,sm) == boost::graph_traits<PMesh>::null_halfedge()
) continue;
halfedge_descriptor start=halfedge_around_vertex;
//halfedges pointing to/running out from vertex indices[i]
//and that need to be possibly consecutive
halfedge_descriptor prev_hd= boost::graph_traits<PMesh>::null_halfedge(),next_hd= boost::graph_traits<PMesh>::null_halfedge();
halfedge_around_vertex = opposite(next(halfedge_around_vertex,sm),sm);
//look for a halfedge incident to vertex indices[i]
//and which opposite is incident to previous_vertex
do{
if(target(opposite(halfedge_around_vertex,sm),sm)==previous_vertex){
prev_hd=halfedge_around_vertex;
CGAL_precondition(is_border(prev_hd,sm));
break;
}
halfedge_around_vertex = opposite(next(halfedge_around_vertex,sm),sm);
}
while (halfedge_around_vertex!=start);
if (prev_hd != boost::graph_traits<PMesh>::null_halfedge()){
halfedge_around_vertex = opposite(next(halfedge_around_vertex,sm),sm);
//prev_hd and next are already consecutive in the HDS
if (target(opposite(halfedge_around_vertex,sm),sm)==next_vertex) continue;
//look for a border halfedge which opposite is
//incident to next_vertex: set next halfedge
do
{
if (target(opposite(halfedge_around_vertex,sm),sm)==next_vertex){
next_hd = opposite(halfedge_around_vertex,sm);
break;
}
halfedge_around_vertex = opposite(next(halfedge_around_vertex,sm),sm);
}
while(halfedge_around_vertex != prev_hd);
if (next_hd==boost::graph_traits<PMesh>::null_halfedge()) continue;
//check if no constraint prevents
//prev_hd and next_hd to be adjacent:
do{
halfedge_around_vertex = opposite(next(halfedge_around_vertex, sm),sm);
if ( is_border(opposite(halfedge_around_vertex,sm),sm) ) break;
}
while (halfedge_around_vertex != prev_hd);
if (halfedge_around_vertex == prev_hd) return false;
start = halfedge_around_vertex;
}
}
return true;
}
/**
* adds a new face defined by a range of vertices (identified by their descriptors,
* `boost::graph_traits<Graph>::%vertex_descriptor`).

View File

@ -104,6 +104,66 @@ struct Face_filtered_graph
typedef Face_filtered_graph<Graph, FIMap, VIMap, HIMap> Self;
/*!
* \brief constructs an empty face filtered graph (no face is selected)
*
* \tparam NamedParameters a sequence of named parameters
*
* \param graph the underlying graph.
*
* \param np optional sequence of named parameters among the ones listed below
*
* \cgalNamedParamsBegin
* \cgalParamNBegin{vertex_index_map}
* \cgalParamDescription{a property map associating to each vertex of `graph` a unique index between `0` and `num_vertices(graph) - 1`}
* \cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits<Graph>::%vertex_descriptor`
* as key type and `std::size_t` as value type}
* \cgalParamDefault{an automatically indexed internal map}
* \cgalParamExtra{If this parameter is not passed, internal machinery will create and initialize
* a face index property map, either using the internal property map if it exists
* or using an external map. The latter might result in - slightly - worsened performance
* in case of non-constant complexity for index access.}
* \cgalParamNEnd
*
* \cgalParamNBegin{halfedge_index_map}
* \cgalParamDescription{a property map associating to each halfedge of `graph` a unique index between `0` and `num_halfedges(graph) - 1`}
* \cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits<Graph>::%halfedge_descriptor`
* as key type and `std::size_t` as value type}
* \cgalParamDefault{an automatically indexed internal map}
* \cgalParamExtra{If this parameter is not passed, internal machinery will create and initialize
* a face index property map, either using the internal property map if it exists
* or using an external map. The latter might result in - slightly - worsened performance
* in case of non-constant complexity for index access.}
* \cgalParamNEnd
*
* \cgalParamNBegin{face_index_map}
* \cgalParamDescription{a property map associating to each face of `graph` a unique index between `0` and `num_faces(graph) - 1`}
* \cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits<Graph>::%face_descriptor`
* as key type and `std::size_t` as value type}
* \cgalParamDefault{an automatically indexed internal map}
* \cgalParamExtra{If this parameter is not passed, internal machinery will create and initialize
* a face index property map, either using the internal property map if it exists
* or using an external map. The latter might result in - slightly - worsened performance
* in case of non-constant complexity for index access.}
* \cgalParamNEnd
* \cgalNamedParamsEnd
*/
template <class CGAL_BGL_NP_TEMPLATE_PARAMETERS>
Face_filtered_graph(const Graph& graph,
const CGAL_BGL_NP_CLASS& np)
: _graph(const_cast<Graph&>(graph))
, fimap(CGAL::get_initialized_face_index_map(graph, np))
, vimap(CGAL::get_initialized_vertex_index_map(graph, np))
, himap(CGAL::get_initialized_halfedge_index_map(graph, np))
, selected_faces(num_faces(graph), 0)
, selected_vertices(num_vertices(graph), 0)
, selected_halfedges(num_halfedges(graph), 0)
{}
Face_filtered_graph(const Graph& graph)
:Face_filtered_graph(graph, parameters::all_default())
{}
/*!
* \brief Constructor where the set of selected faces is specified as a range of patch ids.
*

View File

@ -1,4 +1,3 @@
#ifndef CGAL_BOOST_GRAPH_ALPHA_EXPANSION_GRAPHCUT_H
// Copyright (c) 2014 GeometryFactory (France). All rights reserved.
//
// This file is part of CGAL (www.cgal.org)
@ -10,6 +9,7 @@
//
// Author(s) : Ilker O. Yaz, Simon Giraudot
#ifndef CGAL_BOOST_GRAPH_ALPHA_EXPANSION_GRAPHCUT_H
#define CGAL_BOOST_GRAPH_ALPHA_EXPANSION_GRAPHCUT_H
#include <CGAL/Iterator_range.h>

View File

@ -15,21 +15,6 @@
// This will push/pop a VC15 warning
#include <CGAL/boost/graph/Named_function_parameters.h>
#include <boost/version.hpp>
#include <climits>
#if BOOST_VERSION == 105400
#ifdef BOOST_GRAPH_DIJKSTRA_HPP
# pragma message \
"Warning: the header file boost/graph/dijkstra_shortest_paths.hpp " \
"of boost 1.54 contains a bug that may impact some functions in CGAL. " \
"Please consider including CGAL/boost/graph/dijkstra_shortest_paths.hpp " \
"before boost header"
#endif
#include <CGAL/boost/graph/dijkstra_shortest_paths.hpp>
#else
#include <boost/graph/dijkstra_shortest_paths.hpp>
#endif
#include <boost/graph/dijkstra_shortest_paths.hpp>
#endif // CGAL_BOOST_GRAPH_DIJKSTRA_SHORTEST_PATHS_H

View File

@ -1,633 +0,0 @@
// This file is a copy of the file distributed with boost 1.55
// It is distributed with CGAL to work around a bug in boost 1.54
// and must be used only with boost 1.54 by including
// CGAL/boost/graph/dijkstra_shortest_paths.hpp
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
//=======================================================================
//
// $URL$
// $Id$
// SPDX-License-Identifier: BSL-1.0
//
// Revision History:
// 04 April 2001: Added named parameter variant. (Jeremy Siek)
// 01 April 2001: Modified to use new <boost/limits.hpp> header. (JMaddock)
//
#ifndef BOOST_GRAPH_DIJKSTRA_HPP
#define BOOST_GRAPH_DIJKSTRA_HPP
#include <functional>
#include <boost/limits.hpp>
#include <boost/graph/named_function_params.hpp>
#include <boost/graph/breadth_first_search.hpp>
#include <boost/graph/relax.hpp>
#include <boost/pending/indirect_cmp.hpp>
#include <boost/graph/exception.hpp>
#include <boost/pending/relaxed_heap.hpp>
#include <boost/graph/overloading.hpp>
#include <boost/smart_ptr.hpp>
#include <boost/graph/detail/d_ary_heap.hpp>
#include <boost/graph/two_bit_color_map.hpp>
#include <boost/property_map/property_map.hpp>
#include <boost/property_map/vector_property_map.hpp>
#include <boost/type_traits.hpp>
#include <boost/concept/assert.hpp>
#ifdef BOOST_GRAPH_DIJKSTRA_TESTING
# include <boost/pending/mutable_queue.hpp>
#endif // BOOST_GRAPH_DIJKSTRA_TESTING
namespace boost {
/**
* @brief Updates a particular value in a queue used by Dijkstra's
* algorithm.
*
* This routine is called by Dijkstra's algorithm after it has
* decreased the distance from the source vertex to the given @p
* vertex. By default, this routine will just call @c
* Q.update(vertex). However, other queues may provide more
* specialized versions of this routine.
*
* @param Q the queue that will be updated.
* @param vertex the vertex whose distance has been updated
* @param old_distance the previous distance to @p vertex
*/
template<typename Buffer, typename Vertex, typename DistanceType>
inline void
dijkstra_queue_update(Buffer& Q, Vertex vertex, DistanceType old_distance)
{
(void)old_distance;
Q.update(vertex);
}
#ifdef BOOST_GRAPH_DIJKSTRA_TESTING
// This is a misnomer now: it now just refers to the "default heap", which is
// currently d-ary (d=4) but can be changed by a #define.
static bool dijkstra_relaxed_heap = true;
#endif
template <class Visitor, class Graph>
struct DijkstraVisitorConcept {
void constraints() {
// commented to avoid an unused vaiable warning
// BOOST_CONCEPT_ASSERT(( CopyConstructibleConcept<Visitor> ));
vis.initialize_vertex(u, g);
vis.discover_vertex(u, g);
vis.examine_vertex(u, g);
vis.examine_edge(e, g);
vis.edge_relaxed(e, g);
vis.edge_not_relaxed(e, g);
vis.finish_vertex(u, g);
}
Visitor vis;
Graph g;
typename graph_traits<Graph>::vertex_descriptor u;
typename graph_traits<Graph>::edge_descriptor e;
};
template <class Visitors = null_visitor>
class dijkstra_visitor : public bfs_visitor<Visitors> {
public:
dijkstra_visitor() { }
dijkstra_visitor(Visitors vis)
: bfs_visitor<Visitors>(vis) { }
template <class Edge, class Graph>
void edge_relaxed(Edge e, Graph& g) {
invoke_visitors(this->m_vis, e, g, on_edge_relaxed());
}
template <class Edge, class Graph>
void edge_not_relaxed(Edge e, Graph& g) {
invoke_visitors(this->m_vis, e, g, on_edge_not_relaxed());
}
private:
template <class Edge, class Graph>
void tree_edge(Edge /* u */, Graph& /* g */) { }
};
template <class Visitors>
dijkstra_visitor<Visitors>
make_dijkstra_visitor(Visitors vis) {
return dijkstra_visitor<Visitors>(vis);
}
typedef dijkstra_visitor<> default_dijkstra_visitor;
namespace detail {
template <class UniformCostVisitor, class UpdatableQueue,
class WeightMap, class PredecessorMap, class DistanceMap,
class BinaryFunction, class BinaryPredicate>
struct dijkstra_bfs_visitor
{
typedef typename property_traits<DistanceMap>::value_type D;
typedef typename property_traits<WeightMap>::value_type W;
dijkstra_bfs_visitor(UniformCostVisitor vis, UpdatableQueue& Q,
WeightMap w, PredecessorMap p, DistanceMap d,
BinaryFunction combine, BinaryPredicate compare,
D zero)
: m_vis(vis), m_Q(Q), m_weight(w), m_predecessor(p), m_distance(d),
m_combine(combine), m_compare(compare), m_zero(zero) { }
template <class Edge, class Graph>
void tree_edge(Edge e, Graph& g) {
bool decreased = relax(e, g, m_weight, m_predecessor, m_distance,
m_combine, m_compare);
if (decreased)
m_vis.edge_relaxed(e, g);
else
m_vis.edge_not_relaxed(e, g);
}
template <class Edge, class Graph>
void gray_target(Edge e, Graph& g) {
D old_distance = get(m_distance, target(e, g));
bool decreased = relax(e, g, m_weight, m_predecessor, m_distance,
m_combine, m_compare);
if (decreased) {
dijkstra_queue_update(m_Q, target(e, g), old_distance);
m_vis.edge_relaxed(e, g);
} else
m_vis.edge_not_relaxed(e, g);
}
template <class Vertex, class Graph>
void initialize_vertex(Vertex u, Graph& g)
{ m_vis.initialize_vertex(u, g); }
template <class Edge, class Graph>
void non_tree_edge(Edge, Graph&) { }
template <class Vertex, class Graph>
void discover_vertex(Vertex u, Graph& g) { m_vis.discover_vertex(u, g); }
template <class Vertex, class Graph>
void examine_vertex(Vertex u, Graph& g) { m_vis.examine_vertex(u, g); }
template <class Edge, class Graph>
void examine_edge(Edge e, Graph& g) {
// Test for negative-weight edges:
//
// Reasons that other comparisons do not work:
//
// m_compare(e_weight, D(0)):
// m_compare only needs to work on distances, not weights, and those
// types do not need to be the same (bug 8398,
// https://svn.boost.org/trac/boost/ticket/8398).
// m_compare(m_combine(source_dist, e_weight), source_dist):
// if m_combine is project2nd (as in prim_minimum_spanning_tree),
// this test will claim that the edge weight is negative whenever
// the edge weight is less than source_dist, even if both of those
// are positive (bug 9012,
// https://svn.boost.org/trac/boost/ticket/9012).
// m_compare(m_combine(e_weight, source_dist), source_dist):
// would fix project2nd issue, but documentation only requires that
// m_combine be able to take a distance and a weight (in that order)
// and return a distance.
// W e_weight = get(m_weight, e);
// sd_plus_ew = source_dist + e_weight.
// D sd_plus_ew = m_combine(source_dist, e_weight);
// sd_plus_2ew = source_dist + 2 * e_weight.
// D sd_plus_2ew = m_combine(sd_plus_ew, e_weight);
// The test here is equivalent to e_weight < 0 if m_combine has a
// cancellation law, but always returns false when m_combine is a
// projection operator.
if (m_compare(m_combine(m_zero, get(m_weight, e)), m_zero))
boost::throw_exception(negative_edge());
// End of test for negative-weight edges.
m_vis.examine_edge(e, g);
}
template <class Edge, class Graph>
void black_target(Edge, Graph&) { }
template <class Vertex, class Graph>
void finish_vertex(Vertex u, Graph& g) { m_vis.finish_vertex(u, g); }
UniformCostVisitor m_vis;
UpdatableQueue& m_Q;
WeightMap m_weight;
PredecessorMap m_predecessor;
DistanceMap m_distance;
BinaryFunction m_combine;
BinaryPredicate m_compare;
D m_zero;
};
} // namespace detail
namespace detail {
template <class Graph, class IndexMap, class Value, bool KnownNumVertices>
struct vertex_property_map_generator_helper {};
template <class Graph, class IndexMap, class Value>
struct vertex_property_map_generator_helper<Graph, IndexMap, Value, true> {
typedef boost::iterator_property_map<Value*, IndexMap> type;
static type build(const Graph& g, const IndexMap& index, boost::scoped_array<Value>& array_holder) {
array_holder.reset(new Value[num_vertices(g)]);
std::fill(array_holder.get(), array_holder.get() + num_vertices(g), Value());
return make_iterator_property_map(array_holder.get(), index);
}
};
template <class Graph, class IndexMap, class Value>
struct vertex_property_map_generator_helper<Graph, IndexMap, Value, false> {
typedef boost::vector_property_map<Value, IndexMap> type;
static type build(const Graph& /* g */, const IndexMap& index, boost::scoped_array<Value>& /* array_holder */) {
return boost::make_vector_property_map<Value>(index);
}
};
template <class Graph, class IndexMap, class Value>
struct vertex_property_map_generator {
typedef boost::is_base_and_derived<
boost::vertex_list_graph_tag,
typename boost::graph_traits<Graph>::traversal_category>
known_num_vertices;
typedef vertex_property_map_generator_helper<Graph, IndexMap, Value, known_num_vertices::value> helper;
typedef typename helper::type type;
static type build(const Graph& g, const IndexMap& index, boost::scoped_array<Value>& array_holder) {
return helper::build(g, index, array_holder);
}
};
}
namespace detail {
template <class Graph, class IndexMap, bool KnownNumVertices>
struct default_color_map_generator_helper {};
template <class Graph, class IndexMap>
struct default_color_map_generator_helper<Graph, IndexMap, true> {
typedef boost::two_bit_color_map<IndexMap> type;
static type build(const Graph& g, const IndexMap& index) {
size_t nv = num_vertices(g);
return boost::two_bit_color_map<IndexMap>(nv, index);
}
};
template <class Graph, class IndexMap>
struct default_color_map_generator_helper<Graph, IndexMap, false> {
typedef boost::vector_property_map<boost::two_bit_color_type, IndexMap> type;
static type build(const Graph& /* g */, const IndexMap& index) {
return boost::make_vector_property_map<boost::two_bit_color_type>(index);
}
};
template <class Graph, class IndexMap>
struct default_color_map_generator {
typedef boost::is_base_and_derived<
boost::vertex_list_graph_tag,
typename boost::graph_traits<Graph>::traversal_category>
known_num_vertices;
typedef default_color_map_generator_helper<Graph, IndexMap, known_num_vertices::value> helper;
typedef typename helper::type type;
static type build(const Graph& g, const IndexMap& index) {
return helper::build(g, index);
}
};
}
// Call breadth first search with default color map.
template <class Graph, class SourceInputIter, class DijkstraVisitor,
class PredecessorMap, class DistanceMap,
class WeightMap, class IndexMap, class Compare, class Combine,
class DistZero>
inline void
dijkstra_shortest_paths_no_init
(const Graph& g,
SourceInputIter s_begin, SourceInputIter s_end,
PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
IndexMap index_map,
Compare compare, Combine combine, DistZero zero,
DijkstraVisitor vis)
{
typedef
detail::default_color_map_generator<Graph, IndexMap>
ColorMapHelper;
typedef typename ColorMapHelper::type ColorMap;
ColorMap color =
ColorMapHelper::build(g, index_map);
dijkstra_shortest_paths_no_init( g, s_begin, s_end, predecessor, distance, weight,
index_map, compare, combine, zero, vis,
color);
}
// Call breadth first search with default color map.
template <class Graph, class DijkstraVisitor,
class PredecessorMap, class DistanceMap,
class WeightMap, class IndexMap, class Compare, class Combine,
class DistZero>
inline void
dijkstra_shortest_paths_no_init
(const Graph& g,
typename graph_traits<Graph>::vertex_descriptor s,
PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
IndexMap index_map,
Compare compare, Combine combine, DistZero zero,
DijkstraVisitor vis)
{
dijkstra_shortest_paths_no_init(g, &s, &s + 1, predecessor, distance,
weight, index_map, compare, combine, zero,
vis);
}
// Call breadth first search
template <class Graph, class SourceInputIter, class DijkstraVisitor,
class PredecessorMap, class DistanceMap,
class WeightMap, class IndexMap, class Compare, class Combine,
class DistZero, class ColorMap>
inline void
dijkstra_shortest_paths_no_init
(const Graph& g,
SourceInputIter s_begin, SourceInputIter s_end,
PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
IndexMap index_map,
Compare compare, Combine combine, DistZero zero,
DijkstraVisitor vis, ColorMap color)
{
typedef indirect_cmp<DistanceMap, Compare> IndirectCmp;
IndirectCmp icmp(distance, compare);
typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
#ifdef BOOST_GRAPH_DIJKSTRA_TESTING
if (!dijkstra_relaxed_heap) {
typedef mutable_queue<Vertex, std::vector<Vertex>, IndirectCmp, IndexMap>
MutableQueue;
MutableQueue Q(num_vertices(g), icmp, index_map);
detail::dijkstra_bfs_visitor<DijkstraVisitor, MutableQueue, WeightMap,
PredecessorMap, DistanceMap, Combine, Compare>
bfs_vis(vis, Q, weight, predecessor, distance, combine, compare, zero);
breadth_first_visit(g, s_begin, s_end, Q, bfs_vis, color);
return;
}
#endif // BOOST_GRAPH_DIJKSTRA_TESTING
#ifdef BOOST_GRAPH_DIJKSTRA_USE_RELAXED_HEAP
typedef relaxed_heap<Vertex, IndirectCmp, IndexMap> MutableQueue;
MutableQueue Q(num_vertices(g), icmp, index_map);
#else // Now the default: use a d-ary heap
boost::scoped_array<std::size_t> index_in_heap_map_holder;
typedef
detail::vertex_property_map_generator<Graph, IndexMap, std::size_t>
IndexInHeapMapHelper;
typedef typename IndexInHeapMapHelper::type IndexInHeapMap;
IndexInHeapMap index_in_heap =
IndexInHeapMapHelper::build(g, index_map, index_in_heap_map_holder);
typedef d_ary_heap_indirect<Vertex, 4, IndexInHeapMap, DistanceMap, Compare>
MutableQueue;
MutableQueue Q(distance, index_in_heap, compare);
#endif // Relaxed heap
detail::dijkstra_bfs_visitor<DijkstraVisitor, MutableQueue, WeightMap,
PredecessorMap, DistanceMap, Combine, Compare>
bfs_vis(vis, Q, weight, predecessor, distance, combine, compare, zero);
breadth_first_visit(g, s_begin, s_end, Q, bfs_vis, color);
}
// Call breadth first search
template <class Graph, class DijkstraVisitor,
class PredecessorMap, class DistanceMap,
class WeightMap, class IndexMap, class Compare, class Combine,
class DistZero, class ColorMap>
inline void
dijkstra_shortest_paths_no_init
(const Graph& g,
typename graph_traits<Graph>::vertex_descriptor s,
PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
IndexMap index_map,
Compare compare, Combine combine, DistZero zero,
DijkstraVisitor vis, ColorMap color)
{
dijkstra_shortest_paths_no_init(g, &s, &s + 1, predecessor, distance,
weight, index_map, compare, combine,
zero, vis, color);
}
// Initialize distances and call breadth first search with default color map
template <class VertexListGraph, class SourceInputIter, class DijkstraVisitor,
class PredecessorMap, class DistanceMap,
class WeightMap, class IndexMap, class Compare, class Combine,
class DistInf, class DistZero, typename T, typename Tag,
typename Base>
inline void
dijkstra_shortest_paths
(const VertexListGraph& g,
SourceInputIter s_begin, SourceInputIter s_end,
PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
IndexMap index_map,
Compare compare, Combine combine, DistInf inf, DistZero zero,
DijkstraVisitor vis,
const bgl_named_params<T, Tag, Base>&
BOOST_GRAPH_ENABLE_IF_MODELS_PARM(VertexListGraph,vertex_list_graph_tag))
{
boost::two_bit_color_map<IndexMap> color(num_vertices(g), index_map);
dijkstra_shortest_paths(g, s_begin, s_end, predecessor, distance, weight,
index_map, compare, combine, inf, zero, vis,
color);
}
// Initialize distances and call breadth first search with default color map
template <class VertexListGraph, class DijkstraVisitor,
class PredecessorMap, class DistanceMap,
class WeightMap, class IndexMap, class Compare, class Combine,
class DistInf, class DistZero, typename T, typename Tag,
typename Base>
inline void
dijkstra_shortest_paths
(const VertexListGraph& g,
typename graph_traits<VertexListGraph>::vertex_descriptor s,
PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
IndexMap index_map,
Compare compare, Combine combine, DistInf inf, DistZero zero,
DijkstraVisitor vis,
const bgl_named_params<T, Tag, Base>&
BOOST_GRAPH_ENABLE_IF_MODELS_PARM(VertexListGraph,vertex_list_graph_tag))
{
dijkstra_shortest_paths(g, &s, &s + 1, predecessor, distance, weight,
index_map, compare, combine, inf, zero, vis);
}
// Initialize distances and call breadth first search
template <class VertexListGraph, class SourceInputIter, class DijkstraVisitor,
class PredecessorMap, class DistanceMap,
class WeightMap, class IndexMap, class Compare, class Combine,
class DistInf, class DistZero, class ColorMap>
inline void
dijkstra_shortest_paths
(const VertexListGraph& g,
SourceInputIter s_begin, SourceInputIter s_end,
PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
IndexMap index_map,
Compare compare, Combine combine, DistInf inf, DistZero zero,
DijkstraVisitor vis, ColorMap color)
{
typedef typename property_traits<ColorMap>::value_type ColorValue;
typedef color_traits<ColorValue> Color;
typename graph_traits<VertexListGraph>::vertex_iterator ui, ui_end;
for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) {
vis.initialize_vertex(*ui, g);
put(distance, *ui, inf);
put(predecessor, *ui, *ui);
put(color, *ui, Color::white());
}
for (SourceInputIter it = s_begin; it != s_end; ++it) {
put(distance, *it, zero);
}
dijkstra_shortest_paths_no_init(g, s_begin, s_end, predecessor, distance,
weight, index_map, compare, combine, zero, vis,
color);
}
// Initialize distances and call breadth first search
template <class VertexListGraph, class DijkstraVisitor,
class PredecessorMap, class DistanceMap,
class WeightMap, class IndexMap, class Compare, class Combine,
class DistInf, class DistZero, class ColorMap>
inline void
dijkstra_shortest_paths
(const VertexListGraph& g,
typename graph_traits<VertexListGraph>::vertex_descriptor s,
PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
IndexMap index_map,
Compare compare, Combine combine, DistInf inf, DistZero zero,
DijkstraVisitor vis, ColorMap color)
{
dijkstra_shortest_paths(g, &s, &s + 1, predecessor, distance, weight,
index_map, compare, combine, inf, zero,
vis, color);
}
// Initialize distances and call breadth first search
template <class VertexListGraph, class SourceInputIter,
class DijkstraVisitor,
class PredecessorMap, class DistanceMap,
class WeightMap, class IndexMap, class Compare, class Combine,
class DistInf, class DistZero>
inline void
dijkstra_shortest_paths
(const VertexListGraph& g,
SourceInputIter s_begin, SourceInputIter s_end,
PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
IndexMap index_map,
Compare compare, Combine combine, DistInf inf, DistZero zero,
DijkstraVisitor vis)
{
dijkstra_shortest_paths(g, s_begin, s_end, predecessor, distance,
weight, index_map,
compare, combine, inf, zero, vis,
no_named_parameters());
}
// Initialize distances and call breadth first search
template <class VertexListGraph, class DijkstraVisitor,
class PredecessorMap, class DistanceMap,
class WeightMap, class IndexMap, class Compare, class Combine,
class DistInf, class DistZero>
inline void
dijkstra_shortest_paths
(const VertexListGraph& g,
typename graph_traits<VertexListGraph>::vertex_descriptor s,
PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
IndexMap index_map,
Compare compare, Combine combine, DistInf inf, DistZero zero,
DijkstraVisitor vis)
{
dijkstra_shortest_paths(g, &s, &s + 1, predecessor, distance,
weight, index_map,
compare, combine, inf, zero, vis);
}
namespace detail {
// Handle defaults for PredecessorMap and
// Distance Compare, Combine, Inf and Zero
template <class VertexListGraph, class DistanceMap, class WeightMap,
class IndexMap, class Params>
inline void
dijkstra_dispatch2
(const VertexListGraph& g,
typename graph_traits<VertexListGraph>::vertex_descriptor s,
DistanceMap distance, WeightMap weight, IndexMap index_map,
const Params& params)
{
// Default for predecessor map
dummy_property_map p_map;
typedef typename property_traits<DistanceMap>::value_type D;
D inf = choose_param(get_param(params, distance_inf_t()),
(std::numeric_limits<D>::max)());
dijkstra_shortest_paths
(g, s,
choose_param(get_param(params, vertex_predecessor), p_map),
distance, weight, index_map,
choose_param(get_param(params, distance_compare_t()),
std::less<D>()),
choose_param(get_param(params, distance_combine_t()),
closed_plus<D>(inf)),
inf,
choose_param(get_param(params, distance_zero_t()),
D()),
choose_param(get_param(params, graph_visitor),
make_dijkstra_visitor(null_visitor())),
params);
}
template <class VertexListGraph, class DistanceMap, class WeightMap,
class IndexMap, class Params>
inline void
dijkstra_dispatch1
(const VertexListGraph& g,
typename graph_traits<VertexListGraph>::vertex_descriptor s,
DistanceMap distance, WeightMap weight, IndexMap index_map,
const Params& params)
{
// Default for distance map
typedef typename property_traits<WeightMap>::value_type D;
typename std::vector<D>::size_type
n = is_default_param(distance) ? num_vertices(g) : 1;
std::vector<D> distance_map(n);
detail::dijkstra_dispatch2
(g, s, choose_param(distance, make_iterator_property_map
(distance_map.begin(), index_map,
distance_map[0])),
weight, index_map, params);
}
} // namespace detail
// Named Parameter Variant
template <class VertexListGraph, class Param, class Tag, class Rest>
inline void
dijkstra_shortest_paths
(const VertexListGraph& g,
typename graph_traits<VertexListGraph>::vertex_descriptor s,
const bgl_named_params<Param,Tag,Rest>& params)
{
// Default for edge weight and vertex index map is to ask for them
// from the graph. Default for the visitor is null_visitor.
detail::dijkstra_dispatch1
(g, s,
get_param(params, vertex_distance),
choose_const_pmap(get_param(params, edge_weight), g, edge_weight),
choose_const_pmap(get_param(params, vertex_index), g, vertex_index),
params);
}
} // namespace boost
#ifdef BOOST_GRAPH_USE_MPI
# include <boost/graph/distributed/dijkstra_shortest_paths.hpp>
#endif
#endif // BOOST_GRAPH_DIJKSTRA_HPP

View File

@ -20,13 +20,6 @@
#include <CGAL/boost/graph/IO/STL.h>
#include <CGAL/boost/graph/IO/VTK.h>
#include <CGAL/boost/graph/IO/WRL.h>
\param os the output stream
\param g the graph to be written
\param os the output stream
\param g the graph to be written
\param is the input stream
\param g the graph to be read
#include <CGAL/boost/graph/IO/polygon_mesh_io.h>
#endif // CGAL_BOOST_GRAPH_IO_H

View File

@ -1,18 +1,8 @@
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
//=======================================================================
// Copyright (c) 2007-2015 GeometryFactory (France). All rights reserved.
//
// $URL$
// $Id$
// SPDX-License-Identifier: BSL-1.0
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s) : Andreas Fabri, Fernando Cacciola, Jane Tournois
@ -299,7 +289,6 @@ CGAL_DEF_GET_INITIALIZED_INDEX_MAP(face, typename boost::graph_traits<Graph>::fa
> ::type type;
};
namespace internal {
BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_nested_type_iterator, iterator, false)
}

View File

@ -15,7 +15,7 @@ CGAL_add_named_parameter(halfedge_index_t, halfedge_index, halfedge_index_map)
CGAL_add_named_parameter(edge_index_t, edge_index, edge_index_map)
CGAL_add_named_parameter(face_index_t, face_index, face_index_map)
CGAL_add_named_parameter(vertex_index_t, vertex_index, vertex_index_map)
CGAL_add_named_parameter(graph_visitor_t, graph_visitor, visitor)
CGAL_add_named_parameter(visitor_t, visitor, visitor)
CGAL_add_named_parameter(point_t, point_map, point_map)
@ -186,7 +186,6 @@ CGAL_add_named_parameter(pca_plane_t, pca_plane, pca_plane)
CGAL_add_named_parameter(remesh_boundaries_t, remesh_boundaries, remesh_boundaries)
CGAL_add_named_parameter(cell_selector_t, cell_selector, cell_selector)
CGAL_add_named_parameter(facet_is_constrained_t, facet_is_constrained, facet_is_constrained_map)
CGAL_add_named_parameter(remeshing_visitor_t, remeshing_visitor, remeshing_visitor)
CGAL_add_named_parameter(smooth_constrained_edges_t, smooth_constrained_edges, smooth_constrained_edges)
// output parameters

View File

@ -83,6 +83,8 @@ create_single_source_cgal_program( "test_Face_filtered_graph.cpp" )
create_single_source_cgal_program( "test_Euler_operations.cpp" )
create_single_source_cgal_program( "test_test_face.cpp" )
create_single_source_cgal_program( "test_Collapse_edge.cpp" )
create_single_source_cgal_program( "test_graph_traits.cpp" )

View File

@ -28,7 +28,7 @@ void test(const NamedParameters& np)
// Named parameters that we use in CGAL
assert(get_parameter(np, CGAL::internal_np::vertex_index).v == 0);
assert(get_parameter(np, CGAL::internal_np::graph_visitor).v == 1);
assert(get_parameter(np, CGAL::internal_np::visitor).v == 1);
assert(get_parameter(np, CGAL::internal_np::vertex_point).v == 2);
assert(get_parameter(np, CGAL::internal_np::halfedge_index).v == 3);
assert(get_parameter(np, CGAL::internal_np::edge_index).v == 4);
@ -130,7 +130,7 @@ void test(const NamedParameters& np)
// Named parameters that we use in CGAL
check_same_type<0>(get_parameter(np, CGAL::internal_np::vertex_index));
check_same_type<1>(get_parameter(np, CGAL::internal_np::graph_visitor));
check_same_type<1>(get_parameter(np, CGAL::internal_np::visitor));
check_same_type<2>(get_parameter(np, CGAL::internal_np::vertex_point));
check_same_type<3>(get_parameter(np, CGAL::internal_np::halfedge_index));
check_same_type<4>(get_parameter(np, CGAL::internal_np::edge_index));

View File

@ -0,0 +1,60 @@
#include <CGAL/Surface_mesh.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/boost/graph/Euler_operations.h>
#include <vector>
#include <iostream>
typedef CGAL::Simple_cartesian<double> K;
typedef K::Point_3 Point_3;
typedef CGAL::Surface_mesh<Point_3> SM;
typedef boost::graph_traits<SM>::vertex_descriptor vertex_descriptor;
typedef boost::graph_traits<SM>::vertex_iterator vertex_iterator;
typedef std::vector<vertex_descriptor> V;
int main()
{
{
SM sm;
vertex_descriptor vp = CGAL::add_vertex(sm);
vertex_descriptor vq = CGAL::add_vertex(sm);
vertex_descriptor vr = CGAL::add_vertex(sm);
vertex_descriptor vs = CGAL::add_vertex(sm);
std::array<vertex_descriptor,0> face0;
assert( ! CGAL::Euler::can_add_face(face0,sm) );
std::array<vertex_descriptor,1> face1;
assert( ! CGAL::Euler::can_add_face(face1,sm) );
std::array<vertex_descriptor,2> face2;
assert( ! CGAL::Euler::can_add_face(face2,sm) );
std::array<vertex_descriptor,3> face = { vp, vq, vr };
CGAL::Euler::add_face(face, sm);
assert( ! CGAL::Euler::can_add_face(face,sm) );
std::swap(face[0],face[1]);
assert( CGAL::Euler::can_add_face(face,sm) );
face[2] = vs;
assert( CGAL::Euler::can_add_face(face,sm) );
std::swap(face[0],face[1]);
assert( ! CGAL::Euler::can_add_face(face,sm) );
}
{
SM sm;
Point_3 p(0,0,0), q(1,0,0), r(0,1,0), s(0,0,1);
CGAL::make_tetrahedron(p, q, r, s, sm);
std::array<vertex_descriptor,3> face;
vertex_iterator it = vertices(sm).first;
face[0] = *it;
++it;
face[1] = *it;
face[2] = CGAL::add_vertex(sm);
assert( ! CGAL::Euler::can_add_face(face,sm) );
std::swap(face[0],face[1]);
assert( ! CGAL::Euler::can_add_face(face,sm) );
}
return 0;
}

View File

@ -9,37 +9,16 @@ namespace CGAL {
\authors Kaspar Fischer, Bernd G&auml;rtner, Thomas Herrmann, Michael Hoffmann, and Sven Sch&ouml;nherr
\image html ball.png
\image latex ball.png
This chapter describes algorithms which for a given point set compute
the <i>best</i> circumscribing object from a specific
class. If the class consists of all spheres in \f$ d\f$-dimensional
Euclidean space and <i>best</i> is defined as having smallest radius,
then we obtain the smallest enclosing sphere problem already mentioned
above.
then we obtain the smallest enclosing sphere.
In the following example a smallest enclosing circle
(`Min_circle_2<Traits>`) is constructed from points
on a line and written to standard output. The example
shows that it is advisable to switch on random shuffling
in order to deal with a <i>bad</i> order of the input points.
\cgalExample{Min_circle_2/min_circle_2.cpp}
Other classes for which we provide solutions are ellipses
(`Min_ellipse_2<Traits>`), rectangles
(`min_rectangle_2()`), parallelograms
(`min_parallelogram_2()`) and strips (`min_strip_2()`)
in the plane, with appropriate optimality criteria. For arbitrary
dimensions we provide smallest enclosing spheres for points
(`Min_sphere_d<Traits>`) and spheres for spheres
(`Min_sphere_of_spheres_d<Traits>`), smallest enclosing
annuli (`Min_annulus_d<Traits>`), and approximate
minimum-volume enclosing ellipsoid with user-specified
approximation ratio (`Approximate_min_ellipsoid_d<Traits>`).
\image html annulus.png
\image latex annulus.png
\section SectBoundingIntroduction Introduction
Bounding volumes can be used to obtain simple approximations of
complicated objects. For example, consider the problem of deciding
@ -60,13 +39,74 @@ geometric properties of objects. For example, the smallest enclosing
annulus of a point set can be used to test whether a set of points is
approximately cospherical. Here, the width of the annulus (or its
area, or still another criterion that we use) is a good measure for
this property. The largest area triangle is for example used in
heuristics for matching archaeological aerial photographs. Largest
perimeter triangles are used in scoring cross country soaring flights,
where the goal is basically to fly as far as possible, but still
return to the departure airfield. To score simply based on the total
distance flown is not a good measure, since circling in thermals
allows to increase it easily.
this property.
\section SectBoundingSphere Bounding Spheres in dD
We provide the class `Min_sphere_of_spheres_d<Traits>` for arbitrary dimensions
to compute the smallest enclosing spheres for points as well as for spheres.
The dimension as well as the input type depend on the chosen traits class.
The following example is for 2D points
\cgalExample{Min_circle_2/min_circle_2.cpp}
The example for 2D circles as input looks rather similar.
\cgalExample{Min_sphere_of_spheres_d/min_sphere_of_spheres_d_2.cpp}
\subsection SectBoundingSphereHomogeneous Bounding Spheres for the Homogeneous Kernel
In the previous section we saw that we used `Min_sphere_of_spheres_d`
to compute the smallest circle for points. This package also provides
the classes `Min_circle_2` and `Min_sphere_d`, but they are slower,
and they should only be used in case of homogeneous coordinates which
are not supported by `Min_sphere_of_spheres_d`.
In the following example a smallest enclosing circle
(`Min_circle_2<Traits>`) is constructed from points
on a line and written to standard output. The example
shows that it is advisable to switch on random shuffling
in order to deal with a <i>bad</i> order of the input points.
\cgalExample{Min_circle_2/min_circle_homogeneous_2.cpp}
\section SectBoundingAnnulus Bounding Annulus in dD
We provide the class `Min_annulus_d<Traits>` for arbitrary dimensions
to compute the smalles enclosing annulus for a set of points.
In 2D the annulus consists of two concentric circles, in 3D of
two concentric spheres.
\image html annulus.png
\section SectBounding2D Various Bounding Areas in 2D
Other classes for which we provide solutions are ellipses
(`Min_ellipse_2<Traits>`), rectangles
(`min_rectangle_2()`), parallelograms
(`min_parallelogram_2()`) and strips (`min_strip_2()`)
in the plane, with appropriate optimality criteria.
\section SectBoundingEllipsoid Approximate Bounding Ellipsoid in dD
While this package provides an exact smallest 2D ellipse, it also
provides the class `Approximate_min_ellipsoid_d<Traits>` to compute
an approximate minimum-volume enclosing ellipsoid with user-specified
approximation ratio.
\section SectBoundingPcenter Rectangular P-Center
Bounding volumes also define geometric "center points" of objects.
For example, if two objects are to be matched (approximately), one
@ -81,8 +121,6 @@ planar point set with between two and four minimal boxes
three boxes; the center points are shown in red.
\image html pcenter.png
\image latex pcenter.png
*/
} /* namespace CGAL */

View File

@ -191,7 +191,7 @@ to iterate over the %Cartesian coordinates of the direction of a fixed
axis of the computed ellipsoid, see
`axis_direction_cartesian_begin()`.
*/
typedef unspecified_type Axis_direction_iterator;
typedef unspecified_type Axes_direction_coordinate_iterator;
/// @}

View File

@ -24,17 +24,17 @@ The underlying algorithm can cope with all kinds of input, e.g. \f$ P\f$ may be
empty or points may occur more than once. The algorithm computes a support
set \f$ S\f$ which remains fixed until the next set, insert, or clear operation.
\tparam Traits must be a model for `OptimisationDTraits`.
\tparam Traits must be a model for `MinSphereAnnulusDTraits`.
We provide the models `Optimisation_d_traits_2`,
`Optimisation_d_traits_3`, and `Optimisation_d_traits_d` using the
We provide the models `Min_sphere_annulus_d_traits_2`,
`Min_sphere_annulus_d_traits_3`, and `Min_sphere_annulus_d_traits_d` using the
two-, three-, and \f$ d\f$-dimensional \cgal kernel, respectively.
\sa `CGAL::Min_sphere_d<Traits>`
\sa `CGAL::Optimisation_d_traits_2<K,ET,NT>`
\sa `CGAL::Optimisation_d_traits_3<K,ET,NT>`
\sa `CGAL::Optimisation_d_traits_d<K,ET,NT>`
\sa `OptimisationDTraits`
\sa `CGAL::Min_sphere_annulus_d_traits_2<K,ET,NT>`
\sa `CGAL::Min_sphere_annulus_d_traits_3<K,ET,NT>`
\sa `CGAL::Min_sphere_annulus_d_traits_d<K,ET,NT>`
\sa `MinSphereAnnulusDTraits`
\cgalHeading{Implementation}

View File

@ -23,9 +23,9 @@ The underlying algorithm can cope with all kinds of input, e.g. \f$ P\f$ may be
empty or points may occur more than once. The algorithm computes a support
set \f$ S\f$ which remains fixed until the next insert or clear operation.
<B>Please note:</B> This class is (almost) obsolete. The class
\note This class is (almost) obsolete. The class
`CGAL::Min_sphere_of_spheres_d<Traits>` solves a more general problem
and is faster then `Min_circle_2` even if used only for points in two
and is faster than `Min_circle_2` even if used only for points in two
dimensions as input. Most importantly,
`CGAL::Min_sphere_of_spheres_d<Traits>` has
a specialized implementation for floating-point arithmetic which

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