mirror of https://github.com/CGAL/cgal
Merge remote-tracking branch 'origin' into Number_types-add_benchmarks-danston
This commit is contained in:
commit
bb3e0f2f17
|
|
@ -109,7 +109,7 @@ jobs:
|
||||||
mv tmp.html index.html
|
mv tmp.html index.html
|
||||||
git add ${PR_NUMBER}/$ROUND index.html && git commit -q --amend -m "base commit" && git push -q -f -u origin master
|
git add ${PR_NUMBER}/$ROUND index.html && git commit -q --amend -m "base commit" && git push -q -f -u origin master
|
||||||
else
|
else
|
||||||
echo "::set-output name=DoxygenError::This round already exists. Overwrite it with /force-build"
|
echo "::set-output name=DoxygenError::This round already exists. Overwrite it with /force-build."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
@ -121,7 +121,7 @@ jobs:
|
||||||
const tmp_round = "${{ steps.get_round.outputs.result }}";
|
const tmp_round = "${{ steps.get_round.outputs.result }}";
|
||||||
const id = tmp_round.indexOf(":");
|
const id = tmp_round.indexOf(":");
|
||||||
const round = tmp_round.substring(0,id);
|
const round = tmp_round.substring(0,id);
|
||||||
const address = "The documentation is built. It will be available, after a few minutes, here : https://cgal.github.io/${{ steps.get_pr_number.outputs.result }}/"+round+"/Manual/index.html"
|
const address = "The documentation is built. It will be available, after a few minutes, here: https://cgal.github.io/${{ steps.get_pr_number.outputs.result }}/"+round+"/Manual/index.html"
|
||||||
github.issues.createComment({
|
github.issues.createComment({
|
||||||
owner: "CGAL",
|
owner: "CGAL",
|
||||||
repo: "cgal",
|
repo: "cgal",
|
||||||
|
|
|
||||||
|
|
@ -22,11 +22,10 @@ jobs:
|
||||||
if [ -n "$(diff -q ./index.html ./tmp.html)" ]; then
|
if [ -n "$(diff -q ./index.html ./tmp.html)" ]; then
|
||||||
mv tmp.html index.html
|
mv tmp.html index.html
|
||||||
fi
|
fi
|
||||||
if [ -d ${PR_NUMBER} ]; then
|
if [ -d ${PR_NUMBER} ]; then
|
||||||
git rm -r ${PR_NUMBER}
|
git rm -r ${PR_NUMBER}
|
||||||
fi
|
fi
|
||||||
#git diff exits with 1 if there is no diff
|
# `git diff --quiet` exits with 1 if there is a diff
|
||||||
if git diff --quiet; then
|
if ! git diff --quiet; then
|
||||||
git commit -a --amend -m"base commit" && git push -f -u origin master
|
git commit -a --amend -m"base commit" && git push -f -u origin master
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ jobs:
|
||||||
uses: actions/github-script@v3
|
uses: actions/github-script@v3
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
const address = "The testsuite is lauched. results will be found, after it is done, here : https://cgal.geometryfactory.com/~cgaltest/test_suite/TESTRESULTS/index.shtml "
|
const address = "Testsuite launched. Results will appear on the following page: https://cgal.geometryfactory.com/~cgaltest/test_suite/TESTRESULTS/index.shtml "
|
||||||
github.issues.createComment({
|
github.issues.createComment({
|
||||||
owner: "CGAL",
|
owner: "CGAL",
|
||||||
repo: "cgal",
|
repo: "cgal",
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,19 @@
|
||||||
\ingroup PkgAABBTreeConcepts
|
\ingroup PkgAABBTreeConcepts
|
||||||
\cgalConcept
|
\cgalConcept
|
||||||
|
|
||||||
The concept `AABBGeomTraits` defines the requirements for the first template parameter of the class `CGAL::AABB_traits<AABBGeomTraits, AABBPrimitive>`. It provides predicates and constructors to detect and compute intersections between query objects and the primitives stored in the AABB tree. In addition, it contains predicates and constructors to compute distances between a point query and the primitives stored in the AABB tree.
|
The concept `AABBGeomTraits` defines the requirements for the first template parameter of the class
|
||||||
|
`CGAL::AABB_traits<AABBGeomTraits, AABBPrimitive>`. It provides predicates and constructors to detect
|
||||||
|
and compute intersections between query objects and the primitives stored in the AABB tree.
|
||||||
|
In addition, it contains predicates and constructors to compute distances between a point query
|
||||||
|
and the primitives stored in the AABB tree.
|
||||||
|
|
||||||
\cgalRefines `SearchGeomTraits_3`
|
\cgalRefines `SearchGeomTraits_3`
|
||||||
|
|
||||||
\cgalHasModel Any 3D Kernel is a model of this traits concept.
|
\cgalHasModel All models of the concept `Kernel`
|
||||||
|
|
||||||
\sa `CGAL::AABB_traits<AABBGeomTraits,AABBPrimitive>`
|
\sa `CGAL::AABB_traits<AABBGeomTraits,AABBPrimitive>`
|
||||||
|
\sa `CGAL::AABB_tree<AABBTraits>`
|
||||||
|
\sa `AABBPrimitive`
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -19,118 +25,123 @@ public:
|
||||||
/// \name Types
|
/// \name Types
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/*!
|
|
||||||
A number type model of `Field`.
|
|
||||||
*/
|
|
||||||
typedef unspecified_type FT;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Sphere type, that should be consistent with the distance function chosen for the distance queries, namely the `Squared_distance_3` functor.
|
|
||||||
*/
|
|
||||||
typedef unspecified_type Sphere_3;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Point type.
|
|
||||||
*/
|
|
||||||
typedef unspecified_type Point_3;
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
A functor object to detect intersections between two geometric objects.
|
A functor object to detect intersections between two geometric objects.
|
||||||
Provides the operators:
|
Provides the following operators:
|
||||||
`bool operator()(const Type_1& type_1, const Type_2& type_2);`
|
|
||||||
where `Type_1` and `Type_2` are relevant types
|
`bool operator()(Query, Bbox_3)`,
|
||||||
among `Ray_3`, `Segment_3`, `Line_3`, `Triangle_3`, `Plane_3` and `Bbox_3`. Relevant herein means that a line primitive (ray, segment, line) is tested against a planar or solid primitive (plane, triangle, box), and a solid primitive is tested against another solid primitive (box against box). The operator returns `true` iff `type_1` and `type_2` have a non empty intersection.
|
|
||||||
|
`bool operator()(Query, Primitive::Datum)`,
|
||||||
|
|
||||||
|
`bool operator()(Sphere_3, Bbox_3)`.
|
||||||
|
|
||||||
|
The operator returns `true` iff there exists a non-empty intersection.
|
||||||
*/
|
*/
|
||||||
typedef unspecified_type Do_intersect_3;
|
typedef unspecified_type Do_intersect_3;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
A functor object to construct the intersection between two geometric objects.
|
A functor object to construct the intersection between two geometric objects.
|
||||||
|
|
||||||
Provides the operators:
|
Provides the operator:
|
||||||
`decltype(auto) operator()(const A& a, const B& b);`
|
|
||||||
where `A` and `B` are any relevant types among `Ray_3`, `Segment_3`, `Line_3`,
|
`return_type operator()(const Query& q, const Primitive::Datum& d)`,
|
||||||
`Triangle_3`, `Plane_3` and `Bbox_3`.
|
|
||||||
Relevant herein means that a line primitive (ray, segment, line) is tested
|
which computes the intersection between `q` and `d`. The type of the returned object
|
||||||
against a planar or solid primitive (plane, triangle, box).
|
must be a `boost::optional` of a `boost::variant` of the possible intersection types.
|
||||||
A model of `Kernel::Intersect_3` fulfills those requirements.
|
|
||||||
*/
|
*/
|
||||||
typedef unspecified_type Intersect_3;
|
typedef unspecified_type Intersect_3;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
A functor object to construct the sphere centered at one point and passing through another one. Provides the operator:
|
A functor object to construct the sphere centered at one point and passing through another one.
|
||||||
- `Sphere_3 operator()(const Point_3& p, const FT & sr)` which returns the sphere centered at `p` with `sr` as squared radius.
|
Provides the operator:
|
||||||
|
|
||||||
|
`Sphere_3 operator()(const Point_3& p, const FT & sr)`,
|
||||||
|
|
||||||
|
which returns the sphere centered at `p` with `sr` as squared radius.
|
||||||
*/
|
*/
|
||||||
typedef unspecified_type Construct_sphere_3;
|
typedef unspecified_type Construct_sphere_3;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
A functor object to compute the point on a geometric primitive which is closest from a query. Provides the operator:
|
A functor object to compute the point on a geometric primitive which is closest from a query.
|
||||||
`Point_3 operator()(const Type_2& type_2, const Point_3& p);` where `Type_2` can be any of the following types : `Segment_3`, `Ray_3`, or `Triangle_3`.
|
Provides the operator:
|
||||||
The operator returns the point on `type_2` which is closest to `p`.
|
|
||||||
|
`Point_3 operator()(const Primitive::Datum& d, const Point_3& p)`,
|
||||||
|
|
||||||
|
which returns the point on `d` that is closest to `p`.
|
||||||
*/
|
*/
|
||||||
typedef unspecified_type Construct_projected_point_3;
|
typedef unspecified_type Construct_projected_point_3;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
A functor object to compare the distance of two points wrt a third one.
|
A functor object to compare the distance of two points wrt a third one. Provides the operator:
|
||||||
Provides the operator:
|
|
||||||
`CGAL::Comparision_result operator()(const Point_3& p1, const Point_3& p2, const Point_3& p3)`. The operator compare the distance between `p1 and `p2`, and between `p2` and `p3`.
|
`CGAL::Comparision_result operator()(const Point_3& p1, const Point_3& p2, const Point_3& p3)`,
|
||||||
|
|
||||||
|
which compares the distance between `p1 and `p2`, and between `p2` and `p3`.
|
||||||
*/
|
*/
|
||||||
typedef unspecified_type Compare_distance_3;
|
typedef unspecified_type Compare_distance_3;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
A functor object to detect if a point lies inside a sphere or not.
|
A functor object to compute the squared radius of a sphere.
|
||||||
Provides the operator:
|
Provides the operator:
|
||||||
`bool operator()(const Sphere_3& s, const Point_3& p);` which returns `true` iff the closed volume bounded by `s` contains `p`.
|
|
||||||
*/
|
|
||||||
typedef unspecified_type Has_on_bounded_side_3;
|
|
||||||
|
|
||||||
/*!
|
`FT operator()(const Sphere_3& s),`
|
||||||
A functor object to compute the squared radius of a sphere. Provides the operator:
|
|
||||||
`FT operator()(const Sphere_3& s);` which returns the squared radius of `s`.
|
which returns the squared radius of `s`.
|
||||||
*/
|
*/
|
||||||
typedef unspecified_type Compute_squared_radius_3;
|
typedef unspecified_type Compute_squared_radius_3;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
A functor object to compute the squared distance between two points. Provides the operator:
|
A functor object to compute the squared distance between two points. Provides the operator:
|
||||||
`FT operator()(const Point_3& p, const Point_3& q);}` which returns the squared distance between `p` and `q`.
|
|
||||||
|
`FT operator()(const Point_3& p, const Point_3& q),`
|
||||||
|
|
||||||
|
which returns the squared distance between `p` and `q`.
|
||||||
*/
|
*/
|
||||||
typedef unspecified_type Compute_squared_distance_3;
|
typedef unspecified_type Compute_squared_distance_3;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
A functor object to compare the x-coordinates of two points. Provides the operator:
|
A functor object to compare the x-coordinates of two points. Provides the operator:
|
||||||
`bool operator()(const Point_3& p, const Point_3& q);}` which returns `true` if the x-coordinate of `p` is smaller
|
|
||||||
than the x-coordinate of `q`.
|
`bool operator()(const Point_3& p, const Point_3& q)`,
|
||||||
|
|
||||||
|
which returns `true` iff the x-coordinate of `p` is smaller than the x-coordinate of `q`.
|
||||||
*/
|
*/
|
||||||
typedef unspecified_type Less_x_3;
|
typedef unspecified_type Less_x_3;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
A functor object to compare the y-coordinates of two points. Provides the operator:
|
A functor object to compare the y-coordinates of two points. Provides the operator:
|
||||||
`bool operator()(const Point_3& p, const Point_3& q);}` which returns `true` if the y-coordinate of `p` is smaller
|
|
||||||
than the y-coordinate of `q`.
|
`bool operator()(const Point_3& p, const Point_3& q)`,
|
||||||
|
|
||||||
|
which returns `true` iff the y-coordinate of `p` is smaller than the y-coordinate of `q`.
|
||||||
*/
|
*/
|
||||||
typedef unspecified_type Less_y_3;
|
typedef unspecified_type Less_y_3;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
A functor object to compare the z-coordinates of two points. Provides the operator:
|
A functor object to compare the z-coordinates of two points. Provides the operator:
|
||||||
`bool operator()(const Point_3& p, const Point_3& q);}` which returns `true` if the z-coordinate of `p` is smaller
|
|
||||||
than the z-coordinate of `q`.
|
`bool operator()(const Point_3& p, const Point_3& q)`,
|
||||||
|
|
||||||
|
which returns `true` iff the z-coordinate of `p` is smaller than the z-coordinate of `q`.
|
||||||
*/
|
*/
|
||||||
typedef unspecified_type Less_z_3;
|
typedef unspecified_type Less_z_3;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
A functor object to compare two points. Provides the operator:
|
A functor object to compare two points. Provides the operator:
|
||||||
`bool operator()(const Point_3& p, const Point_3& q);}` which returns `true` if `p` is equal to `q`.
|
|
||||||
|
`bool operator()(const Point_3& p, const Point_3& q)`,
|
||||||
|
|
||||||
|
which returns `true` iff `p` is equal to `q`.
|
||||||
*/
|
*/
|
||||||
typedef unspecified_type Equal_3;
|
typedef unspecified_type Equal_3;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/// \name Operations
|
/// \name Operations
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
returns the intersection detection functor.
|
returns the intersection detection predicate.
|
||||||
*/
|
*/
|
||||||
Do_intersect_3 do_intersect_3_object();
|
Do_intersect_3 do_intersect_3_object();
|
||||||
|
|
||||||
|
|
@ -150,15 +161,10 @@ returns the closest point constructor.
|
||||||
Construct_projected_point_3 construct_projected_point_3_object();
|
Construct_projected_point_3 construct_projected_point_3_object();
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
returns the compare distance constructor.
|
returns the compare distance predicate.
|
||||||
*/
|
*/
|
||||||
Compare_distance_3 compare_distance_3_object();
|
Compare_distance_3 compare_distance_3_object();
|
||||||
|
|
||||||
/*!
|
|
||||||
returns the closest point constructor.
|
|
||||||
*/
|
|
||||||
Has_on_bounded_side_3 has_on_bounded_side_3_object();
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
returns the squared radius functor.
|
returns the squared radius functor.
|
||||||
*/
|
*/
|
||||||
|
|
@ -170,22 +176,22 @@ returns the squared distance functor.
|
||||||
Compute_squared_distance_3 compute_squared_distance_3_object();
|
Compute_squared_distance_3 compute_squared_distance_3_object();
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
returns the `Less_x_3` functor.
|
returns the `Less_x_3` predicate.
|
||||||
*/
|
*/
|
||||||
Less_x_3 less_x_3_object();
|
Less_x_3 less_x_3_object();
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
returns the `Less_y_3` functor.
|
returns the `Less_y_3` predicate.
|
||||||
*/
|
*/
|
||||||
Less_y_3 less_y_3_object();
|
Less_y_3 less_y_3_object();
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
returns the `Less_z_3` functor.
|
returns the `Less_z_3` predicate.
|
||||||
*/
|
*/
|
||||||
Less_z_3 less_z_3_object();
|
Less_z_3 less_z_3_object();
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
returns the equal functor.
|
returns the equal predicate.
|
||||||
*/
|
*/
|
||||||
Equal_3 equal_3_object();
|
Equal_3 equal_3_object();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,8 @@ concept `AABBGeomTraits`. In addition to the types required by
|
||||||
define the Intersection_distance functor.
|
define the Intersection_distance functor.
|
||||||
|
|
||||||
\cgalRefines `AABBGeomTraits`
|
\cgalRefines `AABBGeomTraits`
|
||||||
\cgalHasModel Any 3D Kernel is a model of this concept.
|
|
||||||
|
\cgalHasModel All models of the concept `Kernel`
|
||||||
|
|
||||||
\sa `CGAL::AABB_traits<AABBGeomTraits,AABBPrimitive>`
|
\sa `CGAL::AABB_traits<AABBGeomTraits,AABBPrimitive>`
|
||||||
\sa `CGAL::AABB_tree<AABBTraits>`
|
\sa `CGAL::AABB_tree<AABBTraits>`
|
||||||
|
|
@ -17,11 +18,6 @@ define the Intersection_distance functor.
|
||||||
*/
|
*/
|
||||||
class AABBRayIntersectionGeomTraits {
|
class AABBRayIntersectionGeomTraits {
|
||||||
public:
|
public:
|
||||||
/*!
|
|
||||||
Type of a 3D point.
|
|
||||||
*/
|
|
||||||
typedef unspecified_type Point_3;
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Type of a 3D ray.
|
Type of a 3D ray.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ distance of an intersection along a ray.
|
||||||
|
|
||||||
\cgalHasModel `CGAL::AABB_traits<AABBGeomTraits,AABBPrimitive>`
|
\cgalHasModel `CGAL::AABB_traits<AABBGeomTraits,AABBPrimitive>`
|
||||||
|
|
||||||
\sa `CGAL::AABB_traits<AABBGeomTraits,AABBPrimitive>`
|
|
||||||
\sa `CGAL::AABB_tree<AABBTraits>`
|
\sa `CGAL::AABB_tree<AABBTraits>`
|
||||||
\sa `AABBPrimitive`
|
\sa `AABBPrimitive`
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,10 @@
|
||||||
\cgalCRPSection{Concepts}
|
\cgalCRPSection{Concepts}
|
||||||
- `AABBPrimitive`
|
- `AABBPrimitive`
|
||||||
- `AABBPrimitiveWithSharedData`
|
- `AABBPrimitiveWithSharedData`
|
||||||
- `AABBTraits`
|
|
||||||
- `AABBGeomTraits`
|
- `AABBGeomTraits`
|
||||||
|
- `AABBTraits`
|
||||||
|
- `AABBRayIntersectionGeomTraits`
|
||||||
|
- `AABBRayIntersectionTraits`
|
||||||
|
|
||||||
\cgalCRPSection{Classes}
|
\cgalCRPSection{Classes}
|
||||||
- `CGAL::AABB_traits<GeomTraits,Primitive>`
|
- `CGAL::AABB_traits<GeomTraits,Primitive>`
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ struct Skip
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
const char* filename = (argc > 1) ? argv[1] : "data/tetrahedron.off";
|
const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/tetrahedron.off");
|
||||||
|
|
||||||
Mesh mesh;
|
Mesh mesh;
|
||||||
if(!CGAL::IO::read_polygon_mesh(filename, mesh))
|
if(!CGAL::IO::read_polygon_mesh(filename, mesh))
|
||||||
|
|
|
||||||
|
|
@ -160,7 +160,7 @@ class AABB_tree;
|
||||||
/// \tparam BboxMap must be a model of `ReadablePropertyMap` that has as key type a primitive id,
|
/// \tparam BboxMap must be a model of `ReadablePropertyMap` that has as key type a primitive id,
|
||||||
/// and as value type a `Bounding_box`.
|
/// and as value type a `Bounding_box`.
|
||||||
/// If the type is `Default` the `Datum` must have the
|
/// If the type is `Default` the `Datum` must have the
|
||||||
/// member function `bbox()` that returns the bounding box of the primitive.
|
/// member function `bbox()` that returns the bounding box of the primitive.
|
||||||
///
|
///
|
||||||
/// If the argument `GeomTraits` is a model of the concept \ref
|
/// If the argument `GeomTraits` is a model of the concept \ref
|
||||||
/// AABBRayIntersectionGeomTraits, this class is also a model of \ref
|
/// AABBRayIntersectionGeomTraits, this class is also a model of \ref
|
||||||
|
|
@ -366,7 +366,7 @@ public:
|
||||||
template<typename Query>
|
template<typename Query>
|
||||||
boost::optional< typename Intersection_and_primitive_id<Query>::Type >
|
boost::optional< typename Intersection_and_primitive_id<Query>::Type >
|
||||||
operator()(const Query& query, const typename AT::Primitive& primitive) const {
|
operator()(const Query& query, const typename AT::Primitive& primitive) const {
|
||||||
auto inter_res = GeomTraits().intersect_3_object()(internal::Primitive_helper<AT>::get_datum(primitive,m_traits),query);
|
auto inter_res = GeomTraits().intersect_3_object()(query, internal::Primitive_helper<AT>::get_datum(primitive,m_traits));
|
||||||
if (!inter_res)
|
if (!inter_res)
|
||||||
return boost::none;
|
return boost::none;
|
||||||
return boost::make_optional( std::make_pair(*inter_res, primitive.id()) );
|
return boost::make_optional( std::make_pair(*inter_res, primitive.id()) );
|
||||||
|
|
@ -391,9 +391,9 @@ public:
|
||||||
GeomTraits geom_traits;
|
GeomTraits geom_traits;
|
||||||
Point closest_point = geom_traits.construct_projected_point_3_object()(
|
Point closest_point = geom_traits.construct_projected_point_3_object()(
|
||||||
internal::Primitive_helper<AT>::get_datum(pr,m_traits), p);
|
internal::Primitive_helper<AT>::get_datum(pr,m_traits), p);
|
||||||
return
|
|
||||||
geom_traits.compare_distance_3_object()(p, closest_point, bound)==LARGER ?
|
return (geom_traits.compare_distance_3_object()(p, closest_point, bound) == LARGER) ?
|
||||||
bound : closest_point;
|
bound : closest_point;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -406,15 +406,6 @@ public:
|
||||||
typedef typename AT::FT FT;
|
typedef typename AT::FT FT;
|
||||||
typedef typename AT::Primitive Primitive;
|
typedef typename AT::Primitive Primitive;
|
||||||
public:
|
public:
|
||||||
template <class Solid>
|
|
||||||
CGAL::Comparison_result operator()(const Point& p, const Solid& pr, const Point& bound) const
|
|
||||||
{
|
|
||||||
return GeomTraits().do_intersect_3_object()
|
|
||||||
(GeomTraits().construct_sphere_3_object()
|
|
||||||
(p, GeomTraits().compute_squared_distance_3_object()(p, bound)), pr)?
|
|
||||||
CGAL::SMALLER : CGAL::LARGER;
|
|
||||||
}
|
|
||||||
|
|
||||||
CGAL::Comparison_result operator()(const Point& p, const Bounding_box& bb, const Point& bound, Tag_true) const
|
CGAL::Comparison_result operator()(const Point& p, const Bounding_box& bb, const Point& bound, Tag_true) const
|
||||||
{
|
{
|
||||||
return GeomTraits().do_intersect_3_object()
|
return GeomTraits().do_intersect_3_object()
|
||||||
|
|
@ -436,6 +427,16 @@ public:
|
||||||
return (*this)(p, bb, bound, Boolean_tag<internal::Has_static_filters<GeomTraits>::value>());
|
return (*this)(p, bb, bound, Boolean_tag<internal::Has_static_filters<GeomTraits>::value>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The following functions seem unused...?
|
||||||
|
template <class Solid>
|
||||||
|
CGAL::Comparison_result operator()(const Point& p, const Solid& pr, const Point& bound) const
|
||||||
|
{
|
||||||
|
return GeomTraits().do_intersect_3_object()
|
||||||
|
(GeomTraits().construct_sphere_3_object()
|
||||||
|
(p, GeomTraits().compute_squared_distance_3_object()(p, bound)), pr)?
|
||||||
|
CGAL::SMALLER : CGAL::LARGER;
|
||||||
|
}
|
||||||
|
|
||||||
template <class Solid>
|
template <class Solid>
|
||||||
CGAL::Comparison_result operator()(const Point& p, const Solid& pr, const FT& sq_distance) const
|
CGAL::Comparison_result operator()(const Point& p, const Solid& pr, const FT& sq_distance) const
|
||||||
{
|
{
|
||||||
|
|
@ -445,7 +446,6 @@ public:
|
||||||
CGAL::SMALLER :
|
CGAL::SMALLER :
|
||||||
CGAL::LARGER;
|
CGAL::LARGER;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Closest_point closest_point_object() const {return Closest_point(*this);}
|
Closest_point closest_point_object() const {return Closest_point(*this);}
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ int test()
|
||||||
// load polyhedron
|
// load polyhedron
|
||||||
typedef CGAL::Polyhedron_3<K> Polyhedron;
|
typedef CGAL::Polyhedron_3<K> Polyhedron;
|
||||||
Polyhedron polyhedron;
|
Polyhedron polyhedron;
|
||||||
std::ifstream ifs("./data/tetrahedron.off");
|
std::ifstream ifs(CGAL::data_file_path("meshes/tetrahedron.off"));
|
||||||
ifs >> polyhedron;
|
ifs >> polyhedron;
|
||||||
|
|
||||||
// construct tree from facets
|
// construct tree from facets
|
||||||
|
|
@ -129,4 +129,3 @@ int main()
|
||||||
/* Local Variables: */
|
/* Local Variables: */
|
||||||
/* tab-width: 2 */
|
/* tab-width: 2 */
|
||||||
/* End: */
|
/* End: */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,14 +12,12 @@ struct AABBGeomTraits {
|
||||||
typedef nope Intersect_3;
|
typedef nope Intersect_3;
|
||||||
typedef nope Construct_sphere_3;
|
typedef nope Construct_sphere_3;
|
||||||
typedef nope Compute_closest_point_3;
|
typedef nope Compute_closest_point_3;
|
||||||
typedef nope Has_on_bounded_side_3;
|
|
||||||
typedef nope Compute_squared_radius_3;
|
typedef nope Compute_squared_radius_3;
|
||||||
typedef nope Compute_squared_distance_3;
|
typedef nope Compute_squared_distance_3;
|
||||||
Do_intersect_3 do_intersect_3_object();
|
Do_intersect_3 do_intersect_3_object();
|
||||||
Intersect_3 intersect_3_object();
|
Intersect_3 intersect_3_object();
|
||||||
Construct_sphere_3 construct_sphere_3_object();
|
Construct_sphere_3 construct_sphere_3_object();
|
||||||
Compute_closest_point_3 compute_closest_point_3_object();
|
Compute_closest_point_3 compute_closest_point_3_object();
|
||||||
Has_on_bounded_side_3 has_on_bounded_side_3_object();
|
|
||||||
Compute_squared_radius_3 compute_squared_radius_3_object();
|
Compute_squared_radius_3 compute_squared_radius_3_object();
|
||||||
Compute_squared_distance_3 compute_squared_distance_3_object();
|
Compute_squared_distance_3 compute_squared_distance_3_object();
|
||||||
}; /* end AABBGeomTraits */
|
}; /* end AABBGeomTraits */
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ Kernel_d
|
||||||
Modifier
|
Modifier
|
||||||
Modular_arithmetic
|
Modular_arithmetic
|
||||||
Number_types
|
Number_types
|
||||||
Polygon
|
|
||||||
Polyhedron
|
Polyhedron
|
||||||
Profiling_tools
|
Profiling_tools
|
||||||
Property_map
|
Property_map
|
||||||
|
|
|
||||||
|
|
@ -148,33 +148,26 @@ template<class A , class B, int > struct Coercion_traits_for_level;
|
||||||
|
|
||||||
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(short,int)
|
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(short,int)
|
||||||
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(short,long)
|
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(short,long)
|
||||||
#ifdef CGAL_USE_LONG_LONG
|
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(short,long long)
|
||||||
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(short,long long)
|
|
||||||
#endif
|
|
||||||
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(short,float)
|
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(short,float)
|
||||||
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(short,double)
|
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(short,double)
|
||||||
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(short,long double)
|
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(short,long double)
|
||||||
|
|
||||||
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(int,long)
|
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(int,long)
|
||||||
#ifdef CGAL_USE_LONG_LONG
|
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(int,long long)
|
||||||
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(int,long long)
|
|
||||||
#endif
|
|
||||||
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(int,float)
|
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(int,float)
|
||||||
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(int,double)
|
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(int,double)
|
||||||
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(int,long double)
|
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(int,long double)
|
||||||
|
|
||||||
#ifdef CGAL_USE_LONG_LONG
|
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(long,long long)
|
||||||
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(long,long long)
|
|
||||||
#endif
|
|
||||||
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(long,float)
|
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(long,float)
|
||||||
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(long,double)
|
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(long,double)
|
||||||
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(long,long double)
|
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(long,long double)
|
||||||
|
|
||||||
#ifdef CGAL_USE_LONG_LONG
|
|
||||||
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(long long,float)
|
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(long long,float)
|
||||||
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(long long,double)
|
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(long long,double)
|
||||||
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(long long,long double)
|
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(long long,long double)
|
||||||
#endif
|
|
||||||
|
|
||||||
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(float,double)
|
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(float,double)
|
||||||
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(float,long double)
|
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(float,long double)
|
||||||
|
|
@ -198,9 +191,7 @@ struct Coercion_traits<A,A>{
|
||||||
CGAL_DEFINE_COERCION_TRAITS_FOR_SELF(short)
|
CGAL_DEFINE_COERCION_TRAITS_FOR_SELF(short)
|
||||||
CGAL_DEFINE_COERCION_TRAITS_FOR_SELF(int)
|
CGAL_DEFINE_COERCION_TRAITS_FOR_SELF(int)
|
||||||
CGAL_DEFINE_COERCION_TRAITS_FOR_SELF(long)
|
CGAL_DEFINE_COERCION_TRAITS_FOR_SELF(long)
|
||||||
#ifdef CGAL_USE_LONG_LONG
|
CGAL_DEFINE_COERCION_TRAITS_FOR_SELF(long long)
|
||||||
CGAL_DEFINE_COERCION_TRAITS_FOR_SELF(long long)
|
|
||||||
#endif
|
|
||||||
CGAL_DEFINE_COERCION_TRAITS_FOR_SELF(float)
|
CGAL_DEFINE_COERCION_TRAITS_FOR_SELF(float)
|
||||||
CGAL_DEFINE_COERCION_TRAITS_FOR_SELF(double)
|
CGAL_DEFINE_COERCION_TRAITS_FOR_SELF(double)
|
||||||
CGAL_DEFINE_COERCION_TRAITS_FOR_SELF(long double)
|
CGAL_DEFINE_COERCION_TRAITS_FOR_SELF(long double)
|
||||||
|
|
|
||||||
|
|
@ -75,11 +75,9 @@ template <> struct Needs_parens_as_product<long>{
|
||||||
bool operator()(const long& x){return x < long(0);}
|
bool operator()(const long& x){return x < long(0);}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CGAL_USE_LONG_LONG
|
|
||||||
template <> struct Needs_parens_as_product<long long>{
|
template <> struct Needs_parens_as_product<long long>{
|
||||||
bool operator()(const long long& x){return x < (long long)(0);}
|
bool operator()(const long long& x){return x < (long long)(0);}
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
template <> struct Needs_parens_as_product<float>{
|
template <> struct Needs_parens_as_product<float>{
|
||||||
bool operator()(const float& x){return x < float(0);}
|
bool operator()(const float& x){return x < float(0);}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ Interval_support
|
||||||
Kernel_23
|
Kernel_23
|
||||||
Modular_arithmetic
|
Modular_arithmetic
|
||||||
Number_types
|
Number_types
|
||||||
Polygon
|
|
||||||
Profiling_tools
|
Profiling_tools
|
||||||
Property_map
|
Property_map
|
||||||
STL_Extension
|
STL_Extension
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ Interval_support
|
||||||
Kernel_23
|
Kernel_23
|
||||||
Modular_arithmetic
|
Modular_arithmetic
|
||||||
Number_types
|
Number_types
|
||||||
Polygon
|
|
||||||
Profiling_tools
|
Profiling_tools
|
||||||
Property_map
|
Property_map
|
||||||
STL_Extension
|
STL_Extension
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
#include <CGAL/basic.h>
|
#include <CGAL/basic.h>
|
||||||
#include <CGAL/Arr_enums.h>
|
#include <CGAL/Arr_enums.h>
|
||||||
|
|
@ -885,11 +886,11 @@ public:
|
||||||
|
|
||||||
/*! Clean all operation counters */
|
/*! Clean all operation counters */
|
||||||
void clear_counters()
|
void clear_counters()
|
||||||
{ memset(m_counters, 0, sizeof(m_counters)); }
|
{ m_counters = {}; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*! The operation counters */
|
/*! The operation counters */
|
||||||
mutable size_t m_counters[NUMBER_OF_OPERATIONS];
|
mutable std::array<size_t, NUMBER_OF_OPERATIONS> m_counters;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Out_stream, class Base_traits>
|
template <typename Out_stream, class Base_traits>
|
||||||
|
|
|
||||||
|
|
@ -263,7 +263,7 @@ public:
|
||||||
Comparison_result res =
|
Comparison_result res =
|
||||||
ker.compare_x_2_object()(this->_source, this->_target);
|
ker.compare_x_2_object()(this->_source, this->_target);
|
||||||
|
|
||||||
this->_info = (Conic_arc_2::IS_VALID | DEGREE_1);
|
this->_info = (static_cast<int>(Conic_arc_2::IS_VALID) | static_cast<int>(DEGREE_1));
|
||||||
if (res == EQUAL) {
|
if (res == EQUAL) {
|
||||||
// Mark that the segment is vertical.
|
// Mark that the segment is vertical.
|
||||||
this->_info = (this->_info | IS_VERTICAL_SEGMENT);
|
this->_info = (this->_info | IS_VERTICAL_SEGMENT);
|
||||||
|
|
|
||||||
|
|
@ -169,19 +169,15 @@ overlay(const Arrangement_on_surface_2<GeometryTraitsA_2, TopologyTraitsA>& arr1
|
||||||
typedef typename Arr_res::Allocator Allocator;
|
typedef typename Arr_res::Allocator Allocator;
|
||||||
|
|
||||||
// some type assertions (not all, but better than nothing).
|
// some type assertions (not all, but better than nothing).
|
||||||
#if !defined(CGAL_NO_ASSERTIONS)
|
|
||||||
typedef typename Agt2::Point_2 A_point;
|
typedef typename Agt2::Point_2 A_point;
|
||||||
typedef typename Bgt2::Point_2 B_point;
|
typedef typename Bgt2::Point_2 B_point;
|
||||||
typedef typename Rgt2::Point_2 Res_point;
|
typedef typename Rgt2::Point_2 Res_point;
|
||||||
#endif
|
|
||||||
CGAL_static_assertion((boost::is_convertible<A_point, Res_point>::value));
|
CGAL_static_assertion((boost::is_convertible<A_point, Res_point>::value));
|
||||||
CGAL_static_assertion((boost::is_convertible<B_point, Res_point>::value));
|
CGAL_static_assertion((boost::is_convertible<B_point, Res_point>::value));
|
||||||
|
|
||||||
#if !defined(CGAL_NO_ASSERTIONS)
|
|
||||||
typedef typename Agt2::X_monotone_curve_2 A_xcv;
|
typedef typename Agt2::X_monotone_curve_2 A_xcv;
|
||||||
typedef typename Bgt2::X_monotone_curve_2 B_xcv;
|
typedef typename Bgt2::X_monotone_curve_2 B_xcv;
|
||||||
typedef typename Rgt2::X_monotone_curve_2 Res_xcv;
|
typedef typename Rgt2::X_monotone_curve_2 Res_xcv;
|
||||||
#endif
|
|
||||||
CGAL_static_assertion((boost::is_convertible<A_xcv, Res_xcv>::value));
|
CGAL_static_assertion((boost::is_convertible<A_xcv, Res_xcv>::value));
|
||||||
CGAL_static_assertion((boost::is_convertible<B_xcv, Res_xcv>::value));
|
CGAL_static_assertion((boost::is_convertible<B_xcv, Res_xcv>::value));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
@ -750,14 +751,17 @@ public:
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Prepare a string desribing the color.
|
// Prepare a string desribing the color.
|
||||||
char color_desc [10];
|
|
||||||
|
|
||||||
sprintf ("#%02x%02x%02x", r, g, b);
|
std::stringstream out;
|
||||||
|
out << "0x" << std::hex
|
||||||
|
<< std::setfill('0') << std::setw(2) << r
|
||||||
|
<< std::setfill('0') << std::setw(2) << g
|
||||||
|
<< std::setfill('0') << std::setw(2) << b;
|
||||||
|
|
||||||
// Write the color to the FIG file.
|
// Write the color to the FIG file.
|
||||||
_ofile << "0 " // Desginates a color pseudo-object.
|
_ofile << "0 " // Desginates a color pseudo-object.
|
||||||
<< static_cast<int>(color) << ' '
|
<< static_cast<int>(color) << ' '
|
||||||
<< color_desc << std::endl;
|
<< out.str() << std::endl;
|
||||||
|
|
||||||
// Mark that the color is now defined.
|
// Mark that the color is now defined.
|
||||||
colors[static_cast<int>(color)] = true;
|
colors[static_cast<int>(color)] = true;
|
||||||
|
|
@ -1700,7 +1704,6 @@ protected:
|
||||||
_ofile << ' ' << ix << ' ' << iy << ' ';
|
_ofile << ' ' << ix << ' ' << iy << ' ';
|
||||||
|
|
||||||
// Write the text.
|
// Write the text.
|
||||||
char oct[10];
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < len_text; i++)
|
for (i = 0; i < len_text; i++)
|
||||||
|
|
@ -1712,9 +1715,11 @@ protected:
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Convert the current character to an octal string and write it.
|
// Convert the current character to an octal string and write
|
||||||
sprintf (oct, "\\%03o", text[i]);
|
// it.
|
||||||
_ofile << oct;
|
std::stringstream out;
|
||||||
|
out << "\\" << std::setfill('0') << std::setw(3) << std::oct << text[i];
|
||||||
|
_ofile << out.str();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ bool read_PLY_BGL(std::istream& is,
|
||||||
|
|
||||||
The data is expected to represent a 2-manifold (possibly with borders).
|
The data is expected to represent a 2-manifold (possibly with borders).
|
||||||
|
|
||||||
\attention When reading a binary file, the flag `std::ios::binary` flag must be set during the creation of the `ifstream`.
|
\attention To read a binary file, the flag `std::ios::binary` must be set during the creation of the `ifstream`.
|
||||||
|
|
||||||
\tparam Graph a model of `MutableFaceGraph`
|
\tparam Graph a model of `MutableFaceGraph`
|
||||||
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
||||||
|
|
@ -266,7 +266,9 @@ bool read_PLY(const std::string& fname, Graph& g,
|
||||||
|
|
||||||
\brief writes the graph in an output stream, using the \ref IOStreamPLY.
|
\brief writes the graph in an output stream, using the \ref IOStreamPLY.
|
||||||
|
|
||||||
\attention When writing a binary file, the flag `std::ios::binary` flag must be set during the creation of the `ofstream`.
|
\attention To write to a binary file, the flag `std::ios::binary` must be set during the creation
|
||||||
|
of the `ofstream`, and the \link PkgStreamSupportEnumRef `IO::Mode` \endlink
|
||||||
|
of the stream must be set to `BINARY`.
|
||||||
|
|
||||||
\tparam Graph a model of `FaceListGraph`
|
\tparam Graph a model of `FaceListGraph`
|
||||||
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ public:
|
||||||
|
|
||||||
\attention The graph `g` is not cleared, and the data from the stream are appended.
|
\attention The graph `g` is not cleared, and the data from the stream are appended.
|
||||||
|
|
||||||
\attention When reading a binary file, the flag `std::ios::binary` flag must be set during the creation of the `ifstream`.
|
\attention To read a binary file, the flag `std::ios::binary` must be set during the creation of the `ifstream`.
|
||||||
|
|
||||||
\tparam Graph a model of `MutableFaceGraph`
|
\tparam Graph a model of `MutableFaceGraph`
|
||||||
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
||||||
|
|
@ -208,7 +208,9 @@ bool read_STL(const std::string& fname, Graph& g) { return read_STL(fname, g, pa
|
||||||
|
|
||||||
\brief writes the graph `g` in the output stream `os`, using the \ref IOStreamSTL.
|
\brief writes the graph `g` in the output stream `os`, using the \ref IOStreamSTL.
|
||||||
|
|
||||||
\attention When writing a binary file, the flag `std::ios::binary` flag must be set during the creation of the `ofstream`.
|
\attention To write to a binary file, the flag `std::ios::binary` must be set during the creation
|
||||||
|
of the `ofstream`, and the \link PkgStreamSupportEnumRef `IO::Mode` \endlink of the stream
|
||||||
|
must be set to `BINARY`.
|
||||||
|
|
||||||
\tparam Graph a model of `FaceListGraph` and `HalfedgeListGraph`
|
\tparam Graph a model of `FaceListGraph` and `HalfedgeListGraph`
|
||||||
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#include <boost/type_traits/is_same.hpp>
|
#include <boost/type_traits/is_same.hpp>
|
||||||
#include <boost/mpl/if.hpp>
|
#include <boost/mpl/if.hpp>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
#define CGAL_BGL_NP_TEMPLATE_PARAMETERS T, typename Tag, typename Base
|
#define CGAL_BGL_NP_TEMPLATE_PARAMETERS T, typename Tag, typename Base
|
||||||
#define CGAL_BGL_NP_CLASS CGAL::Named_function_parameters<T,Tag,Base>
|
#define CGAL_BGL_NP_CLASS CGAL::Named_function_parameters<T,Tag,Base>
|
||||||
|
|
@ -38,8 +39,9 @@ enum all_default_t { all_default };
|
||||||
template <typename T, typename Tag, typename Base>
|
template <typename T, typename Tag, typename Base>
|
||||||
struct Named_params_impl : Base
|
struct Named_params_impl : Base
|
||||||
{
|
{
|
||||||
T v; // copy of the parameter
|
typename std::conditional<std::is_copy_constructible<T>::value,
|
||||||
Named_params_impl(T v, const Base& b)
|
T, std::reference_wrapper<const T> >::type v; // copy of the parameter if copyable
|
||||||
|
Named_params_impl(const T& v, const Base& b)
|
||||||
: Base(b)
|
: Base(b)
|
||||||
, v(v)
|
, v(v)
|
||||||
{}
|
{}
|
||||||
|
|
@ -49,8 +51,9 @@ struct Named_params_impl : Base
|
||||||
template <typename T, typename Tag>
|
template <typename T, typename Tag>
|
||||||
struct Named_params_impl<T, Tag, No_property>
|
struct Named_params_impl<T, Tag, No_property>
|
||||||
{
|
{
|
||||||
T v; // copy of the parameter
|
typename std::conditional<std::is_copy_constructible<T>::value,
|
||||||
Named_params_impl(T v)
|
T, std::reference_wrapper<const T> >::type v; // copy of the parameter if copyable
|
||||||
|
Named_params_impl(const T& v)
|
||||||
: v(v)
|
: v(v)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
@ -63,18 +66,39 @@ template< typename T, typename Tag, typename Query_tag>
|
||||||
struct Get_param< Named_params_impl<T, Tag, No_property>, Query_tag >
|
struct Get_param< Named_params_impl<T, Tag, No_property>, Query_tag >
|
||||||
{
|
{
|
||||||
typedef Param_not_found type;
|
typedef Param_not_found type;
|
||||||
|
typedef Param_not_found reference;
|
||||||
};
|
};
|
||||||
|
|
||||||
template< typename T, typename Tag, typename Base>
|
template< typename T, typename Tag, typename Base>
|
||||||
struct Get_param< Named_params_impl<T, Tag, Base>, Tag >
|
struct Get_param< Named_params_impl<T, Tag, Base>, Tag >
|
||||||
{
|
{
|
||||||
typedef T type;
|
typedef typename std::conditional<std::is_copy_constructible<T>::value,
|
||||||
|
T, std::reference_wrapper<const T> >::type type;
|
||||||
|
typedef typename std::conditional<std::is_copy_constructible<T>::value,
|
||||||
|
T, const T&>::type reference;
|
||||||
};
|
};
|
||||||
|
|
||||||
template< typename T, typename Tag>
|
template< typename T, typename Tag>
|
||||||
struct Get_param< Named_params_impl<T, Tag, No_property>, Tag >
|
struct Get_param< Named_params_impl<T, Tag, No_property>, Tag >
|
||||||
{
|
{
|
||||||
typedef T type;
|
typedef typename std::conditional<std::is_copy_constructible<T>::value,
|
||||||
|
T, std::reference_wrapper<const T> >::type type;
|
||||||
|
typedef typename std::conditional<std::is_copy_constructible<T>::value,
|
||||||
|
T, const T&>::type reference;
|
||||||
|
};
|
||||||
|
|
||||||
|
template< typename T, typename Tag, typename Base>
|
||||||
|
struct Get_param< Named_params_impl<std::reference_wrapper<T>, Tag, Base>, Tag >
|
||||||
|
{
|
||||||
|
typedef std::reference_wrapper<T> type;
|
||||||
|
typedef T& reference;
|
||||||
|
};
|
||||||
|
|
||||||
|
template< typename T, typename Tag>
|
||||||
|
struct Get_param< Named_params_impl<std::reference_wrapper<T>, Tag, No_property>, Tag >
|
||||||
|
{
|
||||||
|
typedef std::reference_wrapper<T> type;
|
||||||
|
typedef T& reference;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -82,6 +106,7 @@ template< typename T, typename Tag, typename Base, typename Query_tag>
|
||||||
struct Get_param< Named_params_impl<T,Tag,Base>, Query_tag>
|
struct Get_param< Named_params_impl<T,Tag,Base>, Query_tag>
|
||||||
{
|
{
|
||||||
typedef typename Get_param<typename Base::base, Query_tag>::type type;
|
typedef typename Get_param<typename Base::base, Query_tag>::type type;
|
||||||
|
typedef typename Get_param<typename Base::base, Query_tag>::reference reference;
|
||||||
};
|
};
|
||||||
|
|
||||||
// helper to choose the default
|
// helper to choose the default
|
||||||
|
|
@ -89,16 +114,24 @@ template <typename Query_tag, typename NP, typename D>
|
||||||
struct Lookup_named_param_def
|
struct Lookup_named_param_def
|
||||||
{
|
{
|
||||||
typedef typename internal_np::Get_param<typename NP::base, Query_tag>::type NP_type;
|
typedef typename internal_np::Get_param<typename NP::base, Query_tag>::type NP_type;
|
||||||
|
typedef typename internal_np::Get_param<typename NP::base, Query_tag>::reference NP_reference;
|
||||||
|
|
||||||
typedef typename boost::mpl::if_<
|
typedef typename boost::mpl::if_<
|
||||||
boost::is_same<NP_type, internal_np::Param_not_found>,
|
boost::is_same<NP_type, internal_np::Param_not_found>,
|
||||||
D, NP_type>::type
|
D, NP_type>::type
|
||||||
type;
|
type;
|
||||||
|
|
||||||
|
typedef typename boost::mpl::if_<
|
||||||
|
boost::is_same<NP_reference, internal_np::Param_not_found>,
|
||||||
|
D&, NP_reference>::type
|
||||||
|
reference;
|
||||||
};
|
};
|
||||||
|
|
||||||
// helper function to extract the value from a named parameter pack given a query tag
|
// helper function to extract the value from a named parameter pack given a query tag
|
||||||
template <typename T, typename Tag, typename Base>
|
template <typename T, typename Tag, typename Base>
|
||||||
T get_parameter_impl(const Named_params_impl<T, Tag, Base>& np, Tag)
|
typename std::conditional<std::is_copy_constructible<T>::value,
|
||||||
|
T, std::reference_wrapper<const T> >::type
|
||||||
|
get_parameter_impl(const Named_params_impl<T, Tag, Base>& np, Tag)
|
||||||
{
|
{
|
||||||
return np.v;
|
return np.v;
|
||||||
}
|
}
|
||||||
|
|
@ -110,7 +143,9 @@ Param_not_found get_parameter_impl(const Named_params_impl<T, Tag, No_property>&
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T, typename Tag>
|
template< typename T, typename Tag>
|
||||||
T get_parameter_impl(const Named_params_impl<T, Tag, No_property>& np, Tag)
|
typename std::conditional<std::is_copy_constructible<T>::value,
|
||||||
|
T, std::reference_wrapper<const T> >::type
|
||||||
|
get_parameter_impl(const Named_params_impl<T, Tag, No_property>& np, Tag)
|
||||||
{
|
{
|
||||||
return np.v;
|
return np.v;
|
||||||
};
|
};
|
||||||
|
|
@ -123,6 +158,67 @@ get_parameter_impl(const Named_params_impl<T, Tag, Base>& np, Query_tag tag)
|
||||||
return get_parameter_impl(static_cast<const typename Base::base&>(np), tag);
|
return get_parameter_impl(static_cast<const typename Base::base&>(np), tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// helper for getting references
|
||||||
|
template <class T>
|
||||||
|
const T& get_reference(const T& t)
|
||||||
|
{
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
T& get_reference(const std::reference_wrapper<T>& r)
|
||||||
|
{
|
||||||
|
return r.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
// helper function to extract the reference from a named parameter pack given a query tag
|
||||||
|
template <typename T, typename Tag, typename Base>
|
||||||
|
typename std::conditional<std::is_copy_constructible<T>::value,
|
||||||
|
T, const T& >::type
|
||||||
|
get_parameter_reference_impl(const Named_params_impl<T, Tag, Base>& np, Tag)
|
||||||
|
{
|
||||||
|
return get_reference(np.v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template< typename T, typename Tag, typename Query_tag>
|
||||||
|
Param_not_found
|
||||||
|
get_parameter_reference_impl(const Named_params_impl<T, Tag, No_property>&, Query_tag)
|
||||||
|
{
|
||||||
|
return Param_not_found();
|
||||||
|
}
|
||||||
|
|
||||||
|
template< typename T, typename Tag>
|
||||||
|
typename std::conditional<std::is_copy_constructible<T>::value,
|
||||||
|
T, const T& >::type
|
||||||
|
get_parameter_reference_impl(const Named_params_impl<T, Tag, No_property>& np, Tag)
|
||||||
|
{
|
||||||
|
return get_reference(np.v);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename Tag, typename Base>
|
||||||
|
T&
|
||||||
|
get_parameter_reference_impl(const Named_params_impl<std::reference_wrapper<T>, Tag, Base>& np, Tag)
|
||||||
|
{
|
||||||
|
return np.v.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
template< typename T, typename Tag>
|
||||||
|
T&
|
||||||
|
get_parameter_reference_impl(const Named_params_impl<std::reference_wrapper<T>, Tag, No_property>& np, Tag)
|
||||||
|
{
|
||||||
|
return np.v.get();
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename Tag, typename Base, typename Query_tag>
|
||||||
|
typename Get_param<Named_params_impl<T, Tag, Base>, Query_tag>::reference
|
||||||
|
get_parameter_reference_impl(const Named_params_impl<T, Tag, Base>& np, Query_tag tag)
|
||||||
|
{
|
||||||
|
CGAL_static_assertion( (!boost::is_same<Query_tag, Tag>::value) );
|
||||||
|
return get_parameter_reference_impl(static_cast<const typename Base::base&>(np), tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // end of internal_np namespace
|
} // end of internal_np namespace
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -133,8 +229,9 @@ struct Named_function_parameters
|
||||||
typedef internal_np::Named_params_impl<T, Tag, Base> base;
|
typedef internal_np::Named_params_impl<T, Tag, Base> base;
|
||||||
typedef Named_function_parameters<T, Tag, Base> self;
|
typedef Named_function_parameters<T, Tag, Base> self;
|
||||||
|
|
||||||
Named_function_parameters(T v = T()) : base(v) {}
|
Named_function_parameters() : base(T()) {}
|
||||||
Named_function_parameters(T v, const Base& b) : base(v, b) {}
|
Named_function_parameters(const T& v) : base(v) {}
|
||||||
|
Named_function_parameters(const T& v, const Base& b) : base(v, b) {}
|
||||||
|
|
||||||
Named_function_parameters<bool, internal_np::all_default_t, self>
|
Named_function_parameters<bool, internal_np::all_default_t, self>
|
||||||
all_default() const
|
all_default() const
|
||||||
|
|
@ -178,7 +275,7 @@ inline no_parameters(Named_function_parameters<T,Tag,Base>)
|
||||||
#define CGAL_add_named_parameter(X, Y, Z) \
|
#define CGAL_add_named_parameter(X, Y, Z) \
|
||||||
template <typename K> \
|
template <typename K> \
|
||||||
Named_function_parameters<K, internal_np::X> \
|
Named_function_parameters<K, internal_np::X> \
|
||||||
Z(K const& p) \
|
Z(const K& p) \
|
||||||
{ \
|
{ \
|
||||||
typedef Named_function_parameters<K, internal_np::X> Params;\
|
typedef Named_function_parameters<K, internal_np::X> Params;\
|
||||||
return Params(p); \
|
return Params(p); \
|
||||||
|
|
@ -194,13 +291,40 @@ get_parameter(const Named_function_parameters<T, Tag, Base>& np, Query_tag tag)
|
||||||
return internal_np::get_parameter_impl(static_cast<const internal_np::Named_params_impl<T, Tag, Base>&>(np), tag);
|
return internal_np::get_parameter_impl(static_cast<const internal_np::Named_params_impl<T, Tag, Base>&>(np), tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, typename Tag, typename Base, typename Query_tag>
|
||||||
|
typename internal_np::Get_param<internal_np::Named_params_impl<T, Tag, Base>, Query_tag>::reference
|
||||||
|
get_parameter_reference(const Named_function_parameters<T, Tag, Base>& np, Query_tag tag)
|
||||||
|
{
|
||||||
|
return internal_np::get_parameter_reference_impl(
|
||||||
|
static_cast<const internal_np::Named_params_impl<T, Tag, Base>&>(np),
|
||||||
|
tag);
|
||||||
|
}
|
||||||
|
|
||||||
// Two parameters, non-trivial default value
|
// Two parameters, non-trivial default value
|
||||||
template <typename D>
|
template <typename D>
|
||||||
D choose_parameter(const internal_np::Param_not_found&, const D& d)
|
D& choose_parameter(const internal_np::Param_not_found&, D& d)
|
||||||
{
|
{
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename D>
|
||||||
|
const D& choose_parameter(const internal_np::Param_not_found&, const D& d)
|
||||||
|
{
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename D>
|
||||||
|
D choose_parameter(const internal_np::Param_not_found&, D&& d)
|
||||||
|
{
|
||||||
|
return std::forward<D>(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename D>
|
||||||
|
T& choose_parameter(T& t, D&)
|
||||||
|
{
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T, typename D>
|
template <typename T, typename D>
|
||||||
const T& choose_parameter(const T& t, const D&)
|
const T& choose_parameter(const T& t, const D&)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -205,7 +205,7 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Halfedge_around_source_iterator()
|
Halfedge_around_source_iterator()
|
||||||
: anchor(), pos(), g(0)
|
: anchor(), pos(), g(nullptr), winding(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Halfedge_around_source_iterator(halfedge_descriptor hd, const Graph& g, int n=0)
|
Halfedge_around_source_iterator(halfedge_descriptor hd, const Graph& g, int n=0)
|
||||||
|
|
@ -305,7 +305,7 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Halfedge_around_target_iterator()
|
Halfedge_around_target_iterator()
|
||||||
: anchor(), pos(), g(0)
|
: anchor(), pos(), g(nullptr), winding(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Halfedge_around_target_iterator(halfedge_descriptor hd, const Graph& g, int n=0)
|
Halfedge_around_target_iterator(halfedge_descriptor hd, const Graph& g, int n=0)
|
||||||
|
|
|
||||||
|
|
@ -153,7 +153,7 @@ void duplicate_terminal_vertices(Graph& graph,
|
||||||
{
|
{
|
||||||
typename boost::graph_traits<OrigGraph>::vertex_descriptor orig_v = graph[v];
|
typename boost::graph_traits<OrigGraph>::vertex_descriptor orig_v = graph[v];
|
||||||
typename boost::graph_traits<Graph>::degree_size_type deg = degree(v, graph);
|
typename boost::graph_traits<Graph>::degree_size_type deg = degree(v, graph);
|
||||||
if ((deg != 0 && is_terminal(orig_v, orig)) || deg > 2)
|
if (deg != 2 || is_terminal(orig_v, orig))
|
||||||
{
|
{
|
||||||
out_edge_iterator b, e;
|
out_edge_iterator b, e;
|
||||||
boost::tie(b, e) = out_edges(v, graph);
|
boost::tie(b, e) = out_edges(v, graph);
|
||||||
|
|
@ -170,7 +170,6 @@ void duplicate_terminal_vertices(Graph& graph,
|
||||||
const std::pair<edge_descriptor, bool> pair = add_edge(vc, w, graph);
|
const std::pair<edge_descriptor, bool> pair = add_edge(vc, w, graph);
|
||||||
graph[pair.first] = orig_e;
|
graph[pair.first] = orig_e;
|
||||||
}
|
}
|
||||||
CGAL_assertion(degree(v, graph) == 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,9 @@
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
|
namespace inp = CGAL::internal_np;
|
||||||
|
namespace params = CGAL::parameters;
|
||||||
|
|
||||||
template <int i>
|
template <int i>
|
||||||
struct A
|
struct A
|
||||||
{
|
{
|
||||||
|
|
@ -11,6 +14,12 @@ struct A
|
||||||
int v;
|
int v;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct B
|
||||||
|
{
|
||||||
|
B(){}
|
||||||
|
B(const B&) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
template <int i, class T>
|
template <int i, class T>
|
||||||
void check_same_type(T)
|
void check_same_type(T)
|
||||||
{
|
{
|
||||||
|
|
@ -20,416 +29,78 @@ void check_same_type(T)
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class NamedParameters>
|
template<class NamedParameters>
|
||||||
void test(const NamedParameters& np)
|
void test_values_and_types(const NamedParameters& np)
|
||||||
{
|
{
|
||||||
using CGAL::parameters::get_parameter;
|
using params::get_parameter;
|
||||||
|
|
||||||
// Test values
|
// test values
|
||||||
|
assert(get_parameter(np, inp::vertex_index).v == 0);
|
||||||
|
assert(get_parameter(np, inp::visitor).v == 1);
|
||||||
|
|
||||||
// Named parameters that we use in CGAL
|
// test types
|
||||||
assert(get_parameter(np, CGAL::internal_np::vertex_index).v == 0);
|
check_same_type<0>(get_parameter(np, inp::vertex_index));
|
||||||
assert(get_parameter(np, CGAL::internal_np::visitor).v == 1);
|
check_same_type<1>(get_parameter(np, inp::visitor));
|
||||||
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);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::face_index).v == 5);
|
|
||||||
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::edge_is_constrained).v == 6);
|
template<class NamedParameters>
|
||||||
assert(get_parameter(np, CGAL::internal_np::first_index).v == 7);
|
void test_no_copyable(const NamedParameters& np)
|
||||||
assert(get_parameter(np, CGAL::internal_np::number_of_iterations).v == 8);
|
{
|
||||||
|
typedef typename inp::Get_param<typename NamedParameters::base,inp::visitor_t>::type NP_type;
|
||||||
|
CGAL_static_assertion( (boost::is_same<NP_type,std::reference_wrapper<const B> >::value) );
|
||||||
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::METIS_options).v == 800000001);
|
const A<4>& a = params::choose_parameter(params::get_parameter_reference(np, inp::edge_index), A<4>(4));
|
||||||
assert(get_parameter(np, CGAL::internal_np::vertex_partition_id).v == 800000002);
|
assert(a.v==4);
|
||||||
assert(get_parameter(np, CGAL::internal_np::face_partition_id).v == 800000003);
|
}
|
||||||
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::vertex_to_vertex_output_iterator).v == 800000004);
|
template <class NamedParameters>
|
||||||
assert(get_parameter(np, CGAL::internal_np::halfedge_to_halfedge_output_iterator).v == 800000005);
|
void test_references(const NamedParameters& np)
|
||||||
assert(get_parameter(np, CGAL::internal_np::face_to_face_output_iterator).v == 800000006);
|
{
|
||||||
|
typedef A<2> Default_type;
|
||||||
|
Default_type default_value(2);
|
||||||
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::vertex_to_vertex_map).v == 800000007);
|
// std::reference_wrapper
|
||||||
assert(get_parameter(np, CGAL::internal_np::halfedge_to_halfedge_map).v == 800000008);
|
typedef typename inp::Lookup_named_param_def<inp::visitor_t, NamedParameters, Default_type>::reference Visitor_reference_type;
|
||||||
assert(get_parameter(np, CGAL::internal_np::face_to_face_map).v == 800000009);
|
CGAL_static_assertion( (std::is_same<B&, Visitor_reference_type>::value) );
|
||||||
|
Visitor_reference_type vis_ref = params::choose_parameter(params::get_parameter_reference(np, inp::visitor), default_value);
|
||||||
|
CGAL_USE(vis_ref);
|
||||||
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::implementation_tag).v == 800000010);
|
// std::reference_wrapper of const
|
||||||
assert(get_parameter(np, CGAL::internal_np::prevent_unselection).v == 800000011);
|
typedef typename inp::Lookup_named_param_def<inp::face_index_t, NamedParameters, Default_type>::reference FIM_reference_type;
|
||||||
|
CGAL_static_assertion( (std::is_same<const B&, FIM_reference_type>::value) );
|
||||||
|
FIM_reference_type fim_ref = params::choose_parameter(params::get_parameter_reference(np, inp::face_index), default_value);
|
||||||
|
CGAL_USE(fim_ref);
|
||||||
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::stream_precision).v == 800000012);
|
// non-copyable
|
||||||
|
typedef typename inp::Lookup_named_param_def<inp::vertex_point_t, NamedParameters, Default_type>::reference VPM_reference_type;
|
||||||
|
CGAL_static_assertion( (std::is_same<const B&, VPM_reference_type>::value) );
|
||||||
|
VPM_reference_type vpm_ref = params::choose_parameter(params::get_parameter_reference(np, inp::vertex_point), default_value);
|
||||||
|
CGAL_USE(vpm_ref);
|
||||||
|
|
||||||
// Named parameters that we use in the package 'Mesh_3'
|
// passed by copy
|
||||||
assert(get_parameter(np, CGAL::internal_np::vertex_feature_degree).v == 9);
|
typedef typename inp::Lookup_named_param_def<inp::vertex_index_t, NamedParameters, Default_type>::reference VIM_reference_type;
|
||||||
|
CGAL_static_assertion( (std::is_same<A<0>, VIM_reference_type>::value) );
|
||||||
|
VIM_reference_type vim_ref = params::choose_parameter(params::get_parameter_reference(np, inp::vertex_index), default_value);
|
||||||
|
CGAL_USE(vim_ref);
|
||||||
|
|
||||||
// Named parameters used in the package 'Polygon Mesh Processing'
|
// default
|
||||||
assert(get_parameter(np, CGAL::internal_np::geom_traits).v == 10);
|
typedef typename inp::Lookup_named_param_def<inp::edge_index_t, NamedParameters, Default_type>::reference EIM_reference_type;
|
||||||
assert(get_parameter(np, CGAL::internal_np::vertex_incident_patches).v == 11);
|
CGAL_static_assertion(( std::is_same<Default_type&, EIM_reference_type>::value) );
|
||||||
assert(get_parameter(np, CGAL::internal_np::density_control_factor).v == 12);
|
EIM_reference_type eim_ref = params::choose_parameter(params::get_parameter_reference(np, inp::edge_index), default_value);
|
||||||
assert(get_parameter(np, CGAL::internal_np::use_delaunay_triangulation).v == 13);
|
assert(&eim_ref==&default_value);
|
||||||
assert(get_parameter(np, CGAL::internal_np::use_2d_constrained_delaunay_triangulation).v == 4573);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::fairing_continuity).v == 14);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::sparse_linear_solver).v == 15);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::number_of_relaxation_steps).v == 16);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::protect_constraints).v == 17);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::relax_constraints).v == 18);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::collapse_constraints).v == 43);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::vertex_is_constrained).v == 19);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::face_patch).v == 20);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::random_uniform_sampling).v == 21);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::grid_sampling).v == 22);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::monte_carlo_sampling).v == 23);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::do_sample_edges).v == 24);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::do_sample_vertices).v == 25);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::do_sample_faces).v == 26);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::number_of_points_on_faces).v == 27);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::number_of_points_per_face).v == 28);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::grid_spacing).v == 29);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::number_of_points_per_edge).v == 30);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::number_of_points_on_edges).v == 31);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::nb_points_per_area_unit).v == 32);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::nb_points_per_distance_unit).v == 33);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::throw_on_self_intersection).v == 43);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::clip_volume).v == 44);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::use_compact_clipper).v == 45);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::erase_all_duplicates).v == 48);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::require_same_orientation).v == 49);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::use_bool_op_to_clip_surface).v == 50);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::face_size_map).v == 52);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::use_angle_smoothing).v == 53);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::use_area_smoothing).v == 54);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::use_Delaunay_flips).v == 55);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::use_safety_constraints).v == 56);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::area_threshold).v == 57);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::volume_threshold).v == 58);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::snapping_tolerance).v == 59);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::dry_run).v == 60);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::do_lock_mesh).v == 61);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::halfedges_keeper).v == 62);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::do_simplify_border).v == 64);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::do_not_modify).v == 65);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::allow_self_intersections).v == 66);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::polyhedral_envelope_epsilon).v == 67);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::maximum_number_of_faces).v == 78910);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::non_manifold_feature_map).v == 60);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::filter).v == 61);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::face_epsilon_map).v == 62);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::maximum_number).v == 68);
|
|
||||||
|
|
||||||
// Named parameters that we use in the package 'Surface Mesh Simplification'
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::get_cost_policy).v == 34);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::get_placement_policy).v == 35);
|
|
||||||
|
|
||||||
// Named parameters that we use in the package 'Optimal_bounding_box'
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::use_convex_hull).v == 63);
|
|
||||||
|
|
||||||
// To-be-documented named parameters
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::face_normal).v == 36);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::random_seed).v == 37);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::do_project).v == 38);
|
|
||||||
|
|
||||||
// Internal named parameters
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::weight_calculator).v == 39);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::preserve_genus).v == 40);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::verbosity_level).v == 41);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::use_binary_mode).v == 51);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::projection_functor).v == 42);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::apply_per_connected_component).v == 46);
|
|
||||||
assert(get_parameter(np, CGAL::internal_np::output_iterator).v == 47);
|
|
||||||
|
|
||||||
// Test types
|
|
||||||
|
|
||||||
// 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::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));
|
|
||||||
check_same_type<5>(get_parameter(np, CGAL::internal_np::face_index));
|
|
||||||
|
|
||||||
check_same_type<6>(get_parameter(np, CGAL::internal_np::edge_is_constrained));
|
|
||||||
check_same_type<7>(get_parameter(np, CGAL::internal_np::first_index));
|
|
||||||
check_same_type<8>(get_parameter(np, CGAL::internal_np::number_of_iterations));
|
|
||||||
|
|
||||||
check_same_type<800000001>(get_parameter(np, CGAL::internal_np::METIS_options));
|
|
||||||
check_same_type<800000002>(get_parameter(np, CGAL::internal_np::vertex_partition_id));
|
|
||||||
check_same_type<800000003>(get_parameter(np, CGAL::internal_np::face_partition_id));
|
|
||||||
check_same_type<800000004>(get_parameter(np, CGAL::internal_np::vertex_to_vertex_output_iterator));
|
|
||||||
check_same_type<800000005>(get_parameter(np, CGAL::internal_np::halfedge_to_halfedge_output_iterator));
|
|
||||||
check_same_type<800000006>(get_parameter(np, CGAL::internal_np::face_to_face_output_iterator));
|
|
||||||
check_same_type<800000007>(get_parameter(np, CGAL::internal_np::vertex_to_vertex_map));
|
|
||||||
check_same_type<800000008>(get_parameter(np, CGAL::internal_np::halfedge_to_halfedge_map));
|
|
||||||
check_same_type<800000009>(get_parameter(np, CGAL::internal_np::face_to_face_map));
|
|
||||||
check_same_type<800000010>(get_parameter(np, CGAL::internal_np::implementation_tag));
|
|
||||||
check_same_type<800000011>(get_parameter(np, CGAL::internal_np::prevent_unselection));
|
|
||||||
check_same_type<800000012>(get_parameter(np, CGAL::internal_np::stream_precision));
|
|
||||||
|
|
||||||
// Named parameters that we use in the package 'Mesh_3'
|
|
||||||
check_same_type<9>(get_parameter(np, CGAL::internal_np::vertex_feature_degree));
|
|
||||||
|
|
||||||
// Named parameters used in the package 'Polygon Mesh Processing'
|
|
||||||
check_same_type<10>(get_parameter(np, CGAL::internal_np::geom_traits));
|
|
||||||
check_same_type<11>(get_parameter(np, CGAL::internal_np::vertex_incident_patches));
|
|
||||||
check_same_type<12>(get_parameter(np, CGAL::internal_np::density_control_factor));
|
|
||||||
check_same_type<13>(get_parameter(np, CGAL::internal_np::use_delaunay_triangulation));
|
|
||||||
check_same_type<4573>(get_parameter(np, CGAL::internal_np::use_2d_constrained_delaunay_triangulation));
|
|
||||||
check_same_type<14>(get_parameter(np, CGAL::internal_np::fairing_continuity));
|
|
||||||
check_same_type<15>(get_parameter(np, CGAL::internal_np::sparse_linear_solver));
|
|
||||||
check_same_type<16>(get_parameter(np, CGAL::internal_np::number_of_relaxation_steps));
|
|
||||||
check_same_type<17>(get_parameter(np, CGAL::internal_np::protect_constraints));
|
|
||||||
check_same_type<18>(get_parameter(np, CGAL::internal_np::relax_constraints));
|
|
||||||
check_same_type<43>(get_parameter(np, CGAL::internal_np::collapse_constraints));
|
|
||||||
check_same_type<19>(get_parameter(np, CGAL::internal_np::vertex_is_constrained));
|
|
||||||
check_same_type<20>(get_parameter(np, CGAL::internal_np::face_patch));
|
|
||||||
check_same_type<21>(get_parameter(np, CGAL::internal_np::random_uniform_sampling));
|
|
||||||
check_same_type<22>(get_parameter(np, CGAL::internal_np::grid_sampling));
|
|
||||||
check_same_type<23>(get_parameter(np, CGAL::internal_np::monte_carlo_sampling));
|
|
||||||
check_same_type<24>(get_parameter(np, CGAL::internal_np::do_sample_edges));
|
|
||||||
check_same_type<25>(get_parameter(np, CGAL::internal_np::do_sample_vertices));
|
|
||||||
check_same_type<26>(get_parameter(np, CGAL::internal_np::do_sample_faces));
|
|
||||||
check_same_type<27>(get_parameter(np, CGAL::internal_np::number_of_points_on_faces));
|
|
||||||
check_same_type<28>(get_parameter(np, CGAL::internal_np::number_of_points_per_face));
|
|
||||||
check_same_type<29>(get_parameter(np, CGAL::internal_np::grid_spacing));
|
|
||||||
check_same_type<30>(get_parameter(np, CGAL::internal_np::number_of_points_per_edge));
|
|
||||||
check_same_type<31>(get_parameter(np, CGAL::internal_np::number_of_points_on_edges));
|
|
||||||
check_same_type<32>(get_parameter(np, CGAL::internal_np::nb_points_per_area_unit));
|
|
||||||
check_same_type<33>(get_parameter(np, CGAL::internal_np::nb_points_per_distance_unit));
|
|
||||||
check_same_type<43>(get_parameter(np, CGAL::internal_np::throw_on_self_intersection));
|
|
||||||
check_same_type<44>(get_parameter(np, CGAL::internal_np::clip_volume));
|
|
||||||
check_same_type<45>(get_parameter(np, CGAL::internal_np::use_compact_clipper));
|
|
||||||
check_same_type<48>(get_parameter(np, CGAL::internal_np::erase_all_duplicates));
|
|
||||||
check_same_type<49>(get_parameter(np, CGAL::internal_np::require_same_orientation));
|
|
||||||
check_same_type<50>(get_parameter(np, CGAL::internal_np::use_bool_op_to_clip_surface));
|
|
||||||
check_same_type<52>(get_parameter(np, CGAL::internal_np::face_size_map));
|
|
||||||
check_same_type<53>(get_parameter(np, CGAL::internal_np::use_angle_smoothing));
|
|
||||||
check_same_type<54>(get_parameter(np, CGAL::internal_np::use_area_smoothing));
|
|
||||||
check_same_type<55>(get_parameter(np, CGAL::internal_np::use_Delaunay_flips));
|
|
||||||
check_same_type<56>(get_parameter(np, CGAL::internal_np::use_safety_constraints));
|
|
||||||
check_same_type<65>(get_parameter(np, CGAL::internal_np::do_not_modify));
|
|
||||||
check_same_type<66>(get_parameter(np, CGAL::internal_np::allow_self_intersections));
|
|
||||||
check_same_type<67>(get_parameter(np, CGAL::internal_np::polyhedral_envelope_epsilon));
|
|
||||||
|
|
||||||
check_same_type<12340>(get_parameter(np, CGAL::internal_np::do_self_intersection_tests));
|
|
||||||
check_same_type<12341>(get_parameter(np, CGAL::internal_np::do_orientation_tests));
|
|
||||||
check_same_type<12342>(get_parameter(np, CGAL::internal_np::error_codes));
|
|
||||||
check_same_type<12343>(get_parameter(np, CGAL::internal_np::volume_inclusions));
|
|
||||||
check_same_type<12344>(get_parameter(np, CGAL::internal_np::face_connected_component_map));
|
|
||||||
check_same_type<12345>(get_parameter(np, CGAL::internal_np::connected_component_id_to_volume_id));
|
|
||||||
check_same_type<12346>(get_parameter(np, CGAL::internal_np::is_cc_outward_oriented));
|
|
||||||
check_same_type<12347>(get_parameter(np, CGAL::internal_np::intersecting_volume_pairs_output_iterator));
|
|
||||||
check_same_type<12348>(get_parameter(np, CGAL::internal_np::i_used_as_a_predicate));
|
|
||||||
check_same_type<12349>(get_parameter(np, CGAL::internal_np::nesting_levels));
|
|
||||||
check_same_type<12350>(get_parameter(np, CGAL::internal_np::i_used_for_volume_orientation));
|
|
||||||
|
|
||||||
check_same_type<57>(get_parameter(np, CGAL::internal_np::area_threshold));
|
|
||||||
check_same_type<58>(get_parameter(np, CGAL::internal_np::volume_threshold));
|
|
||||||
check_same_type<59>(get_parameter(np, CGAL::internal_np::snapping_tolerance));
|
|
||||||
check_same_type<60>(get_parameter(np, CGAL::internal_np::dry_run));
|
|
||||||
check_same_type<61>(get_parameter(np, CGAL::internal_np::do_lock_mesh));
|
|
||||||
check_same_type<62>(get_parameter(np, CGAL::internal_np::halfedges_keeper));
|
|
||||||
check_same_type<64>(get_parameter(np, CGAL::internal_np::do_simplify_border));
|
|
||||||
check_same_type<78910>(get_parameter(np, CGAL::internal_np::maximum_number_of_faces));
|
|
||||||
check_same_type<60>(get_parameter(np, CGAL::internal_np::non_manifold_feature_map));
|
|
||||||
check_same_type<61>(get_parameter(np, CGAL::internal_np::filter));
|
|
||||||
check_same_type<62>(get_parameter(np, CGAL::internal_np::face_epsilon_map));
|
|
||||||
check_same_type<68>(get_parameter(np, CGAL::internal_np::maximum_number));
|
|
||||||
|
|
||||||
// Named parameters that we use in the package 'Surface Mesh Simplification'
|
|
||||||
check_same_type<34>(get_parameter(np, CGAL::internal_np::get_cost_policy));
|
|
||||||
check_same_type<35>(get_parameter(np, CGAL::internal_np::get_placement_policy));
|
|
||||||
|
|
||||||
// Named parameters that we use in the package 'Optimal_bounding_box'
|
|
||||||
check_same_type<63>(get_parameter(np, CGAL::internal_np::use_convex_hull));
|
|
||||||
|
|
||||||
// To-be-documented named parameters
|
|
||||||
check_same_type<36>(get_parameter(np, CGAL::internal_np::face_normal));
|
|
||||||
check_same_type<37>(get_parameter(np, CGAL::internal_np::random_seed));
|
|
||||||
check_same_type<38>(get_parameter(np, CGAL::internal_np::do_project));
|
|
||||||
check_same_type<456>(get_parameter(np, CGAL::internal_np::algorithm));
|
|
||||||
|
|
||||||
// Internal named parameters
|
|
||||||
check_same_type<39>(get_parameter(np, CGAL::internal_np::weight_calculator));
|
|
||||||
check_same_type<40>(get_parameter(np, CGAL::internal_np::preserve_genus));
|
|
||||||
check_same_type<41>(get_parameter(np, CGAL::internal_np::verbosity_level));
|
|
||||||
check_same_type<51>(get_parameter(np, CGAL::internal_np::use_binary_mode));
|
|
||||||
check_same_type<42>(get_parameter(np, CGAL::internal_np::projection_functor));
|
|
||||||
check_same_type<46>(get_parameter(np, CGAL::internal_np::apply_per_connected_component));
|
|
||||||
check_same_type<47>(get_parameter(np, CGAL::internal_np::output_iterator));
|
|
||||||
|
|
||||||
// Named parameters used in the package 'Point Set Processing'
|
|
||||||
check_same_type<9000>(get_parameter(np, CGAL::internal_np::point_map));
|
|
||||||
check_same_type<9001>(get_parameter(np, CGAL::internal_np::query_point_map));
|
|
||||||
check_same_type<9002>(get_parameter(np, CGAL::internal_np::normal_map));
|
|
||||||
check_same_type<9003>(get_parameter(np, CGAL::internal_np::diagonalize_traits));
|
|
||||||
check_same_type<9004>(get_parameter(np, CGAL::internal_np::svd_traits));
|
|
||||||
check_same_type<9005>(get_parameter(np, CGAL::internal_np::callback));
|
|
||||||
check_same_type<9006>(get_parameter(np, CGAL::internal_np::sharpness_angle));
|
|
||||||
check_same_type<9007>(get_parameter(np, CGAL::internal_np::edge_sensitivity));
|
|
||||||
check_same_type<9008>(get_parameter(np, CGAL::internal_np::neighbor_radius));
|
|
||||||
check_same_type<9009>(get_parameter(np, CGAL::internal_np::number_of_output_points));
|
|
||||||
check_same_type<9010>(get_parameter(np, CGAL::internal_np::size));
|
|
||||||
check_same_type<9011>(get_parameter(np, CGAL::internal_np::maximum_variation));
|
|
||||||
check_same_type<9012>(get_parameter(np, CGAL::internal_np::degree_fitting));
|
|
||||||
check_same_type<9013>(get_parameter(np, CGAL::internal_np::degree_monge));
|
|
||||||
check_same_type<9014>(get_parameter(np, CGAL::internal_np::threshold_percent));
|
|
||||||
check_same_type<9015>(get_parameter(np, CGAL::internal_np::threshold_distance));
|
|
||||||
check_same_type<9016>(get_parameter(np, CGAL::internal_np::attraction_factor));
|
|
||||||
check_same_type<9017>(get_parameter(np, CGAL::internal_np::plane_map));
|
|
||||||
check_same_type<9018>(get_parameter(np, CGAL::internal_np::plane_index_map));
|
|
||||||
check_same_type<9019>(get_parameter(np, CGAL::internal_np::select_percentage));
|
|
||||||
check_same_type<9020>(get_parameter(np, CGAL::internal_np::require_uniform_sampling));
|
|
||||||
check_same_type<9021>(get_parameter(np, CGAL::internal_np::point_is_constrained));
|
|
||||||
check_same_type<9022>(get_parameter(np, CGAL::internal_np::number_of_samples));
|
|
||||||
check_same_type<9023>(get_parameter(np, CGAL::internal_np::accuracy));
|
|
||||||
check_same_type<9024>(get_parameter(np, CGAL::internal_np::maximum_running_time));
|
|
||||||
check_same_type<9025>(get_parameter(np, CGAL::internal_np::overlap));
|
|
||||||
check_same_type<9026>(get_parameter(np, CGAL::internal_np::transformation));
|
|
||||||
check_same_type<9027>(get_parameter(np, CGAL::internal_np::point_set_filters));
|
|
||||||
check_same_type<9028>(get_parameter(np, CGAL::internal_np::matcher));
|
|
||||||
check_same_type<9029>(get_parameter(np, CGAL::internal_np::outlier_filters));
|
|
||||||
check_same_type<9030>(get_parameter(np, CGAL::internal_np::error_minimizer));
|
|
||||||
check_same_type<9031>(get_parameter(np, CGAL::internal_np::transformation_checkers));
|
|
||||||
check_same_type<9032>(get_parameter(np, CGAL::internal_np::inspector));
|
|
||||||
check_same_type<9033>(get_parameter(np, CGAL::internal_np::logger));
|
|
||||||
check_same_type<9034>(get_parameter(np, CGAL::internal_np::maximum_normal_deviation));
|
|
||||||
check_same_type<9035>(get_parameter(np, CGAL::internal_np::scan_angle_map));
|
|
||||||
check_same_type<9036>(get_parameter(np, CGAL::internal_np::scanline_id_map));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
test(CGAL::parameters::vertex_index_map(A<0>(0))
|
test_values_and_types(params::vertex_index_map(A<0>(0)).visitor(A<1>(1)));
|
||||||
.visitor(A<1>(1))
|
|
||||||
.vertex_point_map(A<2>(2))
|
B b;
|
||||||
.halfedge_index_map(A<3>(3))
|
test_no_copyable(params::visitor(b));
|
||||||
.edge_index_map(A<4>(4))
|
|
||||||
.face_index_map(A<5>(5))
|
test_references(params::visitor(std::ref(b))
|
||||||
.edge_is_constrained_map(A<6>(6))
|
.vertex_point_map(b)
|
||||||
.first_index(A<7>(7))
|
.vertex_index_map(A<0>(0))
|
||||||
.number_of_iterations(A<8>(8))
|
.face_index_map(std::reference_wrapper<const B>(b))
|
||||||
.METIS_options(A<800000001>(800000001))
|
);
|
||||||
.vertex_partition_id_map(A<800000002>(800000002))
|
|
||||||
.face_partition_id_map(A<800000003>(800000003))
|
|
||||||
.vertex_to_vertex_output_iterator(A<800000004>(800000004))
|
|
||||||
.halfedge_to_halfedge_output_iterator(A<800000005>(800000005))
|
|
||||||
.face_to_face_output_iterator(A<800000006>(800000006))
|
|
||||||
.vertex_to_vertex_map(A<800000007>(800000007))
|
|
||||||
.halfedge_to_halfedge_map(A<800000008>(800000008))
|
|
||||||
.face_to_face_map(A<800000009>(800000009))
|
|
||||||
.implementation_tag(A<800000010>(800000010))
|
|
||||||
.prevent_unselection(A<800000011>(800000011))
|
|
||||||
.stream_precision(A<800000012>(800000012))
|
|
||||||
.vertex_feature_degree_map(A<9>(9))
|
|
||||||
.geom_traits(A<10>(10))
|
|
||||||
.vertex_incident_patches_map(A<11>(11))
|
|
||||||
.density_control_factor(A<12>(12))
|
|
||||||
.use_delaunay_triangulation(A<13>(13))
|
|
||||||
.use_2d_constrained_delaunay_triangulation(A<4573>(4573))
|
|
||||||
.fairing_continuity(A<14>(14))
|
|
||||||
.sparse_linear_solver(A<15>(15))
|
|
||||||
.number_of_relaxation_steps(A<16>(16))
|
|
||||||
.protect_constraints(A<17>(17))
|
|
||||||
.relax_constraints(A<18>(18))
|
|
||||||
.collapse_constraints(A<43>(43))
|
|
||||||
.vertex_is_constrained_map(A<19>(19))
|
|
||||||
.face_patch_map(A<20>(20))
|
|
||||||
.use_random_uniform_sampling(A<21>(21))
|
|
||||||
.use_grid_sampling(A<22>(22))
|
|
||||||
.use_monte_carlo_sampling(A<23>(23))
|
|
||||||
.do_sample_edges(A<24>(24))
|
|
||||||
.do_sample_vertices(A<25>(25))
|
|
||||||
.do_sample_faces(A<26>(26))
|
|
||||||
.number_of_points_on_faces(A<27>(27))
|
|
||||||
.number_of_points_per_face(A<28>(28))
|
|
||||||
.grid_spacing(A<29>(29))
|
|
||||||
.number_of_points_per_edge(A<30>(30))
|
|
||||||
.number_of_points_on_edges(A<31>(31))
|
|
||||||
.number_of_points_per_area_unit(A<32>(32))
|
|
||||||
.number_of_points_per_distance_unit(A<33>(33))
|
|
||||||
.get_cost(A<34>(34))
|
|
||||||
.get_placement(A<35>(35))
|
|
||||||
.face_normal_map(A<36>(36))
|
|
||||||
.random_seed(A<37>(37))
|
|
||||||
.do_project(A<38>(38))
|
|
||||||
.algorithm(A<456>(456))
|
|
||||||
.weight_calculator(A<39>(39))
|
|
||||||
.preserve_genus(A<40>(40))
|
|
||||||
.verbosity_level(A<41>(41))
|
|
||||||
.projection_functor(A<42>(42))
|
|
||||||
.throw_on_self_intersection(A<43>(43))
|
|
||||||
.clip_volume(A<44>(44))
|
|
||||||
.use_compact_clipper(A<45>(45))
|
|
||||||
.non_manifold_feature_map(A<60>(60))
|
|
||||||
.filter(A<61>(61))
|
|
||||||
.face_epsilon_map(A<62>(62))
|
|
||||||
.maximum_number(A<68>(68))
|
|
||||||
.apply_per_connected_component(A<46>(46))
|
|
||||||
.output_iterator(A<47>(47))
|
|
||||||
.erase_all_duplicates(A<48>(48))
|
|
||||||
.require_same_orientation(A<49>(49))
|
|
||||||
.use_bool_op_to_clip_surface(A<50>(50))
|
|
||||||
.use_binary_mode(A<51>(51))
|
|
||||||
.face_size_map(A<52>(52))
|
|
||||||
.use_angle_smoothing(A<53>(53))
|
|
||||||
.use_area_smoothing(A<54>(54))
|
|
||||||
.use_Delaunay_flips(A<55>(55))
|
|
||||||
.use_safety_constraints(A<56>(56))
|
|
||||||
.do_self_intersection_tests(A<12340>(12340))
|
|
||||||
.do_orientation_tests(A<12341>(12341))
|
|
||||||
.error_codes(A<12342>(12342))
|
|
||||||
.volume_inclusions(A<12343>(12343))
|
|
||||||
.face_connected_component_map(A<12344>(12344))
|
|
||||||
.connected_component_id_to_volume_id(A<12345>(12345))
|
|
||||||
.is_cc_outward_oriented(A<12346>(12346))
|
|
||||||
.intersecting_volume_pairs_output_iterator(A<12347>(12347))
|
|
||||||
.i_used_as_a_predicate(A<12348>(12348))
|
|
||||||
.nesting_levels(A<12349>(12349))
|
|
||||||
.i_used_for_volume_orientation(A<12350>(12350))
|
|
||||||
.area_threshold(A<57>(57))
|
|
||||||
.volume_threshold(A<58>(58))
|
|
||||||
.snapping_tolerance(A<59>(59))
|
|
||||||
.dry_run(A<60>(60))
|
|
||||||
.do_lock_mesh(A<61>(61))
|
|
||||||
.halfedges_keeper(A<62>(62))
|
|
||||||
.use_convex_hull(A<63>(63))
|
|
||||||
.do_simplify_border(A<64>(64))
|
|
||||||
.do_not_modify(A<65>(65))
|
|
||||||
.allow_self_intersections(A<66>(66))
|
|
||||||
.polyhedral_envelope_epsilon(A<67>(67))
|
|
||||||
.point_map(A<9000>(9000))
|
|
||||||
.query_point_map(A<9001>(9001))
|
|
||||||
.normal_map(A<9002>(9002))
|
|
||||||
.diagonalize_traits(A<9003>(9003))
|
|
||||||
.svd_traits(A<9004>(9004))
|
|
||||||
.callback(A<9005>(9005))
|
|
||||||
.sharpness_angle(A<9006>(9006))
|
|
||||||
.edge_sensitivity(A<9007>(9007))
|
|
||||||
.neighbor_radius(A<9008>(9008))
|
|
||||||
.number_of_output_points(A<9009>(9009))
|
|
||||||
.size(A<9010>(9010))
|
|
||||||
.maximum_variation(A<9011>(9011))
|
|
||||||
.degree_fitting(A<9012>(9012))
|
|
||||||
.degree_monge(A<9013>(9013))
|
|
||||||
.threshold_percent(A<9014>(9014))
|
|
||||||
.threshold_distance(A<9015>(9015))
|
|
||||||
.attraction_factor(A<9016>(9016))
|
|
||||||
.plane_map(A<9017>(9017))
|
|
||||||
.plane_index_map(A<9018>(9018))
|
|
||||||
.select_percentage(A<9019>(9019))
|
|
||||||
.require_uniform_sampling(A<9020>(9020))
|
|
||||||
.point_is_constrained_map(A<9021>(9021))
|
|
||||||
.number_of_samples(A<9022>(9022))
|
|
||||||
.accuracy(A<9023>(9023))
|
|
||||||
.maximum_running_time(A<9024>(9024))
|
|
||||||
.overlap(A<9025>(9025))
|
|
||||||
.transformation(A<9026>(9026))
|
|
||||||
.point_set_filters(A<9027>(9027))
|
|
||||||
.matcher(A<9028>(9028))
|
|
||||||
.outlier_filters(A<9029>(9029))
|
|
||||||
.error_minimizer(A<9030>(9030))
|
|
||||||
.transformation_checkers(A<9031>(9031))
|
|
||||||
.inspector(A<9032>(9032))
|
|
||||||
.logger(A<9033>(9033))
|
|
||||||
.maximum_normal_deviation(A<9034>(9034))
|
|
||||||
.scan_angle_map(A<9035>(9035))
|
|
||||||
.scanline_id_map(A<9036>(9036))
|
|
||||||
.maximum_number_of_faces(A<78910>(78910))
|
|
||||||
);
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,8 @@ namespace CGAL {
|
||||||
// Barycentric coordinates namespace.
|
// Barycentric coordinates namespace.
|
||||||
namespace Barycentric_coordinates {
|
namespace Barycentric_coordinates {
|
||||||
|
|
||||||
|
#if !defined(CGAL_NO_DEPRECATED_CODE) || defined(DOXYGEN_RUNNING)
|
||||||
|
|
||||||
// Examples: see the User Manual here - https://doc.cgal.org/latest/Manual/index.html.
|
// Examples: see the User Manual here - https://doc.cgal.org/latest/Manual/index.html.
|
||||||
// [1] Reference: "M. S. Floater, K. Hormann, and G. Kos. A general construction of barycentric coordinates over convex polygons. Advances in Computational Mathematics, 24(1-4):311-331, 2006.".
|
// [1] Reference: "M. S. Floater, K. Hormann, and G. Kos. A general construction of barycentric coordinates over convex polygons. Advances in Computational Mathematics, 24(1-4):311-331, 2006.".
|
||||||
|
|
||||||
|
|
@ -430,6 +432,8 @@ private:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif // CGAL_NO_DEPRECATED_CODE
|
||||||
|
|
||||||
} // namespace Barycentric_coordinates
|
} // namespace Barycentric_coordinates
|
||||||
|
|
||||||
} // namespace CGAL
|
} // namespace CGAL
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,8 @@ namespace CGAL {
|
||||||
// Barycentric coordinates namespace.
|
// Barycentric coordinates namespace.
|
||||||
namespace Barycentric_coordinates {
|
namespace Barycentric_coordinates {
|
||||||
|
|
||||||
|
#if !defined(CGAL_NO_DEPRECATED_CODE) || defined(DOXYGEN_RUNNING)
|
||||||
|
|
||||||
// Examples: see the User Manual here - https://doc.cgal.org/latest/Manual/index.html.
|
// Examples: see the User Manual here - https://doc.cgal.org/latest/Manual/index.html.
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
@ -585,6 +587,8 @@ private:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif // CGAL_NO_DEPRECATED_CODE
|
||||||
|
|
||||||
} // namespace Barycentric_coordinates
|
} // namespace Barycentric_coordinates
|
||||||
|
|
||||||
} // namespace CGAL
|
} // namespace CGAL
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,8 @@ namespace CGAL {
|
||||||
// Barycentric coordinates namespace.
|
// Barycentric coordinates namespace.
|
||||||
namespace Barycentric_coordinates {
|
namespace Barycentric_coordinates {
|
||||||
|
|
||||||
|
#if !defined(CGAL_NO_DEPRECATED_CODE) || defined(DOXYGEN_RUNNING)
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Try to find a square root object in the provided `Traits` class. If not, then use the default square root from CGAL.
|
// Try to find a square root object in the provided `Traits` class. If not, then use the default square root from CGAL.
|
||||||
|
|
||||||
|
|
@ -498,6 +500,8 @@ private:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif // CGAL_NO_DEPRECATED_CODE
|
||||||
|
|
||||||
} // namespace Barycentric_coordinates
|
} // namespace Barycentric_coordinates
|
||||||
|
|
||||||
} // namespace CGAL
|
} // namespace CGAL
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,8 @@ namespace CGAL {
|
||||||
// Barycentric coordinates namespace.
|
// Barycentric coordinates namespace.
|
||||||
namespace Barycentric_coordinates {
|
namespace Barycentric_coordinates {
|
||||||
|
|
||||||
|
#if !defined(CGAL_NO_DEPRECATED_CODE) || defined(DOXYGEN_RUNNING)
|
||||||
|
|
||||||
// Examples: see the User Manual here - https://doc.cgal.org/latest/Manual/index.html.
|
// Examples: see the User Manual here - https://doc.cgal.org/latest/Manual/index.html.
|
||||||
// [1] Reference: "M. S. Floater, K. Hormann, and G. Kos. A general construction of barycentric coordinates over convex polygons. Advances in Computational Mathematics, 24(1-4):311-331, 2006.".
|
// [1] Reference: "M. S. Floater, K. Hormann, and G. Kos. A general construction of barycentric coordinates over convex polygons. Advances in Computational Mathematics, 24(1-4):311-331, 2006.".
|
||||||
|
|
||||||
|
|
@ -413,6 +415,8 @@ private:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif // CGAL_NO_DEPRECATED_CODE
|
||||||
|
|
||||||
} // namespace Barycentric_coordinates
|
} // namespace Barycentric_coordinates
|
||||||
|
|
||||||
} // namespace CGAL
|
} // namespace CGAL
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,8 @@ enum class Computation_policy_2 {
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
namespace Barycentric_coordinates {
|
namespace Barycentric_coordinates {
|
||||||
|
|
||||||
|
#if !defined(CGAL_NO_DEPRECATED_CODE) || defined(DOXYGEN_RUNNING)
|
||||||
|
|
||||||
/// \name Locations of a Query Point
|
/// \name Locations of a Query Point
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
|
|
@ -142,6 +144,8 @@ enum Type_of_polygon {
|
||||||
|
|
||||||
/// \endcond
|
/// \endcond
|
||||||
|
|
||||||
|
#endif // CGAL_NO_DEPRECATED_CODE
|
||||||
|
|
||||||
} // namespace Barycentric_coordinates
|
} // namespace Barycentric_coordinates
|
||||||
} // namespace CGAL
|
} // namespace CGAL
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -172,6 +172,8 @@ namespace Barycentric_coordinates {
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
namespace Barycentric_coordinates {
|
namespace Barycentric_coordinates {
|
||||||
|
|
||||||
|
#if !defined(CGAL_NO_DEPRECATED_CODE) || defined(DOXYGEN_RUNNING)
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\ingroup PkgBarycentricCoordinates2RefDeprecated
|
\ingroup PkgBarycentricCoordinates2RefDeprecated
|
||||||
* The class `Segment_coordinates_2` implements barycentric coordinates with respect to an arbitrary non-degenerate segment along an arbitrary line in the plane.
|
* The class `Segment_coordinates_2` implements barycentric coordinates with respect to an arbitrary non-degenerate segment along an arbitrary line in the plane.
|
||||||
|
|
@ -376,6 +378,8 @@ namespace Barycentric_coordinates {
|
||||||
return CGAL::make_array(b_first, FT(1) - b_first);
|
return CGAL::make_array(b_first, FT(1) - b_first);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // CGAL_NO_DEPRECATED_CODE
|
||||||
|
|
||||||
} // namespace Barycentric_coordinates
|
} // namespace Barycentric_coordinates
|
||||||
} // namespace CGAL
|
} // namespace CGAL
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -182,6 +182,8 @@ namespace Barycentric_coordinates {
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
namespace Barycentric_coordinates {
|
namespace Barycentric_coordinates {
|
||||||
|
|
||||||
|
#if !defined(CGAL_NO_DEPRECATED_CODE) || defined(DOXYGEN_RUNNING)
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \ingroup PkgBarycentricCoordinates2RefDeprecated
|
* \ingroup PkgBarycentricCoordinates2RefDeprecated
|
||||||
* The class `Triangle_coordinates_2` implements barycentric coordinates ( <a href="https://mathworld.wolfram.com/BarycentricCoordinates.html" target=blanc>[1]</a>,
|
* The class `Triangle_coordinates_2` implements barycentric coordinates ( <a href="https://mathworld.wolfram.com/BarycentricCoordinates.html" target=blanc>[1]</a>,
|
||||||
|
|
@ -413,6 +415,8 @@ namespace Barycentric_coordinates {
|
||||||
return CGAL::make_array(b_first, b_second, FT(1) - b_first - b_second);
|
return CGAL::make_array(b_first, b_second, FT(1) - b_first - b_second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // CGAL_NO_DEPRECATED_CODE
|
||||||
|
|
||||||
} // namespace Barycentric_coordinates
|
} // namespace Barycentric_coordinates
|
||||||
} // namespace CGAL
|
} // namespace CGAL
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
#include <cmath>
|
|
||||||
#include <cassert>
|
|
||||||
#include <CGAL/Installation/internal/disable_deprecation_warnings_and_errors.h>
|
#include <CGAL/Installation/internal/disable_deprecation_warnings_and_errors.h>
|
||||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||||
#include <CGAL/Barycentric_coordinates_2/triangle_coordinates_2.h>
|
#include <CGAL/Barycentric_coordinates_2/triangle_coordinates_2.h>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,3 @@
|
||||||
// #define HMC_SparseLU
|
|
||||||
// #define HMC_SimplicialLLT
|
|
||||||
// #define HMC_SimplicialLDLT // default
|
|
||||||
|
|
||||||
#include <CGAL/Simple_cartesian.h>
|
#include <CGAL/Simple_cartesian.h>
|
||||||
#include <CGAL/Barycentric_coordinates_2/Delaunay_domain_2.h>
|
#include <CGAL/Barycentric_coordinates_2/Delaunay_domain_2.h>
|
||||||
#include <CGAL/Barycentric_coordinates_2/Harmonic_coordinates_2.h>
|
#include <CGAL/Barycentric_coordinates_2/Harmonic_coordinates_2.h>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,3 @@
|
||||||
// #define HMC_SparseLU
|
|
||||||
// #define HMC_SimplicialLLT
|
|
||||||
// #define HMC_SimplicialLDLT // default
|
|
||||||
|
|
||||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||||
#include <CGAL/Barycentric_coordinates_2/Delaunay_domain_2.h>
|
#include <CGAL/Barycentric_coordinates_2/Delaunay_domain_2.h>
|
||||||
#include <CGAL/Barycentric_coordinates_2/Harmonic_coordinates_2.h>
|
#include <CGAL/Barycentric_coordinates_2/Harmonic_coordinates_2.h>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,3 @@
|
||||||
// #define HMC_SparseLU
|
|
||||||
// #define HMC_SimplicialLLT
|
|
||||||
// #define HMC_SimplicialLDLT // default
|
|
||||||
|
|
||||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||||
#include <CGAL/Barycentric_coordinates_2/Delaunay_domain_2.h>
|
#include <CGAL/Barycentric_coordinates_2/Delaunay_domain_2.h>
|
||||||
#include <CGAL/Barycentric_coordinates_2/Harmonic_coordinates_2.h>
|
#include <CGAL/Barycentric_coordinates_2/Harmonic_coordinates_2.h>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
#include <cmath>
|
|
||||||
#include <cassert>
|
|
||||||
#include <CGAL/Installation/internal/disable_deprecation_warnings_and_errors.h>
|
#include <CGAL/Installation/internal/disable_deprecation_warnings_and_errors.h>
|
||||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||||
#include <CGAL/Barycentric_coordinates_2/triangle_coordinates_2.h>
|
#include <CGAL/Barycentric_coordinates_2/triangle_coordinates_2.h>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
#include <cmath>
|
|
||||||
#include <cassert>
|
|
||||||
#include <CGAL/Installation/internal/disable_deprecation_warnings_and_errors.h>
|
#include <CGAL/Installation/internal/disable_deprecation_warnings_and_errors.h>
|
||||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||||
#include <CGAL/Barycentric_coordinates_2/segment_coordinates_2.h>
|
#include <CGAL/Barycentric_coordinates_2/segment_coordinates_2.h>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
#include <cmath>
|
|
||||||
#include <cassert>
|
|
||||||
#include <CGAL/Installation/internal/disable_deprecation_warnings_and_errors.h>
|
#include <CGAL/Installation/internal/disable_deprecation_warnings_and_errors.h>
|
||||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||||
#include <CGAL/Barycentric_coordinates_2/triangle_coordinates_2.h>
|
#include <CGAL/Barycentric_coordinates_2/triangle_coordinates_2.h>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
#include <cmath>
|
|
||||||
#include <cassert>
|
|
||||||
#include <CGAL/Installation/internal/disable_deprecation_warnings_and_errors.h>
|
#include <CGAL/Installation/internal/disable_deprecation_warnings_and_errors.h>
|
||||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||||
#include <CGAL/Barycentric_coordinates_2/Wachspress_2.h>
|
#include <CGAL/Barycentric_coordinates_2/Wachspress_2.h>
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@
|
||||||
|
|
||||||
#include <CGAL/disable_warnings.h>
|
#include <CGAL/disable_warnings.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <CGAL/CORE/BigFloat.h>
|
#include <CGAL/CORE/BigFloat.h>
|
||||||
#include <CGAL/CORE/Expr.h>
|
#include <CGAL/CORE/Expr.h>
|
||||||
|
|
@ -1057,8 +1058,8 @@ void BigFloatRep :: fromString(const char *str, extLong prec ) {
|
||||||
CGAL_INLINE_FUNCTION
|
CGAL_INLINE_FUNCTION
|
||||||
std::istream& BigFloatRep :: operator >>(std::istream& i) {
|
std::istream& BigFloatRep :: operator >>(std::istream& i) {
|
||||||
int size = 20;
|
int size = 20;
|
||||||
char *str = new char[size];
|
std::string str;
|
||||||
char *p = str;
|
str.reserve(size);
|
||||||
char c;
|
char c;
|
||||||
int d = 0, e = 0, s = 0;
|
int d = 0, e = 0, s = 0;
|
||||||
// d=1 means dot is found
|
// d=1 means dot is found
|
||||||
|
|
@ -1084,7 +1085,7 @@ std::istream& BigFloatRep :: operator >>(std::istream& i) {
|
||||||
|
|
||||||
// the current content in "c" should be the first non-whitespace char
|
// the current content in "c" should be the first non-whitespace char
|
||||||
if (c == '-' || c == '+') {
|
if (c == '-' || c == '+') {
|
||||||
*p++ = c;
|
str += c;
|
||||||
i.get(c);
|
i.get(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1096,19 +1097,8 @@ std::istream& BigFloatRep :: operator >>(std::istream& i) {
|
||||||
// xxxx.xxxe+xxx.xxx:
|
// xxxx.xxxe+xxx.xxx:
|
||||||
if (e && (c == '.'))
|
if (e && (c == '.'))
|
||||||
break;
|
break;
|
||||||
if (p - str == size) {
|
|
||||||
char *t = str;
|
|
||||||
str = new char[size*2];
|
|
||||||
memcpy(str, t, size);
|
|
||||||
delete [] t;
|
|
||||||
p = str + size;
|
|
||||||
size *= 2;
|
|
||||||
}
|
|
||||||
#ifdef CGAL_CORE_DEBUG
|
|
||||||
CGAL_assertion((p-str) < size);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
*p++ = c;
|
str += c;
|
||||||
if (c == '.')
|
if (c == '.')
|
||||||
d = 1;
|
d = 1;
|
||||||
// Chen Li: fix a bug -- the sign of exponent can not happen before
|
// Chen Li: fix a bug -- the sign of exponent can not happen before
|
||||||
|
|
@ -1120,24 +1110,8 @@ std::istream& BigFloatRep :: operator >>(std::istream& i) {
|
||||||
e = 1;
|
e = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// chenli: make sure that the p is still in the range
|
|
||||||
if (p - str >= size) {
|
|
||||||
std::size_t len = p - str;
|
|
||||||
char *t = str;
|
|
||||||
str = new char[len + 1];
|
|
||||||
memcpy(str, t, len);
|
|
||||||
delete [] t;
|
|
||||||
p = str + len;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CGAL_CORE_DEBUG
|
|
||||||
CGAL_assertion(p - str < size);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
*p = '\0';
|
|
||||||
i.putback(c);
|
i.putback(c);
|
||||||
fromString(str);
|
fromString(str.c_str());
|
||||||
delete [] str;
|
|
||||||
return i;
|
return i;
|
||||||
}//operator >>
|
}//operator >>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -139,27 +139,6 @@ long gcd(long m, long n) {
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
// char* core_itoa(int n, char* buffer, int buffer_size)
|
|
||||||
// returns a pointer to the null-terminated string in buffer
|
|
||||||
// NOTES:
|
|
||||||
// 0. Buffer size should be 17 bytes (resp., 33 bytes, 65 bytes) on 16-bit
|
|
||||||
// (resp., 32-bit, 64-bit) machines. Formula: 1+sizeof(int)*8 bytes.
|
|
||||||
// 1. itoa(...) is available on some stdlib.h, but it is
|
|
||||||
// not defined by ANSI-C and so not all compilers support it.
|
|
||||||
// 2. Our use of sprintf(...) to do the job is known to
|
|
||||||
// be inefficient, but this is hardly critical for our usage.
|
|
||||||
// 3. A more general program should take a 3rd argument (the radix of
|
|
||||||
// output number). We assume radix 10.
|
|
||||||
CGAL_INLINE_FUNCTION
|
|
||||||
char * core_itoa(int n, char* buffer, int buffer_size) {
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
sprintf_s(buffer, buffer_size, "%d", n);
|
|
||||||
#else
|
|
||||||
CGAL_USE(buffer_size);
|
|
||||||
std::sprintf(buffer, "%d", n);
|
|
||||||
#endif
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// implements the "integer mantissa" function
|
/// implements the "integer mantissa" function
|
||||||
// (See CORE_PATH/progs/ieee/frexp.cpp for details)
|
// (See CORE_PATH/progs/ieee/frexp.cpp for details)
|
||||||
|
|
@ -197,11 +176,8 @@ void core_error(std::string msg, std::string file, int lineno, bool err) {
|
||||||
<< msg << std::endl;
|
<< msg << std::endl;
|
||||||
outFile.close();
|
outFile.close();
|
||||||
if (err) {
|
if (err) {
|
||||||
char buf[65];
|
|
||||||
// perror((std::string("CORE ERROR") + " (file " + file + ", line "
|
|
||||||
// + core_itoa(lineno,buf, 65) +"):" + msg + "\n").c_str());
|
|
||||||
std::cerr << (std::string("CORE ERROR") + " (file " + file + ", line "
|
std::cerr << (std::string("CORE ERROR") + " (file " + file + ", line "
|
||||||
+ core_itoa(lineno,buf, 65) +"):" + msg + "\n").c_str();
|
+ std::to_string(lineno) +"):" + msg + "\n").c_str();
|
||||||
std::exit(1); //Note: do not call abort()
|
std::exit(1); //Note: do not call abort()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@
|
||||||
|
|
||||||
#include <CGAL/disable_warnings.h>
|
#include <CGAL/disable_warnings.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <CGAL/CORE/Real.h>
|
#include <CGAL/CORE/Real.h>
|
||||||
#include <CGAL/tss.h>
|
#include <CGAL/tss.h>
|
||||||
|
|
@ -189,8 +190,9 @@ void Real::constructFromString(const char *str, const extLong& prec )
|
||||||
CGAL_INLINE_FUNCTION
|
CGAL_INLINE_FUNCTION
|
||||||
std::istream& operator >>(std::istream& i, Real& x) {
|
std::istream& operator >>(std::istream& i, Real& x) {
|
||||||
int size = 20;
|
int size = 20;
|
||||||
char *str = new char[size];
|
std::string str;
|
||||||
char *p = str;
|
str.reserve(size);
|
||||||
|
|
||||||
char c;
|
char c;
|
||||||
int d = 0, e = 0, s = 0;
|
int d = 0, e = 0, s = 0;
|
||||||
// int done = 0;
|
// int done = 0;
|
||||||
|
|
@ -211,13 +213,12 @@ std::istream& operator >>(std::istream& i, Real& x) {
|
||||||
|
|
||||||
if (i.eof()) {
|
if (i.eof()) {
|
||||||
i.clear(std::ios::eofbit | std::ios::failbit);
|
i.clear(std::ios::eofbit | std::ios::failbit);
|
||||||
delete [] str;
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
// the current content in "c" should be the first non-whitespace char
|
// the current content in "c" should be the first non-whitespace char
|
||||||
if (c == '-' || c == '+') {
|
if (c == '-' || c == '+') {
|
||||||
*p++ = c;
|
str += c;
|
||||||
i.get(c);
|
i.get(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -230,19 +231,9 @@ std::istream& operator >>(std::istream& i, Real& x) {
|
||||||
// xxxx.xxxe+xxx.xxx:
|
// xxxx.xxxe+xxx.xxx:
|
||||||
if (e && (c == '.'))
|
if (e && (c == '.'))
|
||||||
break;
|
break;
|
||||||
if (p - str == size) {
|
|
||||||
char *t = str;
|
|
||||||
str = new char[size*2];
|
|
||||||
std::memcpy(str, t, size);
|
|
||||||
delete [] t;
|
|
||||||
p = str + size;
|
|
||||||
size *= 2;
|
|
||||||
}
|
|
||||||
#ifdef CORE_DEBUG
|
|
||||||
CGAL_assertion((p-str) < size);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
*p++ = c;
|
str += c;
|
||||||
|
|
||||||
if (c == '.')
|
if (c == '.')
|
||||||
d = 1;
|
d = 1;
|
||||||
// Chen Li: fix a bug -- the sign of exponent can not happen before
|
// Chen Li: fix a bug -- the sign of exponent can not happen before
|
||||||
|
|
@ -255,29 +246,13 @@ std::istream& operator >>(std::istream& i, Real& x) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!i && !i.eof()) {
|
if (!i && !i.eof()) {
|
||||||
delete [] str;
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
// chenli: make sure that the p is still in the range
|
|
||||||
if (p - str >= size) {
|
|
||||||
std::ptrdiff_t len = p - str;
|
|
||||||
char *t = str;
|
|
||||||
str = new char[len + 1];
|
|
||||||
std::memcpy(str, t, len);
|
|
||||||
delete [] t;
|
|
||||||
p = str + len;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CORE_DEBUG
|
|
||||||
CGAL_assertion(p - str < size);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
*p = '\0';
|
|
||||||
i.putback(c);
|
i.putback(c);
|
||||||
i.clear();
|
i.clear();
|
||||||
// old: x = Real(str, i.precision()); // use precision of input stream.
|
// old: x = Real(str, i.precision()); // use precision of input stream.
|
||||||
x = Real(str); // default precision = get_static_defInputDigits()
|
x = Real(str.c_str()); // default precision = get_static_defInputDigits()
|
||||||
delete [] str;
|
|
||||||
return i;
|
return i;
|
||||||
}//operator >> (std::istream&, Real&)
|
}//operator >> (std::istream&, Real&)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,8 @@
|
||||||
#include <CGAL/constructions/kernel_ftC2.h>
|
#include <CGAL/constructions/kernel_ftC2.h>
|
||||||
#include <CGAL/constructions/kernel_ftC3.h>
|
#include <CGAL/constructions/kernel_ftC3.h>
|
||||||
#include <CGAL/Cartesian/solve_3.h>
|
#include <CGAL/Cartesian/solve_3.h>
|
||||||
|
#include <CGAL/Distance_3/Point_3_Point_3.h>
|
||||||
|
#include <CGAL/Distance_3/internal/squared_distance_utils_3.h>
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
|
|
@ -457,6 +459,103 @@ namespace CartesianKernelFunctors {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::Comparison_result
|
||||||
|
compare_distance_pssC3(const typename K::Point_3 &pt,
|
||||||
|
const typename K::Segment_3 &seg1,
|
||||||
|
const typename K::Segment_3 &seg2,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::Vector_3 Vector_3;
|
||||||
|
typedef typename K::RT RT;
|
||||||
|
typedef typename K::FT FT;
|
||||||
|
|
||||||
|
typename K::Construct_vector_3 construct_vector;
|
||||||
|
|
||||||
|
FT d1=FT(0), d2=FT(0);
|
||||||
|
RT e1 = RT(1), e2 = RT(1);
|
||||||
|
// assert that the segment is valid (non zero length).
|
||||||
|
{
|
||||||
|
Vector_3 diff = construct_vector(seg1.source(), pt);
|
||||||
|
Vector_3 segvec = construct_vector(seg1.source(), seg1.target());
|
||||||
|
RT d = CGAL::internal::wdot(diff,segvec, k);
|
||||||
|
if (d <= (RT)0){
|
||||||
|
d1 = (FT(diff*diff));
|
||||||
|
}else{
|
||||||
|
RT e = CGAL::internal::wdot(segvec,segvec, k);
|
||||||
|
if (d > e){
|
||||||
|
d1 = CGAL::internal::squared_distance(pt, seg1.target(), k);
|
||||||
|
} else{
|
||||||
|
Vector_3 wcr = CGAL::internal::wcross(segvec, diff, k);
|
||||||
|
d1 = FT(wcr*wcr);
|
||||||
|
e1 = e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Vector_3 diff = construct_vector(seg2.source(), pt);
|
||||||
|
Vector_3 segvec = construct_vector(seg2.source(), seg2.target());
|
||||||
|
RT d = CGAL::internal::wdot(diff,segvec, k);
|
||||||
|
if (d <= (RT)0){
|
||||||
|
d2 = (FT(diff*diff));
|
||||||
|
}else{
|
||||||
|
RT e = CGAL::internal::wdot(segvec,segvec, k);
|
||||||
|
if (d > e){
|
||||||
|
d2 = CGAL::internal::squared_distance(pt, seg2.target(), k);
|
||||||
|
} else{
|
||||||
|
Vector_3 wcr = CGAL::internal::wcross(segvec, diff, k);
|
||||||
|
d2 = FT(wcr*wcr);
|
||||||
|
e2 = e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return CGAL::compare(d1*e2, d2*e1);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::Comparison_result
|
||||||
|
compare_distance_ppsC3(const typename K::Point_3 &pt,
|
||||||
|
const typename K::Point_3 &pt2,
|
||||||
|
const typename K::Segment_3 &seg,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::Vector_3 Vector_3;
|
||||||
|
typedef typename K::RT RT;
|
||||||
|
typedef typename K::FT FT;
|
||||||
|
|
||||||
|
typename K::Construct_vector_3 construct_vector;
|
||||||
|
|
||||||
|
RT e2 = RT(1);
|
||||||
|
// assert that the segment is valid (non zero length).
|
||||||
|
FT d1 = CGAL::internal::squared_distance(pt, pt2, k);
|
||||||
|
FT d2 = FT(0);
|
||||||
|
{
|
||||||
|
Vector_3 diff = construct_vector(seg.source(), pt);
|
||||||
|
Vector_3 segvec = construct_vector(seg.source(), seg.target());
|
||||||
|
RT d = CGAL::internal::wdot(diff,segvec, k);
|
||||||
|
if (d <= (RT)0){
|
||||||
|
d2 = (FT(diff*diff));
|
||||||
|
}else{
|
||||||
|
RT e = CGAL::internal::wdot(segvec,segvec, k);
|
||||||
|
if (d > e){
|
||||||
|
d2 = CGAL::internal::squared_distance(pt, seg.target(), k);
|
||||||
|
} else{
|
||||||
|
Vector_3 wcr = CGAL::internal::wcross(segvec, diff, k);
|
||||||
|
d2 = FT(wcr*wcr);
|
||||||
|
e2 = e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return CGAL::compare(d1*e2, d2);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
template <typename K>
|
template <typename K>
|
||||||
class Compare_distance_3
|
class Compare_distance_3
|
||||||
{
|
{
|
||||||
|
|
@ -476,19 +575,19 @@ namespace CartesianKernelFunctors {
|
||||||
result_type
|
result_type
|
||||||
operator()(const Point_3& p1, const Segment_3& s1, const Segment_3& s2) const
|
operator()(const Point_3& p1, const Segment_3& s1, const Segment_3& s2) const
|
||||||
{
|
{
|
||||||
return CGAL::internal::compare_distance_pssC3(p1,s1,s2, K());
|
return internal::compare_distance_pssC3(p1,s1,s2, K());
|
||||||
}
|
}
|
||||||
|
|
||||||
result_type
|
result_type
|
||||||
operator()(const Point_3& p1, const Point_3& p2, const Segment_3& s2) const
|
operator()(const Point_3& p1, const Point_3& p2, const Segment_3& s2) const
|
||||||
{
|
{
|
||||||
return CGAL::internal::compare_distance_ppsC3(p1,p2,s2, K());
|
return internal::compare_distance_ppsC3(p1,p2,s2, K());
|
||||||
}
|
}
|
||||||
|
|
||||||
result_type
|
result_type
|
||||||
operator()(const Point_3& p1, const Segment_3& s2, const Point_3& p2) const
|
operator()(const Point_3& p1, const Segment_3& s2, const Point_3& p2) const
|
||||||
{
|
{
|
||||||
return opposite(CGAL::internal::compare_distance_ppsC3(p1,p2,s2, K()));
|
return opposite(internal::compare_distance_ppsC3(p1,p2,s2, K()));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T1, class T2, class T3>
|
template <class T1, class T2, class T3>
|
||||||
|
|
@ -3242,8 +3341,17 @@ namespace CartesianKernelFunctors {
|
||||||
typedef typename K::Segment_3 Segment_3;
|
typedef typename K::Segment_3 Segment_3;
|
||||||
typedef typename K::Ray_3 Ray_3;
|
typedef typename K::Ray_3 Ray_3;
|
||||||
typedef typename K::FT FT;
|
typedef typename K::FT FT;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef Point_3 result_type;
|
template<typename>
|
||||||
|
struct result {
|
||||||
|
typedef const Point_3 type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename F>
|
||||||
|
struct result<F(Point_3, Point_3)> {
|
||||||
|
typedef const Point_3& type;
|
||||||
|
};
|
||||||
|
|
||||||
Point_3
|
Point_3
|
||||||
operator()( const Line_3& l, const Point_3& p ) const
|
operator()( const Line_3& l, const Point_3& p ) const
|
||||||
|
|
@ -3270,15 +3378,19 @@ namespace CartesianKernelFunctors {
|
||||||
|
|
||||||
Point_3
|
Point_3
|
||||||
operator()( const Triangle_3& t, const Point_3& p ) const
|
operator()( const Triangle_3& t, const Point_3& p ) const
|
||||||
{ return CommonKernelFunctors::Construct_projected_point_3<K>()(p,t,K()); }
|
{ return CommonKernelFunctors::Construct_projected_point_3<K>()(t,p,K()); }
|
||||||
|
|
||||||
Point_3
|
Point_3
|
||||||
operator()( const Segment_3& s, const Point_3& p ) const
|
operator()( const Segment_3& s, const Point_3& p ) const
|
||||||
{ return CommonKernelFunctors::Construct_projected_point_3<K>()(p,s,K()); }
|
{ return CommonKernelFunctors::Construct_projected_point_3<K>()(s,p,K()); }
|
||||||
|
|
||||||
Point_3
|
Point_3
|
||||||
operator()( const Ray_3& r, const Point_3& p ) const
|
operator()( const Ray_3& r, const Point_3& p ) const
|
||||||
{ return CommonKernelFunctors::Construct_projected_point_3<K>()(p,r,K()); }
|
{ return CommonKernelFunctors::Construct_projected_point_3<K>()(r,p,K()); }
|
||||||
|
|
||||||
|
const Point_3&
|
||||||
|
operator()( const Point_3& p, const Point_3& q) const
|
||||||
|
{ return CommonKernelFunctors::Construct_projected_point_3<K>()(p,q,K()); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class K>
|
template <class K>
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
4 data/n9.cin
|
|
||||||
|
|
@ -26,26 +26,37 @@ typedef boost::adjacency_list<boost::listS,
|
||||||
|
|
||||||
int main(int argc, char ** argv)
|
int main(int argc, char ** argv)
|
||||||
{
|
{
|
||||||
if (argc < 3) {
|
unsigned int k=4; // By default, no. of cones==4
|
||||||
|
std::string filename="data/n9.cin"; // file used by default
|
||||||
|
|
||||||
|
if (argc > 1 &&
|
||||||
|
(!strcmp(argv[1],"-h") || !strcmp(argv[1],"--help") || !strcmp(argv[1],"-?")))
|
||||||
|
{
|
||||||
std::cout << "Usage: " << argv[0] << " <no. of cones> <input filename> [<direction-x> <direction-y>]" << std::endl;
|
std::cout << "Usage: " << argv[0] << " <no. of cones> <input filename> [<direction-x> <direction-y>]" << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int k = atoi(argv[1]);
|
if (argc > 1)
|
||||||
if (k<2) {
|
{
|
||||||
std::cout << "The number of cones should be larger than 1!" << std::endl;
|
k = atoi(argv[1]);
|
||||||
return 1;
|
if (k<2) {
|
||||||
|
std::cout << "The number of cones should be larger than 1!" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (argc > 2)
|
||||||
|
{ filename=std::string(argv[2]); }
|
||||||
|
|
||||||
// open the file containing the vertex list
|
// open the file containing the vertex list
|
||||||
std::ifstream inf(argv[2]);
|
std::ifstream inf(filename);
|
||||||
if (!inf) {
|
if (!inf) {
|
||||||
std::cout << "Cannot open file " << argv[2] << "!" << std::endl;
|
std::cout << "Cannot open file " << filename << "!" << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Direction_2 initial_direction;
|
Direction_2 initial_direction;
|
||||||
if (argc == 3)
|
if (argc == 1 || argc == 3)
|
||||||
initial_direction = Direction_2(1, 0); // default initial_direction
|
initial_direction = Direction_2(1, 0); // default initial_direction
|
||||||
else if (argc == 5)
|
else if (argc == 5)
|
||||||
initial_direction = Direction_2(atof(argv[3]), atof(argv[4]));
|
initial_direction = Direction_2(atof(argv[3]), atof(argv[4]));
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
#include <CGAL/license/Cone_spanners_2.h>
|
#include <CGAL/license/Cone_spanners_2.h>
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
@ -134,9 +134,8 @@ public:
|
||||||
_Leaf (const key_compare& less, const value_compare& vless, tree_type *const t,
|
_Leaf (const key_compare& less, const value_compare& vless, tree_type *const t,
|
||||||
_leaf_type *const prev = nullptr,
|
_leaf_type *const prev = nullptr,
|
||||||
_leaf_type *const next = nullptr)
|
_leaf_type *const next = nullptr)
|
||||||
: _node_type (less, vless, t), prev (prev), next (next) {
|
: _node_type (less, vless, t), values({nullptr,nullptr}), prev (prev), next (next)
|
||||||
std::memset (values, 0, 2*sizeof(value_type*));
|
{}
|
||||||
}
|
|
||||||
|
|
||||||
/* Destructor.
|
/* Destructor.
|
||||||
* Frees memory used for storing key-value pair, thus invalidating any
|
* Frees memory used for storing key-value pair, thus invalidating any
|
||||||
|
|
@ -242,7 +241,7 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/* Key-value pairs */
|
/* Key-value pairs */
|
||||||
value_type* values[2];
|
std::array<value_type*,2> values;
|
||||||
|
|
||||||
/* Linked list structure of the B+ tree */
|
/* Linked list structure of the B+ tree */
|
||||||
_leaf_type* prev;
|
_leaf_type* prev;
|
||||||
|
|
@ -268,11 +267,8 @@ public:
|
||||||
typedef typename _node_type::tree_type tree_type;
|
typedef typename _node_type::tree_type tree_type;
|
||||||
|
|
||||||
_Internal (const Comp& less, const VComp& vless, tree_type *const t)
|
_Internal (const Comp& less, const VComp& vless, tree_type *const t)
|
||||||
: _node_type(less, vless, t) {
|
: _node_type(less, vless, t), keys({nullptr, nullptr}), children({nullptr, nullptr, nullptr}), vMin({nullptr, nullptr, nullptr})
|
||||||
std::memset (keys, 0, 2*sizeof(key_type*));
|
{}
|
||||||
std::memset (children, 0, 3*sizeof(_node_type*));
|
|
||||||
std::memset (vMin, 0, 3*sizeof(mapped_type*));
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~_Internal() {
|
virtual ~_Internal() {
|
||||||
keys[0] = nullptr;
|
keys[0] = nullptr;
|
||||||
|
|
@ -492,9 +488,9 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const key_type* keys[2];
|
std::array<const key_type*, 2> keys;
|
||||||
_node_type* children[3];
|
std::array< _node_type*, 3> children;
|
||||||
const mapped_type* vMin[3];
|
std::array<const mapped_type*, 3> vMin;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Key, typename T, typename Comp, typename VComp >
|
template <typename Key, typename T, typename Comp, typename VComp >
|
||||||
|
|
|
||||||
|
|
@ -212,7 +212,7 @@ template<typename Nef_, typename FTComparison, typename Container>
|
||||||
SNC_point_locator* pl;
|
SNC_point_locator* pl;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Edge_sorter(Container& cin) : c(cin) {}
|
Edge_sorter(Container& cin) : c(cin), sncp(nullptr), pl(nullptr) {}
|
||||||
|
|
||||||
void operator()(SNC_and_PL& sncpl) {
|
void operator()(SNC_and_PL& sncpl) {
|
||||||
sncp = sncpl.sncp;
|
sncp = sncpl.sncp;
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,8 @@ class Ray_hit_generator2 : public Modifier_base<typename Nef_::SNC_and_PL> {
|
||||||
bool vertex_added;
|
bool vertex_added;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Ray_hit_generator2(Vector_3 d, Vertex_handle v) : dir(d), vs(v) {}
|
Ray_hit_generator2(Vector_3 d, Vertex_handle v)
|
||||||
|
: dir(d), vs(v), sncp(nullptr), pl(nullptr), edge_splitted(false), vertex_added(false) {}
|
||||||
|
|
||||||
Vertex_handle create_vertex_on_first_hit(const Ray_3& r) {
|
Vertex_handle create_vertex_on_first_hit(const Ray_3& r) {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ class Single_wall_creator : public Modifier_base<typename Nef_::SNC_and_PL> {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Single_wall_creator(SVertex_handle e, Vector_3 d)
|
Single_wall_creator(SVertex_handle e, Vector_3 d)
|
||||||
: ein(e), dir(d)
|
: ein(e), dir(d), sncp(nullptr), pl(nullptr)
|
||||||
#ifndef CGAL_NEF_NO_INDEXED_ITEMS
|
#ifndef CGAL_NEF_NO_INDEXED_ITEMS
|
||||||
, index1(0), index2(0)
|
, index1(0), index2(0)
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -359,6 +359,8 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Uncertain_conversion_exception&){}
|
catch (Uncertain_conversion_exception&){}
|
||||||
|
Protector protector(CGAL_FE_TONEAREST);
|
||||||
|
CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST);
|
||||||
if (ek_plane_ptr==nullptr) {
|
if (ek_plane_ptr==nullptr) {
|
||||||
const typename Exact_K::Point_3 ep = to_EK(p);
|
const typename Exact_K::Point_3 ep = to_EK(p);
|
||||||
ek_plane_ptr = new Vector_plus_point<Exact_K>;
|
ek_plane_ptr = new Vector_plus_point<Exact_K>;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
OFF
|
||||||
|
4 4 0
|
||||||
|
0.0 0.0 0.0
|
||||||
|
1.0 0.0 0.0
|
||||||
|
0.0 1.0 0.0
|
||||||
|
0.0 0.0 1.0
|
||||||
|
3 0 1 2
|
||||||
|
3 0 3 1
|
||||||
|
3 0 2 3
|
||||||
|
3 1 3 2
|
||||||
|
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
// Copyright (c) 1998-2004
|
||||||
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org)
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Geert-Jan Giezeman
|
||||||
|
// Michel Hoffmann <hoffmann@inf.ethz.ch>
|
||||||
|
// Andreas Fabri <Andreas.Fabri@geometryfactory.com>
|
||||||
|
|
||||||
|
#ifndef CGAL_DISTANCE_2_LINE_2_LINE_2_H
|
||||||
|
#define CGAL_DISTANCE_2_LINE_2_LINE_2_H
|
||||||
|
|
||||||
|
#include <CGAL/Distance_2/internal/squared_distance_utils_2.h>
|
||||||
|
|
||||||
|
#include <CGAL/Kernel/global_functions.h>
|
||||||
|
#include <CGAL/Line_2.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const typename K::Line_2& line1,
|
||||||
|
const typename K::Line_2& line2,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::FT FT;
|
||||||
|
|
||||||
|
typename K::Compute_squared_distance_2 sq_dist = k.compute_squared_distance_2_object();
|
||||||
|
|
||||||
|
if(internal::parallel(line1, line2, k))
|
||||||
|
return sq_dist(line1.point(), line2);
|
||||||
|
else
|
||||||
|
return FT(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const Line_2<K>& line1,
|
||||||
|
const Line_2<K>& line2)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_2_object()(line1, line2);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_DISTANCE_2_LINE_2_LINE_2_H
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
// Copyright (c) 1998-2004
|
||||||
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org)
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Geert-Jan Giezeman
|
||||||
|
// Michel Hoffmann <hoffmann@inf.ethz.ch>
|
||||||
|
// Andreas Fabri <Andreas.Fabri@geometryfactory.com>
|
||||||
|
|
||||||
|
#ifndef CGAL_DISTANCE_2_LINE_2_TRIANGLE_2_H
|
||||||
|
#define CGAL_DISTANCE_2_LINE_2_TRIANGLE_2_H
|
||||||
|
|
||||||
|
#include <CGAL/Distance_2/internal/squared_distance_utils_2.h>
|
||||||
|
|
||||||
|
#include <CGAL/enum.h>
|
||||||
|
|
||||||
|
#include <CGAL/Line_2.h>
|
||||||
|
#include <CGAL/Triangle_2.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const typename K::Line_2& line,
|
||||||
|
const typename K::Triangle_2& triangle,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::FT FT;
|
||||||
|
|
||||||
|
typename K::Compute_squared_distance_2 sq_dist = k.compute_squared_distance_2_object();
|
||||||
|
|
||||||
|
const Oriented_side side0 = line.oriented_side(triangle.vertex(0));
|
||||||
|
if(line.oriented_side(triangle.vertex(1)) != side0)
|
||||||
|
return FT(0);
|
||||||
|
|
||||||
|
if(line.oriented_side(triangle.vertex(2)) != side0)
|
||||||
|
return FT(0);
|
||||||
|
|
||||||
|
FT mindist = sq_dist(triangle.vertex(0), line);
|
||||||
|
for(int i=1; i<3; ++i)
|
||||||
|
{
|
||||||
|
FT dist = sq_dist(triangle.vertex(i), line);
|
||||||
|
if(dist < mindist)
|
||||||
|
mindist = dist;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mindist;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const typename K::Triangle_2& triangle,
|
||||||
|
const typename K::Line_2& line,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
return internal::squared_distance(line, triangle, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const Line_2<K>& line,
|
||||||
|
const Triangle_2<K>& triangle)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_2_object()(line, triangle);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const Triangle_2<K>& triangle,
|
||||||
|
const Line_2<K>& line)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_2_object()(triangle, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_DISTANCE_2_LINE_2_TRIANGLE_2_H
|
||||||
|
|
@ -0,0 +1,108 @@
|
||||||
|
// Copyright (c) 1998-2004
|
||||||
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org)
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Geert-Jan Giezeman
|
||||||
|
// Michel Hoffmann <hoffmann@inf.ethz.ch>
|
||||||
|
// Andreas Fabri <Andreas.Fabri@geometryfactory.com>
|
||||||
|
|
||||||
|
#ifndef CGAL_DISTANCE_2_POINT_2_LINE_2_H
|
||||||
|
#define CGAL_DISTANCE_2_POINT_2_LINE_2_H
|
||||||
|
|
||||||
|
#include <CGAL/Rational_traits.h>
|
||||||
|
#include <CGAL/number_utils.h>
|
||||||
|
#include <CGAL/tags.h>
|
||||||
|
|
||||||
|
#include <CGAL/Line_2.h>
|
||||||
|
#include <CGAL/Point_2.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const typename K::Point_2& pt,
|
||||||
|
const typename K::Line_2& line,
|
||||||
|
const K&,
|
||||||
|
const Homogeneous_tag&)
|
||||||
|
{
|
||||||
|
typedef typename K::RT RT;
|
||||||
|
typedef typename K::FT FT;
|
||||||
|
|
||||||
|
const RT& a = line.a();
|
||||||
|
const RT& b = line.b();
|
||||||
|
const RT& w = pt.hw();
|
||||||
|
RT n = a*pt.hx() + b*pt.hy() + w*line.c();
|
||||||
|
RT d = (CGAL_NTS square(a) + CGAL_NTS square(b)) * CGAL_NTS square(w);
|
||||||
|
|
||||||
|
return Rational_traits<FT>().make_rational(CGAL_NTS square(n), d);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const typename K::Point_2& pt,
|
||||||
|
const typename K::Line_2& line,
|
||||||
|
const K&,
|
||||||
|
const Cartesian_tag&)
|
||||||
|
{
|
||||||
|
typedef typename K::FT FT;
|
||||||
|
|
||||||
|
const FT& a = line.a();
|
||||||
|
const FT& b = line.b();
|
||||||
|
FT n = a*pt.x() + b*pt.y() + line.c();
|
||||||
|
FT d = CGAL_NTS square(a) + CGAL_NTS square(b);
|
||||||
|
|
||||||
|
return CGAL_NTS square(n)/d;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const typename K::Point_2& pt,
|
||||||
|
const typename K::Line_2& line,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::Kernel_tag Tag;
|
||||||
|
Tag tag;
|
||||||
|
return squared_distance(pt, line, k, tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const typename K::Line_2& line,
|
||||||
|
const typename K::Point_2& pt,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
return internal::squared_distance(pt, line, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const Point_2<K>& pt,
|
||||||
|
const Line_2<K>& line)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_2_object()(pt, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const Line_2<K>& line,
|
||||||
|
const Point_2<K>& pt)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_2_object()(line, pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_DISTANCE_2_POINT_2_LINE_2_H
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
// Copyright (c) 1998-2004
|
||||||
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org)
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Geert-Jan Giezeman
|
||||||
|
// Michel Hoffmann <hoffmann@inf.ethz.ch>
|
||||||
|
// Andreas Fabri <Andreas.Fabri@geometryfactory.com>
|
||||||
|
|
||||||
|
#ifndef CGAL_DISTANCE_2_POINT_2_POINT_2_H
|
||||||
|
#define CGAL_DISTANCE_2_POINT_2_POINT_2_H
|
||||||
|
|
||||||
|
#include <CGAL/Point_2.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const typename K::Point_2& pt1,
|
||||||
|
const typename K::Point_2& pt2,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typename K::Vector_2 vec = k.construct_vector_2_object()(pt2, pt1);
|
||||||
|
return k.compute_squared_length_2_object()(vec);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const Point_2<K>& pt1,
|
||||||
|
const Point_2<K>& pt2)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_2_object()(pt1, pt2);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_DISTANCE_2_POINT_2_POINT_2_H
|
||||||
|
|
@ -0,0 +1,108 @@
|
||||||
|
// Copyright (c) 1998-2004
|
||||||
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org)
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Geert-Jan Giezeman
|
||||||
|
// Michel Hoffmann <hoffmann@inf.ethz.ch>
|
||||||
|
// Andreas Fabri <Andreas.Fabri@geometryfactory.com>
|
||||||
|
|
||||||
|
#ifndef CGAL_DISTANCE_2_POINT_2_RAY_2_H
|
||||||
|
#define CGAL_DISTANCE_2_POINT_2_RAY_2_H
|
||||||
|
|
||||||
|
#include <CGAL/Distance_2/internal/squared_distance_utils_2.h>
|
||||||
|
#include <CGAL/Distance_2/Point_2_Line_2.h>
|
||||||
|
|
||||||
|
#include <CGAL/Point_2.h>
|
||||||
|
#include <CGAL/Ray_2.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
void
|
||||||
|
distance_index(int &ind,
|
||||||
|
const typename K::Point_2 &pt,
|
||||||
|
const typename K::Ray_2 &ray,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typename K::Construct_vector_2 construct_vector = k.construct_vector_2_object();
|
||||||
|
if(!is_acute_angle(ray.direction().vector(), construct_vector(ray.source(), pt), k))
|
||||||
|
{
|
||||||
|
ind = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ind = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance_indexed(const typename K::Point_2 &pt,
|
||||||
|
const typename K::Ray_2 &ray,
|
||||||
|
int ind,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
if(ind == 0)
|
||||||
|
return internal::squared_distance(pt, ray.source(), k);
|
||||||
|
|
||||||
|
return internal::squared_distance(pt, ray.supporting_line(), k);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const typename K::Point_2& pt,
|
||||||
|
const typename K::Ray_2& ray,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::Vector_2 Vector_2;
|
||||||
|
|
||||||
|
typename K::Construct_vector_2 construct_vector = k.construct_vector_2_object();
|
||||||
|
|
||||||
|
Vector_2 diff = construct_vector(ray.source(), pt);
|
||||||
|
const Vector_2& dir = ray.direction().vector();
|
||||||
|
if (!is_acute_angle(dir, diff, k))
|
||||||
|
return k.compute_squared_length_2_object()(diff);
|
||||||
|
|
||||||
|
return internal::squared_distance(pt, ray.supporting_line(), k);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const typename K::Ray_2& ray,
|
||||||
|
const typename K::Point_2& pt,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
return internal::squared_distance(pt, ray, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const Point_2<K>& pt,
|
||||||
|
const Ray_2<K>& ray)
|
||||||
|
{
|
||||||
|
return internal::squared_distance(pt, ray, K());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const Ray_2<K>& ray,
|
||||||
|
const Point_2<K>& pt)
|
||||||
|
{
|
||||||
|
return internal::squared_distance(pt, ray, K());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_DISTANCE_2_POINT_2_RAY_2_H
|
||||||
|
|
@ -0,0 +1,126 @@
|
||||||
|
// Copyright (c) 1998-2004
|
||||||
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org)
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Geert-Jan Giezeman
|
||||||
|
// Michel Hoffmann <hoffmann@inf.ethz.ch>
|
||||||
|
// Andreas Fabri <Andreas.Fabri@geometryfactory.com>
|
||||||
|
|
||||||
|
#ifndef CGAL_DISTANCE_2_POINT_2_SEGMENT_2_H
|
||||||
|
#define CGAL_DISTANCE_2_POINT_2_SEGMENT_2_H
|
||||||
|
|
||||||
|
#include <CGAL/Distance_2/internal/squared_distance_utils_2.h>
|
||||||
|
|
||||||
|
#include <CGAL/Point_2.h>
|
||||||
|
#include <CGAL/Segment_2.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
void
|
||||||
|
distance_index(int &ind,
|
||||||
|
const typename K::Point_2 &pt,
|
||||||
|
const typename K::Segment_2 &seg,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
if(!is_acute_angle(seg.target(),seg.source(),pt, k))
|
||||||
|
{
|
||||||
|
ind = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!is_acute_angle(seg.source(),seg.target(),pt, k))
|
||||||
|
{
|
||||||
|
ind = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ind = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance_indexed(const typename K::Point_2 &pt,
|
||||||
|
const typename K::Segment_2 &seg,
|
||||||
|
int ind,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typename K::Compute_squared_distance_2 sq_dist = k.compute_squared_distance_2_object();
|
||||||
|
|
||||||
|
if(ind == 0)
|
||||||
|
return sq_dist(pt, seg.source());
|
||||||
|
|
||||||
|
if(ind == 1)
|
||||||
|
return sq_dist(pt, seg.target());
|
||||||
|
|
||||||
|
return sq_dist(pt, seg.supporting_line());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const typename K::Point_2& pt,
|
||||||
|
const typename K::Segment_2& seg,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::Vector_2 Vector_2;
|
||||||
|
typedef typename K::RT RT;
|
||||||
|
|
||||||
|
typename K::Construct_vector_2 vector = k.construct_vector_2_object();
|
||||||
|
typename K::Compute_squared_length_2 sq_length = k.compute_squared_length_2_object();
|
||||||
|
typename K::Compute_squared_distance_2 sq_dist = k.compute_squared_distance_2_object();
|
||||||
|
|
||||||
|
// assert that the segment is valid (non zero length).
|
||||||
|
const Vector_2 diff = vector(seg.source(), pt);
|
||||||
|
const Vector_2 segvec = vector(seg.source(), seg.target());
|
||||||
|
|
||||||
|
const RT d = wdot(diff, segvec, k);
|
||||||
|
if(d <= RT(0))
|
||||||
|
return sq_length(diff);
|
||||||
|
|
||||||
|
const RT e = wdot(segvec,segvec, k);
|
||||||
|
if(wmult((K*)0 ,d, segvec.hw()) > wmult((K*)0, e, diff.hw()))
|
||||||
|
return sq_dist(pt, seg.target());
|
||||||
|
|
||||||
|
return sq_dist(pt, seg.supporting_line());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const typename K::Segment_2& seg,
|
||||||
|
const typename K::Point_2& pt,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
return internal::squared_distance(pt, seg, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const Point_2<K>& pt,
|
||||||
|
const Segment_2<K>& seg)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_2_object()(pt, seg);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const Segment_2<K>& seg,
|
||||||
|
const Point_2<K>& pt)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_2_object()(seg, pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_DISTANCE_2_POINT_2_SEGMENT_2_H
|
||||||
|
|
@ -0,0 +1,266 @@
|
||||||
|
// Copyright (c) 1998-2004
|
||||||
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org)
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Geert-Jan Giezeman
|
||||||
|
// Michel Hoffmann <hoffmann@inf.ethz.ch>
|
||||||
|
// Andreas Fabri <Andreas.Fabri@geometryfactory.com>
|
||||||
|
|
||||||
|
#ifndef CGAL_DISTANCE_2_POINT_2_TRIANGLE_2_H
|
||||||
|
#define CGAL_DISTANCE_2_POINT_2_TRIANGLE_2_H
|
||||||
|
|
||||||
|
#include <CGAL/Distance_2/internal/squared_distance_utils_2.h>
|
||||||
|
|
||||||
|
#include <CGAL/Point_2.h>
|
||||||
|
#include <CGAL/Triangle_2.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
void
|
||||||
|
distance_index(int &ind1,
|
||||||
|
int &ind2,
|
||||||
|
const typename K::Point_2 &pt,
|
||||||
|
const typename K::Triangle_2 &triangle,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::Point_2 Point_2;
|
||||||
|
|
||||||
|
typename K::Left_turn_2 leftturn = k.left_turn_2_object();
|
||||||
|
|
||||||
|
const Point_2& vt0 = triangle.vertex(0);
|
||||||
|
const Point_2& vt1 = triangle.vertex(1);
|
||||||
|
const Point_2& vt2 = triangle.vertex(2);
|
||||||
|
|
||||||
|
if(leftturn(vt0, vt1, vt2)) {
|
||||||
|
if(leftturn(pt, vt1, vt0)) {
|
||||||
|
if(!is_acute_angle(vt0, vt1, pt, k)) {
|
||||||
|
if(leftturn(pt, vt2, vt1)) {
|
||||||
|
if(!is_acute_angle(vt1, vt2, pt, k)) {
|
||||||
|
ind1 = 2; ind2 = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(!is_acute_angle(vt2, vt1, pt, k)) {
|
||||||
|
ind1 = 1; ind2 = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ind1 = 1; ind2 = 2;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ind1 = 1; ind2 = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(!is_acute_angle(vt1, vt0, pt, k)) {
|
||||||
|
if(leftturn(pt, vt0, vt2)) {
|
||||||
|
if(!is_acute_angle(vt0, vt2, pt, k)) {
|
||||||
|
ind1 = 2; ind2 = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(!is_acute_angle(vt2, vt0, pt, k)) {
|
||||||
|
ind1 = 0; ind2 = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ind1 = 2; ind2 = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ind1 = 0; ind2 = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ind1 = 0; ind2 = 1;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
if(leftturn(pt, vt2, vt1)) {
|
||||||
|
if(!is_acute_angle(vt1, vt2, pt, k)) {
|
||||||
|
if(leftturn(pt, vt0, vt2)) {
|
||||||
|
if(!is_acute_angle(vt0, vt2, pt, k)) {
|
||||||
|
ind1 = 2; ind2 = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(!is_acute_angle(vt2, vt0, pt, k)) {
|
||||||
|
ind1 = 0; ind2 = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ind1 = 2; ind2 = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ind1 = 0; ind2 = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(!is_acute_angle(vt2, vt1, pt, k)) {
|
||||||
|
ind1 = 1; ind2 = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ind1 = 1; ind2 = 2;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
if(leftturn(pt, vt0, vt2)) {
|
||||||
|
if(!is_acute_angle(vt2, vt0, pt, k)) {
|
||||||
|
ind1 = 0; ind2 = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(!is_acute_angle(vt0, vt2, pt, k)) {
|
||||||
|
ind1 = 2; ind2 = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ind1 = 2; ind2 = 0;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
ind1 = -1; ind2 = -1; // point inside or on boundary.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(leftturn(pt, vt2, vt0)) {
|
||||||
|
if(!is_acute_angle(vt0, vt2, pt, k)) {
|
||||||
|
if(leftturn(pt, vt1, vt2)) {
|
||||||
|
if(!is_acute_angle(vt2, vt1, pt, k)) {
|
||||||
|
ind1 = 1; ind2 = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(!is_acute_angle(vt1, vt2, pt, k)) {
|
||||||
|
ind1 = 2; ind2 = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ind1 = 2; ind2 = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ind1 = 2; ind2 = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(!is_acute_angle(vt2, vt0, pt, k)) {
|
||||||
|
if(leftturn(pt, vt0, vt1)) {
|
||||||
|
if(!is_acute_angle(vt0, vt1, pt, k)) {
|
||||||
|
ind1 = 1; ind2 = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(!is_acute_angle(vt1, vt0, pt, k)) {
|
||||||
|
ind1 = 0; ind2 = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ind1 = 1; ind2 = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ind1 = 0; ind2 = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ind1 = 0; ind2 = 2;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
if(leftturn(pt, vt1, vt2)) {
|
||||||
|
if(!is_acute_angle(vt2, vt1, pt, k)) {
|
||||||
|
if(leftturn(pt, vt0, vt1)) {
|
||||||
|
if(!is_acute_angle(vt0, vt1, pt, k)) {
|
||||||
|
ind1 = 1; ind2 = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(!is_acute_angle(vt1, vt0, pt, k)) {
|
||||||
|
ind1 = 0; ind2 = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ind1 = 1; ind2 = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ind1 = 0; ind2 = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(!is_acute_angle(vt1, vt2, pt, k)) {
|
||||||
|
ind1 = 2; ind2 = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ind1 = 2; ind2 = 1;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
if(leftturn(pt, vt0, vt1)) {
|
||||||
|
if(!is_acute_angle(vt1, vt0, pt, k)) {
|
||||||
|
ind1 = 0; ind2 = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(!is_acute_angle(vt0, vt1, pt, k)) {
|
||||||
|
ind1 = 1; ind2 = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ind1 = 1; ind2 = 0;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
ind1 = -1; ind2 = -1; // point inside or on boundary.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance_indexed(const typename K::Point_2& pt,
|
||||||
|
const typename K::Triangle_2& triangle,
|
||||||
|
int ind1, int ind2,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::FT FT;
|
||||||
|
typedef typename K::Line_2 Line_2;
|
||||||
|
|
||||||
|
typename K::Compute_squared_distance_2 sq_dist = k.compute_squared_distance_2_object();
|
||||||
|
|
||||||
|
if(ind1 == -1)
|
||||||
|
return FT(0);
|
||||||
|
|
||||||
|
if(ind2 == -1)
|
||||||
|
return sq_dist(pt, triangle.vertex(ind1));
|
||||||
|
|
||||||
|
return sq_dist(pt, Line_2{triangle.vertex(ind1), triangle.vertex(ind2)});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const typename K::Point_2& pt,
|
||||||
|
const typename K::Triangle_2& triangle,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
int ind1, ind2;
|
||||||
|
distance_index<K>(ind1, ind2, pt, triangle, k);
|
||||||
|
return squared_distance_indexed(pt, triangle, ind1, ind2, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const typename K::Triangle_2& triangle,
|
||||||
|
const typename K::Point_2& pt,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
return internal::squared_distance(pt, triangle, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const Point_2<K>& pt,
|
||||||
|
const Triangle_2<K>& triangle)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_2_object()(pt, triangle);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const Triangle_2<K>& triangle,
|
||||||
|
const Point_2<K>& pt)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_2_object()(triangle, pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_DISTANCE_2_POINT_2_TRIANGLE_2_H
|
||||||
|
|
@ -0,0 +1,88 @@
|
||||||
|
// Copyright (c) 1998-2004
|
||||||
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org)
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Geert-Jan Giezeman
|
||||||
|
// Michel Hoffmann <hoffmann@inf.ethz.ch>
|
||||||
|
// Andreas Fabri <Andreas.Fabri@geometryfactory.com>
|
||||||
|
|
||||||
|
#ifndef CGAL_DISTANCE_2_RAY_2_LINE_2_H
|
||||||
|
#define CGAL_DISTANCE_2_RAY_2_LINE_2_H
|
||||||
|
|
||||||
|
#include <CGAL/Distance_2/internal/squared_distance_utils_2.h>
|
||||||
|
|
||||||
|
#include <CGAL/Line_2.h>
|
||||||
|
#include <CGAL/Ray_2.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const typename K::Line_2& line,
|
||||||
|
const typename K::Ray_2& ray,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::FT FT;
|
||||||
|
typedef typename K::Vector_2 Vector_2;
|
||||||
|
|
||||||
|
typename K::Construct_vector_2 construct_vector = k.construct_vector_2_object();
|
||||||
|
|
||||||
|
Vector_2 normalvec(line.a(), line.b());
|
||||||
|
Vector_2 diff = construct_vector(line.point(), ray.source());
|
||||||
|
|
||||||
|
FT sign_dist = k.compute_scalar_product_2_object()(diff, normalvec);
|
||||||
|
if(sign_dist < FT(0))
|
||||||
|
{
|
||||||
|
if(is_acute_angle(normalvec, ray.direction().vector(), k))
|
||||||
|
return FT(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(is_obtuse_angle(normalvec, ray.direction().vector(), k))
|
||||||
|
return FT(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (square(sign_dist) / k.compute_squared_length_2_object()(normalvec));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const typename K::Ray_2& ray,
|
||||||
|
const typename K::Line_2& line,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
return internal::squared_distance(line, ray, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const Line_2<K>& line,
|
||||||
|
const Ray_2<K>& ray)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_2_object()(line, ray);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const Ray_2<K>& ray,
|
||||||
|
const Line_2<K>& line)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_2_object()(ray, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_DISTANCE_2_RAY_2_LINE_2_H
|
||||||
|
|
@ -0,0 +1,115 @@
|
||||||
|
// Copyright (c) 1998-2004
|
||||||
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org)
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Geert-Jan Giezeman
|
||||||
|
// Michel Hoffmann <hoffmann@inf.ethz.ch>
|
||||||
|
// Andreas Fabri <Andreas.Fabri@geometryfactory.com>
|
||||||
|
|
||||||
|
#ifndef CGAL_DISTANCE_2_RAY_2_RAY_2_H
|
||||||
|
#define CGAL_DISTANCE_2_RAY_2_RAY_2_H
|
||||||
|
|
||||||
|
#include <CGAL/Distance_2/internal/squared_distance_utils_2.h>
|
||||||
|
#include <CGAL/Distance_2/Point_2_Ray_2.h>
|
||||||
|
|
||||||
|
#include <CGAL/Ray_2.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
ray_ray_squared_distance_parallel(const typename K::Vector_2& ray1dir,
|
||||||
|
const typename K::Vector_2& ray2dir,
|
||||||
|
const typename K::Vector_2& from1to2,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::RT RT;
|
||||||
|
typedef typename K::FT FT;
|
||||||
|
|
||||||
|
if(!is_acute_angle(ray1dir, from1to2, k))
|
||||||
|
{
|
||||||
|
if(!same_direction(ray1dir, ray2dir, k))
|
||||||
|
return k.compute_squared_length_2_object()(from1to2);
|
||||||
|
}
|
||||||
|
|
||||||
|
RT wcr = wcross(ray1dir, from1to2, k);
|
||||||
|
RT w = from1to2.hw();
|
||||||
|
|
||||||
|
return (square(wcr) / FT(wmult((K*)0, wdot(ray1dir, ray1dir, k), w, w)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const typename K::Ray_2& ray1,
|
||||||
|
const typename K::Ray_2& ray2,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::Vector_2 Vector_2;
|
||||||
|
typedef typename K::FT FT;
|
||||||
|
|
||||||
|
typename K::Construct_vector_2 vector = k.construct_vector_2_object();
|
||||||
|
typename K::Compute_squared_distance_2 sq_dist = k.compute_squared_distance_2_object();
|
||||||
|
|
||||||
|
const Vector_2 ray1dir = ray1.direction().vector();
|
||||||
|
const Vector_2 ray2dir = ray2.direction().vector();
|
||||||
|
const Vector_2 diffvec = vector(ray1.source(),ray2.source());
|
||||||
|
|
||||||
|
bool crossing1, crossing2;
|
||||||
|
switch(orientation(ray1dir, ray2dir, k))
|
||||||
|
{
|
||||||
|
case COUNTERCLOCKWISE:
|
||||||
|
crossing1 = !clockwise(diffvec, ray2dir, k);
|
||||||
|
crossing2 = !counterclockwise(ray1dir, diffvec, k);
|
||||||
|
break;
|
||||||
|
case CLOCKWISE:
|
||||||
|
crossing1 = !counterclockwise(diffvec, ray2dir, k);
|
||||||
|
crossing2 = !clockwise(ray1dir, diffvec, k);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return ray_ray_squared_distance_parallel(ray1dir, ray2dir, diffvec,k);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(crossing1)
|
||||||
|
{
|
||||||
|
if(crossing2)
|
||||||
|
return FT(0);
|
||||||
|
return sq_dist(ray2.source(), ray1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(crossing2)
|
||||||
|
{
|
||||||
|
return sq_dist(ray1.source(), ray2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FT min1 = sq_dist(ray1.source(), ray2);
|
||||||
|
FT min2 = sq_dist(ray2.source(), ray1);
|
||||||
|
return (min1 < min2) ? min1 : min2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const Ray_2<K> &ray1, const Ray_2<K> &ray2)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_2_object()(ray1, ray2);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_DISTANCE_2_RAY_2_RAY_2_H
|
||||||
|
|
@ -0,0 +1,121 @@
|
||||||
|
// Copyright (c) 1998-2004
|
||||||
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org)
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Geert-Jan Giezeman
|
||||||
|
// Michel Hoffmann <hoffmann@inf.ethz.ch>
|
||||||
|
// Andreas Fabri <Andreas.Fabri@geometryfactory.com>
|
||||||
|
|
||||||
|
#ifndef CGAL_DISTANCE_2_RAY_2_TRIANGLE_2_H
|
||||||
|
#define CGAL_DISTANCE_2_RAY_2_TRIANGLE_2_H
|
||||||
|
|
||||||
|
#include <CGAL/Distance_2/internal/squared_distance_utils_2.h>
|
||||||
|
#include <CGAL/Distance_2/Point_2_Triangle_2.h>
|
||||||
|
|
||||||
|
#include <CGAL/Ray_2.h>
|
||||||
|
#include <CGAL/Triangle_2.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const typename K::Ray_2& ray,
|
||||||
|
const typename K::Triangle_2& triangle,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::FT FT;
|
||||||
|
typedef typename K::Point_2 Point_2;
|
||||||
|
typedef typename K::Line_2 Line_2;
|
||||||
|
|
||||||
|
int ind_tr1, ind_tr2, ind_ray = 0, ind1;
|
||||||
|
|
||||||
|
distance_index<K>(ind_tr1, ind_tr2, ray.source(), triangle, k);
|
||||||
|
FT mindist = squared_distance_indexed(ray.source(), triangle, ind_tr1, ind_tr2, k);
|
||||||
|
|
||||||
|
for(int i=0; i<3; ++i)
|
||||||
|
{
|
||||||
|
const Point_2& pt = triangle.vertex(i);
|
||||||
|
distance_index<K>(ind1, pt, ray, k);
|
||||||
|
FT dist = squared_distance_indexed(pt, ray, ind1, k);
|
||||||
|
if(dist < mindist)
|
||||||
|
{
|
||||||
|
ind_ray = ind1;
|
||||||
|
ind_tr1 = i; ind_tr2 = -1;
|
||||||
|
mindist = dist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// now check if all vertices are on the right side of the separating line.
|
||||||
|
// In case of vertex-vertex smallest distance this is the case.
|
||||||
|
if(ind_tr2 == -1 && ind_ray != -1)
|
||||||
|
return mindist;
|
||||||
|
|
||||||
|
if(ind_tr2 != -1)
|
||||||
|
{
|
||||||
|
// Check if all the segment vertices lie at the same side of
|
||||||
|
// the triangle segment.
|
||||||
|
const Point_2& vt1 = triangle.vertex(ind_tr1);
|
||||||
|
const Point_2& vt2 = triangle.vertex(ind_tr2);
|
||||||
|
if(clockwise(ray.direction().vector(), vt2-vt1, k))
|
||||||
|
mindist = FT(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Check if all the triangle vertices lie
|
||||||
|
// at the same side of the segment.
|
||||||
|
const Line_2& sl = ray.supporting_line();
|
||||||
|
Oriented_side or_s = sl.oriented_side(triangle.vertex(0));
|
||||||
|
for(int i=1; i<3; ++i)
|
||||||
|
{
|
||||||
|
if(sl.oriented_side(triangle.vertex(i)) != or_s)
|
||||||
|
{
|
||||||
|
mindist = FT(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mindist;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const typename K::Triangle_2& triangle,
|
||||||
|
const typename K::Ray_2& ray,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
return internal::squared_distance(ray, triangle, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const Ray_2<K>& ray,
|
||||||
|
const Triangle_2<K>& triangle)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_2_object()(ray, triangle);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const Triangle_2<K>& triangle,
|
||||||
|
const Ray_2<K>& ray)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_2_object()(triangle, ray);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_DISTANCE_2_RAY_2_TRIANGLE_2_H
|
||||||
|
|
@ -0,0 +1,129 @@
|
||||||
|
// Copyright (c) 1998-2004
|
||||||
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org)
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Geert-Jan Giezeman
|
||||||
|
// Michel Hoffmann <hoffmann@inf.ethz.ch>
|
||||||
|
// Andreas Fabri <Andreas.Fabri@geometryfactory.com>
|
||||||
|
|
||||||
|
#ifndef CGAL_DISTANCE_2_SEGMENT_2_LINE_2_H
|
||||||
|
#define CGAL_DISTANCE_2_SEGMENT_2_LINE_2_H
|
||||||
|
|
||||||
|
#include <CGAL/Distance_2/internal/squared_distance_utils_2.h>
|
||||||
|
#include <CGAL/Distance_2/Point_2_Line_2.h>
|
||||||
|
#include <CGAL/Distance_2/Segment_2_Ray_2.h>
|
||||||
|
|
||||||
|
#include <CGAL/number_utils.h>
|
||||||
|
#include <CGAL/Rational_traits.h>
|
||||||
|
|
||||||
|
#include <CGAL/Line_2.h>
|
||||||
|
#include <CGAL/Segment_2.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
_sqd_to_line(const typename K::Vector_2& diff,
|
||||||
|
const typename K::RT& wcross,
|
||||||
|
const typename K::Vector_2& dir)
|
||||||
|
{
|
||||||
|
typedef typename K::RT RT;
|
||||||
|
typedef typename K::FT FT;
|
||||||
|
|
||||||
|
RT numerator = CGAL_NTS square(wcross);
|
||||||
|
RT denominator = wmult((K*)0, RT(wdot(dir,dir, K())), diff.hw(), diff.hw());
|
||||||
|
return Rational_traits<FT>().make_rational(numerator, denominator);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const typename K::Segment_2& seg,
|
||||||
|
const typename K::Line_2& line,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::RT RT;
|
||||||
|
typedef typename K::FT FT;
|
||||||
|
typedef typename K::Vector_2 Vector_2;
|
||||||
|
typedef typename K::Point_2 Point_2;
|
||||||
|
|
||||||
|
typename K::Construct_vector_2 vector = k.construct_vector_2_object();
|
||||||
|
typename K::Compute_squared_distance_2 sq_dist = k.compute_squared_distance_2_object();
|
||||||
|
|
||||||
|
const Vector_2 linedir = line.direction().vector();
|
||||||
|
const Point_2& linepoint = line.point();
|
||||||
|
const Vector_2 startvec = vector(linepoint, seg.source());
|
||||||
|
const Vector_2 endvec = vector(linepoint, seg.target());
|
||||||
|
|
||||||
|
if(seg.source() == seg.target())
|
||||||
|
return sq_dist(seg.source(), line);
|
||||||
|
|
||||||
|
bool crossing1;
|
||||||
|
const RT c1s = wcross(linedir, startvec, k);
|
||||||
|
const RT c1e = wcross(linedir, endvec, k);
|
||||||
|
if(c1s < RT(0))
|
||||||
|
{
|
||||||
|
crossing1 = (c1e >= RT(0));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(c1e <= RT(0))
|
||||||
|
crossing1 = true;
|
||||||
|
else
|
||||||
|
crossing1 = (c1s == RT(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(crossing1)
|
||||||
|
{
|
||||||
|
return FT(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const RT dm = _distance_measure_sub<K>(c1s, c1e, startvec, endvec);
|
||||||
|
if(dm <= RT(0))
|
||||||
|
return _sqd_to_line<K>(startvec, c1s, linedir);
|
||||||
|
else
|
||||||
|
return _sqd_to_line<K>(endvec, c1e, linedir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const typename K::Line_2& line,
|
||||||
|
const typename K::Segment_2& seg,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
return internal::squared_distance(seg, line, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const Segment_2<K>& seg,
|
||||||
|
const Line_2<K>& line)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_2_object()(seg, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const Line_2<K>& line,
|
||||||
|
const Segment_2<K>& seg)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_2_object()(line, seg);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_DISTANCE_2_SEGMENT_2_LINE_2_H
|
||||||
|
|
@ -0,0 +1,196 @@
|
||||||
|
// Copyright (c) 1998-2004
|
||||||
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org)
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Geert-Jan Giezeman
|
||||||
|
// Michel Hoffmann <hoffmann@inf.ethz.ch>
|
||||||
|
// Andreas Fabri <Andreas.Fabri@geometryfactory.com>
|
||||||
|
|
||||||
|
#ifndef CGAL_DISTANCE_2_SEGMENT_2_RAY_2_H
|
||||||
|
#define CGAL_DISTANCE_2_SEGMENT_2_RAY_2_H
|
||||||
|
|
||||||
|
#include <CGAL/Distance_2/internal/squared_distance_utils_2.h>
|
||||||
|
|
||||||
|
#include <CGAL/Distance_2/Point_2_Line_2.h>
|
||||||
|
#include <CGAL/Distance_2/Point_2_Point_2.h>
|
||||||
|
#include <CGAL/Distance_2/Point_2_Ray_2.h>
|
||||||
|
|
||||||
|
#include <CGAL/Segment_2.h>
|
||||||
|
#include <CGAL/Ray_2.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::RT
|
||||||
|
_distance_measure_sub(const typename K::RT& startwcross,
|
||||||
|
const typename K::RT& endwcross,
|
||||||
|
const typename K::Vector_2& start,
|
||||||
|
const typename K::Vector_2& end)
|
||||||
|
{
|
||||||
|
return CGAL_NTS abs(wmult((K*)0, startwcross, end.hw())) -
|
||||||
|
CGAL_NTS abs(wmult((K*)0, endwcross, start.hw()));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance_parallel(const typename K::Segment_2& seg,
|
||||||
|
const typename K::Ray_2& ray,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::Vector_2 Vector_2;
|
||||||
|
|
||||||
|
typename K::Compute_squared_distance_2 sq_dist = k.compute_squared_distance_2_object();
|
||||||
|
|
||||||
|
const Vector_2 dir1 = seg.direction().vector();
|
||||||
|
const Vector_2 dir2 = ray.direction().vector();
|
||||||
|
|
||||||
|
if(same_direction(dir1, dir2, k))
|
||||||
|
{
|
||||||
|
if(!is_acute_angle(seg.source(), seg.target(), ray.source(), k))
|
||||||
|
return sq_dist(seg.target(), ray.source());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!is_acute_angle(seg.target(), seg.source(), ray.source(), k))
|
||||||
|
return sq_dist(seg.source(), ray.source());
|
||||||
|
}
|
||||||
|
|
||||||
|
return sq_dist(ray.source(), seg.supporting_line());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const typename K::Segment_2& seg,
|
||||||
|
const typename K::Ray_2& ray,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::RT RT;
|
||||||
|
typedef typename K::FT FT;
|
||||||
|
typedef typename K::Vector_2 Vector_2;
|
||||||
|
|
||||||
|
typename K::Construct_vector_2 vector = k.construct_vector_2_object();
|
||||||
|
typename K::Orientation_2 orientation = k.orientation_2_object();
|
||||||
|
typename K::Compute_squared_distance_2 sq_dist = k.compute_squared_distance_2_object();
|
||||||
|
|
||||||
|
const Vector_2& raydir = ray.direction().vector();
|
||||||
|
const Vector_2 startvec = vector(ray.source(), seg.source());
|
||||||
|
const Vector_2 endvec = vector(ray.source(), seg.target());
|
||||||
|
|
||||||
|
if(seg.source() == seg.target())
|
||||||
|
return internal::squared_distance(seg.source(), ray, k);
|
||||||
|
|
||||||
|
bool crossing1, crossing2;
|
||||||
|
const RT c1s = wcross(raydir, startvec, k);
|
||||||
|
const RT c1e = wcross(raydir, endvec, k);
|
||||||
|
if(c1s < RT(0))
|
||||||
|
{
|
||||||
|
crossing1 = (c1e >= RT(0));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(c1e <= RT(0))
|
||||||
|
{
|
||||||
|
if(c1s == RT(0) && c1e == RT(0))
|
||||||
|
return internal::squared_distance_parallel(seg, ray, k);
|
||||||
|
|
||||||
|
crossing1 = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
crossing1 = (c1s == RT(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (orientation(seg.source(), seg.target(), ray.source()))
|
||||||
|
{
|
||||||
|
case LEFT_TURN:
|
||||||
|
crossing2 = right_turn(vector(seg.source(), seg.target()), raydir, k);
|
||||||
|
break;
|
||||||
|
case RIGHT_TURN:
|
||||||
|
crossing2 = left_turn(vector(seg.source(), seg.target()), raydir, k);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
crossing2 = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(crossing1)
|
||||||
|
{
|
||||||
|
if(crossing2)
|
||||||
|
return FT(0);
|
||||||
|
|
||||||
|
return sq_dist(ray.source(), seg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(crossing2)
|
||||||
|
{
|
||||||
|
const RT dm = _distance_measure_sub<K>(c1s, c1e, startvec, endvec);
|
||||||
|
if(dm < RT(0))
|
||||||
|
{
|
||||||
|
return sq_dist(seg.source(), ray);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(dm > RT(0))
|
||||||
|
return sq_dist(seg.target(), ray);
|
||||||
|
else // parallel, should not happen (no crossing)
|
||||||
|
return internal::squared_distance_parallel(seg, ray, k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const RT dm = _distance_measure_sub<K>(c1s, c1e, startvec, endvec);
|
||||||
|
if(dm == RT(0))
|
||||||
|
return internal::squared_distance_parallel(seg, ray, k);
|
||||||
|
|
||||||
|
const FT min1 = (dm < RT(0)) ? sq_dist(seg.source(), ray)
|
||||||
|
: sq_dist(seg.target(), ray);
|
||||||
|
const FT min2 = sq_dist(ray.source(), seg);
|
||||||
|
|
||||||
|
return (min1 < min2) ? min1 : min2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const typename K::Ray_2& ray,
|
||||||
|
const typename K::Segment_2& seg,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
return internal::squared_distance(seg, ray, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const Segment_2<K>& seg,
|
||||||
|
const Ray_2<K>& ray)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_2_object()(seg, ray);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const Ray_2<K>& ray,
|
||||||
|
const Segment_2<K>& seg)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_2_object()(ray, seg);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_DISTANCE_2_SEGMENT_2_RAY_2_H
|
||||||
|
|
@ -0,0 +1,351 @@
|
||||||
|
// Copyright (c) 1998-2004
|
||||||
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org)
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Geert-Jan Giezeman
|
||||||
|
// Michel Hoffmann <hoffmann@inf.ethz.ch>
|
||||||
|
// Andreas Fabri <Andreas.Fabri@geometryfactory.com>
|
||||||
|
|
||||||
|
#ifndef CGAL_DISTANCE_2_SEGMENT_2_SEGMENT_2_H
|
||||||
|
#define CGAL_DISTANCE_2_SEGMENT_2_SEGMENT_2_H
|
||||||
|
|
||||||
|
#include <CGAL/Distance_2/internal/squared_distance_utils_2.h>
|
||||||
|
#include <CGAL/Distance_2/Point_2_Line_2.h>
|
||||||
|
#include <CGAL/Distance_2/Point_2_Point_2.h>
|
||||||
|
#include <CGAL/Distance_2/Point_2_Segment_2.h>
|
||||||
|
|
||||||
|
#include <CGAL/number_utils.h>
|
||||||
|
#include <CGAL/tags.h>
|
||||||
|
|
||||||
|
#include <CGAL/Segment_2.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance_parallel(const typename K::Segment_2& seg1,
|
||||||
|
const typename K::Segment_2& seg2,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::Vector_2 Vector_2;
|
||||||
|
|
||||||
|
typename K::Compute_squared_distance_2 sq_dist = k.compute_squared_distance_2_object();
|
||||||
|
|
||||||
|
const Vector_2 dir1 = seg1.direction().vector();
|
||||||
|
const Vector_2 dir2 = seg2.direction().vector();
|
||||||
|
|
||||||
|
if(same_direction(dir1, dir2, k))
|
||||||
|
{
|
||||||
|
if(!is_acute_angle(seg1.source(), seg1.target(), seg2.source(), k))
|
||||||
|
return sq_dist(seg1.target(), seg2.source());
|
||||||
|
|
||||||
|
if(!is_acute_angle(seg1.target(), seg1.source(), seg2.target(), k))
|
||||||
|
return sq_dist(seg1.source(), seg2.target());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!is_acute_angle(seg1.source(), seg1.target(), seg2.target(), k))
|
||||||
|
return sq_dist(seg1.target(), seg2.target());
|
||||||
|
|
||||||
|
if(!is_acute_angle(seg1.target(), seg1.source(), seg2.source(), k))
|
||||||
|
return sq_dist(seg1.source(), seg2.source());
|
||||||
|
}
|
||||||
|
|
||||||
|
return sq_dist(seg2.source(), seg1.supporting_line());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::RT
|
||||||
|
_distance_measure_sub(const typename K::RT& startwcross,
|
||||||
|
const typename K::RT& endwcross,
|
||||||
|
const typename K::Point_2& start,
|
||||||
|
const typename K::Point_2& end)
|
||||||
|
{
|
||||||
|
return CGAL_NTS abs(wmult((K*)0, startwcross, end.hw())) -
|
||||||
|
CGAL_NTS abs(wmult((K*)0, endwcross, start.hw()));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const typename K::Segment_2& seg1,
|
||||||
|
const typename K::Segment_2& seg2,
|
||||||
|
const K& k,
|
||||||
|
const Cartesian_tag&)
|
||||||
|
{
|
||||||
|
typedef typename K::RT RT;
|
||||||
|
typedef typename K::FT FT;
|
||||||
|
|
||||||
|
typename K::Orientation_2 orientation = k.orientation_2_object();
|
||||||
|
typename K::Compute_squared_distance_2 sq_dist = k.compute_squared_distance_2_object();
|
||||||
|
|
||||||
|
if(seg1.source() == seg1.target())
|
||||||
|
return sq_dist(seg1.source(), seg2);
|
||||||
|
|
||||||
|
if(seg2.source() == seg2.target())
|
||||||
|
return sq_dist(seg2.source(), seg1);
|
||||||
|
|
||||||
|
const Orientation o1s = orientation(seg2.source(), seg2.target(), seg1.source());
|
||||||
|
const Orientation o1e = orientation(seg2.source(), seg2.target(), seg1.target());
|
||||||
|
|
||||||
|
bool crossing1, crossing2;
|
||||||
|
if(o1s == RIGHT_TURN)
|
||||||
|
{
|
||||||
|
crossing1 = (o1e != RIGHT_TURN);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(o1e != LEFT_TURN)
|
||||||
|
{
|
||||||
|
if(o1s == COLLINEAR && o1e == COLLINEAR)
|
||||||
|
return internal::squared_distance_parallel(seg1, seg2, k);
|
||||||
|
|
||||||
|
crossing1 = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
crossing1 = (o1s == COLLINEAR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const Orientation o2s = orientation(seg1.source(), seg1.target(), seg2.source());
|
||||||
|
const Orientation o2e = orientation(seg1.source(), seg1.target(), seg2.target());
|
||||||
|
if(o2s == RIGHT_TURN)
|
||||||
|
{
|
||||||
|
crossing2 = (o2e != RIGHT_TURN);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(o2e != LEFT_TURN)
|
||||||
|
{
|
||||||
|
if(o2s == COLLINEAR && o2e == COLLINEAR)
|
||||||
|
return internal::squared_distance_parallel(seg1, seg2, k);
|
||||||
|
|
||||||
|
crossing2 = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
crossing2 = (o2s == COLLINEAR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(crossing1)
|
||||||
|
{
|
||||||
|
if(crossing2)
|
||||||
|
return (FT)0;
|
||||||
|
|
||||||
|
const RT c2s = CGAL_NTS abs(wcross(seg1.source(), seg1.target(), seg2.source(), k));
|
||||||
|
const RT c2e = CGAL_NTS abs(wcross(seg1.source(), seg1.target(), seg2.target(), k));
|
||||||
|
Comparison_result dm = CGAL_NTS compare(c2s, c2e);
|
||||||
|
|
||||||
|
if(dm == SMALLER)
|
||||||
|
{
|
||||||
|
return sq_dist(seg2.source(), seg1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(dm == LARGER)
|
||||||
|
{
|
||||||
|
return sq_dist(seg2.target(), seg1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// parallel, should not happen (no crossing)
|
||||||
|
return internal::squared_distance_parallel(seg1, seg2, k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const RT c1s = CGAL_NTS abs(wcross(seg2.source(), seg2.target(), seg1.source(), k));
|
||||||
|
const RT c1e = CGAL_NTS abs(wcross(seg2.source(), seg2.target(), seg1.target(), k));
|
||||||
|
Comparison_result dm = CGAL_NTS compare(c1s, c1e);
|
||||||
|
if(crossing2)
|
||||||
|
{
|
||||||
|
if(dm == SMALLER)
|
||||||
|
{
|
||||||
|
return sq_dist(seg1.source(), seg2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(dm == LARGER)
|
||||||
|
return sq_dist(seg1.target(), seg2);
|
||||||
|
else // parallel, should not happen (no crossing)
|
||||||
|
return internal::squared_distance_parallel(seg1, seg2, k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(dm == EQUAL)
|
||||||
|
return internal::squared_distance_parallel(seg1, seg2, k);
|
||||||
|
|
||||||
|
FT min1 = (dm == SMALLER) ? sq_dist(seg1.source(), seg2):
|
||||||
|
sq_dist(seg1.target(), seg2);
|
||||||
|
|
||||||
|
const RT c2s = CGAL_NTS abs(wcross(seg1.source(), seg1.target(), seg2.source(), k));
|
||||||
|
const RT c2e = CGAL_NTS abs(wcross(seg1.source(), seg1.target(), seg2.target(), k));
|
||||||
|
|
||||||
|
dm = CGAL_NTS compare(c2s,c2e);
|
||||||
|
if(dm == EQUAL) // should not happen.
|
||||||
|
return internal::squared_distance_parallel(seg1, seg2, k);
|
||||||
|
|
||||||
|
FT min2 = (dm == SMALLER) ? sq_dist(seg2.source(), seg1):
|
||||||
|
sq_dist(seg2.target(), seg1);
|
||||||
|
|
||||||
|
return (min1 < min2) ? min1 : min2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const typename K::Segment_2& seg1,
|
||||||
|
const typename K::Segment_2& seg2,
|
||||||
|
const K& k,
|
||||||
|
const Homogeneous_tag&)
|
||||||
|
{
|
||||||
|
typedef typename K::RT RT;
|
||||||
|
typedef typename K::FT FT;
|
||||||
|
|
||||||
|
typename K::Compute_squared_distance_2 sq_dist = k.compute_squared_distance_2_object();
|
||||||
|
|
||||||
|
if(seg1.source() == seg1.target())
|
||||||
|
return sq_dist(seg1.source(), seg2);
|
||||||
|
|
||||||
|
if(seg2.source() == seg2.target())
|
||||||
|
return sq_dist(seg2.source(), seg1);
|
||||||
|
|
||||||
|
const RT c1s = wcross(seg2.source(), seg2.target(), seg1.source(), k);
|
||||||
|
const RT c1e = wcross(seg2.source(), seg2.target(), seg1.target(), k);
|
||||||
|
const RT c2s = wcross(seg1.source(), seg1.target(), seg2.source(), k);
|
||||||
|
const RT c2e = wcross(seg1.source(), seg1.target(), seg2.target(), k);
|
||||||
|
|
||||||
|
bool crossing1, crossing2;
|
||||||
|
|
||||||
|
if(c1s < RT(0))
|
||||||
|
{
|
||||||
|
crossing1 = (c1e >= RT(0));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(c1e <= RT(0))
|
||||||
|
{
|
||||||
|
if(c1s == RT(0) && c1e == RT(0))
|
||||||
|
return internal::squared_distance_parallel(seg1, seg2, k);
|
||||||
|
|
||||||
|
crossing1 = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
crossing1 = (c1s == RT(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(c2s < RT(0))
|
||||||
|
{
|
||||||
|
crossing2 = (c2e >= RT(0));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(c2e <= RT(0))
|
||||||
|
{
|
||||||
|
if(c2s == RT(0) && c2e == RT(0))
|
||||||
|
return internal::squared_distance_parallel(seg1, seg2, k);
|
||||||
|
|
||||||
|
crossing2 = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
crossing2 = (c2s == RT(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(crossing1)
|
||||||
|
{
|
||||||
|
if(crossing2)
|
||||||
|
return (FT)0;
|
||||||
|
|
||||||
|
const RT dm = _distance_measure_sub<K>(c2s,c2e, seg2.source(), seg2.target());
|
||||||
|
if(dm < RT(0))
|
||||||
|
{
|
||||||
|
return sq_dist(seg2.source(), seg1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(dm > RT(0))
|
||||||
|
return sq_dist(seg2.target(), seg1);
|
||||||
|
else // parallel, should not happen (no crossing)
|
||||||
|
return internal::squared_distance_parallel(seg1, seg2, k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(crossing2)
|
||||||
|
{
|
||||||
|
const RT dm = _distance_measure_sub<K>(c1s, c1e,seg1.source(),seg1.target());
|
||||||
|
if(dm < RT(0))
|
||||||
|
{
|
||||||
|
return sq_dist(seg1.source(), seg2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(dm > RT(0))
|
||||||
|
return sq_dist(seg1.target(), seg2);
|
||||||
|
else // parallel, should not happen (no crossing)
|
||||||
|
return internal::squared_distance_parallel(seg1, seg2, k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RT dm = _distance_measure_sub<K>(c1s, c1e, seg1.source(), seg1.target());
|
||||||
|
if(dm == RT(0))
|
||||||
|
return internal::squared_distance_parallel(seg1, seg2, k);
|
||||||
|
|
||||||
|
FT min1 = (dm < RT(0)) ? sq_dist(seg1.source(), seg2):
|
||||||
|
sq_dist(seg1.target(), seg2);
|
||||||
|
|
||||||
|
dm = _distance_measure_sub<K>(c2s, c2e, seg2.source(), seg2.target());
|
||||||
|
if(dm == RT(0)) // should not happen.
|
||||||
|
return internal::squared_distance_parallel(seg1, seg2, k);
|
||||||
|
|
||||||
|
FT min2 = (dm < RT(0)) ? sq_dist(seg2.source(), seg1):
|
||||||
|
sq_dist(seg2.target(), seg1);
|
||||||
|
|
||||||
|
return (min1 < min2) ? min1 : min2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const Segment_2<K>& seg1,
|
||||||
|
const Segment_2<K>& seg2,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::Kernel_tag Tag;
|
||||||
|
return squared_distance(seg1, seg2, k, Tag());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const Segment_2<K>& seg1,
|
||||||
|
const Segment_2<K>& seg2)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_2_object()(seg1, seg2);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_DISTANCE_2_SEGMENT_2_SEGMENT_2_H
|
||||||
|
|
@ -0,0 +1,136 @@
|
||||||
|
// Copyright (c) 1998-2004
|
||||||
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org)
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Geert-Jan Giezeman
|
||||||
|
// Michel Hoffmann <hoffmann@inf.ethz.ch>
|
||||||
|
// Andreas Fabri <Andreas.Fabri@geometryfactory.com>
|
||||||
|
|
||||||
|
#ifndef CGAL_DISTANCE_2_SEGMENT_2_TRIANGLE_2_H
|
||||||
|
#define CGAL_DISTANCE_2_SEGMENT_2_TRIANGLE_2_H
|
||||||
|
|
||||||
|
#include <CGAL/Distance_2/internal/squared_distance_utils_2.h>
|
||||||
|
#include <CGAL/Distance_2/Point_2_Triangle_2.h>
|
||||||
|
|
||||||
|
#include <CGAL/Segment_2.h>
|
||||||
|
#include <CGAL/Triangle_2.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const typename K::Segment_2& seg,
|
||||||
|
const typename K::Triangle_2& triangle,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::FT FT;
|
||||||
|
typedef typename K::Point_2 Point_2;
|
||||||
|
|
||||||
|
typename K::Orientation_2 orientation = k.orientation_2_object();
|
||||||
|
|
||||||
|
int i, ind_tr1 = 0, ind_tr2 = -1, ind_seg = 0, ind1, ind2;
|
||||||
|
FT dist;
|
||||||
|
|
||||||
|
FT mindist = internal::squared_distance(seg.source(), triangle.vertex(0), k);
|
||||||
|
for(i=0; i<2; ++i)
|
||||||
|
{
|
||||||
|
const Point_2& pt = seg.vertex(i);
|
||||||
|
distance_index<K>(ind1, ind2, pt, triangle, k);
|
||||||
|
dist = internal::squared_distance_indexed(pt, triangle, ind1, ind2, k);
|
||||||
|
if(dist < mindist)
|
||||||
|
{
|
||||||
|
ind_seg = i;
|
||||||
|
ind_tr1 = ind1; ind_tr2 = ind2;
|
||||||
|
mindist = dist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i=0; i<3; ++i)
|
||||||
|
{
|
||||||
|
const Point_2& pt = triangle.vertex(i);
|
||||||
|
distance_index<K>(ind1, pt, seg, k);
|
||||||
|
dist = internal::squared_distance_indexed(pt, seg, ind1, k);
|
||||||
|
if(dist < mindist)
|
||||||
|
{
|
||||||
|
ind_seg = ind1;
|
||||||
|
ind_tr1 = i; ind_tr2 = -1;
|
||||||
|
mindist = dist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// now check if all vertices are on the right side of the separating line.
|
||||||
|
// In case of vertex-vertex smallest distance this is the case.
|
||||||
|
if(ind_tr2 == -1 && ind_seg != -1)
|
||||||
|
return mindist;
|
||||||
|
|
||||||
|
if(ind_tr2 != -1)
|
||||||
|
{
|
||||||
|
// Check if all the segment vertices lie at the same side of
|
||||||
|
// the triangle segment.
|
||||||
|
const Point_2 &vt1 = triangle.vertex(ind_tr1);
|
||||||
|
const Point_2 &vt2 = triangle.vertex(ind_tr2);
|
||||||
|
const Orientation or_s = orientation(vt1, vt2, seg.source());
|
||||||
|
if(orientation(vt1, vt2, seg.target()) != or_s)
|
||||||
|
mindist = FT(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Check if all the triangle vertices lie
|
||||||
|
// at the same side of the segment.
|
||||||
|
const Point_2& vt1 = seg.source();
|
||||||
|
const Point_2& vt2 = seg.target();
|
||||||
|
const Orientation or_s = orientation(vt1, vt2, triangle.vertex(0));
|
||||||
|
for(i=1; i<3; ++i)
|
||||||
|
{
|
||||||
|
if(orientation(vt1, vt2, triangle.vertex(i)) != or_s)
|
||||||
|
{
|
||||||
|
mindist = FT(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mindist;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const typename K::Triangle_2 & triangle,
|
||||||
|
const typename K::Segment_2 & seg,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
return internal::squared_distance(seg, triangle, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const Segment_2<K>& seg,
|
||||||
|
const Triangle_2<K>& triangle)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_2_object()(seg, triangle);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const Triangle_2<K>& triangle,
|
||||||
|
const Segment_2<K>& seg)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_2_object()(triangle, seg);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_DISTANCE_2_SEGMENT_2_TRIANGLE_2_H
|
||||||
|
|
@ -0,0 +1,123 @@
|
||||||
|
// Copyright (c) 1998-2004
|
||||||
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org)
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Geert-Jan Giezeman
|
||||||
|
// Michel Hoffmann <hoffmann@inf.ethz.ch>
|
||||||
|
// Andreas Fabri <Andreas.Fabri@geometryfactory.com>
|
||||||
|
|
||||||
|
#ifndef CGAL_DISTANCE_2_TRIANGLE_2_TRIANGLE_2_H
|
||||||
|
#define CGAL_DISTANCE_2_TRIANGLE_2_TRIANGLE_2_H
|
||||||
|
|
||||||
|
#include <CGAL/Distance_2/internal/squared_distance_utils_2.h>
|
||||||
|
#include <CGAL/Distance_2/Point_2_Point_2.h>
|
||||||
|
#include <CGAL/Distance_2/Point_2_Triangle_2.h>
|
||||||
|
|
||||||
|
#include <CGAL/Triangle_2.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const typename K::Triangle_2& triangle1,
|
||||||
|
const typename K::Triangle_2& triangle2,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::FT FT;
|
||||||
|
typedef typename K::Point_2 Point_2;
|
||||||
|
|
||||||
|
typename K::Orientation_2 orientation = k.orientation_2_object();
|
||||||
|
|
||||||
|
int ind1_1 = 0, ind1_2 = -1, ind2_1 = 0, ind2_2 = -1, ind1, ind2;
|
||||||
|
FT dist;
|
||||||
|
|
||||||
|
FT mindist = internal::squared_distance(triangle1.vertex(0), triangle2.vertex(0), k);
|
||||||
|
for(int i=0; i<3; ++i)
|
||||||
|
{
|
||||||
|
const Point_2& pt = triangle1.vertex(i);
|
||||||
|
distance_index<K>(ind1, ind2, pt, triangle2, k);
|
||||||
|
dist = squared_distance_indexed(pt, triangle2, ind1, ind2, k);
|
||||||
|
if(dist < mindist)
|
||||||
|
{
|
||||||
|
ind1_1 = i; ind1_2 = -1;
|
||||||
|
ind2_1 = ind1; ind2_2 = ind2;
|
||||||
|
mindist = dist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i=0; i<3; ++i)
|
||||||
|
{
|
||||||
|
const Point_2& pt = triangle2.vertex(i);
|
||||||
|
distance_index<K>(ind1, ind2, pt, triangle1, k);
|
||||||
|
dist = squared_distance_indexed(pt, triangle1, ind1, ind2, k);
|
||||||
|
if(dist < mindist)
|
||||||
|
{
|
||||||
|
ind1_1 = ind1; ind1_2 = ind2;
|
||||||
|
ind2_1 = i; ind2_2 = -1;
|
||||||
|
mindist = dist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// now check if all vertices are on the right side of the separating line.
|
||||||
|
if(ind1_2 == -1 && ind2_2 == -1)
|
||||||
|
return mindist;
|
||||||
|
|
||||||
|
// In case of point-segment closest distance, there is still the
|
||||||
|
// possibility of overlapping triangles. Check if all the
|
||||||
|
// vertices lie at the same side of the segment.
|
||||||
|
if(ind1_2 != -1)
|
||||||
|
{
|
||||||
|
const Point_2& vt1 = triangle1.vertex(ind1_1);
|
||||||
|
const Point_2& vt2 = triangle1.vertex(ind1_2);
|
||||||
|
const Orientation or_s = orientation(vt1, vt2, triangle2.vertex(0));
|
||||||
|
for(int i=1; i<3; ++i)
|
||||||
|
{
|
||||||
|
if(orientation(vt1, vt2, triangle2.vertex(i)) != or_s)
|
||||||
|
{
|
||||||
|
mindist = FT(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const Point_2& vt1 = triangle2.vertex(ind2_1);
|
||||||
|
const Point_2& vt2 = triangle2.vertex(ind2_2);
|
||||||
|
const Orientation or_s = orientation(vt1, vt2, triangle1.vertex(0));
|
||||||
|
for(int i=1; i<3; ++i)
|
||||||
|
{
|
||||||
|
if(orientation(vt1, vt2, triangle1.vertex(i)) != or_s)
|
||||||
|
{
|
||||||
|
mindist = FT(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mindist;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const Triangle_2<K>& triangle1,
|
||||||
|
const Triangle_2<K>& triangle2)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_2_object()(triangle1, triangle2);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_DISTANCE_2_TRIANGLE_2_TRIANGLE_2_H
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
#define CGAL_SQUARED_DISTANCE_UTILS_H
|
#define CGAL_SQUARED_DISTANCE_UTILS_H
|
||||||
|
|
||||||
#include <CGAL/determinant.h>
|
#include <CGAL/determinant.h>
|
||||||
|
#include <CGAL/number_utils.h>
|
||||||
#include <CGAL/wmult.h>
|
#include <CGAL/wmult.h>
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
@ -294,7 +295,6 @@ same_direction(const typename K::Vector_2 &u,
|
||||||
return same_direction_tag(u,v, k, tag);
|
return same_direction_tag(u,v, k, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
} //namespace CGAL
|
} //namespace CGAL
|
||||||
|
|
@ -14,11 +14,27 @@
|
||||||
//
|
//
|
||||||
// Author(s) : Geert-Jan Giezeman
|
// Author(s) : Geert-Jan Giezeman
|
||||||
|
|
||||||
|
|
||||||
#ifndef CGAL_SQUARED_DISTANCE_2_H
|
#ifndef CGAL_SQUARED_DISTANCE_2_H
|
||||||
#define CGAL_SQUARED_DISTANCE_2_H
|
#define CGAL_SQUARED_DISTANCE_2_H
|
||||||
|
|
||||||
#include <CGAL/squared_distance_2_1.h>
|
#include <CGAL/Distance_2/Point_2_Point_2.h>
|
||||||
#include <CGAL/squared_distance_2_2.h>
|
#include <CGAL/Distance_2/Point_2_Segment_2.h>
|
||||||
|
#include <CGAL/Distance_2/Point_2_Ray_2.h>
|
||||||
|
#include <CGAL/Distance_2/Point_2_Line_2.h>
|
||||||
|
#include <CGAL/Distance_2/Point_2_Triangle_2.h>
|
||||||
|
|
||||||
|
#include <CGAL/Distance_2/Segment_2_Segment_2.h>
|
||||||
|
#include <CGAL/Distance_2/Segment_2_Ray_2.h>
|
||||||
|
#include <CGAL/Distance_2/Segment_2_Line_2.h>
|
||||||
|
#include <CGAL/Distance_2/Segment_2_Triangle_2.h>
|
||||||
|
|
||||||
|
#include <CGAL/Distance_2/Ray_2_Ray_2.h>
|
||||||
|
#include <CGAL/Distance_2/Ray_2_Line_2.h>
|
||||||
|
#include <CGAL/Distance_2/Ray_2_Triangle_2.h>
|
||||||
|
|
||||||
|
#include <CGAL/Distance_2/Line_2_Line_2.h>
|
||||||
|
#include <CGAL/Distance_2/Line_2_Triangle_2.h>
|
||||||
|
|
||||||
|
#include <CGAL/Distance_2/Triangle_2_Triangle_2.h>
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1,857 +0,0 @@
|
||||||
// Copyright (c) 1998-2004
|
|
||||||
// Utrecht University (The Netherlands),
|
|
||||||
// ETH Zurich (Switzerland),
|
|
||||||
// INRIA Sophia-Antipolis (France),
|
|
||||||
// Max-Planck-Institute Saarbruecken (Germany),
|
|
||||||
// and Tel-Aviv University (Israel). All rights reserved.
|
|
||||||
//
|
|
||||||
// This file is part of CGAL (www.cgal.org)
|
|
||||||
//
|
|
||||||
// $URL$
|
|
||||||
// $Id$
|
|
||||||
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Author(s) : Geert-Jan Giezeman
|
|
||||||
// Michel Hoffmann <hoffmann@inf.ethz.ch>
|
|
||||||
// Andreas Fabri <Andreas.Fabri@geometryfactory.com>
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef CGAL_SQUARED_DISTANCE_2_1_H
|
|
||||||
#define CGAL_SQUARED_DISTANCE_2_1_H
|
|
||||||
|
|
||||||
#include <CGAL/user_classes.h>
|
|
||||||
|
|
||||||
|
|
||||||
#include <CGAL/kernel_assertions.h>
|
|
||||||
#include <CGAL/enum.h>
|
|
||||||
#include <CGAL/wmult.h>
|
|
||||||
#include <CGAL/squared_distance_utils.h>
|
|
||||||
#include <CGAL/Kernel/global_functions_2.h>
|
|
||||||
|
|
||||||
namespace CGAL {
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(const typename K::Point_2 & pt1,
|
|
||||||
const typename K::Point_2 & pt2,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
typename K::Vector_2 vec = k.construct_vector_2_object()(pt2, pt1);
|
|
||||||
return (typename K::FT)k.compute_squared_length_2_object()(vec);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
typename K::FT
|
|
||||||
squared_distance(const typename K::Point_2 &pt,
|
|
||||||
const typename K::Line_2 &line,
|
|
||||||
const K&,
|
|
||||||
const Homogeneous_tag&)
|
|
||||||
{
|
|
||||||
typedef typename K::RT RT;
|
|
||||||
typedef typename K::FT FT;
|
|
||||||
const RT & a = line.a();
|
|
||||||
const RT & b = line.b();
|
|
||||||
const RT & w = pt.hw();
|
|
||||||
RT n = a*pt.hx() + b*pt.hy() + w * line.c();
|
|
||||||
RT d = (CGAL_NTS square(a) + CGAL_NTS square(b)) * CGAL_NTS square(w);
|
|
||||||
return Rational_traits<FT>().make_rational(CGAL_NTS square(n), d);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
typename K::FT
|
|
||||||
squared_distance(const typename K::Point_2 &pt,
|
|
||||||
const typename K::Line_2 &line,
|
|
||||||
const K&,
|
|
||||||
const Cartesian_tag&)
|
|
||||||
{
|
|
||||||
typedef typename K::FT FT;
|
|
||||||
const FT & a = line.a();
|
|
||||||
const FT & b = line.b();
|
|
||||||
FT n = a*pt.x() + b*pt.y() + line.c();
|
|
||||||
FT d = CGAL_NTS square(a) + CGAL_NTS square(b);
|
|
||||||
return CGAL_NTS square(n)/d;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
typename K::FT
|
|
||||||
squared_distance(const typename K::Point_2 &pt,
|
|
||||||
const typename K::Line_2 &line,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
typedef typename K::Kernel_tag Tag;
|
|
||||||
Tag tag;
|
|
||||||
return squared_distance(pt, line, k, tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(const typename K::Line_2 &line,
|
|
||||||
const typename K::Point_2 &pt,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(pt, line, k);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
typename K::FT
|
|
||||||
squared_distance(const typename K::Point_2 &pt,
|
|
||||||
const typename K::Ray_2 &ray,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
typedef typename K::Vector_2 Vector_2;
|
|
||||||
typename K::Construct_vector_2 construct_vector;
|
|
||||||
Vector_2 diff = construct_vector(ray.source(), pt);
|
|
||||||
const Vector_2 &dir = ray.direction().vector();
|
|
||||||
if (!is_acute_angle(dir,diff, k) )
|
|
||||||
return (typename K::FT)k.compute_squared_length_2_object()(diff);
|
|
||||||
return internal::squared_distance(pt, ray.supporting_line(), k);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(const typename K::Ray_2 &ray,
|
|
||||||
const typename K::Point_2 &pt,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(pt, ray, k);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
typename K::FT
|
|
||||||
squared_distance(const typename K::Point_2 &pt,
|
|
||||||
const typename K::Segment_2 &seg,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
typename K::Construct_vector_2 construct_vector;
|
|
||||||
typedef typename K::Vector_2 Vector_2;
|
|
||||||
typedef typename K::RT RT;
|
|
||||||
// assert that the segment is valid (non zero length).
|
|
||||||
Vector_2 diff = construct_vector(seg.source(), pt);
|
|
||||||
Vector_2 segvec = construct_vector(seg.source(), seg.target());
|
|
||||||
RT d = wdot(diff,segvec, k);
|
|
||||||
if (d <= (RT)0)
|
|
||||||
return (typename K::FT)k.compute_squared_length_2_object()(diff);
|
|
||||||
RT e = wdot(segvec,segvec, k);
|
|
||||||
if (wmult((K*)0 ,d, segvec.hw()) > wmult((K*)0, e, diff.hw()))
|
|
||||||
return internal::squared_distance(pt, seg.target(), k);
|
|
||||||
return internal::squared_distance(pt, seg.supporting_line(), k);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(const typename K::Segment_2 &seg,
|
|
||||||
const typename K::Point_2 &pt,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(pt, seg, k);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
typename K::FT
|
|
||||||
squared_distance_parallel(const typename K::Segment_2 &seg1,
|
|
||||||
const typename K::Segment_2 &seg2,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
typedef typename K::Vector_2 Vector_2;
|
|
||||||
const Vector_2 &dir1 = seg1.direction().vector();
|
|
||||||
const Vector_2 &dir2 = seg2.direction().vector();
|
|
||||||
if (same_direction(dir1, dir2, k)) {
|
|
||||||
if (!is_acute_angle(seg1.source(), seg1.target(), seg2.source(), k))
|
|
||||||
return internal::squared_distance(seg1.target(), seg2.source(), k);
|
|
||||||
if (!is_acute_angle(seg1.target(), seg1.source(), seg2.target(), k))
|
|
||||||
return internal::squared_distance(seg1.source(), seg2.target(), k);
|
|
||||||
} else {
|
|
||||||
if (!is_acute_angle(seg1.source(), seg1.target(), seg2.target(), k))
|
|
||||||
return internal::squared_distance(seg1.target(), seg2.target(), k);
|
|
||||||
if (!is_acute_angle(seg1.target(), seg1.source(), seg2.source(), k))
|
|
||||||
return internal::squared_distance(seg1.source(), seg2.source(), k);
|
|
||||||
}
|
|
||||||
return internal::squared_distance(seg2.source(), seg1.supporting_line(), k);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::RT
|
|
||||||
_distance_measure_sub(const typename K::RT &startwcross,
|
|
||||||
const typename K::RT &endwcross,
|
|
||||||
const typename K::Point_2 &start,
|
|
||||||
const typename K::Point_2 &end)
|
|
||||||
{
|
|
||||||
return CGAL_NTS abs(wmult((K*)0, startwcross, end.hw())) -
|
|
||||||
CGAL_NTS abs(wmult((K*)0, endwcross, start.hw()));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
typename K::FT
|
|
||||||
squared_distance(const typename K::Segment_2 &seg1,
|
|
||||||
const typename K::Segment_2 &seg2,
|
|
||||||
const K& k,
|
|
||||||
const Cartesian_tag&)
|
|
||||||
{
|
|
||||||
typedef typename K::RT RT;
|
|
||||||
typedef typename K::FT FT;
|
|
||||||
bool crossing1, crossing2;
|
|
||||||
RT c1s, c1e, c2s, c2e;
|
|
||||||
if (seg1.source() == seg1.target())
|
|
||||||
return internal::squared_distance(seg1.source(), seg2, k);
|
|
||||||
if (seg2.source() == seg2.target())
|
|
||||||
return internal::squared_distance(seg2.source(), seg1, k);
|
|
||||||
|
|
||||||
Orientation o1s = orientation(seg2.source(), seg2.target(), seg1.source());
|
|
||||||
Orientation o1e = orientation(seg2.source(), seg2.target(), seg1.target());
|
|
||||||
if (o1s == RIGHT_TURN) {
|
|
||||||
crossing1 = (o1e != RIGHT_TURN);
|
|
||||||
} else {
|
|
||||||
if (o1e != LEFT_TURN) {
|
|
||||||
if (o1s == COLLINEAR && o1e == COLLINEAR)
|
|
||||||
return internal::squared_distance_parallel(seg1, seg2, k);
|
|
||||||
crossing1 = true;
|
|
||||||
} else {
|
|
||||||
crossing1 = (o1s == COLLINEAR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Orientation o2s = orientation(seg1.source(), seg1.target(), seg2.source());
|
|
||||||
Orientation o2e = orientation(seg1.source(), seg1.target(), seg2.target());
|
|
||||||
if (o2s == RIGHT_TURN) {
|
|
||||||
crossing2 = (o2e != RIGHT_TURN);
|
|
||||||
} else {
|
|
||||||
if (o2e != LEFT_TURN) {
|
|
||||||
if (o2s == COLLINEAR && o2e == COLLINEAR)
|
|
||||||
return internal::squared_distance_parallel(seg1, seg2, k);
|
|
||||||
crossing2 = true;
|
|
||||||
} else {
|
|
||||||
crossing2 = (o2s == COLLINEAR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (crossing1) {
|
|
||||||
if (crossing2)
|
|
||||||
return (FT)0;
|
|
||||||
|
|
||||||
c2s = CGAL::abs(wcross(seg1.source(), seg1.target(), seg2.source(), k));
|
|
||||||
c2e = CGAL::abs(wcross(seg1.source(), seg1.target(), seg2.target(), k));
|
|
||||||
Comparison_result dm = CGAL::compare(c2s,c2e);
|
|
||||||
|
|
||||||
if (dm == SMALLER) {
|
|
||||||
return internal::squared_distance(seg2.source(), seg1, k);
|
|
||||||
} else {
|
|
||||||
if (dm == LARGER) {
|
|
||||||
return internal::squared_distance(seg2.target(), seg1, k);
|
|
||||||
} else {
|
|
||||||
// parallel, should not happen (no crossing)
|
|
||||||
return internal::squared_distance_parallel(seg1, seg2, k);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
c1s = CGAL::abs(wcross(seg2.source(), seg2.target(), seg1.source(), k));
|
|
||||||
c1e = CGAL::abs(wcross(seg2.source(), seg2.target(), seg1.target(), k));
|
|
||||||
Comparison_result dm = CGAL::compare(c1s,c1e);
|
|
||||||
if (crossing2) {
|
|
||||||
if (dm == SMALLER) {
|
|
||||||
return internal::squared_distance(seg1.source(), seg2, k);
|
|
||||||
} else {
|
|
||||||
if (dm == LARGER) {
|
|
||||||
return internal::squared_distance(seg1.target(), seg2, k);
|
|
||||||
} else {
|
|
||||||
// parallel, should not happen (no crossing)
|
|
||||||
return internal::squared_distance_parallel(seg1, seg2, k);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
FT min1, min2;
|
|
||||||
|
|
||||||
if (dm == EQUAL)
|
|
||||||
return internal::squared_distance_parallel(seg1, seg2, k);
|
|
||||||
min1 = (dm == SMALLER) ?
|
|
||||||
internal::squared_distance(seg1.source(), seg2, k):
|
|
||||||
internal::squared_distance(seg1.target(), seg2, k);
|
|
||||||
|
|
||||||
c2s = CGAL::abs(wcross(seg1.source(), seg1.target(), seg2.source(), k));
|
|
||||||
c2e = CGAL::abs(wcross(seg1.source(), seg1.target(), seg2.target(), k));
|
|
||||||
dm = CGAL::compare(c2s,c2e);
|
|
||||||
|
|
||||||
if (dm == EQUAL) // should not happen.
|
|
||||||
return internal::squared_distance_parallel(seg1, seg2, k);
|
|
||||||
min2 = (dm == SMALLER) ?
|
|
||||||
internal::squared_distance(seg2.source(), seg1, k):
|
|
||||||
internal::squared_distance(seg2.target(), seg1, k);
|
|
||||||
return (min1 < min2) ? min1 : min2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
typename K::FT
|
|
||||||
squared_distance(const typename K::Segment_2 &seg1,
|
|
||||||
const typename K::Segment_2 &seg2,
|
|
||||||
const K& k,
|
|
||||||
const Homogeneous_tag&)
|
|
||||||
{
|
|
||||||
typedef typename K::RT RT;
|
|
||||||
typedef typename K::FT FT;
|
|
||||||
bool crossing1, crossing2;
|
|
||||||
RT c1s, c1e, c2s, c2e;
|
|
||||||
if (seg1.source() == seg1.target())
|
|
||||||
return internal::squared_distance(seg1.source(), seg2, k);
|
|
||||||
if (seg2.source() == seg2.target())
|
|
||||||
return internal::squared_distance(seg2.source(), seg1, k);
|
|
||||||
c1s = wcross(seg2.source(), seg2.target(), seg1.source(), k);
|
|
||||||
c1e = wcross(seg2.source(), seg2.target(), seg1.target(), k);
|
|
||||||
c2s = wcross(seg1.source(), seg1.target(), seg2.source(), k);
|
|
||||||
c2e = wcross(seg1.source(), seg1.target(), seg2.target(), k);
|
|
||||||
if (c1s < RT(0)) {
|
|
||||||
crossing1 = (c1e >= RT(0));
|
|
||||||
} else {
|
|
||||||
if (c1e <= RT(0)) {
|
|
||||||
if (c1s == RT(0) && c1e == RT(0))
|
|
||||||
return internal::squared_distance_parallel(seg1, seg2, k);
|
|
||||||
crossing1 = true;
|
|
||||||
} else {
|
|
||||||
crossing1 = (c1s == RT(0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (c2s < RT(0)) {
|
|
||||||
crossing2 = (c2e >= RT(0));
|
|
||||||
} else {
|
|
||||||
if (c2e <= RT(0)) {
|
|
||||||
if (c2s == RT(0) && c2e == RT(0))
|
|
||||||
return internal::squared_distance_parallel(seg1, seg2, k);
|
|
||||||
crossing2 = true;
|
|
||||||
} else {
|
|
||||||
crossing2 = (c2s == RT(0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (crossing1) {
|
|
||||||
if (crossing2)
|
|
||||||
return (FT)0;
|
|
||||||
RT dm;
|
|
||||||
dm = _distance_measure_sub<K>(c2s,c2e, seg2.source(), seg2.target());
|
|
||||||
if (dm < RT(0)) {
|
|
||||||
return internal::squared_distance(seg2.source(), seg1, k);
|
|
||||||
} else {
|
|
||||||
if (dm > RT(0)) {
|
|
||||||
return internal::squared_distance(seg2.target(), seg1, k);
|
|
||||||
} else {
|
|
||||||
// parallel, should not happen (no crossing)
|
|
||||||
return internal::squared_distance_parallel(seg1, seg2, k);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (crossing2) {
|
|
||||||
RT dm;
|
|
||||||
dm =
|
|
||||||
_distance_measure_sub<K>(c1s, c1e,seg1.source(),seg1.target());
|
|
||||||
if (dm < RT(0)) {
|
|
||||||
return internal::squared_distance(seg1.source(), seg2, k);
|
|
||||||
} else {
|
|
||||||
if (dm > RT(0)) {
|
|
||||||
return internal::squared_distance(seg1.target(), seg2, k);
|
|
||||||
} else {
|
|
||||||
// parallel, should not happen (no crossing)
|
|
||||||
return internal::squared_distance_parallel(seg1, seg2, k);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
|
|
||||||
FT min1, min2;
|
|
||||||
RT dm = _distance_measure_sub<K>(
|
|
||||||
c1s, c1e, seg1.source(), seg1.target());
|
|
||||||
if (dm == RT(0))
|
|
||||||
return internal::squared_distance_parallel(seg1, seg2, k);
|
|
||||||
min1 = (dm < RT(0)) ?
|
|
||||||
internal::squared_distance(seg1.source(), seg2, k):
|
|
||||||
internal::squared_distance(seg1.target(), seg2, k);
|
|
||||||
dm = _distance_measure_sub<K>(
|
|
||||||
c2s, c2e, seg2.source(), seg2.target());
|
|
||||||
if (dm == RT(0)) // should not happen.
|
|
||||||
return internal::squared_distance_parallel(seg1, seg2, k);
|
|
||||||
min2 = (dm < RT(0)) ?
|
|
||||||
internal::squared_distance(seg2.source(), seg1, k):
|
|
||||||
internal::squared_distance(seg2.target(), seg1, k);
|
|
||||||
return (min1 < min2) ? min1 : min2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::RT
|
|
||||||
_distance_measure_sub(const typename K::RT &startwcross,
|
|
||||||
const typename K::RT &endwcross,
|
|
||||||
const typename K::Vector_2 &start,
|
|
||||||
const typename K::Vector_2 &end)
|
|
||||||
{
|
|
||||||
return CGAL_NTS abs(wmult((K*)0, startwcross, end.hw())) -
|
|
||||||
CGAL_NTS abs(wmult((K*)0, endwcross, start.hw()));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
typename K::FT
|
|
||||||
squared_distance_parallel(const typename K::Segment_2 &seg,
|
|
||||||
const typename K::Ray_2 &ray,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
typedef typename K::Vector_2 Vector_2;
|
|
||||||
const Vector_2 &dir1 = seg.direction().vector();
|
|
||||||
const Vector_2 &dir2 = ray.direction().vector();
|
|
||||||
|
|
||||||
if (same_direction(dir1, dir2, k)) {
|
|
||||||
if (!is_acute_angle(seg.source(), seg.target(), ray.source(), k))
|
|
||||||
return internal::squared_distance(seg.target(), ray.source(), k);
|
|
||||||
} else {
|
|
||||||
if (!is_acute_angle(seg.target(), seg.source(), ray.source(), k))
|
|
||||||
return internal::squared_distance(seg.source(), ray.source(), k);
|
|
||||||
}
|
|
||||||
return internal::squared_distance(ray.source(), seg.supporting_line(), k);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
typename K::FT
|
|
||||||
squared_distance(const typename K::Segment_2 &seg,
|
|
||||||
const typename K::Ray_2 &ray,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
typename K::Construct_vector_2 construct_vector;
|
|
||||||
typedef typename K::RT RT;
|
|
||||||
typedef typename K::FT FT;
|
|
||||||
typedef typename K::Vector_2 Vector_2;
|
|
||||||
const Vector_2 &raydir = ray.direction().vector();
|
|
||||||
Vector_2 startvec(construct_vector(ray.source(), seg.source()));
|
|
||||||
Vector_2 endvec(construct_vector(ray.source(), seg.target()));
|
|
||||||
typename K::Orientation_2 orientation;
|
|
||||||
|
|
||||||
bool crossing1, crossing2;
|
|
||||||
RT c1s, c1e;
|
|
||||||
if (seg.source() == seg.target())
|
|
||||||
return internal::squared_distance(seg.source(), ray, k);
|
|
||||||
c1s = wcross(raydir, startvec, k);
|
|
||||||
c1e = wcross(raydir, endvec, k);
|
|
||||||
if (c1s < RT(0)) {
|
|
||||||
crossing1 = (c1e >= RT(0));
|
|
||||||
} else {
|
|
||||||
if (c1e <= RT(0)) {
|
|
||||||
if (c1s == RT(0) && c1e == RT(0))
|
|
||||||
return internal::squared_distance_parallel(seg, ray, k);
|
|
||||||
crossing1 = true;
|
|
||||||
} else {
|
|
||||||
crossing1 = (c1s == RT(0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
switch (orientation(seg.source(), seg.target(), ray.source())) {
|
|
||||||
case LEFT_TURN:
|
|
||||||
crossing2 = right_turn(construct_vector(seg.source(), seg.target()), raydir, k);
|
|
||||||
break;
|
|
||||||
case RIGHT_TURN:
|
|
||||||
crossing2 = left_turn(construct_vector(seg.source(), seg.target()), raydir, k);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
crossing2 = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (crossing1) {
|
|
||||||
if (crossing2)
|
|
||||||
return FT(0);
|
|
||||||
return internal::squared_distance(ray.source(), seg, k);
|
|
||||||
} else {
|
|
||||||
if (crossing2) {
|
|
||||||
RT dm;
|
|
||||||
dm = _distance_measure_sub<K>(c1s, c1e, startvec, endvec);
|
|
||||||
if (dm < RT(0)) {
|
|
||||||
return internal::squared_distance(seg.source(), ray, k);
|
|
||||||
} else {
|
|
||||||
if (dm > RT(0)) {
|
|
||||||
return internal::squared_distance(seg.target(), ray, k);
|
|
||||||
} else {
|
|
||||||
// parallel, should not happen (no crossing)
|
|
||||||
return internal::squared_distance_parallel(seg, ray, k);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
FT min1, min2;
|
|
||||||
RT dm = _distance_measure_sub<K>(c1s, c1e, startvec, endvec);
|
|
||||||
if (dm == RT(0))
|
|
||||||
return internal::squared_distance_parallel(seg, ray, k);
|
|
||||||
min1 = (dm < RT(0))
|
|
||||||
? internal::squared_distance(seg.source(), ray, k)
|
|
||||||
: internal::squared_distance(seg.target(), ray, k);
|
|
||||||
min2 = internal::squared_distance(ray.source(), seg, k);
|
|
||||||
return (min1 < min2) ? min1 : min2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(const typename K::Ray_2 &ray,
|
|
||||||
const typename K::Segment_2 &seg,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(seg, ray, k);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
typename K::FT
|
|
||||||
_sqd_to_line(const typename K::Vector_2 &diff,
|
|
||||||
const typename K::RT & wcross,
|
|
||||||
const typename K::Vector_2 &dir )
|
|
||||||
{
|
|
||||||
typedef typename K::RT RT;
|
|
||||||
typedef typename K::FT FT;
|
|
||||||
RT numerator = CGAL_NTS square(wcross);
|
|
||||||
RT denominator = wmult((K*)0, RT(wdot(dir,dir, K())),
|
|
||||||
diff.hw(), diff.hw());
|
|
||||||
return Rational_traits<FT>().make_rational(numerator, denominator);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
typename K::FT
|
|
||||||
squared_distance(const typename K::Segment_2 &seg,
|
|
||||||
const typename K::Line_2 &line,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
typename K::Construct_vector_2 construct_vector;
|
|
||||||
typedef typename K::RT RT;
|
|
||||||
typedef typename K::FT FT;
|
|
||||||
typedef typename K::Vector_2 Vector_2;
|
|
||||||
typedef typename K::Point_2 Point_2;
|
|
||||||
const Vector_2 &linedir = line.direction().vector();
|
|
||||||
const Point_2 &linepoint = line.point();
|
|
||||||
Vector_2 startvec(construct_vector(linepoint, seg.source()));
|
|
||||||
Vector_2 endvec(construct_vector(linepoint, seg.target()));
|
|
||||||
|
|
||||||
bool crossing1;
|
|
||||||
RT c1s, c1e;
|
|
||||||
if (seg.source() == seg.target())
|
|
||||||
return internal::squared_distance(seg.source(), line, k);
|
|
||||||
c1s = wcross(linedir, startvec, k);
|
|
||||||
c1e = wcross(linedir, endvec, k);
|
|
||||||
if (c1s < RT(0)) {
|
|
||||||
crossing1 = (c1e >= RT(0));
|
|
||||||
} else {
|
|
||||||
if (c1e <= RT(0)) {
|
|
||||||
crossing1 = true;
|
|
||||||
} else {
|
|
||||||
crossing1 = (c1s == RT(0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (crossing1) {
|
|
||||||
return (FT)0;
|
|
||||||
} else {
|
|
||||||
RT dm;
|
|
||||||
dm = _distance_measure_sub<K>(c1s, c1e, startvec, endvec);
|
|
||||||
if (dm <= RT(0)) {
|
|
||||||
return _sqd_to_line<K>(startvec, c1s, linedir);
|
|
||||||
} else {
|
|
||||||
return _sqd_to_line<K>(endvec, c1e, linedir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(const typename K::Line_2 &line,
|
|
||||||
const typename K::Segment_2 &seg,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(seg, line, k);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
typename K::FT
|
|
||||||
ray_ray_squared_distance_parallel(
|
|
||||||
const typename K::Vector_2 &ray1dir,
|
|
||||||
const typename K::Vector_2 &ray2dir,
|
|
||||||
const typename K::Vector_2 &from1to2,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
typedef typename K::RT RT;
|
|
||||||
typedef typename K::FT FT;
|
|
||||||
if (!is_acute_angle(ray1dir, from1to2, k)) {
|
|
||||||
if (!same_direction(ray1dir, ray2dir, k))
|
|
||||||
return (typename K::FT)k.compute_squared_length_2_object()(from1to2);
|
|
||||||
}
|
|
||||||
RT wcr, w;
|
|
||||||
wcr = wcross(ray1dir, from1to2, k);
|
|
||||||
w = from1to2.hw();
|
|
||||||
return (typename K::FT)(FT(wcr*wcr)
|
|
||||||
/ FT(wmult((K*)0, RT(wdot(ray1dir, ray1dir, k)), w, w)));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
typename K::FT
|
|
||||||
squared_distance(const typename K::Ray_2 &ray1,
|
|
||||||
const typename K::Ray_2 &ray2,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
typename K::Construct_vector_2 construct_vector;
|
|
||||||
typedef typename K::Vector_2 Vector_2;
|
|
||||||
typedef typename K::FT FT;
|
|
||||||
const Vector_2 &ray1dir = ray1.direction().vector();
|
|
||||||
const Vector_2 &ray2dir = ray2.direction().vector();
|
|
||||||
Vector_2 diffvec(construct_vector(ray1.source(),ray2.source()));
|
|
||||||
|
|
||||||
bool crossing1, crossing2;
|
|
||||||
switch (orientation(ray1dir, ray2dir, k)) {
|
|
||||||
case COUNTERCLOCKWISE:
|
|
||||||
crossing1 = !clockwise(diffvec, ray2dir, k);
|
|
||||||
crossing2 = !counterclockwise(ray1dir, diffvec, k);
|
|
||||||
break;
|
|
||||||
case CLOCKWISE:
|
|
||||||
crossing1 = !counterclockwise(diffvec, ray2dir, k);
|
|
||||||
crossing2 = !clockwise(ray1dir, diffvec, k);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return ray_ray_squared_distance_parallel(ray1dir,ray2dir,diffvec,k);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (crossing1) {
|
|
||||||
if (crossing2)
|
|
||||||
return (FT)0;
|
|
||||||
return internal::squared_distance(ray2.source(), ray1, k);
|
|
||||||
} else {
|
|
||||||
if (crossing2) {
|
|
||||||
return internal::squared_distance(ray1.source(), ray2, k);
|
|
||||||
} else {
|
|
||||||
|
|
||||||
FT min1, min2;
|
|
||||||
min1 = internal::squared_distance(ray1.source(), ray2, k);
|
|
||||||
min2 = internal::squared_distance(ray2.source(), ray1, k);
|
|
||||||
return (min1 < min2) ? min1 : min2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
typename K::FT
|
|
||||||
squared_distance(const typename K::Line_2 &line,
|
|
||||||
const typename K::Ray_2 &ray,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
typename K::Construct_vector_2 construct_vector;
|
|
||||||
typedef typename K::FT FT;
|
|
||||||
typedef typename K::Vector_2 Vector_2;
|
|
||||||
Vector_2 normalvec(line.a(), line.b());
|
|
||||||
Vector_2 diff = construct_vector(line.point(), ray.source());
|
|
||||||
FT sign_dist = k.compute_scalar_product_2_object()(diff,normalvec);
|
|
||||||
if (sign_dist < FT(0)) {
|
|
||||||
if (is_acute_angle(normalvec, ray.direction().vector(), k) )
|
|
||||||
return (FT)0;
|
|
||||||
} else {
|
|
||||||
if (is_obtuse_angle(normalvec, ray.direction().vector(), k) )
|
|
||||||
return (FT)0;
|
|
||||||
}
|
|
||||||
return (typename K::FT)((sign_dist*sign_dist)/k.compute_squared_length_2_object()(normalvec));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(const typename K::Ray_2 &ray,
|
|
||||||
const typename K::Line_2 &line,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(line, ray, k);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(const typename K::Line_2 &line1,
|
|
||||||
const typename K::Line_2 &line2,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
typedef typename K::FT FT;
|
|
||||||
if (internal::parallel(line1, line2, k))
|
|
||||||
return internal::squared_distance(line1.point(), line2, k);
|
|
||||||
else
|
|
||||||
return (FT)0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
void
|
|
||||||
distance_index(int &ind,
|
|
||||||
const typename K::Point_2 &pt,
|
|
||||||
const typename K::Ray_2 &ray,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
typename K::Construct_vector_2 construct_vector;
|
|
||||||
if (!is_acute_angle(ray.direction().vector(), construct_vector(ray.source(), pt), k)) {
|
|
||||||
ind = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ind = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
void
|
|
||||||
distance_index(int &ind,
|
|
||||||
const typename K::Point_2 &pt,
|
|
||||||
const typename K::Segment_2 &seg,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
if (!is_acute_angle(seg.target(),seg.source(),pt, k)) {
|
|
||||||
ind = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!is_acute_angle(seg.source(),seg.target(),pt, k)) {
|
|
||||||
ind = 1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ind = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance_indexed(const typename K::Point_2 &pt,
|
|
||||||
const typename K::Ray_2 &ray,
|
|
||||||
int ind,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
if (ind == 0)
|
|
||||||
return internal::squared_distance(pt, ray.source(), k);
|
|
||||||
return internal::squared_distance(pt, ray.supporting_line(), k);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance_indexed(const typename K::Point_2 &pt,
|
|
||||||
const typename K::Segment_2 &seg,
|
|
||||||
int ind,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
if (ind == 0)
|
|
||||||
return internal::squared_distance(pt, seg.source(), k);
|
|
||||||
if (ind == 1)
|
|
||||||
return internal::squared_distance(pt, seg.target(), k);
|
|
||||||
return internal::squared_distance(pt, seg.supporting_line(), k);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(const Point_2<K> & pt1, const Point_2<K> & pt2)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(pt1, pt2, K());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(const Point_2<K> &pt, const Line_2<K> &line)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(pt, line, K());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(const Line_2<K> & line, const Point_2<K> & pt)
|
|
||||||
{
|
|
||||||
return squared_distance(pt, line);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(const Point_2<K> &pt, const Ray_2<K> &ray)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(pt, ray, K());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(const Ray_2<K> & ray, const Point_2<K> & pt)
|
|
||||||
{
|
|
||||||
return squared_distance(pt, ray);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(const Point_2<K> &pt, const Segment_2<K> &seg)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(pt, seg, K());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(const Segment_2<K> & seg, const Point_2<K> & pt)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(pt, seg, K());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(const Segment_2<K> &seg1, const Segment_2<K> &seg2)
|
|
||||||
{
|
|
||||||
typedef typename K::Kernel_tag Tag;
|
|
||||||
return internal::squared_distance(seg1, seg2, K(), Tag());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(const Segment_2<K> &seg, const Ray_2<K> &ray)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(seg, ray, K());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(const Ray_2<K> & ray, const Segment_2<K> & seg)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(seg, ray, K());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(const Segment_2<K> &seg, const Line_2<K> &line)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(seg, line, K());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(const Line_2<K> & line, const Segment_2<K> & seg)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(seg, line, K());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(const Ray_2<K> &ray1, const Ray_2<K> &ray2)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(ray1, ray2, K());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(const Line_2<K> &line, const Ray_2<K> &ray)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(line, ray, K());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(const Ray_2<K> & ray, const Line_2<K> & line)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(line, ray, K());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(const Line_2<K> &line1, const Line_2<K> &line2)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(line1, line2, K());
|
|
||||||
}
|
|
||||||
|
|
||||||
} //namespace CGAL
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,566 +0,0 @@
|
||||||
// Copyright (c) 1998-2004
|
|
||||||
// Utrecht University (The Netherlands),
|
|
||||||
// ETH Zurich (Switzerland),
|
|
||||||
// INRIA Sophia-Antipolis (France),
|
|
||||||
// Max-Planck-Institute Saarbruecken (Germany),
|
|
||||||
// and Tel-Aviv University (Israel). All rights reserved.
|
|
||||||
//
|
|
||||||
// This file is part of CGAL (www.cgal.org)
|
|
||||||
//
|
|
||||||
// $URL$
|
|
||||||
// $Id$
|
|
||||||
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Author(s) : Geert-Jan Giezeman
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef CGAL_SQUARED_DISTANCE_2_2_H
|
|
||||||
#define CGAL_SQUARED_DISTANCE_2_2_H
|
|
||||||
|
|
||||||
#include <CGAL/user_classes.h>
|
|
||||||
|
|
||||||
#include <CGAL/kernel_assertions.h>
|
|
||||||
#include <CGAL/Point_2.h>
|
|
||||||
#include <CGAL/Segment_2.h>
|
|
||||||
#include <CGAL/Line_2.h>
|
|
||||||
#include <CGAL/Ray_2.h>
|
|
||||||
#include <CGAL/Triangle_2.h>
|
|
||||||
#include <CGAL/enum.h>
|
|
||||||
#include <CGAL/wmult.h>
|
|
||||||
#include <CGAL/squared_distance_utils.h>
|
|
||||||
#include <CGAL/squared_distance_2_1.h>
|
|
||||||
|
|
||||||
namespace CGAL {
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
void
|
|
||||||
distance_index(int &ind1,
|
|
||||||
int &ind2,
|
|
||||||
const typename K::Point_2 &pt,
|
|
||||||
const typename K::Triangle_2 &triangle,
|
|
||||||
const K& k )
|
|
||||||
{
|
|
||||||
typename K::Left_turn_2 leftturn = k.left_turn_2_object();
|
|
||||||
typedef typename K::Point_2 Point_2;
|
|
||||||
const Point_2 &vt0 = triangle.vertex(0);
|
|
||||||
const Point_2 &vt1 = triangle.vertex(1);
|
|
||||||
const Point_2 &vt2 = triangle.vertex(2);
|
|
||||||
if (leftturn(vt0, vt1, vt2)) {
|
|
||||||
if (leftturn(pt, vt1, vt0)) {
|
|
||||||
if (!is_acute_angle(vt0, vt1, pt, k)) {
|
|
||||||
if (leftturn(pt, vt2, vt1)) {
|
|
||||||
if (!is_acute_angle(vt1, vt2, pt, k)) {
|
|
||||||
ind1 = 2; ind2 = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!is_acute_angle(vt2, vt1, pt, k)) {
|
|
||||||
ind1 = 1; ind2 = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ind1 = 1; ind2 = 2;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ind1 = 1; ind2 = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!is_acute_angle(vt1, vt0, pt, k)) {
|
|
||||||
if (leftturn(pt, vt0, vt2)) {
|
|
||||||
if (!is_acute_angle(vt0, vt2, pt, k)) {
|
|
||||||
ind1 = 2; ind2 = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!is_acute_angle(vt2, vt0, pt, k)) {
|
|
||||||
ind1 = 0; ind2 = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ind1 = 2; ind2 = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ind1 = 0; ind2 = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ind1 = 0; ind2 = 1;
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
if (leftturn(pt, vt2, vt1)) {
|
|
||||||
if (!is_acute_angle(vt1, vt2, pt, k)) {
|
|
||||||
if (leftturn(pt, vt0, vt2)) {
|
|
||||||
if (!is_acute_angle(vt0, vt2, pt, k)) {
|
|
||||||
ind1 = 2; ind2 = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!is_acute_angle(vt2, vt0, pt, k)) {
|
|
||||||
ind1 = 0; ind2 = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ind1 = 2; ind2 = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ind1 = 0; ind2 = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!is_acute_angle(vt2, vt1, pt, k)) {
|
|
||||||
ind1 = 1; ind2 = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ind1 = 1; ind2 = 2;
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
if (leftturn(pt, vt0, vt2)) {
|
|
||||||
if (!is_acute_angle(vt2, vt0, pt, k)) {
|
|
||||||
ind1 = 0; ind2 = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!is_acute_angle(vt0, vt2, pt, k)) {
|
|
||||||
ind1 = 2; ind2 = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ind1 = 2; ind2 = 0;
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
ind1 = -1; ind2 = -1; // point inside or on boundary.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (leftturn(pt, vt2, vt0)) {
|
|
||||||
if (!is_acute_angle(vt0, vt2, pt, k)) {
|
|
||||||
if (leftturn(pt, vt1, vt2)) {
|
|
||||||
if (!is_acute_angle(vt2, vt1, pt, k)) {
|
|
||||||
ind1 = 1; ind2 = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!is_acute_angle(vt1, vt2, pt, k)) {
|
|
||||||
ind1 = 2; ind2 = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ind1 = 2; ind2 = 1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ind1 = 2; ind2 = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!is_acute_angle(vt2, vt0, pt, k)) {
|
|
||||||
if (leftturn(pt, vt0, vt1)) {
|
|
||||||
if (!is_acute_angle(vt0, vt1, pt, k)) {
|
|
||||||
ind1 = 1; ind2 = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!is_acute_angle(vt1, vt0, pt, k)) {
|
|
||||||
ind1 = 0; ind2 = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ind1 = 1; ind2 = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ind1 = 0; ind2 = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ind1 = 0; ind2 = 2;
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
if (leftturn(pt, vt1, vt2)) {
|
|
||||||
if (!is_acute_angle(vt2, vt1, pt, k)) {
|
|
||||||
if (leftturn(pt, vt0, vt1)) {
|
|
||||||
if (!is_acute_angle(vt0, vt1, pt, k)) {
|
|
||||||
ind1 = 1; ind2 = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!is_acute_angle(vt1, vt0, pt, k)) {
|
|
||||||
ind1 = 0; ind2 = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ind1 = 1; ind2 = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ind1 = 0; ind2 = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!is_acute_angle(vt1, vt2, pt, k)) {
|
|
||||||
ind1 = 2; ind2 = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ind1 = 2; ind2 = 1;
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
if (leftturn(pt, vt0, vt1)) {
|
|
||||||
if (!is_acute_angle(vt1, vt0, pt, k)) {
|
|
||||||
ind1 = 0; ind2 = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!is_acute_angle(vt0, vt1, pt, k)) {
|
|
||||||
ind1 = 1; ind2 = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ind1 = 1; ind2 = 0;
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
ind1 = -1; ind2 = -1; // point inside or on boundary.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
typename K::FT
|
|
||||||
squared_distance_indexed(const typename K::Point_2 &pt,
|
|
||||||
const typename K::Triangle_2 &triangle,
|
|
||||||
int ind1, int ind2,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
typedef typename K::FT FT;
|
|
||||||
typedef typename K::Line_2 Line_2;
|
|
||||||
if (ind1 == -1)
|
|
||||||
return FT(0);
|
|
||||||
if (ind2 == -1)
|
|
||||||
return internal::squared_distance(pt, triangle.vertex(ind1), k);
|
|
||||||
return internal::squared_distance(pt,
|
|
||||||
Line_2(triangle.vertex(ind1), triangle.vertex(ind2)),
|
|
||||||
k);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
typename K::FT
|
|
||||||
squared_distance(const typename K::Point_2 &pt,
|
|
||||||
const typename K::Triangle_2 &triangle,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
int ind1,ind2;
|
|
||||||
distance_index<K>(ind1, ind2, pt, triangle, k);
|
|
||||||
return squared_distance_indexed(pt, triangle, ind1, ind2, k);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(const typename K::Triangle_2 & triangle,
|
|
||||||
const typename K::Point_2 & pt,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(pt, triangle, k);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
typename K::FT
|
|
||||||
squared_distance(const typename K::Line_2 &line,
|
|
||||||
const typename K::Triangle_2 &triangle,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
typedef typename K::FT FT;
|
|
||||||
Oriented_side side0;
|
|
||||||
side0 = line.oriented_side(triangle.vertex(0));
|
|
||||||
if (line.oriented_side(triangle.vertex(1)) != side0)
|
|
||||||
return FT(0);
|
|
||||||
if (line.oriented_side(triangle.vertex(2)) != side0)
|
|
||||||
return FT(0);
|
|
||||||
FT mindist, dist;
|
|
||||||
int i;
|
|
||||||
mindist = internal::squared_distance(triangle.vertex(0),line,k);
|
|
||||||
for (i=1; i<3; i++) {
|
|
||||||
dist = internal::squared_distance(triangle.vertex(i),line,k);
|
|
||||||
if (dist < mindist)
|
|
||||||
mindist = dist;
|
|
||||||
}
|
|
||||||
return mindist;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(const typename K::Triangle_2 & triangle,
|
|
||||||
const typename K::Line_2 & line,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(line, triangle, k);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
typename K::FT
|
|
||||||
squared_distance(const typename K::Ray_2 &ray,
|
|
||||||
const typename K::Triangle_2 &triangle,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
typedef typename K::FT FT;
|
|
||||||
typedef typename K::Point_2 Point_2;
|
|
||||||
typedef typename K::Line_2 Line_2;
|
|
||||||
int i, ind_tr1, ind_tr2, ind_ray = 0, ind1;
|
|
||||||
FT mindist, dist;
|
|
||||||
distance_index<K>(ind_tr1, ind_tr2, ray.source(), triangle, k);
|
|
||||||
mindist =
|
|
||||||
squared_distance_indexed(ray.source(), triangle, ind_tr1, ind_tr2, k);
|
|
||||||
for (i=0; i<3; i++) {
|
|
||||||
const Point_2& pt = triangle.vertex(i);
|
|
||||||
distance_index<K>(ind1, pt, ray, k);
|
|
||||||
dist = squared_distance_indexed(pt, ray, ind1, k);
|
|
||||||
if (dist < mindist) {
|
|
||||||
ind_ray = ind1;
|
|
||||||
ind_tr1 = i; ind_tr2 = -1;
|
|
||||||
mindist = dist;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// now check if all vertices are on the right side of the separating line.
|
|
||||||
// In case of vertex-vertex smallest distance this is the case.
|
|
||||||
if (ind_tr2 == -1 && ind_ray != -1)
|
|
||||||
return mindist;
|
|
||||||
if (ind_tr2 != -1) {
|
|
||||||
// Check if all the segment vertices lie at the same side of
|
|
||||||
// the triangle segment.
|
|
||||||
const Point_2 &vt1 = triangle.vertex(ind_tr1);
|
|
||||||
const Point_2 &vt2 = triangle.vertex(ind_tr2);
|
|
||||||
if (clockwise(ray.direction().vector(), vt2-vt1, k)) {
|
|
||||||
mindist = FT(0);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Check if all the triangle vertices lie
|
|
||||||
// at the same side of the segment.
|
|
||||||
const Line_2 &sl = ray.supporting_line();
|
|
||||||
Oriented_side or_s = sl.oriented_side(triangle.vertex(0));
|
|
||||||
for (i=1; i<3; i++) {
|
|
||||||
if (sl.oriented_side(triangle.vertex(i)) != or_s) {
|
|
||||||
mindist = FT(0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return mindist;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(const typename K::Triangle_2 & triangle,
|
|
||||||
const typename K::Ray_2 & ray,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(ray, triangle, k);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
typename K::FT
|
|
||||||
squared_distance(const typename K::Segment_2 &seg,
|
|
||||||
const typename K::Triangle_2 &triangle,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
typedef typename K::FT FT;
|
|
||||||
typedef typename K::Point_2 Point_2;
|
|
||||||
typename K::Orientation_2 orientation;
|
|
||||||
int i, ind_tr1 = 0, ind_tr2 = -1, ind_seg = 0, ind1, ind2;
|
|
||||||
FT mindist, dist;
|
|
||||||
mindist = internal::squared_distance(seg.source(), triangle.vertex(0), k);
|
|
||||||
for (i=0; i<2; i++) {
|
|
||||||
const Point_2 &pt = seg.vertex(i);
|
|
||||||
distance_index<K>(ind1, ind2, pt, triangle, k);
|
|
||||||
dist = internal::squared_distance_indexed(pt, triangle, ind1, ind2, k);
|
|
||||||
if (dist < mindist) {
|
|
||||||
ind_seg = i;
|
|
||||||
ind_tr1 = ind1; ind_tr2 = ind2;
|
|
||||||
mindist = dist;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (i=0; i<3; i++) {
|
|
||||||
const Point_2& pt = triangle.vertex(i);
|
|
||||||
distance_index<K>(ind1, pt, seg, k);
|
|
||||||
dist = internal::squared_distance_indexed(pt, seg, ind1, k);
|
|
||||||
if (dist < mindist) {
|
|
||||||
ind_seg = ind1;
|
|
||||||
ind_tr1 = i; ind_tr2 = -1;
|
|
||||||
mindist = dist;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// now check if all vertices are on the right side of the separating line.
|
|
||||||
// In case of vertex-vertex smallest distance this is the case.
|
|
||||||
if (ind_tr2 == -1 && ind_seg != -1)
|
|
||||||
return mindist;
|
|
||||||
|
|
||||||
if (ind_tr2 != -1) {
|
|
||||||
// Check if all the segment vertices lie at the same side of
|
|
||||||
// the triangle segment.
|
|
||||||
const Point_2 &vt1 = triangle.vertex(ind_tr1);
|
|
||||||
const Point_2 &vt2 = triangle.vertex(ind_tr2);
|
|
||||||
Orientation or_s = orientation(vt1, vt2, seg.source());
|
|
||||||
if (orientation(vt1, vt2, seg.target()) != or_s) {
|
|
||||||
mindist = FT(0);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Check if all the triangle vertices lie
|
|
||||||
// at the same side of the segment.
|
|
||||||
const Point_2 &vt1 = seg.source();
|
|
||||||
const Point_2 &vt2 = seg.target();
|
|
||||||
Orientation or_s = orientation(vt1, vt2, triangle.vertex(0));
|
|
||||||
for (i=1; i<3; i++) {
|
|
||||||
if (orientation(vt1, vt2, triangle.vertex(i)) != or_s) {
|
|
||||||
mindist = FT(0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return mindist;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(const typename K::Triangle_2 & triangle,
|
|
||||||
const typename K::Segment_2 & seg,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(seg, triangle, k);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
typename K::FT
|
|
||||||
squared_distance(const typename K::Triangle_2 &triangle1,
|
|
||||||
const typename K::Triangle_2 &triangle2,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
typedef typename K::FT FT;
|
|
||||||
typedef typename K::Point_2 Point_2;
|
|
||||||
typename K::Orientation_2 orientation;
|
|
||||||
int i, ind1_1 = 0,ind1_2 = -1, ind2_1 = 0, ind2_2 = -1, ind1, ind2;
|
|
||||||
FT mindist, dist;
|
|
||||||
mindist =
|
|
||||||
internal::squared_distance(triangle1.vertex(0), triangle2.vertex(0), k);
|
|
||||||
for (i=0; i<3; i++) {
|
|
||||||
const Point_2& pt = triangle1.vertex(i);
|
|
||||||
distance_index<K>(ind1, ind2, pt, triangle2, k);
|
|
||||||
dist = squared_distance_indexed(pt, triangle2, ind1, ind2, k);
|
|
||||||
if (dist < mindist) {
|
|
||||||
ind1_1 = i; ind1_2 = -1;
|
|
||||||
ind2_1 = ind1; ind2_2 = ind2;
|
|
||||||
mindist = dist;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (i=0; i<3; i++) {
|
|
||||||
const Point_2& pt = triangle2.vertex(i);
|
|
||||||
distance_index<K>(ind1, ind2, pt, triangle1, k);
|
|
||||||
dist = squared_distance_indexed(pt, triangle1, ind1, ind2, k);
|
|
||||||
if (dist < mindist) {
|
|
||||||
ind1_1 = ind1; ind1_2 = ind2;
|
|
||||||
ind2_1 = i; ind2_2 = -1;
|
|
||||||
mindist = dist;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// now check if all vertices are on the right side of the
|
|
||||||
// separating line.
|
|
||||||
if (ind1_2 == -1 && ind2_2 == -1)
|
|
||||||
return mindist;
|
|
||||||
// In case of point-segment closest distance, there is still the
|
|
||||||
// possibility of overlapping triangles. Check if all the
|
|
||||||
// vertices lie at the same side of the segment.
|
|
||||||
if (ind1_2 != -1) {
|
|
||||||
const Point_2 &vt1 = triangle1.vertex(ind1_1);
|
|
||||||
const Point_2 &vt2 = triangle1.vertex(ind1_2);
|
|
||||||
Orientation or_s = orientation(vt1, vt2, triangle2.vertex(0));
|
|
||||||
for (i=1; i<3; i++) {
|
|
||||||
if (orientation(vt1, vt2, triangle2.vertex(i)) != or_s) {
|
|
||||||
mindist = FT(0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const Point_2 &vt1 = triangle2.vertex(ind2_1);
|
|
||||||
const Point_2 &vt2 = triangle2.vertex(ind2_2);
|
|
||||||
Orientation or_s = orientation(vt1, vt2, triangle1.vertex(0));
|
|
||||||
for (i=1; i<3; i++) {
|
|
||||||
if (orientation(vt1, vt2, triangle1.vertex(i)) != or_s) {
|
|
||||||
mindist = FT(0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return mindist;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(const Point_2<K> &pt,
|
|
||||||
const Triangle_2<K> &triangle)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(pt, triangle, K());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(const Triangle_2<K> &triangle,
|
|
||||||
const Point_2<K> &pt)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(pt, triangle, K());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(const Line_2<K> &line,
|
|
||||||
const Triangle_2<K> &triangle)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(line, triangle, K());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(const Triangle_2<K> &triangle,
|
|
||||||
const Line_2<K> &line)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(line, triangle, K());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(const Ray_2<K> &ray,
|
|
||||||
const Triangle_2<K> &triangle)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(ray, triangle, K());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(const Triangle_2<K> &triangle,
|
|
||||||
const Ray_2<K> &ray)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(ray, triangle, K());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(const Segment_2<K> &seg,
|
|
||||||
const Triangle_2<K> &triangle)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(seg, triangle, K());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(const Triangle_2<K> &triangle,
|
|
||||||
const Segment_2<K> &seg)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(seg, triangle, K());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(const Triangle_2<K> &triangle1,
|
|
||||||
const Triangle_2<K> &triangle2)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(triangle1, triangle2, K());
|
|
||||||
}
|
|
||||||
|
|
||||||
} //namespace CGAL
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
// 2D distance tests.
|
|
||||||
|
|
||||||
#ifdef NDEBUG
|
#ifdef NDEBUG
|
||||||
#undef NDEBUG //this testsuite requires NDEBUG to be not defined
|
#undef NDEBUG //this testsuite requires NDEBUG to be not defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include <CGAL/Simple_cartesian.h>
|
#include <CGAL/Simple_cartesian.h>
|
||||||
#include <CGAL/Simple_homogeneous.h>
|
#include <CGAL/Simple_homogeneous.h>
|
||||||
|
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||||
|
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||||
|
#include <CGAL/Homogeneous.h>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
@ -167,7 +167,7 @@ struct Test {
|
||||||
check_squared_distance (R(p( 4, 0), p(-3, -1)), R(p( 1, 1), p( 2, 11)), 2);
|
check_squared_distance (R(p( 4, 0), p(-3, -1)), R(p( 1, 1), p( 2, 11)), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void R_S()
|
void S_R()
|
||||||
{
|
{
|
||||||
std::cout << "Ray - Segment\n";
|
std::cout << "Ray - Segment\n";
|
||||||
check_squared_distance (R(p(2, 0), p( 0, 2)), S(p( 1, 1), p( 4, 0)), 0);
|
check_squared_distance (R(p(2, 0), p( 0, 2)), S(p( 1, 1), p( 4, 0)), 0);
|
||||||
|
|
@ -216,7 +216,7 @@ struct Test {
|
||||||
check_squared_distance (p( 1, 1), L(p( 4, 0), p( -3, -1)), 2);
|
check_squared_distance (p( 1, 1), L(p( 4, 0), p( -3, -1)), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void L_S()
|
void S_L()
|
||||||
{
|
{
|
||||||
std::cout << "Line - Segment\n";
|
std::cout << "Line - Segment\n";
|
||||||
check_squared_distance (L(p( 0, 0), p( 1, 0)), S(p( 2, 2), p( 3, 3)), 4);
|
check_squared_distance (L(p( 0, 0), p( 1, 0)), S(p( 2, 2), p( 3, 3)), 4);
|
||||||
|
|
@ -268,29 +268,38 @@ struct Test {
|
||||||
|
|
||||||
void run()
|
void run()
|
||||||
{
|
{
|
||||||
std::cout << "2D Distance tests\n";
|
std::cout << "-- Kernel: " << typeid(K).name() << std::endl;
|
||||||
|
|
||||||
P_P();
|
P_P();
|
||||||
P_S();
|
P_S();
|
||||||
S_S();
|
|
||||||
P_R();
|
P_R();
|
||||||
R_R();
|
|
||||||
R_S();
|
|
||||||
R_L();
|
|
||||||
P_L();
|
P_L();
|
||||||
L_S();
|
|
||||||
L_L();
|
|
||||||
P_T();
|
P_T();
|
||||||
L_T();
|
|
||||||
R_T();
|
S_S();
|
||||||
S_T();
|
S_T();
|
||||||
|
S_R();
|
||||||
|
S_L();
|
||||||
|
|
||||||
|
R_R();
|
||||||
|
R_L();
|
||||||
|
R_T();
|
||||||
|
|
||||||
|
L_L();
|
||||||
|
L_T();
|
||||||
|
|
||||||
T_T();
|
T_T();
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
Test< CGAL::Simple_cartesian<double> >().run();
|
std::cout << "2D Distance tests\n";
|
||||||
Test< CGAL::Simple_homogeneous<double> >().run();
|
|
||||||
// TODO : test more kernels.
|
Test<CGAL::Simple_cartesian<double> >().run();
|
||||||
|
Test<CGAL::Simple_homogeneous<double> >().run();
|
||||||
|
|
||||||
|
Test<CGAL::Homogeneous<CGAL::Epeck_ft> >().run();
|
||||||
|
Test<CGAL::Exact_predicates_inexact_constructions_kernel>().run();
|
||||||
|
Test<CGAL::Exact_predicates_exact_constructions_kernel>().run();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
// Copyright (c) 1998-2021
|
||||||
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org)
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Geert-Jan Giezeman, Andreas Fabri
|
||||||
|
|
||||||
|
#ifndef CGAL_DISTANCE_3_LINE_3_LINE_3_H
|
||||||
|
#define CGAL_DISTANCE_3_LINE_3_LINE_3_H
|
||||||
|
|
||||||
|
#include <CGAL/Distance_3/internal/squared_distance_utils_3.h>
|
||||||
|
|
||||||
|
#include <CGAL/Line_3.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const typename K::Line_3& line1,
|
||||||
|
const typename K::Line_3& line2,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::Vector_3 Vector_3;
|
||||||
|
|
||||||
|
typename K::Construct_vector_3 vector = k.construct_vector_3_object();
|
||||||
|
|
||||||
|
const Vector_3 dir1 = line1.direction().vector();
|
||||||
|
const Vector_3 dir2 = line2.direction().vector();
|
||||||
|
const Vector_3 normal = wcross(dir1, dir2, k);
|
||||||
|
const Vector_3 diff = vector(line1.point(), line2.point());
|
||||||
|
|
||||||
|
if (is_null(normal, k))
|
||||||
|
return squared_distance_to_line(dir2, diff, k);
|
||||||
|
|
||||||
|
return squared_distance_to_plane(normal, diff, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const Line_3<K>& line1,
|
||||||
|
const Line_3<K>& line2)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_3_object()(line1, line2);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_DISTANCE_3_LINE_3_LINE_3_H
|
||||||
|
|
@ -0,0 +1,86 @@
|
||||||
|
// Copyright (c) 1998-2021
|
||||||
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org)
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Geert-Jan Giezeman, Andreas Fabri
|
||||||
|
|
||||||
|
#ifndef CGAL_DISTANCE_3_LINE_3_PLANE_3_H
|
||||||
|
#define CGAL_DISTANCE_3_LINE_3_PLANE_3_H
|
||||||
|
|
||||||
|
#include <CGAL/Distance_3/internal/squared_distance_utils_3.h>
|
||||||
|
|
||||||
|
#include <CGAL/Line_3.h>
|
||||||
|
#include <CGAL/Plane_3.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
bool
|
||||||
|
contains_vector(const typename K::Plane_3& pl,
|
||||||
|
const typename K::Vector_3& vec,
|
||||||
|
const K&)
|
||||||
|
{
|
||||||
|
typedef typename K::RT RT;
|
||||||
|
|
||||||
|
return pl.a()*vec.hx() + pl.b()*vec.hy() + pl.c() * vec.hz() == RT(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const typename K::Line_3& l,
|
||||||
|
const typename K::Plane_3& pl,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::FT FT;
|
||||||
|
|
||||||
|
typename K::Compute_squared_distance_3 sq_dist = k.compute_squared_distance_3_object();
|
||||||
|
|
||||||
|
if(contains_vector(pl, l.direction().vector(), k))
|
||||||
|
return sq_dist(pl, l.point());
|
||||||
|
|
||||||
|
return FT(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const typename K::Plane_3& pl,
|
||||||
|
const typename K::Line_3& l,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
return squared_distance(l, pl, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const Line_3<K>& line,
|
||||||
|
const Plane_3<K>& plane)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_3_object()(line, plane);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const Plane_3<K>& plane,
|
||||||
|
const Line_3<K>& line)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_3_object()(plane, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_DISTANCE_3_LINE_3_PLANE_3_H
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
// Copyright (c) 1998-2021
|
||||||
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org)
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Geert-Jan Giezeman, Andreas Fabri
|
||||||
|
|
||||||
|
#ifndef CGAL_DISTANCE_3_PLANE_3_PLANE_3_H
|
||||||
|
#define CGAL_DISTANCE_3_PLANE_3_PLANE_3_H
|
||||||
|
|
||||||
|
#include <CGAL/Distance_3/internal/squared_distance_utils_3.h>
|
||||||
|
|
||||||
|
#include <CGAL/Plane_3.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const typename K::Plane_3& plane1,
|
||||||
|
const typename K::Plane_3& plane2,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typename K::Construct_orthogonal_vector_3 ortho_vec = k.construct_orthogonal_vector_3_object();
|
||||||
|
typename K::Compute_squared_distance_3 sq_dist = k.compute_squared_distance_3_object();
|
||||||
|
|
||||||
|
if(!is_null(wcross(ortho_vec(plane1), ortho_vec(plane2), k), k))
|
||||||
|
return typename K::FT(0);
|
||||||
|
else
|
||||||
|
return sq_dist(plane1.point(), plane2);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const Plane_3<K>& plane1,
|
||||||
|
const Plane_3<K>& plane2)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_3_object()(plane1, plane2);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_DISTANCE_3_PLANE_3_PLANE_3_H
|
||||||
|
|
@ -0,0 +1,91 @@
|
||||||
|
// Copyright (c) 1998-2021
|
||||||
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org)
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Geert-Jan Giezeman, Andreas Fabri, Mael Rouxel-Labbé
|
||||||
|
|
||||||
|
#ifndef CGAL_DISTANCE_3_POINT_3_LINE_3_H
|
||||||
|
#define CGAL_DISTANCE_3_POINT_3_LINE_3_H
|
||||||
|
|
||||||
|
#include <CGAL/Distance_3/internal/squared_distance_utils_3.h>
|
||||||
|
|
||||||
|
#include <CGAL/Line_3.h>
|
||||||
|
#include <CGAL/Point_3.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
void
|
||||||
|
squared_distance_RT(const typename K::Point_3 &pt,
|
||||||
|
const typename K::Line_3 &line,
|
||||||
|
typename K::RT& num,
|
||||||
|
typename K::RT& den,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::Vector_3 Vector_3;
|
||||||
|
|
||||||
|
typename K::Construct_vector_3 vector = k.construct_vector_3_object();
|
||||||
|
|
||||||
|
const Vector_3& dir = line.direction().vector();
|
||||||
|
const Vector_3 diff = vector(line.point(), pt);
|
||||||
|
|
||||||
|
return internal::squared_distance_to_line_RT(dir, diff, num, den, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const typename K::Point_3& pt,
|
||||||
|
const typename K::Line_3& line,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::RT RT;
|
||||||
|
typedef typename K::FT FT;
|
||||||
|
RT num, den;
|
||||||
|
squared_distance_RT(pt, line, num, den, k);
|
||||||
|
return Rational_traits<FT>().make_rational(num, den);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const typename K::Line_3& line,
|
||||||
|
const typename K::Point_3& pt,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
return squared_distance(pt, line, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const Point_3<K>& pt,
|
||||||
|
const Line_3<K>& line)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_3_object()(pt, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const Line_3<K>& line,
|
||||||
|
const Point_3<K>& pt)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_3_object()(line, pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_DISTANCE_3_POINT_3_LINE_3_H
|
||||||
|
|
@ -0,0 +1,73 @@
|
||||||
|
// Copyright (c) 1998-2021
|
||||||
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org)
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Geert-Jan Giezeman, Andreas Fabri
|
||||||
|
|
||||||
|
#ifndef CGAL_DISTANCE_3_POINT_3_PLANE_3_H
|
||||||
|
#define CGAL_DISTANCE_3_POINT_3_PLANE_3_H
|
||||||
|
|
||||||
|
#include <CGAL/Distance_3/internal/squared_distance_utils_3.h>
|
||||||
|
|
||||||
|
#include <CGAL/Point_3.h>
|
||||||
|
#include <CGAL/Plane_3.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const typename K::Point_3& pt,
|
||||||
|
const typename K::Plane_3& plane,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::Vector_3 Vector_3;
|
||||||
|
|
||||||
|
typename K::Construct_vector_3 vector = k.construct_vector_3_object();
|
||||||
|
|
||||||
|
Vector_3 diff = vector(plane.point(), pt);
|
||||||
|
return squared_distance_to_plane(plane.orthogonal_vector(), diff, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const typename K::Plane_3& plane,
|
||||||
|
const typename K::Point_3& pt,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
return squared_distance(pt, plane, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const Point_3<K>& pt,
|
||||||
|
const Plane_3<K>& plane)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_3_object()(pt, plane);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const Plane_3<K>& plane,
|
||||||
|
const Point_3<K>& pt)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_3_object()(plane, pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_DISTANCE_3_POINT_3_PLANE_3_H
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
// Copyright (c) 1998-2021
|
||||||
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org)
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Geert-Jan Giezeman, Andreas Fabri
|
||||||
|
|
||||||
|
#ifndef CGAL_DISTANCE_3_POINT_3_POINT_3_H
|
||||||
|
#define CGAL_DISTANCE_3_POINT_3_POINT_3_H
|
||||||
|
|
||||||
|
#include <CGAL/Point_3.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const typename K::Point_3& pt1,
|
||||||
|
const typename K::Point_3& pt2,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
return k.compute_squared_distance_3_object()(pt1, pt2);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const Point_3<K>& pt1,
|
||||||
|
const Point_3<K>& pt2)
|
||||||
|
{
|
||||||
|
return internal::squared_distance(pt1, pt2, K());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_DISTANCE_3_POINT_3_POINT_3_H
|
||||||
|
|
@ -0,0 +1,112 @@
|
||||||
|
// Copyright (c) 1998-2021
|
||||||
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org)
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Geert-Jan Giezeman, Andreas Fabri, Mael Rouxel-Labbé
|
||||||
|
|
||||||
|
#ifndef CGAL_DISTANCE_3_POINT_3_RAY_3_H
|
||||||
|
#define CGAL_DISTANCE_3_POINT_3_RAY_3_H
|
||||||
|
|
||||||
|
#include <CGAL/Distance_3/internal/squared_distance_utils_3.h>
|
||||||
|
|
||||||
|
#include <CGAL/Point_3.h>
|
||||||
|
#include <CGAL/Ray_3.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
void
|
||||||
|
squared_distance_RT(const typename K::Point_3 &pt,
|
||||||
|
const typename K::Ray_3 &ray,
|
||||||
|
typename K::RT& num,
|
||||||
|
typename K::RT& den,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::Vector_3 Vector_3;
|
||||||
|
typedef typename K::RT RT;
|
||||||
|
|
||||||
|
typename K::Construct_vector_3 vector = k.construct_vector_3_object();
|
||||||
|
|
||||||
|
const Vector_3 dir = ray.direction().vector();
|
||||||
|
const Vector_3 diff = vector(ray.source(), pt);
|
||||||
|
|
||||||
|
if(!is_acute_angle(dir, diff, k))
|
||||||
|
{
|
||||||
|
num = wdot(diff, diff, k);
|
||||||
|
den = wmult((K*)0, RT(1), diff.hw(), diff.hw());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
squared_distance_to_line_RT(dir, diff, num, den, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const typename K::Point_3& pt,
|
||||||
|
const typename K::Ray_3& ray,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
// This duplicates code from the _RT functions, but it is a slowdown to do something like:
|
||||||
|
//
|
||||||
|
// RT num, den;
|
||||||
|
// squared_distance_RT(pt, ray, num, den, k);
|
||||||
|
// return Rational_traits<FT>().make_rational(num, den);
|
||||||
|
//
|
||||||
|
// See https://github.com/CGAL/cgal/pull/5680
|
||||||
|
|
||||||
|
typedef typename K::Vector_3 Vector_3;
|
||||||
|
|
||||||
|
typename K::Construct_vector_3 vector = k.construct_vector_3_object();
|
||||||
|
|
||||||
|
const Vector_3 dir = ray.direction().vector();
|
||||||
|
const Vector_3 diff = vector(ray.source(), pt);
|
||||||
|
|
||||||
|
if(!is_acute_angle(dir, diff, k))
|
||||||
|
return diff*diff;
|
||||||
|
|
||||||
|
return squared_distance_to_line(dir, diff, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const typename K::Ray_3& ray,
|
||||||
|
const typename K::Point_3& pt,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
return squared_distance(pt, ray, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const Point_3<K>& pt,
|
||||||
|
const Ray_3<K>& ray)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_3_object()(pt, ray);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const Ray_3<K>& ray,
|
||||||
|
const Point_3<K>& pt)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_3_object()(ray, pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_DISTANCE_3_POINT_3_RAY_3_H
|
||||||
|
|
@ -0,0 +1,133 @@
|
||||||
|
// Copyright (c) 1998-2021
|
||||||
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org)
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Geert-Jan Giezeman, Andreas Fabri
|
||||||
|
|
||||||
|
#ifndef CGAL_DISTANCE_3_POINT_3_SEGMENT_3_H
|
||||||
|
#define CGAL_DISTANCE_3_POINT_3_SEGMENT_3_H
|
||||||
|
|
||||||
|
#include <CGAL/Distance_3/internal/squared_distance_utils_3.h>
|
||||||
|
#include <CGAL/Distance_3/Point_3_Point_3.h>
|
||||||
|
|
||||||
|
#include <CGAL/Point_3.h>
|
||||||
|
#include <CGAL/Segment_3.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
void
|
||||||
|
squared_distance_RT(const typename K::Point_3& pt,
|
||||||
|
const typename K::Segment_3& seg,
|
||||||
|
typename K::RT& num,
|
||||||
|
typename K::RT& den,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::RT RT;
|
||||||
|
typedef typename K::Vector_3 Vector_3;
|
||||||
|
|
||||||
|
typename K::Construct_vector_3 vector = k.construct_vector_3_object();
|
||||||
|
|
||||||
|
// assert that the segment is valid (non zero length).
|
||||||
|
const Vector_3 diff_s = vector(seg.source(), pt);
|
||||||
|
const Vector_3 segvec = vector(seg.source(), seg.target());
|
||||||
|
|
||||||
|
const RT d = wdot(diff_s, segvec, k);
|
||||||
|
if(d <= RT(0))
|
||||||
|
{
|
||||||
|
// this is squared_distance(pt, seg.source())
|
||||||
|
num = wdot(diff_s, diff_s, k);
|
||||||
|
den = wmult((K*)0, RT(1), diff_s.hw(), diff_s.hw());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const RT e = wdot(segvec, segvec, k);
|
||||||
|
if(wmult((K*)0, d, segvec.hw()) > wmult((K*)0, e, diff_s.hw()))
|
||||||
|
{
|
||||||
|
// this is squared_distance(pt, seg.target())
|
||||||
|
const Vector_3 diff_t = vector(seg.target(), pt);
|
||||||
|
num = wdot(diff_t, diff_t, k);
|
||||||
|
den = wmult((K*)0, RT(1), diff_t.hw(), diff_t.hw());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is an expanded call to squared_distance_to_line_RT() to avoid recomputing 'e'
|
||||||
|
const Vector_3 wcr = wcross(segvec, diff_s, k);
|
||||||
|
num = wdot(wcr, wcr, k);
|
||||||
|
den = wmult((K*)0, e, diff_s.hw(), diff_s.hw());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const typename K::Point_3& pt,
|
||||||
|
const typename K::Segment_3& seg,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::RT RT;
|
||||||
|
typedef typename K::FT FT;
|
||||||
|
typedef typename K::Vector_3 Vector_3;
|
||||||
|
|
||||||
|
typename K::Construct_vector_3 vector = k.construct_vector_3_object();
|
||||||
|
|
||||||
|
// assert that the segment is valid (non zero length).
|
||||||
|
const Vector_3 diff = vector(seg.source(), pt);
|
||||||
|
const Vector_3 segvec = vector(seg.source(), seg.target());
|
||||||
|
|
||||||
|
const RT d = wdot(diff, segvec, k);
|
||||||
|
if(d <= RT(0))
|
||||||
|
return (FT(diff*diff));
|
||||||
|
|
||||||
|
const RT e = wdot(segvec, segvec, k);
|
||||||
|
if(wmult((K*)0, d, segvec.hw()) > wmult((K*)0, e, diff.hw()))
|
||||||
|
return squared_distance(pt, seg.target(), k);
|
||||||
|
|
||||||
|
// This is an expanded call to squared_distance_to_line() to avoid recomputing 'e'
|
||||||
|
const Vector_3 wcr = wcross(segvec, diff, k);
|
||||||
|
|
||||||
|
return FT(wcr*wcr) / wmult((K*)0, e, diff.hw(), diff.hw());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const typename K::Segment_3& seg,
|
||||||
|
const typename K::Point_3& pt,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
return squared_distance(pt, seg, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const Point_3<K>& pt,
|
||||||
|
const Segment_3<K>& seg)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_3_object()(pt, seg);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const Segment_3<K>& seg,
|
||||||
|
const Point_3<K>& pt)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_3_object()(seg, pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_DISTANCE_3_POINT_3_SEGMENT_3_H
|
||||||
|
|
@ -0,0 +1,148 @@
|
||||||
|
// Copyright (c) 1998-2021
|
||||||
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org)
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Andreas Fabri
|
||||||
|
|
||||||
|
#ifndef CGAL_DISTANCE_3_POINT_3_TETRAHEDRON_3_H
|
||||||
|
#define CGAL_DISTANCE_3_POINT_3_TETRAHEDRON_3_H
|
||||||
|
|
||||||
|
#include <CGAL/Distance_3/Point_3_Triangle_3.h>
|
||||||
|
|
||||||
|
#include <CGAL/Point_3.h>
|
||||||
|
#include <CGAL/Tetrahedron_3.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const typename K::Point_3& pt,
|
||||||
|
const typename K::Tetrahedron_3& tet,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::Point_3 Point_3;
|
||||||
|
|
||||||
|
typename K::Construct_vertex_3 vertex = k.construct_vertex_3_object();
|
||||||
|
typename K::Orientation_3 orientation = k.orientation_3_object();
|
||||||
|
|
||||||
|
bool on_bounded_side = true;
|
||||||
|
const Point_3& t0 = vertex(tet, 0);
|
||||||
|
const Point_3& t1 = vertex(tet, 1);
|
||||||
|
const Point_3& t2 = vertex(tet, 2);
|
||||||
|
const Point_3& t3 = vertex(tet, 3);
|
||||||
|
|
||||||
|
bool dmin_initialized = false;
|
||||||
|
typename K::FT dmin;
|
||||||
|
bool inside = false;
|
||||||
|
if(orientation(t0,t1,t2, pt) == NEGATIVE)
|
||||||
|
{
|
||||||
|
on_bounded_side = false;
|
||||||
|
dmin = squared_distance_to_triangle(pt, t0, t1, t2, k, inside);
|
||||||
|
dmin_initialized = true;
|
||||||
|
if(inside)
|
||||||
|
return dmin;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(orientation(t0,t3,t1, pt) == NEGATIVE)
|
||||||
|
{
|
||||||
|
on_bounded_side = false;
|
||||||
|
const typename K::FT d = squared_distance_to_triangle(pt, t0, t3, t1, k, inside);
|
||||||
|
if(inside)
|
||||||
|
return d;
|
||||||
|
|
||||||
|
if(!dmin_initialized)
|
||||||
|
{
|
||||||
|
dmin = d;
|
||||||
|
dmin_initialized = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dmin = (std::min)(d, dmin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(orientation(t1,t3,t2, pt) == NEGATIVE)
|
||||||
|
{
|
||||||
|
on_bounded_side = false;
|
||||||
|
const typename K::FT d = squared_distance_to_triangle(pt, t1, t3, t2, k, inside);
|
||||||
|
if(inside)
|
||||||
|
return d;
|
||||||
|
|
||||||
|
if(!dmin_initialized)
|
||||||
|
{
|
||||||
|
dmin = d;
|
||||||
|
dmin_initialized = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dmin = (std::min)(d, dmin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(orientation(t2,t3,t0, pt) == NEGATIVE)
|
||||||
|
{
|
||||||
|
on_bounded_side = false;
|
||||||
|
const typename K::FT d = squared_distance_to_triangle(pt, t2, t3, t0, k, inside);
|
||||||
|
if(inside)
|
||||||
|
return d;
|
||||||
|
|
||||||
|
if(!dmin_initialized)
|
||||||
|
{
|
||||||
|
dmin = d;
|
||||||
|
dmin_initialized = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dmin = (std::min)(d, dmin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(on_bounded_side)
|
||||||
|
return typename K::FT(0);
|
||||||
|
|
||||||
|
return dmin;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const typename K::Tetrahedron_3& tet,
|
||||||
|
const typename K::Point_3& pt,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
return squared_distance(pt, tet, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const Tetrahedron_3<K>& tet,
|
||||||
|
const Point_3<K>& pt)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_3_object()(tet, pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const Point_3<K>& pt,
|
||||||
|
const Tetrahedron_3<K>& tet)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_3_object()(pt, tet);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_DISTANCE_3_POINT_3_TETRAHEDRON_3_H
|
||||||
|
|
@ -0,0 +1,242 @@
|
||||||
|
// Copyright (c) 1998-2021
|
||||||
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org)
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Geert-Jan Giezeman, Andreas Fabri
|
||||||
|
|
||||||
|
#ifndef CGAL_DISTANCE_3_POINT_3_TRIANGLE_3_H
|
||||||
|
#define CGAL_DISTANCE_3_POINT_3_TRIANGLE_3_H
|
||||||
|
|
||||||
|
#include <CGAL/Distance_3/internal/squared_distance_utils_3.h>
|
||||||
|
#include <CGAL/Distance_3/Point_3_Segment_3.h>
|
||||||
|
|
||||||
|
#include <CGAL/Point_3.h>
|
||||||
|
#include <CGAL/Triangle_3.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
// returns true iff pt is on the negative side of the plane defined by (ep0, ep1) and normal
|
||||||
|
template <class K>
|
||||||
|
inline bool
|
||||||
|
on_left_of_triangle_edge(const typename K::Point_3& pt,
|
||||||
|
const typename K::Vector_3& normal,
|
||||||
|
const typename K::Point_3& ep0,
|
||||||
|
const typename K::Point_3& ep1,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::RT RT;
|
||||||
|
typedef typename K::Vector_3 Vector_3;
|
||||||
|
|
||||||
|
typename K::Construct_vector_3 vector = k.construct_vector_3_object();
|
||||||
|
|
||||||
|
const Vector_3 edge = vector(ep0, ep1);
|
||||||
|
const Vector_3 diff = vector(ep0, pt);
|
||||||
|
|
||||||
|
return (wdot(wcross(edge, normal, k), diff, k) <= RT(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline void
|
||||||
|
squared_distance_to_triangle_RT(const typename K::Point_3& pt,
|
||||||
|
const typename K::Point_3& t0,
|
||||||
|
const typename K::Point_3& t1,
|
||||||
|
const typename K::Point_3& t2,
|
||||||
|
bool& inside,
|
||||||
|
typename K::RT& num,
|
||||||
|
typename K::RT& den,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::Vector_3 Vector_3;
|
||||||
|
|
||||||
|
typename K::Construct_vector_3 vector = k.construct_vector_3_object();
|
||||||
|
typename K::Construct_segment_3 segment = k.construct_segment_3_object();
|
||||||
|
|
||||||
|
const Vector_3 e1 = vector(t0, t1);
|
||||||
|
const Vector_3 oe3 = vector(t0, t2);
|
||||||
|
const Vector_3 normal = wcross(e1, oe3, k);
|
||||||
|
|
||||||
|
if(normal == NULL_VECTOR)
|
||||||
|
{
|
||||||
|
// The case normal==NULL_VECTOR covers the case when the triangle
|
||||||
|
// is colinear, or even more degenerate. In that case, we can
|
||||||
|
// simply take also the distance to the three segments.
|
||||||
|
squared_distance_RT(pt, segment(t2, t0), num, den, k);
|
||||||
|
|
||||||
|
typename K::RT num2, den2;
|
||||||
|
squared_distance_RT(pt, segment(t1, t2), num2, den2, k);
|
||||||
|
if(compare_quotients(num2,den2, num,den) == SMALLER)
|
||||||
|
{
|
||||||
|
num = num2;
|
||||||
|
den = den2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Should not be needed since at most 2 edges cover the full triangle in the degenerate case,
|
||||||
|
// but leaving it for robustness
|
||||||
|
squared_distance_RT(pt, segment(t0, t1), num2, den2, k);
|
||||||
|
if(compare_quotients(num2,den2, num,den) == SMALLER)
|
||||||
|
{
|
||||||
|
num = num2;
|
||||||
|
den = den2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool b01 = on_left_of_triangle_edge(pt, normal, t0, t1, k);
|
||||||
|
if(!b01)
|
||||||
|
{
|
||||||
|
squared_distance_RT(pt, segment(t0, t1), num, den, k);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool b12 = on_left_of_triangle_edge(pt, normal, t1, t2, k);
|
||||||
|
if(!b12)
|
||||||
|
{
|
||||||
|
squared_distance_RT(pt, segment(t1, t2), num, den, k);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool b20 = on_left_of_triangle_edge(pt, normal, t2, t0, k);
|
||||||
|
if(!b20)
|
||||||
|
{
|
||||||
|
squared_distance_RT(pt, segment(t2, t0), num, den, k);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The projection of pt is inside the triangle
|
||||||
|
inside = true;
|
||||||
|
squared_distance_to_plane_RT(normal, vector(t0, pt), num, den, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
void
|
||||||
|
squared_distance_RT(const typename K::Point_3& pt,
|
||||||
|
const typename K::Triangle_3& t,
|
||||||
|
typename K::RT& num,
|
||||||
|
typename K::RT& den,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typename K::Construct_vertex_3 vertex;
|
||||||
|
bool inside = false;
|
||||||
|
squared_distance_to_triangle_RT(pt,
|
||||||
|
vertex(t, 0),
|
||||||
|
vertex(t, 1),
|
||||||
|
vertex(t, 2),
|
||||||
|
inside,
|
||||||
|
num,
|
||||||
|
den,
|
||||||
|
k);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance_to_triangle(const typename K::Point_3& pt,
|
||||||
|
const typename K::Point_3& t0,
|
||||||
|
const typename K::Point_3& t1,
|
||||||
|
const typename K::Point_3& t2,
|
||||||
|
const K& k,
|
||||||
|
bool& inside)
|
||||||
|
{
|
||||||
|
typedef typename K::Vector_3 Vector_3;
|
||||||
|
|
||||||
|
typename K::Construct_segment_3 segment = k.construct_segment_3_object();
|
||||||
|
typename K::Construct_vector_3 vector = k.construct_vector_3_object();
|
||||||
|
typename K::Compute_squared_distance_3 sq_dist = k.compute_squared_distance_3_object();
|
||||||
|
|
||||||
|
const Vector_3 e1 = vector(t0, t1);
|
||||||
|
const Vector_3 oe3 = vector(t0, t2);
|
||||||
|
const Vector_3 normal = wcross(e1, oe3, k);
|
||||||
|
|
||||||
|
if(normal == NULL_VECTOR)
|
||||||
|
{
|
||||||
|
// The case normal == NULL_VECTOR covers the case when the triangle
|
||||||
|
// is colinear, or even more degenerate. In that case, we can
|
||||||
|
// simply take also the distance to the three segments.
|
||||||
|
//
|
||||||
|
// Note that in the degenerate case, at most 2 edges cover the full triangle,
|
||||||
|
// and only two distances could be used, but leaving 3 for the case of
|
||||||
|
// inexact constructions as it might improve the accuracy.
|
||||||
|
typename K::FT d1 = sq_dist(pt, segment(t2, t0));
|
||||||
|
typename K::FT d2 = sq_dist(pt, segment(t1, t2));
|
||||||
|
typename K::FT d3 = sq_dist(pt, segment(t0, t1));
|
||||||
|
|
||||||
|
return (std::min)((std::min)(d1, d2), d3);
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool b01 = on_left_of_triangle_edge(pt, normal, t0, t1, k);
|
||||||
|
if(!b01)
|
||||||
|
return sq_dist(pt, segment(t0, t1));
|
||||||
|
|
||||||
|
const bool b12 = on_left_of_triangle_edge(pt, normal, t1, t2, k);
|
||||||
|
if(!b12)
|
||||||
|
return sq_dist(pt, segment(t1, t2));
|
||||||
|
|
||||||
|
const bool b20 = on_left_of_triangle_edge(pt, normal, t2, t0, k);
|
||||||
|
if(!b20)
|
||||||
|
return sq_dist(pt, segment(t2, t0));
|
||||||
|
|
||||||
|
// The projection of pt is inside the triangle
|
||||||
|
inside = true;
|
||||||
|
return squared_distance_to_plane(normal, vector(t0, pt), k);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const typename K::Point_3& pt,
|
||||||
|
const typename K::Triangle_3& t,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typename K::Construct_vertex_3 vertex = k.construct_vertex_3_object();
|
||||||
|
|
||||||
|
bool unused_inside = false;
|
||||||
|
return squared_distance_to_triangle(pt,
|
||||||
|
vertex(t, 0),
|
||||||
|
vertex(t, 1),
|
||||||
|
vertex(t, 2),
|
||||||
|
k,
|
||||||
|
unused_inside);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const typename K::Triangle_3& t,
|
||||||
|
const typename K::Point_3& pt,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
return squared_distance(pt, t, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const Point_3<K>& pt,
|
||||||
|
const Triangle_3<K>& t)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_3_object()(pt, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const Triangle_3<K>& t,
|
||||||
|
const Point_3<K>& pt)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_3_object()(t, pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_DISTANCE_3_POINT_3_TRIANGLE_3_H
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
// Copyright (c) 1998-2021
|
||||||
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org)
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Geert-Jan Giezeman, Andreas Fabri
|
||||||
|
|
||||||
|
#ifndef CGAL_DISTANCE_3_POINT_3_WEIGHTED_POINT_3_H
|
||||||
|
#define CGAL_DISTANCE_3_POINT_3_WEIGHTED_POINT_3_H
|
||||||
|
|
||||||
|
#include <CGAL/Distance_3/Point_3_Point_3.h>
|
||||||
|
|
||||||
|
#include <CGAL/Point_3.h>
|
||||||
|
#include <CGAL/Weighted_point_3.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const Weighted_point_3<K>& wpt,
|
||||||
|
const Point_3<K>& pt)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_3_object()(wpt.point(), pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const Point_3<K>& pt,
|
||||||
|
const Weighted_point_3<K>& wpt)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_3_object()(pt, wpt.point());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_DISTANCE_3_POINT_3_WEIGHTED_POINT_3_H
|
||||||
|
|
@ -0,0 +1,102 @@
|
||||||
|
// Copyright (c) 1998-2021
|
||||||
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org)
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Geert-Jan Giezeman, Andreas Fabri
|
||||||
|
|
||||||
|
#ifndef CGAL_DISTANCE_3_RAY_3_LINE_3_H
|
||||||
|
#define CGAL_DISTANCE_3_RAY_3_LINE_3_H
|
||||||
|
|
||||||
|
#include <CGAL/Distance_3/internal/squared_distance_utils_3.h>
|
||||||
|
|
||||||
|
#include <CGAL/Line_3.h>
|
||||||
|
#include <CGAL/Ray_3.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const typename K::Ray_3& ray,
|
||||||
|
const typename K::Line_3& line,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::Vector_3 Vector_3;
|
||||||
|
typedef typename K::Point_3 Point_3;
|
||||||
|
typedef typename K::RT RT;
|
||||||
|
|
||||||
|
typename K::Construct_vector_3 vector = k.construct_vector_3_object();
|
||||||
|
|
||||||
|
const Point_3& rs = ray.source();
|
||||||
|
|
||||||
|
const Vector_3 linedir = line.direction().vector();
|
||||||
|
const Vector_3 raydir = ray.direction().vector();
|
||||||
|
const Vector_3 normal = wcross(raydir, linedir, k);
|
||||||
|
|
||||||
|
const Vector_3 rs_min_lp = vector(line.point(), rs);
|
||||||
|
if(is_null(normal, k))
|
||||||
|
return squared_distance_to_line(linedir, rs_min_lp, k);
|
||||||
|
|
||||||
|
bool crossing;
|
||||||
|
const Vector_3 perpend2l = wcross(linedir, normal, k);
|
||||||
|
const RT sdm_sr_l = wdot(perpend2l, rs_min_lp, k);
|
||||||
|
if(sdm_sr_l < RT(0))
|
||||||
|
{
|
||||||
|
crossing = (wdot(perpend2l, raydir, k) >= RT(0));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(wdot(perpend2l, raydir, k) <= RT(0))
|
||||||
|
crossing = true;
|
||||||
|
else
|
||||||
|
crossing = (sdm_sr_l == RT(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(crossing)
|
||||||
|
return squared_distance_to_plane(normal, rs_min_lp, k);
|
||||||
|
else
|
||||||
|
return squared_distance_to_line(linedir, rs_min_lp, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const typename K::Line_3& line,
|
||||||
|
const typename K::Ray_3& ray,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
return squared_distance(ray, line, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const Line_3<K>& line,
|
||||||
|
const Ray_3<K>& ray)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_3_object()(line, ray);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const Ray_3<K>& ray,
|
||||||
|
const Line_3<K>& line)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_3_object()(ray, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_DISTANCE_3_RAY_3_LINE_3_H
|
||||||
|
|
@ -0,0 +1,97 @@
|
||||||
|
// Copyright (c) 1998-2021
|
||||||
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org)
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Geert-Jan Giezeman, Andreas Fabri
|
||||||
|
|
||||||
|
#ifndef CGAL_DISTANCE_3_RAY_3_PLANE_3_H
|
||||||
|
#define CGAL_DISTANCE_3_RAY_3_PLANE_3_H
|
||||||
|
|
||||||
|
#include <CGAL/Distance_3/internal/squared_distance_utils_3.h>
|
||||||
|
#include <CGAL/number_utils.h>
|
||||||
|
|
||||||
|
#include <CGAL/Plane_3.h>
|
||||||
|
#include <CGAL/Ray_3.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const typename K::Ray_3 &ray,
|
||||||
|
const typename K::Plane_3 &plane,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::RT RT;
|
||||||
|
typedef typename K::FT FT;
|
||||||
|
typedef typename K::Point_3 Point_3;
|
||||||
|
typedef typename K::Vector_3 Vector_3;
|
||||||
|
|
||||||
|
typename K::Construct_vector_3 construct_vector = k.construct_vector_3_object();
|
||||||
|
|
||||||
|
const Point_3& start = ray.start();
|
||||||
|
const Point_3& planepoint = plane.point();
|
||||||
|
const Vector_3 start_min_pp = construct_vector(planepoint, start);
|
||||||
|
const Vector_3 end_min_pp = ray.direction().vector();
|
||||||
|
const Vector_3 normal = plane.orthogonal_vector();
|
||||||
|
const RT sdm_rs2pp = wdot(normal, start_min_pp, k);
|
||||||
|
const RT sdm_re2pp = wdot(normal, end_min_pp, k);
|
||||||
|
|
||||||
|
switch (CGAL_NTS sign(sdm_rs2pp))
|
||||||
|
{
|
||||||
|
case -1:
|
||||||
|
if(sdm_re2pp > RT(0))
|
||||||
|
return FT(0);
|
||||||
|
return squared_distance_to_plane(normal, start_min_pp, k);
|
||||||
|
case 0:
|
||||||
|
default:
|
||||||
|
return FT(0);
|
||||||
|
case 1:
|
||||||
|
if(sdm_re2pp < RT(0))
|
||||||
|
return FT(0);
|
||||||
|
return squared_distance_to_plane(normal, start_min_pp, k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const typename K::Plane_3& plane,
|
||||||
|
const typename K::Ray_3& ray,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
return squared_distance(ray, plane, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const Ray_3<K>& ray,
|
||||||
|
const Plane_3<K>& plane)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_3_object()(ray, plane);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const Plane_3<K>& plane,
|
||||||
|
const Ray_3<K>& ray)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_3_object()(plane, ray);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_DISTANCE_3_RAY_3_PLANE_3_H
|
||||||
|
|
@ -0,0 +1,143 @@
|
||||||
|
// Copyright (c) 1998-2021
|
||||||
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org)
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Geert-Jan Giezeman, Andreas Fabri
|
||||||
|
|
||||||
|
#ifndef CGAL_DISTANCE_3_RAY_3_RAY_3_H
|
||||||
|
#define CGAL_DISTANCE_3_RAY_3_RAY_3_H
|
||||||
|
|
||||||
|
#include <CGAL/Distance_3/internal/squared_distance_utils_3.h>
|
||||||
|
|
||||||
|
#include <CGAL/Ray_3.h>
|
||||||
|
#include <CGAL/Vector_3.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
ray_ray_squared_distance_parallel(const typename K::Vector_3& ray1dir,
|
||||||
|
const typename K::Vector_3& ray2dir,
|
||||||
|
const typename K::Vector_3& s1_min_s2,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
if(!is_acute_angle(ray2dir, s1_min_s2, k))
|
||||||
|
if(!same_direction(ray1dir, ray2dir, k))
|
||||||
|
return typename K::FT(s1_min_s2*s1_min_s2);
|
||||||
|
|
||||||
|
return squared_distance_to_line(ray1dir, s1_min_s2, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const typename K::Ray_3& ray1,
|
||||||
|
const typename K::Ray_3& ray2,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::RT RT;
|
||||||
|
typedef typename K::FT FT;
|
||||||
|
typedef typename K::Point_3 Point_3;
|
||||||
|
typedef typename K::Vector_3 Vector_3;
|
||||||
|
|
||||||
|
typename K::Construct_vector_3 construct_vector = k.construct_vector_3_object();
|
||||||
|
typename K::Compute_squared_distance_3 sq_dist = k.compute_squared_distance_3_object();
|
||||||
|
|
||||||
|
const Point_3& s1 = ray1.source();
|
||||||
|
const Point_3& s2 = ray2.source();
|
||||||
|
const Vector_3 dir1 = ray1.direction().vector();
|
||||||
|
const Vector_3 dir2 = ray2.direction().vector();
|
||||||
|
const Vector_3 normal = wcross(dir1, dir2, k);
|
||||||
|
const Vector_3 s1_min_s2 = construct_vector(s2, s1);
|
||||||
|
|
||||||
|
if(is_null(normal, k))
|
||||||
|
return ray_ray_squared_distance_parallel(dir1, dir2, s1_min_s2, k);
|
||||||
|
|
||||||
|
bool crossing1, crossing2;
|
||||||
|
|
||||||
|
const Vector_3 perpend1 = wcross(dir1, normal, k);
|
||||||
|
const Vector_3 perpend2 = wcross(dir2, normal, k);
|
||||||
|
|
||||||
|
const RT sdm_s1_2 = wdot(perpend2, s1_min_s2, k);
|
||||||
|
if(sdm_s1_2 < RT(0))
|
||||||
|
{
|
||||||
|
crossing1 = (wdot(perpend2, dir1, k) >= RT(0));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(RT(wdot(perpend2, dir1, k)) <= RT(0))
|
||||||
|
crossing1 = true;
|
||||||
|
else
|
||||||
|
crossing1 = (sdm_s1_2 == RT(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
const RT sdm_s2_1 = - wdot(perpend1, s1_min_s2, k);
|
||||||
|
if(sdm_s2_1 < RT(0))
|
||||||
|
{
|
||||||
|
crossing2 = (wdot(perpend1, dir2, k) >= RT(0));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(wdot(perpend1, dir2, k) <= RT(0))
|
||||||
|
crossing2 = true;
|
||||||
|
else
|
||||||
|
crossing2 = (sdm_s2_1 == RT(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(crossing1)
|
||||||
|
{
|
||||||
|
if(crossing2)
|
||||||
|
return squared_distance_to_plane(normal, s1_min_s2, k);
|
||||||
|
|
||||||
|
return sq_dist(s2, ray1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(crossing2)
|
||||||
|
{
|
||||||
|
return sq_dist(s1, ray2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FT min1, min2;
|
||||||
|
min1 = sq_dist(s1, ray2);
|
||||||
|
min2 = sq_dist(s2, ray1);
|
||||||
|
return (min1 < min2) ? min1 : min2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::FT
|
||||||
|
ray_ray_squared_distance_parallel(const Vector_3<K>& ray1dir,
|
||||||
|
const Vector_3<K>& ray2dir,
|
||||||
|
const Vector_3<K>& s1_min_s2)
|
||||||
|
{
|
||||||
|
return internal::ray_ray_squared_distance_parallel(ray1dir, ray2dir, s1_min_s2, K());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const Ray_3<K>& ray1,
|
||||||
|
const Ray_3<K>& ray2)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_3_object()(ray1, ray2);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_DISTANCE_3_RAY_3_RAY_3_H
|
||||||
|
|
@ -0,0 +1,116 @@
|
||||||
|
// Copyright (c) 1998-2021
|
||||||
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org)
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Geert-Jan Giezeman, Andreas Fabri
|
||||||
|
|
||||||
|
#ifndef CGAL_DISTANCE_3_SEGMENT_3_LINE_3_H
|
||||||
|
#define CGAL_DISTANCE_3_SEGMENT_3_LINE_3_H
|
||||||
|
|
||||||
|
#include <CGAL/Distance_3/internal/squared_distance_utils_3.h>
|
||||||
|
|
||||||
|
#include <CGAL/Line_3.h>
|
||||||
|
#include <CGAL/Segment_3.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const typename K::Segment_3& seg,
|
||||||
|
const typename K::Line_3& line,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::RT RT;
|
||||||
|
typedef typename K::Point_3 Point_3;
|
||||||
|
typedef typename K::Vector_3 Vector_3;
|
||||||
|
|
||||||
|
typename K::Construct_vector_3 vector = k.construct_vector_3_object();
|
||||||
|
typename K::Compute_squared_distance_3 sq_dist = k.compute_squared_distance_3_object();
|
||||||
|
|
||||||
|
const Point_3& linepoint = line.point();
|
||||||
|
const Point_3& start = seg.source();
|
||||||
|
const Point_3& end = seg.target();
|
||||||
|
|
||||||
|
if(start == end)
|
||||||
|
return sq_dist(start, line);
|
||||||
|
|
||||||
|
const Vector_3 linedir = line.direction().vector();
|
||||||
|
const Vector_3 segdir = seg.direction().vector();
|
||||||
|
const Vector_3 normal = wcross(segdir, linedir, k);
|
||||||
|
|
||||||
|
if(is_null(normal, k))
|
||||||
|
return squared_distance_to_line(linedir, vector(linepoint,start), k);
|
||||||
|
|
||||||
|
bool crossing;
|
||||||
|
|
||||||
|
const Vector_3 perpend2line = wcross(linedir, normal, k);
|
||||||
|
const Vector_3 start_min_lp = vector(linepoint, start);
|
||||||
|
const Vector_3 end_min_lp = vector(linepoint, end);
|
||||||
|
const RT sdm_ss2l = wdot(perpend2line, start_min_lp, k);
|
||||||
|
const RT sdm_se2l = wdot(perpend2line, end_min_lp, k);
|
||||||
|
|
||||||
|
if(sdm_ss2l < RT(0)) {
|
||||||
|
crossing = (sdm_se2l >= RT(0));
|
||||||
|
} else {
|
||||||
|
if(sdm_se2l <= RT(0)) {
|
||||||
|
crossing = true;
|
||||||
|
} else {
|
||||||
|
crossing = (sdm_ss2l == RT(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(crossing) {
|
||||||
|
return squared_distance_to_plane(normal, start_min_lp, k);
|
||||||
|
} else {
|
||||||
|
const RT dm = distance_measure_sub(sdm_ss2l, sdm_se2l, start_min_lp, end_min_lp, k);
|
||||||
|
if(dm <= RT(0)) {
|
||||||
|
return squared_distance_to_line(linedir, start_min_lp, k);
|
||||||
|
} else {
|
||||||
|
return squared_distance_to_line(linedir, end_min_lp, k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const typename K::Line_3& line,
|
||||||
|
const typename K::Segment_3& seg,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
return squared_distance(seg, line, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const Segment_3<K>& seg,
|
||||||
|
const Line_3<K>& line)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_3_object()(seg, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const Line_3<K>& line,
|
||||||
|
const Segment_3<K>& seg)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_3_object()(line, seg);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_DISTANCE_3_SEGMENT_3_LINE_3_H
|
||||||
|
|
@ -0,0 +1,108 @@
|
||||||
|
// Copyright (c) 1998-2021
|
||||||
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org)
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Geert-Jan Giezeman, Andreas Fabri
|
||||||
|
|
||||||
|
#ifndef CGAL_DISTANCE_3_SEGMENT_3_PLANE_3_H
|
||||||
|
#define CGAL_DISTANCE_3_SEGMENT_3_PLANE_3_H
|
||||||
|
|
||||||
|
#include <CGAL/Distance_3/internal/squared_distance_utils_3.h>
|
||||||
|
|
||||||
|
#include <CGAL/Segment_3.h>
|
||||||
|
#include <CGAL/Plane_3.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const typename K::Segment_3 &seg,
|
||||||
|
const typename K::Plane_3 &plane,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::RT RT;
|
||||||
|
typedef typename K::FT FT;
|
||||||
|
typedef typename K::Vector_3 Vector_3;
|
||||||
|
typedef typename K::Point_3 Point_3;
|
||||||
|
|
||||||
|
typename K::Construct_vector_3 vector = k.construct_vector_3_object();
|
||||||
|
|
||||||
|
const Point_3& start = seg.start();
|
||||||
|
const Point_3& end = seg.end();
|
||||||
|
|
||||||
|
if (start == end)
|
||||||
|
return squared_distance(start, plane, k);
|
||||||
|
|
||||||
|
const Point_3& planepoint = plane.point();
|
||||||
|
const Vector_3 start_min_pp = vector(planepoint, start);
|
||||||
|
const Vector_3 end_min_pp = vector(planepoint, end);
|
||||||
|
const Vector_3& normal = plane.orthogonal_vector();
|
||||||
|
|
||||||
|
const RT sdm_ss2pp = wdot(normal, start_min_pp, k);
|
||||||
|
const RT sdm_se2pp = wdot(normal, end_min_pp, k);
|
||||||
|
|
||||||
|
switch (CGAL_NTS sign(sdm_ss2pp))
|
||||||
|
{
|
||||||
|
case -1:
|
||||||
|
if (sdm_se2pp >= RT(0))
|
||||||
|
return FT(0);
|
||||||
|
if (sdm_ss2pp * end_min_pp.hw() >= sdm_se2pp * start_min_pp.hw())
|
||||||
|
return squared_distance_to_plane(normal, start_min_pp, k);
|
||||||
|
else
|
||||||
|
return squared_distance_to_plane(normal, end_min_pp, k);
|
||||||
|
case 0:
|
||||||
|
default:
|
||||||
|
return FT(0);
|
||||||
|
case 1:
|
||||||
|
if (sdm_se2pp <= RT(0))
|
||||||
|
return FT(0);
|
||||||
|
if (sdm_ss2pp * end_min_pp.hw() <= sdm_se2pp * start_min_pp.hw())
|
||||||
|
return squared_distance_to_plane(normal, start_min_pp, k);
|
||||||
|
else
|
||||||
|
return squared_distance_to_plane(normal, end_min_pp, k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline typename K::FT
|
||||||
|
squared_distance(const typename K::Plane_3& plane,
|
||||||
|
const typename K::Segment_3& seg,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
return squared_distance(seg, plane, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const Segment_3<K>& seg,
|
||||||
|
const Plane_3<K>& plane)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_3_object()(seg, plane);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const Plane_3<K>& plane,
|
||||||
|
const Segment_3<K>& seg)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_3_object()(plane, seg);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_DISTANCE_3_SEGMENT_3_PLANE_3_H
|
||||||
|
|
@ -0,0 +1,200 @@
|
||||||
|
// Copyright (c) 1998-2021
|
||||||
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org)
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Geert-Jan Giezeman, Andreas Fabri
|
||||||
|
|
||||||
|
#ifndef CGAL_DISTANCE_3_SEGMENT_3_RAY_3_H
|
||||||
|
#define CGAL_DISTANCE_3_SEGMENT_3_RAY_3_H
|
||||||
|
|
||||||
|
#include <CGAL/Distance_3/internal/squared_distance_utils_3.h>
|
||||||
|
|
||||||
|
#include <CGAL/Segment_3.h>
|
||||||
|
#include <CGAL/Ray_3.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance_parallel(const typename K::Segment_3& seg,
|
||||||
|
const typename K::Ray_3& ray,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::Vector_3 Vector_3;
|
||||||
|
|
||||||
|
const Vector_3 dir1 = seg.direction().vector();
|
||||||
|
const Vector_3 dir2 = ray.direction().vector();
|
||||||
|
|
||||||
|
bool same_direction;
|
||||||
|
if(CGAL_NTS abs(dir1.hx()) > CGAL_NTS abs(dir1.hy()))
|
||||||
|
same_direction = (CGAL_NTS sign(dir1.hx()) == CGAL_NTS sign(dir2.hx()));
|
||||||
|
else
|
||||||
|
same_direction = (CGAL_NTS sign(dir1.hy()) == CGAL_NTS sign(dir2.hy()));
|
||||||
|
|
||||||
|
if(same_direction)
|
||||||
|
{
|
||||||
|
if(!is_acute_angle(seg.source(), seg.target(), ray.source(), k))
|
||||||
|
return squared_distance(seg.target(), ray.source(), k);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!is_acute_angle(seg.target(), seg.source(), ray.source(), k))
|
||||||
|
return squared_distance(seg.source(), ray.source(), k);
|
||||||
|
}
|
||||||
|
|
||||||
|
return squared_distance(ray.source(), seg.supporting_line(), k);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const typename K::Segment_3& seg,
|
||||||
|
const typename K::Ray_3& ray,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::RT RT;
|
||||||
|
typedef typename K::FT FT;
|
||||||
|
typedef typename K::Point_3 Point_3;
|
||||||
|
typedef typename K::Vector_3 Vector_3;
|
||||||
|
|
||||||
|
typename K::Construct_vector_3 vector = k.construct_vector_3_object();
|
||||||
|
typename K::Compute_squared_distance_3 sq_dist = k.compute_squared_distance_3_object();
|
||||||
|
|
||||||
|
const Point_3& ss = seg.source();
|
||||||
|
const Point_3& se = seg.target();
|
||||||
|
|
||||||
|
if(ss == se)
|
||||||
|
return sq_dist(ss, ray);
|
||||||
|
|
||||||
|
const Vector_3 raydir = ray.direction().vector();
|
||||||
|
const Vector_3 segdir = seg.direction().vector();
|
||||||
|
const Vector_3 normal = wcross(segdir, raydir, k);
|
||||||
|
|
||||||
|
if(is_null(normal, k))
|
||||||
|
return squared_distance_parallel(seg, ray, k);
|
||||||
|
|
||||||
|
bool crossing1, crossing2;
|
||||||
|
|
||||||
|
const Vector_3 perpend2seg = wcross(segdir, normal, k);
|
||||||
|
const Vector_3 perpend2ray = wcross(raydir, normal, k);
|
||||||
|
const Vector_3 ss_min_rs = vector(ray.source(), ss);
|
||||||
|
const Vector_3 se_min_rs = vector(ray.source(), se);
|
||||||
|
const RT sdm_ss2r = wdot(perpend2ray, ss_min_rs, k);
|
||||||
|
const RT sdm_se2r = wdot(perpend2ray, se_min_rs, k);
|
||||||
|
|
||||||
|
if(sdm_ss2r < RT(0))
|
||||||
|
{
|
||||||
|
crossing1 = (sdm_se2r >= RT(0));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(sdm_se2r <= RT(0))
|
||||||
|
crossing1 = true;
|
||||||
|
else
|
||||||
|
crossing1 = (sdm_ss2r == RT(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
const RT sdm_rs2s = - wdot(perpend2seg, ss_min_rs, k);
|
||||||
|
const RT sdm_re2s = wdot(perpend2seg, raydir, k);
|
||||||
|
if(sdm_rs2s < RT(0))
|
||||||
|
{
|
||||||
|
crossing2 = (sdm_re2s >= RT(0));
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
if(sdm_re2s <= RT(0))
|
||||||
|
crossing2 = true;
|
||||||
|
else
|
||||||
|
crossing2 = (sdm_rs2s == RT(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(crossing1)
|
||||||
|
{
|
||||||
|
if(crossing2)
|
||||||
|
return squared_distance_to_plane(normal, ss_min_rs, k);
|
||||||
|
|
||||||
|
return sq_dist(ray.source(), seg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(crossing2)
|
||||||
|
{
|
||||||
|
const RT dm = distance_measure_sub(sdm_ss2r, sdm_se2r, ss_min_rs, se_min_rs, k);
|
||||||
|
if(dm < RT(0))
|
||||||
|
{
|
||||||
|
return sq_dist(ss, ray);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(dm > RT(0))
|
||||||
|
return sq_dist(se, ray);
|
||||||
|
else
|
||||||
|
// parallel, should not happen (no crossing)
|
||||||
|
return squared_distance_parallel(seg, ray, k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const RT dm = distance_measure_sub(sdm_ss2r, sdm_se2r, ss_min_rs, se_min_rs, k);
|
||||||
|
if(dm == RT(0))
|
||||||
|
return squared_distance_parallel(seg, ray, k);
|
||||||
|
|
||||||
|
const FT min1 = (dm < RT(0)) ? sq_dist(ss, ray)
|
||||||
|
: sq_dist(se, ray);
|
||||||
|
const FT min2 = sq_dist(ray.source(), seg);
|
||||||
|
|
||||||
|
return (min1 < min2) ? min1 : min2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const typename K::Ray_3& ray,
|
||||||
|
const typename K::Segment_3& seg,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
return squared_distance(seg, ray, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::FT
|
||||||
|
squared_distance_parallel(const Segment_3<K>& seg,
|
||||||
|
const Ray_3<K>& ray)
|
||||||
|
{
|
||||||
|
return internal::squared_distance_parallel(ray, seg, K());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const Segment_3<K>& seg,
|
||||||
|
const Ray_3<K>& ray)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_3_object()(seg, ray);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const Ray_3<K>& ray,
|
||||||
|
const Segment_3<K>& seg)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_3_object()(ray, seg);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_DISTANCE_3_SEGMENT_3_RAY_3_H
|
||||||
|
|
@ -0,0 +1,208 @@
|
||||||
|
// Copyright (c) 1998-2021
|
||||||
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org)
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Mael Rouxel-Labbé
|
||||||
|
|
||||||
|
#ifndef CGAL_DISTANCE_3_SEGMENT_3_SEGMENT_3_H
|
||||||
|
#define CGAL_DISTANCE_3_SEGMENT_3_SEGMENT_3_H
|
||||||
|
|
||||||
|
#include <CGAL/Distance_3/internal/squared_distance_utils_3.h>
|
||||||
|
|
||||||
|
#include <CGAL/Segment_3.h>
|
||||||
|
|
||||||
|
#include <boost/algorithm/clamp.hpp>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace Distance_3 {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <typename K>
|
||||||
|
struct Segment_3_Segment_3_Result
|
||||||
|
{
|
||||||
|
typename K::FT x, y;
|
||||||
|
typename K::FT squared_distance;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Using Lumelsky, 'On Fast Computation of Distance Between Line Segments' 1984
|
||||||
|
template <typename K>
|
||||||
|
Segment_3_Segment_3_Result<K>
|
||||||
|
squared_distance(const typename K::Segment_3& s1,
|
||||||
|
const typename K::Segment_3& s2,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::FT FT;
|
||||||
|
typedef typename K::Point_3 Point_3;
|
||||||
|
typedef typename K::Vector_3 Vector_3;
|
||||||
|
|
||||||
|
typename K::Construct_vertex_3 vertex = k.construct_vertex_3_object();
|
||||||
|
typename K::Construct_vector_3 cv = k.construct_vector_3_object();
|
||||||
|
typename K::Compute_scalar_product_3 sp = k.compute_scalar_product_3_object();
|
||||||
|
typename K::Compute_squared_distance_3 sq_dist = k.compute_squared_distance_3_object();
|
||||||
|
|
||||||
|
Segment_3_Segment_3_Result<K> res;
|
||||||
|
|
||||||
|
const Point_3& p1 = vertex(s1, 0);
|
||||||
|
const Point_3& q1 = vertex(s1, 1);
|
||||||
|
const Point_3& p2 = vertex(s2, 0);
|
||||||
|
const Point_3& q2 = vertex(s2, 1);
|
||||||
|
const Vector_3 v1 = cv(p1, q1), v2 = cv(p2, q2);
|
||||||
|
const Vector_3 p1p2 = cv(p1, p2);
|
||||||
|
|
||||||
|
// @todo compute these only when needed?
|
||||||
|
const FT a = sp(v1, v1);
|
||||||
|
const FT b = - sp(v1, v2);
|
||||||
|
const FT c = - b;
|
||||||
|
const FT d = - sp(v2, v2);
|
||||||
|
const FT e = sp(v1, p1p2);
|
||||||
|
const FT f = sp(v2, p1p2);
|
||||||
|
|
||||||
|
if(p1 == q1)
|
||||||
|
{
|
||||||
|
if(p2 == q2)
|
||||||
|
{
|
||||||
|
res.x = 0;
|
||||||
|
res.y = 0;
|
||||||
|
res.squared_distance = sq_dist(p1, p2);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
CGAL_assertion(d < 0);
|
||||||
|
|
||||||
|
res.x = 0;
|
||||||
|
res.y = boost::algorithm::clamp<FT>(f/d, 0, 1); // (f - x*c) / d
|
||||||
|
res.squared_distance = sq_dist(p1, p2 + res.y*v2);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
else if(p2 == q2)
|
||||||
|
{
|
||||||
|
CGAL_assertion(a > 0);
|
||||||
|
|
||||||
|
res.y = 0;
|
||||||
|
res.x = boost::algorithm::clamp<FT>(e/a, 0, 1); // (e + y*c) / a
|
||||||
|
res.squared_distance = sq_dist(p1 + res.x*v1, p2);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
CGAL_assertion(a > 0 && d < 0);
|
||||||
|
|
||||||
|
const FT det = a*d - b*c;
|
||||||
|
if(det == 0)
|
||||||
|
res.x = 0;
|
||||||
|
else
|
||||||
|
res.x = boost::algorithm::clamp<FT>((e*d - b*f) / det, 0, 1);
|
||||||
|
|
||||||
|
FT xc = res.x*c;
|
||||||
|
// res.y = (f - xc) / d, by definition, but building it up more efficiently
|
||||||
|
if(f > xc) // y < 0 <=> f - xc / d < 0 <=> f - xc > 0 (since d is -||v2||)
|
||||||
|
{
|
||||||
|
res.y = 0;
|
||||||
|
res.x = boost::algorithm::clamp<FT>(e/a, 0, 1); // (e + y*c) / a
|
||||||
|
}
|
||||||
|
else // y >= 0
|
||||||
|
{
|
||||||
|
FT n = f - xc; // delay the division by d
|
||||||
|
if(n < d) // y > 1 <=> n / d > 1 <=> n < d (once again, important to note that d is negative!)
|
||||||
|
{
|
||||||
|
res.y = 1;
|
||||||
|
res.x = boost::algorithm::clamp<FT>((e + c) / a, 0, 1); // (e + y*c) / a
|
||||||
|
}
|
||||||
|
else // 0 <= y <= 1
|
||||||
|
{
|
||||||
|
res.y = n / d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CGAL_postcondition(FT(0) <= res.x && res.x <= FT(1));
|
||||||
|
CGAL_postcondition(FT(0) <= res.y && res.y <= FT(1));
|
||||||
|
|
||||||
|
res.squared_distance = sq_dist(p1 + res.x*v1, p2 + res.y*v2);
|
||||||
|
|
||||||
|
CGAL_postcondition(res.squared_distance >= FT(0));
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace Distance_3
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance_parallel(const typename K::Segment_3& seg1,
|
||||||
|
const typename K::Segment_3& seg2,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::Vector_3 Vector_3;
|
||||||
|
|
||||||
|
typename K::Compute_squared_distance_3 sq_dist = k.compute_squared_distance_3_object();
|
||||||
|
|
||||||
|
const Vector_3 dir1 = seg1.direction().vector();
|
||||||
|
const Vector_3 dir2 = seg2.direction().vector();
|
||||||
|
|
||||||
|
if(same_direction(dir1, dir2, k))
|
||||||
|
{
|
||||||
|
if(!is_acute_angle(seg1.source(), seg1.target(), seg2.source(), k))
|
||||||
|
return sq_dist(seg1.target(), seg2.source(), k);
|
||||||
|
if(!is_acute_angle(seg1.target(), seg1.source(), seg2.target(), k))
|
||||||
|
return sq_dist(seg1.source(), seg2.target(), k);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!is_acute_angle(seg1.source(), seg1.target(), seg2.target(), k))
|
||||||
|
return sq_dist(seg1.target(), seg2.target(), k);
|
||||||
|
if(!is_acute_angle(seg1.target(), seg1.source(), seg2.source(), k))
|
||||||
|
return sq_dist(seg1.source(), seg2.source(), k);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sq_dist(seg2.source(), seg1.supporting_line(), k);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const typename K::Segment_3& seg1,
|
||||||
|
const typename K::Segment_3& seg2,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
Distance_3::internal::Segment_3_Segment_3_Result<K> res =
|
||||||
|
Distance_3::internal::squared_distance(seg1, seg2, k);
|
||||||
|
|
||||||
|
return res.squared_distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::FT
|
||||||
|
squared_distance_parallel(const Segment_3<K>& seg1,
|
||||||
|
const Segment_3<K>& seg2)
|
||||||
|
{
|
||||||
|
return internal::squared_distance_parallel(seg1, seg2, K());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const Segment_3<K>& seg1,
|
||||||
|
const Segment_3<K>& seg2)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_3_object()(seg1, seg2);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_DISTANCE_3_SEGMENT_3_SEGMENT_3_H
|
||||||
|
|
@ -0,0 +1,229 @@
|
||||||
|
// Copyright (c) 1998-2021
|
||||||
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org)
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Mael Rouxel-Labbé
|
||||||
|
|
||||||
|
#ifndef CGAL_DISTANCE_3_TRIANGLE_3_TRIANGLE_3_H
|
||||||
|
#define CGAL_DISTANCE_3_TRIANGLE_3_TRIANGLE_3_H
|
||||||
|
|
||||||
|
#include <CGAL/Distance_3/Point_3_Point_3.h>
|
||||||
|
#include <CGAL/Distance_3/Segment_3_Segment_3.h>
|
||||||
|
|
||||||
|
#include <CGAL/Triangle_3.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace Distance_3 {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <typename K>
|
||||||
|
std::pair<Segment_3_Segment_3_Result<K>, bool>
|
||||||
|
test_edge_pair(const typename K::Point_3& p1,
|
||||||
|
const typename K::Point_3& q1,
|
||||||
|
const typename K::Point_3& r1,
|
||||||
|
const typename K::Point_3& p2,
|
||||||
|
const typename K::Point_3& q2,
|
||||||
|
const typename K::Point_3& r2,
|
||||||
|
const K& k,
|
||||||
|
typename K::FT& global_min_sqd,
|
||||||
|
bool& are_triangles_known_to_be_disjoint)
|
||||||
|
{
|
||||||
|
typedef typename K::FT FT;
|
||||||
|
typedef typename K::Point_3 Point_3;
|
||||||
|
typedef typename K::Vector_3 Vector_3;
|
||||||
|
|
||||||
|
typename K::Compute_scalar_product_3 scalar_product = k.compute_scalar_product_3_object();
|
||||||
|
typename K::Construct_segment_3 segment = k.construct_segment_3_object();
|
||||||
|
typename K::Construct_scaled_vector_3 scale_vector = k.construct_scaled_vector_3_object();
|
||||||
|
typename K::Construct_vector_3 vector = k.construct_vector_3_object();
|
||||||
|
typename K::Construct_translated_point_3 translate = k.construct_translated_point_3_object();
|
||||||
|
|
||||||
|
Distance_3::internal::Segment_3_Segment_3_Result<K> res =
|
||||||
|
internal::squared_distance(segment(p1, q1), segment(p2, q2), k);
|
||||||
|
|
||||||
|
if(res.squared_distance <= global_min_sqd)
|
||||||
|
global_min_sqd = res.squared_distance;
|
||||||
|
else
|
||||||
|
return std::make_pair(res, false);
|
||||||
|
|
||||||
|
const Vector_3 v1 = vector(p1, q1), v2 = vector(p2, q2);
|
||||||
|
const Point_3 m1 = translate(p1, scale_vector(v1, res.x));
|
||||||
|
const Point_3 m2 = translate(p2, scale_vector(v2, res.y));
|
||||||
|
const Vector_3 vr1 = vector(m1, r1), vr2 = vector(m2, r2);
|
||||||
|
const Vector_3 n = vector(m1, m2);
|
||||||
|
|
||||||
|
const FT sp_r1 = scalar_product(vr1, n);
|
||||||
|
const FT sp_r2 = scalar_product(vr2, n);
|
||||||
|
const bool is_r1_closer = (sp_r1 > 0); // Plane_3{m1, n}.has_on_positive_side(r1);
|
||||||
|
const bool is_r2_closer = (sp_r2 < 0); // Plane_3{m2, -n}.has_on_positive_side(r2);
|
||||||
|
const bool is_best_pair = !is_r1_closer && !is_r2_closer;
|
||||||
|
|
||||||
|
// Even if it is not the best pair, one may be able to deduce if the triangles do not intersect
|
||||||
|
// by checking if there is a void space between the planes orthogonal to the vector realizing
|
||||||
|
// the min distance between the edges and passing through the third points.
|
||||||
|
if(!is_best_pair)
|
||||||
|
{
|
||||||
|
FT separating_distance = res.squared_distance;
|
||||||
|
if(is_r1_closer)
|
||||||
|
separating_distance -= sp_r1;
|
||||||
|
if(is_r2_closer)
|
||||||
|
separating_distance += sp_r2;
|
||||||
|
|
||||||
|
if(separating_distance > 0)
|
||||||
|
are_triangles_known_to_be_disjoint = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_pair(res, is_best_pair);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename K>
|
||||||
|
std::pair<typename K::FT, bool>
|
||||||
|
test_vertex_triangle(const typename K::Triangle_3& tr1,
|
||||||
|
const typename K::Triangle_3& tr2,
|
||||||
|
const K& k,
|
||||||
|
bool& are_triangles_known_to_be_disjoint)
|
||||||
|
{
|
||||||
|
typedef typename K::FT FT;
|
||||||
|
typedef typename K::Point_3 Point_3;
|
||||||
|
typedef typename K::Vector_3 Vector_3;
|
||||||
|
|
||||||
|
typename K::Compute_scalar_product_3 scalar_product = k.compute_scalar_product_3_object();
|
||||||
|
typename K::Construct_cross_product_vector_3 cross_product = k.construct_cross_product_vector_3_object();
|
||||||
|
typename K::Construct_vector_3 vector = k.construct_vector_3_object();
|
||||||
|
typename K::Construct_vertex_3 vertex = k.construct_vertex_3_object();
|
||||||
|
|
||||||
|
const Point_3& p1 = vertex(tr1, 0);
|
||||||
|
const Point_3& q1 = vertex(tr1, 1);
|
||||||
|
const Point_3& r1 = vertex(tr1, 2);
|
||||||
|
const Point_3& p2 = vertex(tr2, 0);
|
||||||
|
const Point_3& q2 = vertex(tr2, 1);
|
||||||
|
const Point_3& r2 = vertex(tr2, 2);
|
||||||
|
|
||||||
|
const Vector_3 p2q2 = vector(p2, q2);
|
||||||
|
const Vector_3 p2r2 = vector(p2, r2);
|
||||||
|
const Vector_3 n2 = cross_product(p2q2, p2r2);
|
||||||
|
|
||||||
|
if(scalar_product(n2, n2) == FT(0))
|
||||||
|
return std::make_pair(0, false);
|
||||||
|
|
||||||
|
std::array<FT, 3> sps = { scalar_product(vector(p2, p1), n2),
|
||||||
|
scalar_product(vector(p2, q1), n2),
|
||||||
|
scalar_product(vector(p2, r1), n2) };
|
||||||
|
|
||||||
|
// All the vertices of tr1 must be on the same side of tr2
|
||||||
|
// Coplanarity is tolerated, so '1' and '0' should be allowed, but not '1' and '-1'
|
||||||
|
if(CGAL::sign(sps[0]) == - CGAL::sign(sps[1]) || CGAL::sign(sps[1]) == - CGAL::sign(sps[2]))
|
||||||
|
return std::make_pair(0, false);
|
||||||
|
|
||||||
|
std::for_each(sps.begin(), sps.end(), [](FT& v) { v = abs(v); });
|
||||||
|
const auto min_pos = std::min_element(sps.begin(), sps.end());
|
||||||
|
const std::size_t min_id = static_cast<std::size_t>(std::distance(sps.begin(), min_pos));
|
||||||
|
|
||||||
|
if(sps[min_id] > 0)
|
||||||
|
are_triangles_known_to_be_disjoint = true;
|
||||||
|
|
||||||
|
const Point_3& x1 = vertex(tr1, static_cast<int>(min_id));
|
||||||
|
|
||||||
|
if(CGAL::internal::on_left_of_triangle_edge(x1, n2, p2, q2, k) &&
|
||||||
|
CGAL::internal::on_left_of_triangle_edge(x1, n2, q2, r2, k) &&
|
||||||
|
CGAL::internal::on_left_of_triangle_edge(x1, n2, r2, p2, k))
|
||||||
|
{
|
||||||
|
// the projection of `x1` is inside the triangle
|
||||||
|
return std::make_pair(CGAL::internal::squared_distance_to_plane(n2, vector(p2, x1), k), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_pair(0, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace Distance_3
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <typename K>
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const typename K::Triangle_3& tr1,
|
||||||
|
const typename K::Triangle_3& tr2,
|
||||||
|
const K& k)
|
||||||
|
{
|
||||||
|
typedef typename K::FT FT;
|
||||||
|
|
||||||
|
typename K::Construct_vertex_3 vertex = k.construct_vertex_3_object();
|
||||||
|
|
||||||
|
// ideally just limits<FT>::infinity|max(), but it is not available for exact NTs...
|
||||||
|
FT global_min_sqd = squared_distance(vertex(tr1, 0), vertex(tr2, 0));
|
||||||
|
|
||||||
|
bool are_triangles_known_to_be_disjoint = false;
|
||||||
|
std::pair<Distance_3::internal::Segment_3_Segment_3_Result<K>, bool> ss_res;
|
||||||
|
for(int i=0; i<3; ++i)
|
||||||
|
{
|
||||||
|
for(int j=0; j<3; ++j)
|
||||||
|
{
|
||||||
|
ss_res = Distance_3::internal::test_edge_pair(
|
||||||
|
vertex(tr1, i%3), vertex(tr1, (i+1)%3), vertex(tr1, (i+2)%3),
|
||||||
|
vertex(tr2, j%3), vertex(tr2, (j+1)%3), vertex(tr2, (j+2)%3), k,
|
||||||
|
global_min_sqd, are_triangles_known_to_be_disjoint);
|
||||||
|
|
||||||
|
if(ss_res.second)
|
||||||
|
return ss_res.first.squared_distance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Failed to find a minimum between segment pairs, explore vertex-triangle distances
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
std::pair<FT, bool> pt_res =
|
||||||
|
Distance_3::internal::test_vertex_triangle(tr1, tr2, k, are_triangles_known_to_be_disjoint);
|
||||||
|
if(pt_res.second)
|
||||||
|
return pt_res.first;
|
||||||
|
|
||||||
|
pt_res = Distance_3::internal::test_vertex_triangle(tr2, tr1, k, are_triangles_known_to_be_disjoint);
|
||||||
|
if(pt_res.second)
|
||||||
|
return pt_res.first;
|
||||||
|
|
||||||
|
if(are_triangles_known_to_be_disjoint)
|
||||||
|
return global_min_sqd;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
#else // A tiny bit less efficient, but a lot clearer!
|
||||||
|
// @todo does not handle degenerate inputs
|
||||||
|
if(!are_triangles_known_to_be_disjoint && CGAL::do_intersect(tr1, tr2))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
FT sqd_p1 = CGAL::squared_distance(vertex(tr1, 0), tr2);
|
||||||
|
FT sqd_q1 = CGAL::squared_distance(vertex(tr1, 1), tr2);
|
||||||
|
FT sqd_r1 = CGAL::squared_distance(vertex(tr1, 2), tr2);
|
||||||
|
FT sqd_p2 = CGAL::squared_distance(vertex(tr2, 0), tr1);
|
||||||
|
FT sqd_q2 = CGAL::squared_distance(vertex(tr2, 1), tr1);
|
||||||
|
FT sqd_r2 = CGAL::squared_distance(vertex(tr2, 2), tr1);
|
||||||
|
|
||||||
|
const FT m = std::min({sqd_p1, sqd_q1, sqd_r1, sqd_p2, sqd_q2, sqd_r2});
|
||||||
|
|
||||||
|
return m;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const Triangle_3<K>& tr1,
|
||||||
|
const Triangle_3<K>& tr2)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_3_object()(tr1, tr2);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_DISTANCE_3_TRIANGLE_3_TRIANGLE_3_H
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
// Copyright (c) 1998-2021
|
||||||
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org)
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Geert-Jan Giezeman, Andreas Fabri
|
||||||
|
|
||||||
|
#ifndef CGAL_DISTANCE_3_WEIGHTED_POINT_3_WEIGHTED_POINT_3_H
|
||||||
|
#define CGAL_DISTANCE_3_WEIGHTED_POINT_3_WEIGHTED_POINT_3_H
|
||||||
|
|
||||||
|
#include <CGAL/Weighted_point_3.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::FT
|
||||||
|
squared_distance(const Weighted_point_3<K>& wpt1,
|
||||||
|
const Weighted_point_3<K>& wpt2)
|
||||||
|
{
|
||||||
|
return K().compute_squared_distance_3_object()(wpt1.point(), wpt2.point());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_DISTANCE_3_WEIGHTED_POINT_3_WEIGHTED_POINT_3_H
|
||||||
|
|
@ -12,43 +12,34 @@
|
||||||
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Author(s) : Geert-Jan Giezeman, Andreas Fabri
|
// Author(s) : Geert-Jan Giezeman
|
||||||
|
|
||||||
|
#ifndef CGAL_SQUARED_DISTANCE_UTILS_3_H
|
||||||
|
#define CGAL_SQUARED_DISTANCE_UTILS_3_H
|
||||||
|
|
||||||
#ifndef CGAL_DISTANCE_3_0_H
|
#include <CGAL/determinant.h>
|
||||||
#define CGAL_DISTANCE_3_0_H
|
|
||||||
|
|
||||||
#include <CGAL/kernel_assertions.h>
|
|
||||||
#include <CGAL/enum.h>
|
#include <CGAL/enum.h>
|
||||||
#include <CGAL/wmult.h>
|
|
||||||
|
|
||||||
#include <CGAL/Point_3.h>
|
|
||||||
#include <CGAL/Weighted_point_3.h>
|
|
||||||
#include <CGAL/Vector_3.h>
|
|
||||||
#include <CGAL/number_utils.h>
|
#include <CGAL/number_utils.h>
|
||||||
#include <CGAL/Rational_traits.h>
|
#include <CGAL/Rational_traits.h>
|
||||||
|
#include <CGAL/wmult.h>
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
template <class K>
|
template <class K>
|
||||||
bool is_null(const typename K::Vector_3 &v, const K&)
|
bool is_null(const typename K::Vector_3 &v, const K&)
|
||||||
{
|
{
|
||||||
typedef typename K::RT RT;
|
typedef typename K::RT RT;
|
||||||
return v.hx()==RT(0) && v.hy()==RT(0) && v.hz()==RT(0);
|
return v.hx() == RT(0) && v.hy() == RT(0) && v.hz() == RT(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
template <class K>
|
||||||
typename K::RT
|
typename K::RT
|
||||||
wdot(const typename K::Vector_3 &u,
|
wdot(const typename K::Vector_3 &u,
|
||||||
const typename K::Vector_3 &v,
|
const typename K::Vector_3 &v,
|
||||||
const K&)
|
const K&)
|
||||||
{
|
{
|
||||||
return (u.hx()*v.hx() + u.hy()*v.hy() + u.hz()*v.hz());
|
return (u.hx()*v.hx() + u.hy()*v.hy() + u.hz()*v.hz());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class K>
|
template <class K>
|
||||||
|
|
@ -72,12 +63,12 @@ wdot_tag(const typename K::Point_3 &p,
|
||||||
const K&,
|
const K&,
|
||||||
const Homogeneous_tag&)
|
const Homogeneous_tag&)
|
||||||
{
|
{
|
||||||
return ( (p.hx() * q.hw() - q.hx() * p.hw())
|
return ( (p.hx() * q.hw() - q.hx() * p.hw())
|
||||||
* (r.hx() * q.hw() - q.hx() * r.hw())
|
* (r.hx() * q.hw() - q.hx() * r.hw())
|
||||||
+ (p.hy() * q.hw() - q.hy() * p.hw())
|
+ (p.hy() * q.hw() - q.hy() * p.hw())
|
||||||
* (r.hy() * q.hw() - q.hy() * r.hw())
|
* (r.hy() * q.hw() - q.hy() * r.hw())
|
||||||
+ (p.hz() * q.hw() - q.hz() * p.hw())
|
+ (p.hz() * q.hw() - q.hz() * p.hw())
|
||||||
* (r.hz() * q.hw() - q.hz() * r.hw()));
|
* (r.hz() * q.hw() - q.hz() * r.hw()));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class K>
|
template <class K>
|
||||||
|
|
@ -93,9 +84,6 @@ wdot(const typename K::Point_3 &p,
|
||||||
return wdot_tag(p, q, r, k, tag);
|
return wdot_tag(p, q, r, k, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
template <class K>
|
||||||
typename K::Vector_3
|
typename K::Vector_3
|
||||||
wcross(const typename K::Vector_3 &u,
|
wcross(const typename K::Vector_3 &u,
|
||||||
|
|
@ -103,13 +91,12 @@ wcross(const typename K::Vector_3 &u,
|
||||||
const K&)
|
const K&)
|
||||||
{
|
{
|
||||||
typedef typename K::Vector_3 Vector_3;
|
typedef typename K::Vector_3 Vector_3;
|
||||||
return Vector_3(
|
return Vector_3(
|
||||||
u.hy()*v.hz() - u.hz()*v.hy(),
|
u.hy()*v.hz() - u.hz()*v.hy(),
|
||||||
u.hz()*v.hx() - u.hx()*v.hz(),
|
u.hz()*v.hx() - u.hx()*v.hz(),
|
||||||
u.hx()*v.hy() - u.hy()*v.hx());
|
u.hx()*v.hy() - u.hy()*v.hx());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
template <class K>
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
|
|
@ -117,8 +104,8 @@ is_acute_angle(const typename K::Vector_3 &u,
|
||||||
const typename K::Vector_3 &v,
|
const typename K::Vector_3 &v,
|
||||||
const K& k)
|
const K& k)
|
||||||
{
|
{
|
||||||
typedef typename K::RT RT;
|
typedef typename K::RT RT;
|
||||||
return RT(wdot(u, v, k)) > RT(0) ;
|
return RT(wdot(u, v, k)) > RT(0) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class K>
|
template <class K>
|
||||||
|
|
@ -128,8 +115,8 @@ is_straight_angle(const typename K::Vector_3 &u,
|
||||||
const typename K::Vector_3 &v,
|
const typename K::Vector_3 &v,
|
||||||
const K& k)
|
const K& k)
|
||||||
{
|
{
|
||||||
typedef typename K::RT RT;
|
typedef typename K::RT RT;
|
||||||
return RT(wdot(u, v, k)) == RT(0) ;
|
return RT(wdot(u, v, k)) == RT(0) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class K>
|
template <class K>
|
||||||
|
|
@ -139,8 +126,8 @@ is_obtuse_angle(const typename K::Vector_3 &u,
|
||||||
const typename K::Vector_3 &v,
|
const typename K::Vector_3 &v,
|
||||||
const K& k)
|
const K& k)
|
||||||
{
|
{
|
||||||
typedef typename K::RT RT;
|
typedef typename K::RT RT;
|
||||||
return RT(wdot(u, v, k)) < RT(0) ;
|
return RT(wdot(u, v, k)) < RT(0) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class K>
|
template <class K>
|
||||||
|
|
@ -151,8 +138,8 @@ is_acute_angle(const typename K::Point_3 &p,
|
||||||
const typename K::Point_3 &r,
|
const typename K::Point_3 &r,
|
||||||
const K& k)
|
const K& k)
|
||||||
{
|
{
|
||||||
typedef typename K::RT RT;
|
typedef typename K::RT RT;
|
||||||
return RT(wdot(p, q, r, k)) > RT(0) ;
|
return RT(wdot(p, q, r, k)) > RT(0) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class K>
|
template <class K>
|
||||||
|
|
@ -163,8 +150,8 @@ is_straight_angle(const typename K::Point_3 &p,
|
||||||
const typename K::Point_3 &r,
|
const typename K::Point_3 &r,
|
||||||
const K& k)
|
const K& k)
|
||||||
{
|
{
|
||||||
typedef typename K::RT RT;
|
typedef typename K::RT RT;
|
||||||
return RT(wdot(p, q, r, k)) == RT(0) ;
|
return RT(wdot(p, q, r, k)) == RT(0) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class K>
|
template <class K>
|
||||||
|
|
@ -173,25 +160,15 @@ bool
|
||||||
is_obtuse_angle(const typename K::Point_3 &p,
|
is_obtuse_angle(const typename K::Point_3 &p,
|
||||||
const typename K::Point_3 &q,
|
const typename K::Point_3 &q,
|
||||||
const typename K::Point_3 &r,
|
const typename K::Point_3 &r,
|
||||||
const K& k)
|
const K& k)
|
||||||
{
|
{
|
||||||
typedef typename K::RT RT;
|
typedef typename K::RT RT;
|
||||||
return RT(wdot(p, q, r, k)) < RT(0) ;
|
return RT(wdot(p, q, r, k)) < RT(0) ;
|
||||||
}
|
}
|
||||||
template <class K>
|
|
||||||
inline
|
|
||||||
typename K::FT
|
|
||||||
squared_distance(const typename K::Point_3 & pt1,
|
|
||||||
const typename K::Point_3 & pt2,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
return k.compute_squared_distance_3_object()(pt1, pt2);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
template <class K>
|
||||||
void
|
void
|
||||||
squared_distance_to_plane_RT(const typename K::Vector_3 & normal,
|
squared_distance_to_plane_RT(const typename K::Vector_3& normal,
|
||||||
const typename K::Vector_3 & diff,
|
const typename K::Vector_3& diff,
|
||||||
typename K::RT& num,
|
typename K::RT& num,
|
||||||
typename K::RT& den,
|
typename K::RT& den,
|
||||||
const K& k)
|
const K& k)
|
||||||
|
|
@ -206,8 +183,8 @@ squared_distance_to_plane_RT(const typename K::Vector_3 & normal,
|
||||||
|
|
||||||
template <class K>
|
template <class K>
|
||||||
typename K::FT
|
typename K::FT
|
||||||
squared_distance_to_plane(const typename K::Vector_3 & normal,
|
squared_distance_to_plane(const typename K::Vector_3& normal,
|
||||||
const typename K::Vector_3 & diff,
|
const typename K::Vector_3& diff,
|
||||||
const K& k)
|
const K& k)
|
||||||
{
|
{
|
||||||
typedef typename K::RT RT;
|
typedef typename K::RT RT;
|
||||||
|
|
@ -219,8 +196,8 @@ squared_distance_to_plane(const typename K::Vector_3 & normal,
|
||||||
|
|
||||||
template <class K>
|
template <class K>
|
||||||
void
|
void
|
||||||
squared_distance_to_line_RT(const typename K::Vector_3 & dir,
|
squared_distance_to_line_RT(const typename K::Vector_3& dir,
|
||||||
const typename K::Vector_3 & diff,
|
const typename K::Vector_3& diff,
|
||||||
typename K::RT& num,
|
typename K::RT& num,
|
||||||
typename K::RT& den,
|
typename K::RT& den,
|
||||||
const K& k)
|
const K& k)
|
||||||
|
|
@ -233,8 +210,8 @@ squared_distance_to_line_RT(const typename K::Vector_3 & dir,
|
||||||
|
|
||||||
template <class K>
|
template <class K>
|
||||||
typename K::FT
|
typename K::FT
|
||||||
squared_distance_to_line(const typename K::Vector_3 & dir,
|
squared_distance_to_line(const typename K::Vector_3& dir,
|
||||||
const typename K::Vector_3 & diff,
|
const typename K::Vector_3& diff,
|
||||||
const K& k)
|
const K& k)
|
||||||
{
|
{
|
||||||
typedef typename K::RT RT;
|
typedef typename K::RT RT;
|
||||||
|
|
@ -271,7 +248,6 @@ same_direction_tag(const typename K::Vector_3 &u,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
template <class K>
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
|
|
@ -299,7 +275,6 @@ same_direction_tag(const typename K::Vector_3 &u,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
template <class K>
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
|
|
@ -312,70 +287,19 @@ same_direction(const typename K::Vector_3 &u,
|
||||||
return same_direction_tag(u, v, k, tag);
|
return same_direction_tag(u, v, k, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
inline
|
||||||
|
typename K::RT
|
||||||
|
distance_measure_sub(typename K::RT startwdist, typename K::RT endwdist,
|
||||||
|
const typename K::Vector_3 &start,
|
||||||
|
const typename K::Vector_3 &end,
|
||||||
|
const K&)
|
||||||
|
{
|
||||||
|
return CGAL_NTS abs(wmult((K*)0, startwdist, end.hw())) -
|
||||||
|
CGAL_NTS abs(wmult((K*)0, endwdist, start.hw()));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
template <class K>
|
#endif // CGAL_SQUARED_DISTANCE_UTILS_3_H
|
||||||
inline
|
|
||||||
typename K::FT
|
|
||||||
squared_distance(const Point_3<K> & pt1,
|
|
||||||
const Point_3<K> & pt2)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(pt1,pt2, K());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline
|
|
||||||
typename K::FT
|
|
||||||
squared_distance(const Weighted_point_3<K> & pt1,
|
|
||||||
const Weighted_point_3<K> & pt2)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(pt1.point(),pt2.point(), K());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline
|
|
||||||
typename K::FT
|
|
||||||
squared_distance(const Weighted_point_3<K> & pt1,
|
|
||||||
const Point_3<K> & pt2)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(pt1.point(),pt2, K());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline
|
|
||||||
typename K::FT
|
|
||||||
squared_distance(const Point_3<K> & pt1,
|
|
||||||
const Weighted_point_3<K> & pt2)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(pt1,pt2.point(), K());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline
|
|
||||||
typename K::FT
|
|
||||||
squared_distance_to_plane(const Vector_3<K> & normal,
|
|
||||||
const Vector_3<K> & diff)
|
|
||||||
{
|
|
||||||
return internal::squared_distance_to_plane(normal, diff, K());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline
|
|
||||||
typename K::FT
|
|
||||||
squared_distance_to_line(const Vector_3<K> & dir,
|
|
||||||
const Vector_3<K> & diff)
|
|
||||||
{
|
|
||||||
return internal::squared_distance_to_line(dir, diff, K());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} //namespace CGAL
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -18,9 +18,31 @@
|
||||||
#ifndef CGAL_DISTANCE_3_H
|
#ifndef CGAL_DISTANCE_3_H
|
||||||
#define CGAL_DISTANCE_3_H
|
#define CGAL_DISTANCE_3_H
|
||||||
|
|
||||||
#include <CGAL/squared_distance_3_0.h>
|
#include <CGAL/Distance_3/Point_3_Point_3.h>
|
||||||
#include <CGAL/squared_distance_3_1.h>
|
#include <CGAL/Distance_3/Point_3_Weighted_point_3.h>
|
||||||
#include <CGAL/squared_distance_3_2.h>
|
#include <CGAL/Distance_3/Point_3_Segment_3.h>
|
||||||
#include <CGAL/squared_distance_3_3.h>
|
#include <CGAL/Distance_3/Point_3_Ray_3.h>
|
||||||
|
#include <CGAL/Distance_3/Point_3_Line_3.h>
|
||||||
|
#include <CGAL/Distance_3/Point_3_Triangle_3.h>
|
||||||
|
#include <CGAL/Distance_3/Point_3_Plane_3.h>
|
||||||
|
#include <CGAL/Distance_3/Point_3_Tetrahedron_3.h>
|
||||||
|
|
||||||
#endif
|
#include <CGAL/Distance_3/Weighted_point_3_Weighted_point_3.h>
|
||||||
|
|
||||||
|
#include <CGAL/Distance_3/Segment_3_Segment_3.h>
|
||||||
|
#include <CGAL/Distance_3/Segment_3_Ray_3.h>
|
||||||
|
#include <CGAL/Distance_3/Segment_3_Line_3.h>
|
||||||
|
#include <CGAL/Distance_3/Segment_3_Plane_3.h>
|
||||||
|
|
||||||
|
#include <CGAL/Distance_3/Ray_3_Ray_3.h>
|
||||||
|
#include <CGAL/Distance_3/Ray_3_Line_3.h>
|
||||||
|
#include <CGAL/Distance_3/Ray_3_Plane_3.h>
|
||||||
|
|
||||||
|
#include <CGAL/Distance_3/Line_3_Line_3.h>
|
||||||
|
#include <CGAL/Distance_3/Line_3_Plane_3.h>
|
||||||
|
|
||||||
|
#include <CGAL/Distance_3/Triangle_3_Triangle_3.h>
|
||||||
|
|
||||||
|
#include <CGAL/Distance_3/Plane_3_Plane_3.h>
|
||||||
|
|
||||||
|
#endif // CGAL_DISTANCE_3_H
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,505 +0,0 @@
|
||||||
// Copyright (c) 1998-2004
|
|
||||||
// Utrecht University (The Netherlands),
|
|
||||||
// ETH Zurich (Switzerland),
|
|
||||||
// INRIA Sophia-Antipolis (France),
|
|
||||||
// Max-Planck-Institute Saarbruecken (Germany),
|
|
||||||
// and Tel-Aviv University (Israel). All rights reserved.
|
|
||||||
//
|
|
||||||
// This file is part of CGAL (www.cgal.org)
|
|
||||||
//
|
|
||||||
// $URL$
|
|
||||||
// $Id$
|
|
||||||
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Author(s) : Geert-Jan Giezeman, Andreas Fabri
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef CGAL_DISTANCE_3_2_H
|
|
||||||
#define CGAL_DISTANCE_3_2_H
|
|
||||||
|
|
||||||
#include <CGAL/squared_distance_3_0.h>
|
|
||||||
#include <CGAL/squared_distance_3_1.h>
|
|
||||||
#include <CGAL/wmult.h>
|
|
||||||
|
|
||||||
#include <CGAL/Point_3.h>
|
|
||||||
#include <CGAL/Segment_3.h>
|
|
||||||
#include <CGAL/Line_3.h>
|
|
||||||
#include <CGAL/Ray_3.h>
|
|
||||||
#include <CGAL/Triangle_3.h>
|
|
||||||
#include <CGAL/Plane_3.h>
|
|
||||||
|
|
||||||
namespace CGAL {
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
bool
|
|
||||||
contains_vector(const typename K::Plane_3 &pl,
|
|
||||||
const typename K::Vector_3 &vec,
|
|
||||||
const K&)
|
|
||||||
{
|
|
||||||
typedef typename K::RT RT;
|
|
||||||
return pl.a()*vec.hx() + pl.b()*vec.hy() + pl.c() * vec.hz() == RT(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(
|
|
||||||
const typename K::Point_3 & pt,
|
|
||||||
const typename K::Plane_3 & plane,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
typename K::Construct_vector_3 construct_vector;
|
|
||||||
typedef typename K::Vector_3 Vector_3;
|
|
||||||
Vector_3 diff = construct_vector(plane.point(), pt);
|
|
||||||
return squared_distance_to_plane(plane.orthogonal_vector(), diff, k);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(
|
|
||||||
const typename K::Plane_3 & plane,
|
|
||||||
const typename K::Point_3 & pt,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
return squared_distance(pt, plane, k);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
typename K::FT
|
|
||||||
squared_distance(
|
|
||||||
const typename K::Line_3 &line,
|
|
||||||
const typename K::Plane_3 &plane,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
typedef typename K::FT FT;
|
|
||||||
if (contains_vector(plane, line.direction().vector(), k))
|
|
||||||
return squared_distance(plane, line.point(), k);
|
|
||||||
return FT(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(
|
|
||||||
const typename K::Plane_3 & p,
|
|
||||||
const typename K::Line_3 & line,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
return squared_distance(line, p, k);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
typename K::FT
|
|
||||||
squared_distance(
|
|
||||||
const typename K::Ray_3 &ray,
|
|
||||||
const typename K::Plane_3 &plane,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
typename K::Construct_vector_3 construct_vector;
|
|
||||||
typedef typename K::Point_3 Point_3;
|
|
||||||
typedef typename K::Vector_3 Vector_3;
|
|
||||||
typedef typename K::RT RT;
|
|
||||||
typedef typename K::FT FT;
|
|
||||||
const Point_3 &start = ray.start();
|
|
||||||
const Point_3 &planepoint = plane.point();
|
|
||||||
Vector_3 start_min_pp = construct_vector(planepoint, start);
|
|
||||||
Vector_3 end_min_pp = ray.direction().vector();
|
|
||||||
const Vector_3 &normal = plane.orthogonal_vector();
|
|
||||||
RT sdm_rs2pp = wdot(normal, start_min_pp, k);
|
|
||||||
RT sdm_re2pp = wdot(normal, end_min_pp, k);
|
|
||||||
switch (CGAL_NTS sign(sdm_rs2pp)) {
|
|
||||||
case -1:
|
|
||||||
if (sdm_re2pp > RT(0))
|
|
||||||
return FT(0);
|
|
||||||
return squared_distance_to_plane(normal, start_min_pp, k);
|
|
||||||
case 0:
|
|
||||||
default:
|
|
||||||
return FT(0);
|
|
||||||
case 1:
|
|
||||||
if (sdm_re2pp < RT(0))
|
|
||||||
return FT(0);
|
|
||||||
return squared_distance_to_plane(normal, start_min_pp, k);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(
|
|
||||||
const typename K::Plane_3 & plane,
|
|
||||||
const typename K::Ray_3 & ray,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
return squared_distance(ray, plane, k);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
typename K::FT
|
|
||||||
squared_distance(
|
|
||||||
const typename K::Segment_3 &seg,
|
|
||||||
const typename K::Plane_3 &plane,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
typename K::Construct_vector_3 construct_vector;
|
|
||||||
typedef typename K::Point_3 Point_3;
|
|
||||||
typedef typename K::Vector_3 Vector_3;
|
|
||||||
typedef typename K::RT RT;
|
|
||||||
typedef typename K::FT FT;
|
|
||||||
const Point_3 &start = seg.start();
|
|
||||||
const Point_3 &end = seg.end();
|
|
||||||
if (start == end)
|
|
||||||
return squared_distance(start, plane, k);
|
|
||||||
const Point_3 &planepoint = plane.point();
|
|
||||||
Vector_3 start_min_pp = construct_vector(planepoint, start);
|
|
||||||
Vector_3 end_min_pp = construct_vector(planepoint, end);
|
|
||||||
const Vector_3 &normal = plane.orthogonal_vector();
|
|
||||||
RT sdm_ss2pp = wdot(normal, start_min_pp, k);
|
|
||||||
RT sdm_se2pp = wdot(normal, end_min_pp, k);
|
|
||||||
switch (CGAL_NTS sign(sdm_ss2pp)) {
|
|
||||||
case -1:
|
|
||||||
if (sdm_se2pp >= RT(0))
|
|
||||||
return FT(0);
|
|
||||||
if (sdm_ss2pp * end_min_pp.hw() >= sdm_se2pp * start_min_pp.hw())
|
|
||||||
return squared_distance_to_plane(normal, start_min_pp, k);
|
|
||||||
else
|
|
||||||
return squared_distance_to_plane(normal, end_min_pp, k);
|
|
||||||
case 0:
|
|
||||||
default:
|
|
||||||
return FT(0);
|
|
||||||
case 1:
|
|
||||||
if (sdm_se2pp <= RT(0))
|
|
||||||
return FT(0);
|
|
||||||
if (sdm_ss2pp * end_min_pp.hw() <= sdm_se2pp * start_min_pp.hw())
|
|
||||||
return squared_distance_to_plane(normal, start_min_pp, k);
|
|
||||||
else
|
|
||||||
return squared_distance_to_plane(normal, end_min_pp, k);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(
|
|
||||||
const typename K::Plane_3 & plane,
|
|
||||||
const typename K::Segment_3 & seg,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
return squared_distance(seg, plane, k);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline bool
|
|
||||||
on_left_of_triangle_edge(const typename K::Point_3 & pt,
|
|
||||||
const typename K::Vector_3 & normal,
|
|
||||||
const typename K::Point_3 & ep0,
|
|
||||||
const typename K::Point_3 & ep1,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
// return true iff pt is on the negative side of the plane defined
|
|
||||||
// by (ep0, ep1) and normal
|
|
||||||
typename K::Construct_vector_3 vector;
|
|
||||||
typename K::Vector_3 edge = vector(ep0, ep1);
|
|
||||||
typename K::Vector_3 diff = vector(ep0, pt);
|
|
||||||
|
|
||||||
typedef typename K::RT RT;
|
|
||||||
|
|
||||||
const bool result =
|
|
||||||
RT(wdot(wcross(edge,
|
|
||||||
normal,
|
|
||||||
k),
|
|
||||||
diff,
|
|
||||||
k)) <= RT(0);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline void
|
|
||||||
squared_distance_to_triangle_RT(
|
|
||||||
const typename K::Point_3 & pt,
|
|
||||||
const typename K::Point_3 & t0,
|
|
||||||
const typename K::Point_3 & t1,
|
|
||||||
const typename K::Point_3 & t2,
|
|
||||||
bool & inside,
|
|
||||||
typename K::RT& num,
|
|
||||||
typename K::RT& den,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
typename K::Construct_vector_3 vector;
|
|
||||||
typedef typename K::Vector_3 Vector_3;
|
|
||||||
const Vector_3 e1 = vector(t0, t1);
|
|
||||||
const Vector_3 oe3 = vector(t0, t2);
|
|
||||||
const Vector_3 normal = wcross(e1, oe3, k);
|
|
||||||
|
|
||||||
if(normal == NULL_VECTOR) {
|
|
||||||
// The case normal==NULL_VECTOR covers the case when the triangle
|
|
||||||
// is colinear, or even more degenerate. In that case, we can
|
|
||||||
// simply take also the distance to the three segments.
|
|
||||||
squared_distance_RT(pt, typename K::Segment_3(t2, t0), num, den, k);
|
|
||||||
|
|
||||||
typename K::RT num2, den2;
|
|
||||||
squared_distance_RT(pt, typename K::Segment_3(t1, t2), num2, den2, k);
|
|
||||||
if(compare_quotients(num2,den2, num,den) == SMALLER) {
|
|
||||||
num = num2;
|
|
||||||
den = den2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// should not be needed since at most 2 edges cover the full triangle in the degenerate case
|
|
||||||
squared_distance_RT(pt, typename K::Segment_3(t0, t1), num2, den2, k);
|
|
||||||
if(compare_quotients(num2,den2, num,den) == SMALLER){
|
|
||||||
num = num2;
|
|
||||||
den = den2;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool b01 = on_left_of_triangle_edge(pt, normal, t0, t1, k);
|
|
||||||
if(!b01) {
|
|
||||||
squared_distance_RT(pt, typename K::Segment_3(t0, t1), num, den, k);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool b12 = on_left_of_triangle_edge(pt, normal, t1, t2, k);
|
|
||||||
if(!b12) {
|
|
||||||
squared_distance_RT(pt, typename K::Segment_3(t1, t2), num, den, k);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool b20 = on_left_of_triangle_edge(pt, normal, t2, t0, k);
|
|
||||||
if(!b20) {
|
|
||||||
squared_distance_RT(pt, typename K::Segment_3(t2, t0), num, den, k);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The projection of pt is inside the triangle
|
|
||||||
inside = true;
|
|
||||||
squared_distance_to_plane_RT(normal, vector(t0, pt), num, den, k);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
void
|
|
||||||
squared_distance_RT(
|
|
||||||
const typename K::Point_3 & pt,
|
|
||||||
const typename K::Triangle_3 & t,
|
|
||||||
typename K::RT& num,
|
|
||||||
typename K::RT& den,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
typename K::Construct_vertex_3 vertex;
|
|
||||||
bool inside = false;
|
|
||||||
squared_distance_to_triangle_RT(pt,
|
|
||||||
vertex(t, 0),
|
|
||||||
vertex(t, 1),
|
|
||||||
vertex(t, 2),
|
|
||||||
inside,
|
|
||||||
num,
|
|
||||||
den,
|
|
||||||
k);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance_to_triangle(
|
|
||||||
const typename K::Point_3 & pt,
|
|
||||||
const typename K::Point_3 & t0,
|
|
||||||
const typename K::Point_3 & t1,
|
|
||||||
const typename K::Point_3 & t2,
|
|
||||||
bool & inside,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
typename K::Construct_vector_3 vector;
|
|
||||||
typedef typename K::Vector_3 Vector_3;
|
|
||||||
const Vector_3 e1 = vector(t0, t1);
|
|
||||||
const Vector_3 oe3 = vector(t0, t2);
|
|
||||||
const Vector_3 normal = wcross(e1, oe3, k);
|
|
||||||
|
|
||||||
if(normal == NULL_VECTOR) {
|
|
||||||
// The case normal==NULL_VECTOR covers the case when the triangle
|
|
||||||
// is colinear, or even more degenerate. In that case, we can
|
|
||||||
// simply take also the distance to the three segments.
|
|
||||||
typename K::FT d1 = squared_distance(pt, typename K::Segment_3(t2, t0), k);
|
|
||||||
typename K::FT d2 = squared_distance(pt, typename K::Segment_3(t1, t2), k);
|
|
||||||
|
|
||||||
// should not be needed since at most 2 edges cover the full triangle in the degenerate case
|
|
||||||
typename K::FT d3 = squared_distance(pt, typename K::Segment_3(t0, t1), k);
|
|
||||||
|
|
||||||
return (std::min)( (std::min)(d1, d2), d3);
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool b01 = on_left_of_triangle_edge(pt, normal, t0, t1, k);
|
|
||||||
if(!b01) {
|
|
||||||
return internal::squared_distance(pt, typename K::Segment_3(t0, t1), k);
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool b12 = on_left_of_triangle_edge(pt, normal, t1, t2, k);
|
|
||||||
if(!b12) {
|
|
||||||
return internal::squared_distance(pt, typename K::Segment_3(t1, t2), k);
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool b20 = on_left_of_triangle_edge(pt, normal, t2, t0, k);
|
|
||||||
if(!b20) {
|
|
||||||
return internal::squared_distance(pt, typename K::Segment_3(t2, t0), k);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The projection of pt is inside the triangle
|
|
||||||
inside = true;
|
|
||||||
return squared_distance_to_plane(normal, vector(t0, pt), k);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline typename K::FT
|
|
||||||
squared_distance(
|
|
||||||
const typename K::Point_3 & pt,
|
|
||||||
const typename K::Triangle_3 & t,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
typename K::Construct_vertex_3 vertex = k.construct_vertex_3_object();
|
|
||||||
bool inside = false;
|
|
||||||
return squared_distance_to_triangle(pt,
|
|
||||||
vertex(t, 0),
|
|
||||||
vertex(t, 1),
|
|
||||||
vertex(t, 2),
|
|
||||||
inside,
|
|
||||||
k);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
bool
|
|
||||||
contains_vector(const Plane_3<K> &pl, const Vector_3<K> &vec)
|
|
||||||
{
|
|
||||||
return internal::contains_vector(pl,vec, K());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline
|
|
||||||
typename K::FT
|
|
||||||
squared_distance(
|
|
||||||
const Point_3<K> & pt,
|
|
||||||
const Plane_3<K> & plane)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(pt, plane, K());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline
|
|
||||||
typename K::FT
|
|
||||||
squared_distance(
|
|
||||||
const Plane_3<K> & plane,
|
|
||||||
const Point_3<K> & pt)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(pt, plane, K());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline
|
|
||||||
typename K::FT
|
|
||||||
squared_distance(
|
|
||||||
const Line_3<K> &line,
|
|
||||||
const Plane_3<K> &plane)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(line, plane, K());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline
|
|
||||||
typename K::FT
|
|
||||||
squared_distance(
|
|
||||||
const Plane_3<K> & p,
|
|
||||||
const Line_3<K> & line)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(line, p, K());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline
|
|
||||||
typename K::FT
|
|
||||||
squared_distance(
|
|
||||||
const Ray_3<K> &ray,
|
|
||||||
const Plane_3<K> &plane)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(ray, plane, K());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline
|
|
||||||
typename K::FT
|
|
||||||
squared_distance(
|
|
||||||
const Plane_3<K> & plane,
|
|
||||||
const Ray_3<K> & ray)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(ray, plane, K());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline
|
|
||||||
typename K::FT
|
|
||||||
squared_distance(
|
|
||||||
const Segment_3<K> &seg,
|
|
||||||
const Plane_3<K> &plane)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(seg, plane, K());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline
|
|
||||||
typename K::FT
|
|
||||||
squared_distance(
|
|
||||||
const Plane_3<K> & plane,
|
|
||||||
const Segment_3<K> & seg)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(seg, plane, K());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline
|
|
||||||
typename K::FT
|
|
||||||
squared_distance(const Point_3<K> & pt,
|
|
||||||
const Triangle_3<K> & t) {
|
|
||||||
return internal::squared_distance(pt, t, K());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline
|
|
||||||
typename K::FT
|
|
||||||
squared_distance(const Triangle_3<K> & t,
|
|
||||||
const Point_3<K> & pt) {
|
|
||||||
return internal::squared_distance(pt, t, K());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline
|
|
||||||
typename K::FT
|
|
||||||
squared_distance(const Plane_3<K> & p1,
|
|
||||||
const Plane_3<K> & p2) {
|
|
||||||
K k;
|
|
||||||
typename K::Construct_orthogonal_vector_3 ortho_vec =
|
|
||||||
k.construct_orthogonal_vector_3_object();
|
|
||||||
if (!internal::is_null(internal::wcross(ortho_vec(p1), ortho_vec(p2), k), k))
|
|
||||||
return typename K::FT(0);
|
|
||||||
else
|
|
||||||
return internal::squared_distance(p1.point(), p2, k);
|
|
||||||
}
|
|
||||||
|
|
||||||
} //namespace CGAL
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,126 +0,0 @@
|
||||||
// Copyright (c) 1998-2021
|
|
||||||
// Utrecht University (The Netherlands),
|
|
||||||
// ETH Zurich (Switzerland),
|
|
||||||
// INRIA Sophia-Antipolis (France),
|
|
||||||
// Max-Planck-Institute Saarbruecken (Germany),
|
|
||||||
// and Tel-Aviv University (Israel). All rights reserved.
|
|
||||||
//
|
|
||||||
// This file is part of CGAL (www.cgal.org)
|
|
||||||
//
|
|
||||||
// $URL$
|
|
||||||
// $Id$
|
|
||||||
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Author(s) : Geert-Jan Giezeman, Andreas Fabri
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef CGAL_DISTANCE_3_3_H
|
|
||||||
#define CGAL_DISTANCE_3_3_H
|
|
||||||
|
|
||||||
#include <CGAL/squared_distance_3_2.h>
|
|
||||||
|
|
||||||
#include <CGAL/Point_3.h>
|
|
||||||
#include <CGAL/Tetrahedron_3.h>
|
|
||||||
|
|
||||||
namespace CGAL {
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
inline
|
|
||||||
typename K::FT
|
|
||||||
squared_distance(const typename K::Tetrahedron_3 & t,
|
|
||||||
const typename K::Point_3 & pt,
|
|
||||||
const K& k)
|
|
||||||
{
|
|
||||||
bool on_bounded_side = true;
|
|
||||||
const typename K::Point_3 t0 = t[0];
|
|
||||||
const typename K::Point_3 t1 = t[1];
|
|
||||||
const typename K::Point_3 t2 = t[2];
|
|
||||||
const typename K::Point_3 t3 = t[3];
|
|
||||||
|
|
||||||
bool dmin_initialized = false;
|
|
||||||
typename K::FT dmin;
|
|
||||||
bool inside = false;
|
|
||||||
if(orientation(t0,t1,t2, pt) == NEGATIVE){
|
|
||||||
on_bounded_side = false;
|
|
||||||
dmin = squared_distance_to_triangle(pt, t0, t1, t2, inside, k);
|
|
||||||
dmin_initialized = true;
|
|
||||||
if(inside){
|
|
||||||
return dmin;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(orientation(t0,t3,t1, pt) == NEGATIVE){
|
|
||||||
on_bounded_side = false;
|
|
||||||
const typename K::FT d = squared_distance_to_triangle(pt, t0, t3, t1, inside, k);
|
|
||||||
if(inside){
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
if(! dmin_initialized){
|
|
||||||
dmin = d;
|
|
||||||
dmin_initialized = true;
|
|
||||||
}else{
|
|
||||||
dmin = (std::min)(d,dmin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(orientation(t1,t3,t2, pt) == NEGATIVE){
|
|
||||||
on_bounded_side = false;
|
|
||||||
const typename K::FT d = squared_distance_to_triangle(pt, t1, t3, t2, inside, k);
|
|
||||||
if(inside){
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
if(! dmin_initialized){
|
|
||||||
dmin = d;
|
|
||||||
dmin_initialized = true;
|
|
||||||
}else{
|
|
||||||
dmin = (std::min)(d,dmin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(orientation(t2,t3,t0, pt) == NEGATIVE){
|
|
||||||
on_bounded_side = false;
|
|
||||||
const typename K::FT d = squared_distance_to_triangle(pt, t2, t3, t0, inside, k);
|
|
||||||
if(inside){
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
if(! dmin_initialized){
|
|
||||||
dmin = d;
|
|
||||||
dmin_initialized = true;
|
|
||||||
}else{
|
|
||||||
dmin = (std::min)(d,dmin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(on_bounded_side){
|
|
||||||
return typename K::FT(0);
|
|
||||||
}
|
|
||||||
return dmin;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
typename K::FT
|
|
||||||
squared_distance(const Tetrahedron_3<K> & t,
|
|
||||||
const Point_3<K> & pt)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(t,pt,K());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
typename K::FT
|
|
||||||
squared_distance(const Point_3<K> & pt,
|
|
||||||
const Tetrahedron_3<K> & t)
|
|
||||||
{
|
|
||||||
return internal::squared_distance(t,pt,K());
|
|
||||||
}
|
|
||||||
|
|
||||||
} //namespace CGAL
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,22 +1,33 @@
|
||||||
// 3D distance tests.
|
|
||||||
|
|
||||||
#ifdef NDEBUG
|
|
||||||
#undef NDEBUG //this testsuite requires NDEBUG to be not defined
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <CGAL/Simple_cartesian.h>
|
#include <CGAL/Simple_cartesian.h>
|
||||||
#include <CGAL/Simple_homogeneous.h>
|
#include <CGAL/Simple_homogeneous.h>
|
||||||
|
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||||
|
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||||
|
#include <CGAL/Exact_integer.h>
|
||||||
|
#include <CGAL/Homogeneous.h>
|
||||||
|
|
||||||
|
#include <CGAL/squared_distance_3.h>
|
||||||
|
|
||||||
|
#include <CGAL/Random.h>
|
||||||
|
#include <CGAL/Timer.h>
|
||||||
|
|
||||||
|
// #define CGAL_USE_GTE_AS_SANITY_CHECK
|
||||||
|
#ifdef CGAL_USE_GTE_AS_SANITY_CHECK
|
||||||
|
#include <Mathematics/DistTriangle3Triangle3.h>
|
||||||
|
#include <Mathematics/DistSegmentSegment.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <iostream>
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
const double epsilon = 0.001;
|
struct randomint
|
||||||
|
{
|
||||||
struct randomint {
|
|
||||||
randomint() ;
|
randomint() ;
|
||||||
int get() const { return sequence[cur]; }
|
int get() const { return sequence[cur]; }
|
||||||
int next() { cur = (cur+1)%11; return get();}
|
int next() {
|
||||||
|
cur = (cur + 1) % 11;
|
||||||
|
return get();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int sequence[11];
|
int sequence[11];
|
||||||
int cur;
|
int cur;
|
||||||
|
|
@ -40,43 +51,32 @@ inline randomint::randomint()
|
||||||
|
|
||||||
randomint ri;
|
randomint ri;
|
||||||
|
|
||||||
inline double to_nt(int d)
|
template <typename K>
|
||||||
|
struct Test
|
||||||
{
|
{
|
||||||
return double(d);
|
typedef typename K::RT RT;
|
||||||
}
|
|
||||||
|
|
||||||
template < typename K >
|
|
||||||
struct Test {
|
|
||||||
|
|
||||||
typedef typename K::FT FT;
|
typedef typename K::FT FT;
|
||||||
typedef CGAL::Point_3< K > P;
|
typedef typename K::Point_3 P;
|
||||||
typedef CGAL::Line_3< K > L;
|
typedef typename K::Segment_3 S;
|
||||||
typedef CGAL::Segment_3< K > S;
|
typedef typename K::Vector_3 V;
|
||||||
typedef CGAL::Ray_3< K > R;
|
typedef typename K::Ray_3 R;
|
||||||
typedef CGAL::Triangle_3< K > T;
|
typedef typename K::Line_3 L;
|
||||||
typedef CGAL::Plane_3< K > Pl;
|
typedef typename K::Triangle_3 T;
|
||||||
typedef CGAL::Iso_cuboid_3< K > Cub;
|
typedef typename K::Plane_3 Pl;
|
||||||
typedef CGAL::Tetrahedron_3< K > Tet;
|
typedef typename K::Tetrahedron_3 Tet;
|
||||||
|
typedef typename K::Iso_cuboid_3 Cub;
|
||||||
|
|
||||||
|
private:
|
||||||
|
CGAL::Random& r;
|
||||||
|
const double epsilon = 1e-14;
|
||||||
|
int N = 10;
|
||||||
|
double m = 0, M = 1;
|
||||||
|
|
||||||
template < typename Type >
|
public:
|
||||||
bool approx_equal_nt(const Type &t1, const Type &t2)
|
Test(CGAL::Random& r, const double epsilon) : r(r), epsilon(epsilon) { }
|
||||||
{
|
|
||||||
if (t1 == t2)
|
|
||||||
return true;
|
|
||||||
if (CGAL::abs(t1 - t2) / (CGAL::max)(CGAL::abs(t1), CGAL::abs(t2)) < epsilon)
|
|
||||||
return true;
|
|
||||||
std::cout << " Approximate comparison failed between : " << t1 << " and " << t2 << "\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename O1, typename O2 >
|
|
||||||
void check_squared_distance(const O1& o1, const O2& o2, const FT& result)
|
|
||||||
{
|
|
||||||
assert(approx_equal_nt(CGAL::squared_distance(o1, o2), result));
|
|
||||||
assert(approx_equal_nt(CGAL::squared_distance(o2, o1), result));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
inline RT to_nt(int d) const { return RT(d); }
|
||||||
|
|
||||||
P p(int x, int y, int z)
|
P p(int x, int y, int z)
|
||||||
{
|
{
|
||||||
|
|
@ -84,34 +84,119 @@ struct Test {
|
||||||
return P(to_nt(x*w), to_nt(y*w), to_nt(z*w), to_nt(w));
|
return P(to_nt(x*w), to_nt(y*w), to_nt(z*w), to_nt(w));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
P random_point() const
|
||||||
|
{
|
||||||
|
return P(r.get_double(m, M), r.get_double(m, M), r.get_double(m, M));
|
||||||
|
}
|
||||||
|
|
||||||
Pl pl(int a, int b, int c, int d)
|
Pl pl(int a, int b, int c, int d)
|
||||||
{
|
{
|
||||||
int w = ri.next();
|
int w = ri.next();
|
||||||
return Pl(to_nt(a*w), to_nt(b*w), to_nt(c*w), to_nt(d*w));
|
return Pl(to_nt(a*w), to_nt(b*w), to_nt(c*w), to_nt(d*w));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <typename Type>
|
||||||
|
bool are_equal(const Type& t1, const Type& t2, const bool verbose = true)
|
||||||
|
{
|
||||||
|
const FT diff = CGAL::abs(t1 - t2);
|
||||||
|
if(diff > std::numeric_limits<FT>::epsilon() &&
|
||||||
|
diff > epsilon * (CGAL::abs(t1) + CGAL::abs(t2)))
|
||||||
|
{
|
||||||
|
if(verbose)
|
||||||
|
{
|
||||||
|
std::cerr << "Approximate comparison failed (t1|t2): got " << t1 << " but expected " << t2 << std::endl;
|
||||||
|
std::cerr << "Diff: " << CGAL::abs(t1 - t2) << " vs eps: " << epsilon * (CGAL::abs(t1) + CGAL::abs(t2)) << std::endl;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename O1, typename O2>
|
||||||
|
void check_ss_distance(const O1& o1, const O2& o2)
|
||||||
|
{
|
||||||
|
FT res = CGAL::squared_distance(o1, o2);
|
||||||
|
FT asd = compute_squared_distance_interval_between_segments(o1.source(), o1.target(),
|
||||||
|
o2.source(), o2.target(), K());
|
||||||
|
|
||||||
|
assert(res == asd);
|
||||||
|
|
||||||
|
std::cout << "input: " << o1.source() << " " << o1.target() << " " << o2.source() << " " << o2.target() << std::endl;
|
||||||
|
std::cout << "result (old) = " << res << std::endl;
|
||||||
|
std::cout << "result (new) = " << asd << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void do_intersect_check(const P&, const P&) { }
|
||||||
|
|
||||||
|
template <typename O2>
|
||||||
|
void do_intersect_check(const P& p, const O2& o2)
|
||||||
|
{
|
||||||
|
if(!o2.is_degenerate() && CGAL::do_intersect(p, o2))
|
||||||
|
{
|
||||||
|
assert(are_equal(CGAL::squared_distance(p, o2), FT(0)));
|
||||||
|
assert(are_equal(CGAL::squared_distance(o2, p), FT(0)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename O1, typename O2>
|
||||||
|
void do_intersect_check(const O1& o1, const O2& o2)
|
||||||
|
{
|
||||||
|
if(!o1.is_degenerate() && !o2.is_degenerate() && CGAL::do_intersect(o1, o2))
|
||||||
|
{
|
||||||
|
assert(are_equal(CGAL::squared_distance(o1, o2), FT(0)));
|
||||||
|
assert(are_equal(CGAL::squared_distance(o2, o1), FT(0)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename O1, typename O2>
|
||||||
|
void check_squared_distance(const O1& o1, const O2& o2, const FT& expected_result)
|
||||||
|
{
|
||||||
|
const FT res_o1o2 = CGAL::squared_distance(o1, o2);
|
||||||
|
const FT res_o2o1 = CGAL::squared_distance(o2, o1);
|
||||||
|
|
||||||
|
assert(are_equal(res_o1o2, expected_result));
|
||||||
|
assert(are_equal(res_o2o1, expected_result));
|
||||||
|
|
||||||
|
do_intersect_check(o1, o2);
|
||||||
|
do_intersect_check(o1, o2);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename O1, typename O2>
|
||||||
|
void check_squared_distance_with_bound(const O1& o1, const O2& o2, const FT& ubound)
|
||||||
|
{
|
||||||
|
const FT res_o1o2 = CGAL::squared_distance(o1, o2);
|
||||||
|
const FT res_o2o1 = CGAL::squared_distance(o2, o1);
|
||||||
|
|
||||||
|
do_intersect_check(o1, o2);
|
||||||
|
do_intersect_check(o1, o2);
|
||||||
|
|
||||||
|
assert(res_o1o2 <= ubound);
|
||||||
|
assert(res_o2o1 <= ubound);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
void P_P()
|
void P_P()
|
||||||
{
|
{
|
||||||
std::cout << "Point - Point\n";
|
std::cout << "Point - Point" << std::endl;
|
||||||
check_squared_distance (p(0, 0, 0), p(0, 0, 0), 0);
|
check_squared_distance(p(0, 0, 0), p(0, 0, 0), 0);
|
||||||
check_squared_distance (p(1, 1, 1), p(0, 0, 0), 3);
|
check_squared_distance(p(3, 5, 7), p(0, 0, 0), 83);
|
||||||
}
|
}
|
||||||
|
|
||||||
void P_S()
|
void P_S()
|
||||||
{
|
{
|
||||||
// Note : the values are not verified by hand
|
std::cout << "Point - Segment" << std::endl;
|
||||||
std::cout << "Point - Segment\n";
|
check_squared_distance(p(0, 1, 2), S{p(-3, 0, 0), p( 2, 0, 0)}, 5);
|
||||||
check_squared_distance (p(0, 1, 2), S(p(-3, 0, 0), p( 2, 0, 0)), 5);
|
check_squared_distance(p(0, 1, 2), S{p( 3, 0, 0), p( 2, 0, 0)}, 9);
|
||||||
check_squared_distance (p(0, 1, 2), S(p( 3, 0, 0), p( 2, 0, 0)), 9);
|
check_squared_distance(p(0, 1, 2), S{p( 2, 0, 0), p( 3, 0, 0)}, 9);
|
||||||
check_squared_distance (p(0, 1, 2), S(p( 2, 0, 0), p( 3, 0, 0)), 9);
|
check_squared_distance(p(6, 1, 2), S{p( 2, 0, 0), p( 3, 0, 0)}, 14);
|
||||||
check_squared_distance (p(6, 1, 2), S(p( 2, 0, 0), p( 3, 0, 0)), 14);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void P_T()
|
void P_T()
|
||||||
{
|
{
|
||||||
std::cout << "Point - Triangle\n";
|
std::cout << "Point - Triangle" << std::endl;
|
||||||
check_squared_distance (p(0, 1, 2), T(p(0, 0, 0), p( 2, 0, 0), p( 0, 2, 0)), 4);
|
check_squared_distance(p(0, 1, 2), T{p(0, 0, 0), p(2, 0, 0), p(0, 2, 0)}, 4);
|
||||||
|
|
||||||
T t(p(0,0,0), p(3,0,0), p(3,3,0));
|
T t(p(0,0,0), p(3,0,0), p(3,3,0));
|
||||||
check_squared_distance (p(-1, -1, 0), t, 2);
|
check_squared_distance (p(-1, -1, 0), t, 2);
|
||||||
|
|
@ -136,150 +221,475 @@ struct Test {
|
||||||
|
|
||||||
void S_S()
|
void S_S()
|
||||||
{
|
{
|
||||||
std::cout << "Segment - Segment\n";
|
std::cout << "Segment - Segment" << std::endl;
|
||||||
check_squared_distance (S(p( -8, -7, 0), p( 11, 6, 0)), S(p(23, -27, 2), p( -17, 16, 2)), 4);
|
|
||||||
check_squared_distance (S(p( 0, 0, 0), p( 5, 0, 0)), S(p( 1, 1, 2), p( 6, 1, 2)), 5);
|
// coplanar segments (hardcoded)
|
||||||
check_squared_distance (S(p( 0, 0, 0), p( 5, 0, 0)), S(p( 1, 1, 2), p( 2, 1, 2)), 5);
|
double z = std::sqrt(2.);
|
||||||
check_squared_distance (S(p( 5, 0, 0), p( 8, 0, 0)), S(p( 1, 1, 2), p( 2, 1, 2)), 14);
|
P p0{-1, 0, z};
|
||||||
check_squared_distance (S(p( 5, 0, 0), p( 0, 0, 0)), S(p( 1, 1, 2), p( 2, 1, 2)), 5);
|
P p1{ 1, 0, z};
|
||||||
check_squared_distance (S(p( 0, 0, 0), p( 5, 0, 0)), S(p( 6, 1, 2), p( 8, 1, 2)), 6);
|
|
||||||
check_squared_distance (S(p( 0, 0, 0), p( 0,-3, 0)), S(p( 1, 4, 2), p( 1, 7, 2)), 21);
|
// translations of (0, -1, z) -- (0, 1, z) to have all variations of x&y (<0, [0;1]; >1) in the code
|
||||||
check_squared_distance (S(p( 0, 0, 0), p( 5, 0, 0)), S(p( 8, 1, 2), p( 6, 1, 2)), 6);
|
for(int j=-2;j<4; j+=2)
|
||||||
check_squared_distance (S(p( 0, 0, 0), p( 0, 0, 0)), S(p( 8, 1, 2), p( 6, 1, 2)), 41);
|
{
|
||||||
check_squared_distance (S(p( 0, 0, 0), p( 1, 0, 0)), S(p( 2, 1, 2), p( 2, -1, 2)), 5);
|
for(int k=-3;k<3; k+=2)
|
||||||
check_squared_distance (S(p( 2, 0, 0), p( 0, 2, 0)), S(p( 1, 1, 4), p( 4, 0, 4)), 16);
|
{
|
||||||
check_squared_distance (S(p( 10, 0, 0), p( 0,10, 0)), S(p( 6, 6,20), p( 20, 0,20)), 402);
|
P p2{j, k, z};
|
||||||
check_squared_distance (S(p(-10,-13, 0), p( 0,10, 0)), S(p(10, 5,20), p( 70,-30,20)), 524.642);
|
P p3{j, k+2, z};
|
||||||
check_squared_distance (S(p( 0, 0, 0), p(30,-10, 0)), S(p(-5, 20,20), p( 40, 30,20)), 824.706);
|
|
||||||
check_squared_distance (S(p( 4, 0, 0), p(-3, -1, 0)), S(p( 1, 1, 2), p( 2, 11, 2)), 6);
|
// to explicit the expected distances
|
||||||
check_squared_distance (S(p( 3, 4, 0), p( 7, 7, 0)), S(p( 7, 0, 2), p( 6, 5, 2)), 5);
|
if(j == -2 && k == -3)
|
||||||
check_squared_distance (S(p( -1, 1, 0), p( 3, 4, 0)), S(p( 7, 0, 2), p( 6, 5, 2)), 13.8462);
|
check_squared_distance(S{p0, p1}, S{p2, p3}, CGAL::squared_distance(p3, p0));
|
||||||
|
else if(j == -2 && k == -1)
|
||||||
|
check_squared_distance(S{p0, p1}, S{p2, p3}, 1);
|
||||||
|
else if(j == -2 && k == 1)
|
||||||
|
check_squared_distance(S{p0, p1}, S{p2, p3}, CGAL::squared_distance(p2, p0));
|
||||||
|
else if(j == 0 && k == -3)
|
||||||
|
check_squared_distance(S{p0, p1}, S{p2, p3}, 1);
|
||||||
|
else if(j == 0 && k == -1)
|
||||||
|
check_squared_distance(S{p0, p1}, S{p2, p3}, 0);
|
||||||
|
else if(j == 0 && k == 1)
|
||||||
|
check_squared_distance(S{p0, p1}, S{p2, p3}, 1);
|
||||||
|
else if(j == 2 && k == -3)
|
||||||
|
check_squared_distance(S{p0, p1}, S{p2, p3}, CGAL::squared_distance(p3, p1));
|
||||||
|
else if(j == 2 && k == -1)
|
||||||
|
check_squared_distance(S{p0, p1}, S{p2, p3}, 1);
|
||||||
|
else if(j == 2 && k == 1)
|
||||||
|
check_squared_distance(S{p0, p1}, S{p2, p3}, CGAL::squared_distance(p2, p1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i=0; i<N; ++i)
|
||||||
|
{
|
||||||
|
P p0 = random_point();
|
||||||
|
P p1 = random_point();
|
||||||
|
P p2 = random_point();
|
||||||
|
P p3 = random_point();
|
||||||
|
p0 = CGAL::midpoint(p0, p1);
|
||||||
|
p1 = p0 + FT(0.1) * V{p1 - p0};
|
||||||
|
p2 = p2 + V{p2 - CGAL::ORIGIN} / CGAL::approximate_sqrt(CGAL::square(p2.x()) + CGAL::square(p2.y()) + CGAL::square(p2.z()) + 3);
|
||||||
|
p3 = p3 + V{p3 - CGAL::ORIGIN} * FT(std::cos(1.3));
|
||||||
|
|
||||||
|
// degenerate inputs
|
||||||
|
check_squared_distance(S{p0, p0}, S{p0, p0}, 0); // both degen
|
||||||
|
check_squared_distance(S{p3, p3}, S{p3, p3}, 0); // both degen
|
||||||
|
check_squared_distance(S{p0, p0}, S{p0, p1}, 0); // left degen + common extremity (left)
|
||||||
|
check_squared_distance(S{p0, p0}, S{p1, p0}, 0); // left degen + common extremity (right)
|
||||||
|
check_squared_distance(S{p0, p0}, S{p2, p3}, CGAL::squared_distance(p0, S(p2, p3))); // left degen
|
||||||
|
|
||||||
|
// common extremities
|
||||||
|
check_squared_distance(S{p2, p3}, S{p2, p3}, 0); // equal segments
|
||||||
|
check_squared_distance(S{p3, p2}, S{p2, p3}, 0); // equal segments but opposite dirs
|
||||||
|
check_squared_distance(S{p2, p3}, S{p2, p1}, 0); // common generic (p2 common)
|
||||||
|
check_squared_distance(S{p2, p3}, S{p1, p2}, 0); // common generic (p2 common)
|
||||||
|
check_squared_distance(S{p2, p3}, S{p3, p1}, 0); // common generic (p3 common)
|
||||||
|
check_squared_distance(S{p2, p3}, S{p1, p3}, 0); // common generic (p3 common)
|
||||||
|
|
||||||
|
// collinear segments
|
||||||
|
const double lambda_4 = r.get_double(0, 1);
|
||||||
|
const P p4 = p2 + FT(lambda_4) * V{p3 - p2};
|
||||||
|
const double lambda_5 = r.get_double(0, 1);
|
||||||
|
const P p5 = p2 + FT(lambda_5) * V{p3 - p2};
|
||||||
|
|
||||||
|
// [p2;p3) fully contains [p4;p5]
|
||||||
|
check_squared_distance(S{p2, p3}, S{p4, p5}, 0);
|
||||||
|
check_squared_distance(S{p2, p3}, S{p5, p4}, 0);
|
||||||
|
check_squared_distance(S{p3, p2}, S{p4, p5}, 0);
|
||||||
|
check_squared_distance(S{p3, p2}, S{p4, p5}, 0);
|
||||||
|
|
||||||
|
const double lambda_6 = r.get_double(0, 1);
|
||||||
|
const P p6 = p3 + FT(lambda_6) * V{p3 - p2};
|
||||||
|
// [p2;p3] overlaps [p5;p6]
|
||||||
|
check_squared_distance(S{p2, p3}, S{p6, p5}, 0);
|
||||||
|
check_squared_distance(S{p2, p3}, S{p5, p6}, 0);
|
||||||
|
check_squared_distance(S{p3, p2}, S{p6, p5}, 0);
|
||||||
|
check_squared_distance(S{p3, p2}, S{p6, p5}, 0);
|
||||||
|
|
||||||
|
const double lambda_7 = r.get_double(1, 2);
|
||||||
|
const P p7 = p3 + FT(lambda_7) * V{p3 - p2};
|
||||||
|
|
||||||
|
// [p2;p3] disjoint && left of [p6;p7]
|
||||||
|
check_squared_distance(S{p2, p3}, S{p6, p7}, CGAL::squared_distance(p3, p6));
|
||||||
|
check_squared_distance(S{p2, p3}, S{p7, p6}, CGAL::squared_distance(p3, p6));
|
||||||
|
check_squared_distance(S{p3, p2}, S{p6, p7}, CGAL::squared_distance(p3, p6));
|
||||||
|
check_squared_distance(S{p3, p2}, S{p7, p6}, CGAL::squared_distance(p3, p6));
|
||||||
|
|
||||||
|
// Generic collinear
|
||||||
|
const double lambda_8 = r.get_double(-M, M);
|
||||||
|
const P p8 = p2 + FT(lambda_8) * V{p3 - p2};
|
||||||
|
const double lambda_9 = r.get_double(-M, M);
|
||||||
|
const P p9 = p2 + FT(lambda_9) * V{p3 - p2};
|
||||||
|
|
||||||
|
S s89(p8, p9);
|
||||||
|
S s32(p3, p2);
|
||||||
|
FT result;
|
||||||
|
if(!s89.is_degenerate() && !s32.is_degenerate()) // for do_intersect...
|
||||||
|
{
|
||||||
|
if(CGAL::do_intersect(s89, s32))
|
||||||
|
result = 0;
|
||||||
|
else
|
||||||
|
result = (std::min)(CGAL::squared_distance(p2, p8),
|
||||||
|
(std::min)(CGAL::squared_distance(p2, p9),
|
||||||
|
(std::min)(CGAL::squared_distance(p3, p8),
|
||||||
|
CGAL::squared_distance(p3, p9))));
|
||||||
|
|
||||||
|
#ifdef CGAL_USE_GTE_AS_SANITY_CHECK
|
||||||
|
gte::DCPQuery<FT, gte::Segment<3, FT>, gte::Segment<3, FT> > GTE_SS_checker;
|
||||||
|
gte::Segment<3, FT> gte_s1{{p8.x(), p8.y(), p8.z()}, {p9.x(), p9.y(), p9.z()}};
|
||||||
|
gte::Segment<3, FT> gte_s2{{p3.x(), p3.y(), p3.z()}, {p2.x(), p2.y(), p2.z()}};
|
||||||
|
auto gte_res = GTE_SS_checker(gte_s1, gte_s2);
|
||||||
|
std::cout << "-------" << std::endl;
|
||||||
|
std::cout << "old: " << CGAL::internal::squared_distance_old(s89, s32, K()) << std::endl;
|
||||||
|
std::cout << "dist (GTE) : " << gte_res.sqrDistance << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Because do_intersect() with constructions is likely to return 'false' even for overlaps
|
||||||
|
assert(are_equal(CGAL::squared_distance(s89, s32), result, false /*verbose*/) ||
|
||||||
|
are_equal(CGAL::squared_distance(s32, s89), FT(0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// completely generic
|
||||||
|
S s1{p0, p1}, s2{p2, p3};
|
||||||
|
do_intersect_check(s1, s2);
|
||||||
|
|
||||||
|
#ifdef CGAL_USE_GTE_AS_SANITY_CHECK
|
||||||
|
gte::DCPQuery<FT, gte::Segment<3, FT>, gte::Segment<3, FT> > GTE_SS_checker;
|
||||||
|
gte::Segment<3, FT> gte_s1{{p0.x(), p0.y(), p0.z()}, {p1.x(), p1.y(), p1.z()}};
|
||||||
|
gte::Segment<3, FT> gte_s2{{p2.x(), p2.y(), p2.z()}, {p3.x(), p3.y(), p3.z()}};
|
||||||
|
auto gte_res = GTE_SS_checker(gte_s1, gte_s2);
|
||||||
|
|
||||||
|
std::cout << "dist (CGAL) : " << CGAL::squared_distance(s1, s2) << std::endl;
|
||||||
|
std::cout << "dist (GTE) : " << gte_res.sqrDistance << std::endl;
|
||||||
|
assert(are_equal(CGAL::squared_distance(s1, s2), gte_res.sqrDistance));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// a few brute force checks: sample a segments and use squared_distance(P3, S3)
|
||||||
|
for(int i=0; i<10; ++i)
|
||||||
|
{
|
||||||
|
P p0 = random_point();
|
||||||
|
P p1 = random_point();
|
||||||
|
P p2 = random_point();
|
||||||
|
P p3 = random_point();
|
||||||
|
|
||||||
|
S s01{p0, p1};
|
||||||
|
S s23{p2, p3};
|
||||||
|
|
||||||
|
FT upper_bound = CGAL::squared_distance(p0, p2);
|
||||||
|
|
||||||
|
V p01 = V{p0, p1} / FT(N);
|
||||||
|
for(int l=0; l<N; ++l)
|
||||||
|
{
|
||||||
|
P tp = p0 + FT(l) * p01;
|
||||||
|
FT sqd = CGAL::squared_distance(tp, s23);
|
||||||
|
if(sqd < upper_bound)
|
||||||
|
upper_bound = sqd;
|
||||||
|
}
|
||||||
|
|
||||||
|
// bit ugly, but if constructions are not exact, building `tp` introduces some error
|
||||||
|
if(epsilon != 0)
|
||||||
|
upper_bound *= (1 + 1e-10);
|
||||||
|
|
||||||
|
check_squared_distance_with_bound(s01, s23, upper_bound);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void P_R()
|
void P_R()
|
||||||
{
|
{
|
||||||
// Note : the value is not verified by hand
|
// Note : the value is not verified by hand
|
||||||
std::cout << "Point - Ray\n";
|
std::cout << "Point - Ray" << std::endl;
|
||||||
check_squared_distance (p( -8, -7, 0), R(p(23, -27, 2), p( -17, 16, 2)), 86.3685);
|
check_squared_distance_with_bound(p( -8, -7, 0), R{p(23, -27, 2), p( -17, 16, 2)}, 86.368512613);
|
||||||
}
|
}
|
||||||
|
|
||||||
void R_R()
|
void R_R()
|
||||||
{
|
{
|
||||||
// Note : the values are not verified by hand
|
// Note : the values are not verified by hand
|
||||||
std::cout << "Ray - Ray\n";
|
std::cout << "Ray - Ray" << std::endl;
|
||||||
check_squared_distance (R(p( 0, 0, 30), p( 0, 30, 30)), R(p(100, -100, 0), p( 200, 1, 0)), 20899.5);
|
check_squared_distance_with_bound(R{p( 0, 0, 30), p( 0, 30, 30)}, R{p(100, -100, 0), p( 200, 1, 0)}, 20899.504975002);
|
||||||
check_squared_distance (R(p( 1, 0, 0), p( 0, 0, 0)), R(p( 1, 3, 3), p( 0, 0, 3)), 9);
|
check_squared_distance(R{p( 1, 0, 0), p( 0, 0, 0)}, R{p( 1, 3, 3), p( 0, 0, 3)}, 9);
|
||||||
check_squared_distance (R(p( 0, 0, 0), p( 1, 0, 0)), R(p( 0, 0, 2), p( -1, 0, 2)), 4);
|
check_squared_distance(R{p( 0, 0, 0), p( 1, 0, 0)}, R{p( 0, 0, 2), p( -1, 0, 2)}, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void S_R()
|
void S_R()
|
||||||
{
|
{
|
||||||
// Note : the values are not verified by hand
|
// Note : the values are not verified by hand
|
||||||
std::cout << "Segment - Ray\n";
|
std::cout << "Segment - Ray" << std::endl;
|
||||||
check_squared_distance (S(p( 0, 0, 30), p( 0, 30, 30)), R(p(100, -100, 0), p( 200, 1, 0)), 20899.5);
|
check_squared_distance_with_bound(S{p( 0, 0, 30), p( 0, 30, 30)}, R{p(100, -100, 0), p( 200, 1, 0)}, 20899.504975002);
|
||||||
}
|
}
|
||||||
|
|
||||||
void R_L()
|
void R_L()
|
||||||
{
|
{
|
||||||
// Note : the values are not verified by hand
|
// Note : the values are not verified by hand
|
||||||
std::cout << "Ray - Line\n";
|
std::cout << "Ray - Line" << std::endl;
|
||||||
check_squared_distance (R(p(10, 0, 0), p( 20, 0, 0)), L(p( 0, 0, 3), p( 0, 3, 3)), 109);
|
check_squared_distance_with_bound(R{p( 0, 0, 30), p( 0, 30, 30)}, L{p(100, -100, 0), p( 200, 1, 0)}, 20899.504975002);
|
||||||
check_squared_distance (R(p( 0, 0, 30), p( 0, 30, 30)), L(p(100, -100, 0), p( 200, 1, 0)), 20899.5);
|
check_squared_distance(R{p(10, 0, 0), p( 20, 0, 0)}, L{p( 0, 0, 3), p( 0, 3, 3)}, 109);
|
||||||
check_squared_distance (R(p( 1, 0, 0), p( 0, 0, 0)), L(p( 1, 3, 3), p( 0, 0, 3)), 9);
|
check_squared_distance(R{p( 1, 0, 0), p( 0, 0, 0)}, L{p( 1, 3, 3), p( 0, 0, 3)}, 9);
|
||||||
check_squared_distance (R(p( 0, 0, 0), p( 1, 0, 0)), L(p( 0, 0, 2), p( -1, 0, 2)), 4);
|
check_squared_distance(R{p( 0, 0, 0), p( 1, 0, 0)}, L{p( 0, 0, 2), p( -1, 0, 2)}, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void P_L()
|
void P_L()
|
||||||
{
|
{
|
||||||
std::cout << "Point - Line\n";
|
std::cout << "Point - Line" << std::endl;
|
||||||
check_squared_distance (p( 0, 1, 2), L(p( 2, 0, 0), p( 3, 0, 0)), 5);
|
check_squared_distance(p( 0, 1, 2), L{p( 2, 0, 0), p( 3, 0, 0)}, 5);
|
||||||
check_squared_distance (p( 0, 0, 2), L(p( 0, 0, 0), p( 1, 2, 0)), 4);
|
check_squared_distance(p( 0, 0, 2), L{p( 0, 0, 0), p( 1, 2, 0)}, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void S_L()
|
void S_L()
|
||||||
{
|
{
|
||||||
// Note : the values are not verified by hand
|
// Note : the values are not verified by hand
|
||||||
std::cout << "Segment - Line\n";
|
std::cout << "Segment - Line" << std::endl;
|
||||||
check_squared_distance (S(p( 1, 0, 0), p( 0, 0, 0)), L(p( 1, 3, 3), p( 0, 0, 3)), 9);
|
check_squared_distance(S{p( 1, 0, 0), p( 0, 0, 0)}, L{p( 1, 3, 3), p( 0, 0, 3)}, 9);
|
||||||
check_squared_distance (S(p(-90, 0, 0), p(-10, 0, 0)), L(p( 0, 0, 3), p( 0, 3, 3)), 109);
|
check_squared_distance(S{p(-90, 0, 0), p(-10, 0, 0)}, L{p( 0, 0, 3), p( 0, 3, 3)}, 109);
|
||||||
check_squared_distance (S(p( 0, 0, 0), p( 1, 0, 0)), L(p( 0, 0, 2), p( -1, 0, 2)), 4);
|
check_squared_distance(S{p( 0, 0, 0), p( 1, 0, 0)}, L{p( 0, 0, 2), p( -1, 0, 2)}, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void L_L()
|
void L_L()
|
||||||
{
|
{
|
||||||
// Note : the values are not verified by hand
|
// Note : the values are not verified by hand
|
||||||
std::cout << "Line - Line\n";
|
std::cout << "Line - Line" << std::endl;
|
||||||
check_squared_distance (L(p(-10, 0, 0), p(-90, 0, 0)), L(p( 0, 0, 3), p( 0, 3, 3)), 9);
|
check_squared_distance(L{p(-10, 0, 0), p(-90, 0, 0)}, L{p( 0, 0, 3), p( 0, 3, 3)}, 9);
|
||||||
check_squared_distance (L(p( 1, 0, 0), p( 0, 0, 0)), L(p( 1, 3, 3), p( 0, 0, 3)), 9);
|
check_squared_distance(L{p( 1, 0, 0), p( 0, 0, 0)}, L{p( 1, 3, 3), p( 0, 0, 3)}, 9);
|
||||||
check_squared_distance (L(p( 0, 0, 0), p( 1, 0, 0)), L(p( 0, 0, 2), p( -1, 0, 2)), 4);
|
check_squared_distance(L{p( 0, 0, 0), p( 1, 0, 0)}, L{p( 0, 0, 2), p( -1, 0, 2)}, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void P_Pl()
|
void P_Pl()
|
||||||
{
|
{
|
||||||
std::cout << "Point - Plane\n";
|
std::cout << "Point - Plane" << std::endl;
|
||||||
check_squared_distance (p(2, 5, 3), Pl(0, 1, 0, 0), 25);
|
check_squared_distance(p(2, 5, 3), Pl(0, 1, 0, 0), 25);
|
||||||
}
|
}
|
||||||
|
|
||||||
void S_Pl()
|
void S_Pl()
|
||||||
{
|
{
|
||||||
std::cout << "Segment - Plane\n";
|
std::cout << "Segment - Plane" << std::endl;
|
||||||
check_squared_distance (S(p(2, -3, 3), p( 3,-7, 4)), pl(0, 1, 0, 0), 9);
|
check_squared_distance(S{p(2, -3, 3), p( 3,-7, 4)}, pl(0, 1, 0, 0), 9);
|
||||||
}
|
}
|
||||||
|
|
||||||
void R_Pl()
|
void R_Pl()
|
||||||
{
|
{
|
||||||
std::cout << "Ray - Plane\n";
|
std::cout << "Ray - Plane" << std::endl;
|
||||||
check_squared_distance (R(p(2, -4, 3), p( 3,-4, 4)), Pl(0, 1, 0, 0), 16);
|
check_squared_distance(R{p(2, -4, 3), p( 3,-4, 4)}, Pl(0, 1, 0, 0), 16);
|
||||||
check_squared_distance (R(p(2, -4, 3), p( 3, 4, 4)), Pl(0, 1, 0, 0), 0);
|
check_squared_distance(R{p(2, -4, 3), p( 3, 4, 4)}, Pl(0, 1, 0, 0), 0);
|
||||||
check_squared_distance (R(p(2, -4, 3), p( 3,-8, 4)), Pl(0, 1, 0, 0), 16);
|
check_squared_distance(R{p(2, -4, 3), p( 3,-8, 4)}, Pl(0, 1, 0, 0), 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
void L_Pl()
|
void L_Pl()
|
||||||
{
|
{
|
||||||
std::cout << "Line - Plane\n";
|
std::cout << "Line - Plane" << std::endl;
|
||||||
check_squared_distance (L(p(2, -4, 3), p( 3,-4, 4)), Pl(0, 1, 0, 0), 16);
|
check_squared_distance(L{p(2, -4, 3), p( 3,-4, 4)}, Pl(0, 1, 0, 0), 16);
|
||||||
check_squared_distance (L(p(2, -4, 3), p( 3, 4, 4)), Pl(0, 1, 0, 0), 0);
|
check_squared_distance(L{p(2, -4, 3), p( 3, 4, 4)}, Pl(0, 1, 0, 0), 0);
|
||||||
check_squared_distance (L(p(2, -4, 3), p( 3,-8, 4)), Pl(0, 1, 0, 0), 0);
|
check_squared_distance(L{p(2, -4, 3), p( 3,-8, 4)}, Pl(0, 1, 0, 0), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pl_Pl()
|
void Pl_Pl()
|
||||||
{
|
{
|
||||||
std::cout << "Plane - Plane\n";
|
std::cout << "Plane - Plane" << std::endl;
|
||||||
Pl p1(0, 1, 0, 0);
|
Pl p1(0, 1, 0, 0);
|
||||||
typename K::Vector_3 v = -p1.orthogonal_vector();
|
typename K::Vector_3 v = -p1.orthogonal_vector();
|
||||||
v /= CGAL::sqrt(v.squared_length());
|
v /= CGAL::approximate_sqrt(v.squared_length());
|
||||||
Pl p2 = Pl(0,-1,0,6);
|
Pl p2 = Pl(0,-1,0,6);
|
||||||
check_squared_distance (p1,p2, 36);
|
check_squared_distance(p1,p2, 36);
|
||||||
check_squared_distance (Pl(-2, 1, 1, 0), Pl(2, 1, 3, 0), 0);
|
check_squared_distance(Pl(-2, 1, 1, 0), Pl(2, 1, 3, 0), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void T_T()
|
||||||
|
{
|
||||||
|
std::cout << "Triangle - Triangle" << std::endl;
|
||||||
|
|
||||||
|
// min between vertices (hardcoded)
|
||||||
|
check_squared_distance(T{p(0,0,0), p(1,0,0), p(0,1,0)}, T{p(0,0,2), p(-1,0,2), p(0,-1,2)}, 4);
|
||||||
|
check_squared_distance(T{p(0,0,0), p(1,0,0), p(0,1,0)}, T{p(-1,0,2), p(0,0,2), p(0,-1,2)}, 4);
|
||||||
|
|
||||||
|
check_squared_distance(T{p(1,2,3), P{4.2,5.3,-6}, p(7,-8,9)},
|
||||||
|
T{P{10.1, 12, -10}, p(15, 14, -12), p(19, 45, -20)},
|
||||||
|
CGAL::squared_distance(P{4.2,5.3,-6}, P{10.1, 12, -10}));
|
||||||
|
|
||||||
|
// min vertex-edge (hardcoded)
|
||||||
|
check_squared_distance(T{p(0,0,0), p(1,0,0), p(0,1,0)}, T{p(1,1,0), p(2,1,0), p(1,2,0)}, 0.5);
|
||||||
|
check_squared_distance(T{p(0,0,0), p(2,0,0), p(0,2,0)}, T{p(0,-1,1), p(2,0,1), p(2,-1,1)}, 1);
|
||||||
|
|
||||||
|
for(int i=0; i<N; ++i)
|
||||||
|
{
|
||||||
|
P p0 = random_point();
|
||||||
|
P p1 = random_point();
|
||||||
|
P p2 = random_point();
|
||||||
|
P p3 = random_point();
|
||||||
|
P p4 = random_point();
|
||||||
|
P p5 = random_point();
|
||||||
|
|
||||||
|
// these are still exact with EPECK
|
||||||
|
p0 = CGAL::midpoint(p0, p1);
|
||||||
|
p1 = p0 + FT(0.1) * V{p1 - p0};
|
||||||
|
p2 = p2 + V{p2 - p0} / FT(CGAL_PI);
|
||||||
|
|
||||||
|
// this is still exact with EPECK_with_sqrt
|
||||||
|
p4 = p4 + V{p4 - CGAL::ORIGIN} / CGAL::approximate_sqrt(CGAL::square(p4.x()) + CGAL::square(p4.y()) + CGAL::square(p4.z()) + 3);
|
||||||
|
|
||||||
|
p5 = p5 + V{p5 - CGAL::ORIGIN} * FT(std::cos(1.3));
|
||||||
|
|
||||||
|
// degenerate inputs
|
||||||
|
check_squared_distance(T{p3, p3, p3}, T{p3, p3, p3}, 0); // both degen
|
||||||
|
check_squared_distance(T{p0, p0, p0}, T{p3, p3, p3}, CGAL::squared_distance(p0, p3)); // both degen
|
||||||
|
|
||||||
|
check_squared_distance(T{p0, p0, p0}, T{p0, p0, p3}, 0); // single degen and common edge
|
||||||
|
check_squared_distance(T{p0, p0, p0}, T{p3, p0, p0}, 0);
|
||||||
|
check_squared_distance(T{p0, p0, p0}, T{p0, p3, p0}, 0);
|
||||||
|
|
||||||
|
check_squared_distance(T{p0, p0, p0}, T{p0, p3, p4}, 0); // single degen and common vertex
|
||||||
|
check_squared_distance(T{p0, p0, p0}, T{p3, p0, p4}, 0);
|
||||||
|
check_squared_distance(T{p0, p0, p0}, T{p3, p4, p0}, 0);
|
||||||
|
|
||||||
|
// degen into point & degen into segment
|
||||||
|
check_squared_distance(T{p1, p1, p1}, T{p4, p3, p3}, CGAL::squared_distance(p1, S{p3, p4}));
|
||||||
|
check_squared_distance(T{p5, p5, p5}, T{p3, p3, p4}, CGAL::squared_distance(p5, S{p3, p4}));
|
||||||
|
|
||||||
|
// both degen into segment
|
||||||
|
check_squared_distance(T{p0, p1, p0}, T{p3, p3, p4}, CGAL::squared_distance(S{p0, p1}, S{p3, p4}));
|
||||||
|
check_squared_distance(T{p5, p5, p4}, T{p4, p3, p3}, CGAL::squared_distance(S{p5, p4}, S{p3, p4}));
|
||||||
|
|
||||||
|
// common vertex
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{p0, p3, p4}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{p3, p0, p4}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{p4, p3, p0}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{p1, p3, p4}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{p3, p1, p4}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{p4, p3, p1}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{p2, p3, p4}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{p3, p2, p4}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{p4, p3, p2}, 0);
|
||||||
|
|
||||||
|
// common edge
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{p0, p1, p4}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{p1, p0, p4}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{p4, p0, p1}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{p4, p1, p0}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{p0, p4, p1}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{p1, p4, p2}, 0);
|
||||||
|
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{p2, p1, p4}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{p1, p2, p4}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{p4, p2, p1}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{p4, p1, p2}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{p2, p4, p1}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{p1, p4, p2}, 0);
|
||||||
|
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{p0, p2, p4}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{p2, p0, p4}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{p4, p0, p2}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{p4, p2, p0}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{p0, p4, p2}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{p2, p4, p0}, 0);
|
||||||
|
|
||||||
|
// same triangle
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{p0, p1, p2}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{p1, p2, p0}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{p2, p0, p1}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{p2, p1, p0}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{p0, p2, p1}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{p1, p0, p2}, 0);
|
||||||
|
|
||||||
|
// vertex on triangle
|
||||||
|
double lambda = r.get_double(0, 1);
|
||||||
|
double mu = r.get_double(0, 1 - lambda);
|
||||||
|
const P bp = CGAL::barycenter(p0, lambda, p1, mu, p2, 1 - lambda - mu);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{bp, p3, p4}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{p3, bp, p4}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{p3, p4, bp}, 0);
|
||||||
|
|
||||||
|
// edge on triangle
|
||||||
|
lambda = r.get_double(0, 1);
|
||||||
|
mu = r.get_double(0, 1 - lambda);
|
||||||
|
P bp2 = CGAL::barycenter(p0, lambda, p1, mu, p2, 1 - lambda - mu);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{bp, bp2, p4}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{bp2, bp, p4}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{bp, p4, bp2}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{bp2, p4, bp}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{p4, bp, bp2}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{p4, bp2, bp}, 0);
|
||||||
|
|
||||||
|
// part of the edge crossing the triangle
|
||||||
|
lambda = r.get_double(-1, 1);
|
||||||
|
mu = r.get_double(-1, 1);
|
||||||
|
bp2 = CGAL::barycenter(p0, lambda, p1, mu, p2, 1 - lambda - mu);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{bp, bp2, p4}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{bp2, bp, p4}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{bp, p4, bp2}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{bp2, p4, bp}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{p4, bp, bp2}, 0);
|
||||||
|
check_squared_distance(T{p0, p1, p2}, T{p4, bp2, bp}, 0);
|
||||||
|
|
||||||
|
// generic triangles
|
||||||
|
T tr1{p0, p1, p2}, tr2{p3, p4, p5};
|
||||||
|
do_intersect_check(tr1, tr2);
|
||||||
|
|
||||||
|
#ifdef CGAL_USE_GTE_AS_SANITY_CHECK
|
||||||
|
gte::DCPQuery<FT, gte::Triangle3<FT>, gte::Triangle3<FT> > GTE_TT_checker;
|
||||||
|
gte::Triangle3<FT> gte_tr1{{p0.x(), p0.y(), p0.z()}, {p1.x(), p1.y(), p1.z()}, {p2.x(), p2.y(), p2.z()}};
|
||||||
|
gte::Triangle3<FT> gte_tr2{{p3.x(), p3.y(), p3.z()}, {p4.x(), p4.y(), p4.z()}, {p5.x(), p5.y(), p5.z()}};
|
||||||
|
auto gte_res = GTE_TT_checker(gte_tr1, gte_tr2);
|
||||||
|
|
||||||
|
std::cout << "dist (CGAL) : " << CGAL::squared_distance(tr1, tr2) << std::endl;
|
||||||
|
std::cout << "dist (GTE) : " << gte_res.sqrDistance << std::endl;
|
||||||
|
std::cout << "diff CGAL GTE : " << (gte_res.sqrDistance - CGAL::squared_distance(tr1, tr2)) << std::endl;
|
||||||
|
|
||||||
|
// don't assert on purpose, GTE has slightly (10^-30 different results, even with an exact NT)
|
||||||
|
are_equal(CGAL::squared_distance(tr1, tr2), gte_res.sqrDistance);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
void run()
|
void run()
|
||||||
{
|
{
|
||||||
std::cout << "3D Distance tests\n";
|
std::cout << "Kernel: " << typeid(K).name() << std::endl;
|
||||||
|
|
||||||
P_P();
|
P_P();
|
||||||
P_S();
|
P_S();
|
||||||
P_T();
|
|
||||||
P_Tet();
|
|
||||||
S_S();
|
|
||||||
P_R();
|
P_R();
|
||||||
R_R();
|
|
||||||
S_R();
|
|
||||||
R_L();
|
|
||||||
P_L();
|
P_L();
|
||||||
S_L();
|
P_T();
|
||||||
L_L();
|
|
||||||
P_Pl();
|
P_Pl();
|
||||||
|
P_Tet();
|
||||||
|
|
||||||
|
S_S();
|
||||||
|
S_R();
|
||||||
|
S_L();
|
||||||
S_Pl();
|
S_Pl();
|
||||||
|
|
||||||
|
R_R();
|
||||||
|
R_L();
|
||||||
R_Pl();
|
R_Pl();
|
||||||
|
|
||||||
|
L_L();
|
||||||
L_Pl();
|
L_Pl();
|
||||||
|
|
||||||
|
T_T();
|
||||||
|
|
||||||
Pl_Pl();
|
Pl_Pl();
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
Test< CGAL::Simple_cartesian<double> >().run();
|
std::cout.precision(17);
|
||||||
Test< CGAL::Simple_homogeneous<double> >().run();
|
std::cerr.precision(17);
|
||||||
// TODO : test more kernels.
|
|
||||||
|
std::cout << "3D Distance tests" << std::endl;
|
||||||
|
|
||||||
|
CGAL::Random r;
|
||||||
|
std::cout << "random seed = " << r.get_seed() << std::endl;
|
||||||
|
|
||||||
|
// @todo Some tests are too difficult for these kernels
|
||||||
|
// Test<CGAL::Simple_cartesian<double> >(r, 1e-5).run();
|
||||||
|
// Test<CGAL::Simple_homogeneous<double> >(r, 1e-5).run();
|
||||||
|
// Test<CGAL::Simple_cartesian<CGAL::Interval_nt<true> > >(r, 1e-5).run();
|
||||||
|
|
||||||
|
Test<CGAL::Homogeneous<CGAL::Exact_integer> >(r, 0).run();
|
||||||
|
|
||||||
|
const double epick_eps = 10 * std::numeric_limits<double>::epsilon();
|
||||||
|
Test<CGAL::Exact_predicates_inexact_constructions_kernel>(r, epick_eps).run();
|
||||||
|
|
||||||
|
Test<CGAL::Exact_predicates_exact_constructions_kernel>(r, 0).run();
|
||||||
|
|
||||||
|
std::cout << "Done!" << std::endl;
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue