mirror of https://github.com/CGAL/cgal
Merge remote-tracking branch 'cgal/master' into CGAL_IO-maxGimeno
This commit is contained in:
commit
f55ef7dd50
|
|
@ -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
|
||||
});
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
/// @}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 =
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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 = "
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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())) ||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
//@}
|
||||
|
||||
|
|
|
|||
|
|
@ -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()); }
|
||||
|
|
|
|||
|
|
@ -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
|
||||
//@{
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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).
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -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); }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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).
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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.");
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@
|
|||
#include <boost/optional.hpp>
|
||||
|
||||
#include <CGAL/Arr_tags.h>
|
||||
#include <CGAL/Object.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -262,7 +262,7 @@ private:
|
|||
void allocate_pl()
|
||||
{
|
||||
Strategy* locator = new Strategy();
|
||||
CGAL_assertion(locator);
|
||||
assert(locator);
|
||||
m_locators[id].m_variant = locator;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*/
|
||||
˛
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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`).
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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" )
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -9,37 +9,16 @@ namespace CGAL {
|
|||
\authors Kaspar Fischer, Bernd Gärtner, Thomas Herrmann, Michael Hoffmann, and Sven Schö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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
/// @}
|
||||
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Reference in New Issue