mirror of https://github.com/CGAL/cgal
Merge branch 'Distance_3-Add_Tri_Tri-GF-old' into Distance_3-Add_Tri_Tri-GF
This commit is contained in:
commit
8a92d51601
|
|
@ -23,6 +23,8 @@
|
|||
#include <CGAL/constructions/kernel_ftC2.h>
|
||||
#include <CGAL/constructions/kernel_ftC3.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 {
|
||||
|
||||
|
|
@ -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>
|
||||
class Compare_distance_3
|
||||
{
|
||||
|
|
@ -476,19 +575,19 @@ namespace CartesianKernelFunctors {
|
|||
result_type
|
||||
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
|
||||
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
|
||||
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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
#include <CGAL/determinant.h>
|
||||
#include <CGAL/number_utils.h>
|
||||
#include <CGAL/wmult.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
|
@ -294,7 +295,6 @@ same_direction(const typename K::Vector_2 &u,
|
|||
return same_direction_tag(u,v, k, tag);
|
||||
}
|
||||
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} //namespace CGAL
|
||||
|
|
@ -14,11 +14,27 @@
|
|||
//
|
||||
// Author(s) : Geert-Jan Giezeman
|
||||
|
||||
|
||||
#ifndef CGAL_SQUARED_DISTANCE_2_H
|
||||
#define CGAL_SQUARED_DISTANCE_2_H
|
||||
|
||||
#include <CGAL/squared_distance_2_1.h>
|
||||
#include <CGAL/squared_distance_2_2.h>
|
||||
#include <CGAL/Distance_2/Point_2_Point_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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
#undef NDEBUG //this testsuite requires NDEBUG to be not defined
|
||||
#endif
|
||||
|
||||
|
||||
#include <CGAL/Simple_cartesian.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 <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);
|
||||
}
|
||||
|
||||
void R_S()
|
||||
void S_R()
|
||||
{
|
||||
std::cout << "Ray - Segment\n";
|
||||
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);
|
||||
}
|
||||
|
||||
void L_S()
|
||||
void S_L()
|
||||
{
|
||||
std::cout << "Line - Segment\n";
|
||||
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()
|
||||
{
|
||||
std::cout << "2D Distance tests\n";
|
||||
std::cout << "-- Kernel: " << typeid(K).name() << std::endl;
|
||||
|
||||
P_P();
|
||||
P_S();
|
||||
S_S();
|
||||
P_R();
|
||||
R_R();
|
||||
R_S();
|
||||
R_L();
|
||||
P_L();
|
||||
L_S();
|
||||
L_L();
|
||||
P_T();
|
||||
L_T();
|
||||
R_T();
|
||||
|
||||
S_S();
|
||||
S_T();
|
||||
S_R();
|
||||
S_L();
|
||||
|
||||
R_R();
|
||||
R_L();
|
||||
R_T();
|
||||
|
||||
L_L();
|
||||
L_T();
|
||||
|
||||
T_T();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
Test< CGAL::Simple_cartesian<double> >().run();
|
||||
Test< CGAL::Simple_homogeneous<double> >().run();
|
||||
// TODO : test more kernels.
|
||||
std::cout << "2D Distance tests\n";
|
||||
|
||||
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
|
||||
//
|
||||
//
|
||||
// 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
|
||||
#define CGAL_DISTANCE_3_0_H
|
||||
|
||||
#include <CGAL/kernel_assertions.h>
|
||||
#include <CGAL/determinant.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/Rational_traits.h>
|
||||
#include <CGAL/wmult.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
|
||||
namespace internal {
|
||||
|
||||
template <class K>
|
||||
bool is_null(const typename K::Vector_3 &v, const K&)
|
||||
{
|
||||
typedef typename K::RT RT;
|
||||
return v.hx()==RT(0) && v.hy()==RT(0) && v.hz()==RT(0);
|
||||
typedef typename K::RT RT;
|
||||
return v.hx() == RT(0) && v.hy() == RT(0) && v.hz() == RT(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class K>
|
||||
typename K::RT
|
||||
wdot(const typename K::Vector_3 &u,
|
||||
const typename K::Vector_3 &v,
|
||||
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>
|
||||
|
|
@ -72,12 +63,12 @@ wdot_tag(const typename K::Point_3 &p,
|
|||
const K&,
|
||||
const Homogeneous_tag&)
|
||||
{
|
||||
return ( (p.hx() * q.hw() - q.hx() * p.hw())
|
||||
* (r.hx() * q.hw() - q.hx() * r.hw())
|
||||
+ (p.hy() * q.hw() - q.hy() * p.hw())
|
||||
* (r.hy() * q.hw() - q.hy() * r.hw())
|
||||
+ (p.hz() * q.hw() - q.hz() * p.hw())
|
||||
* (r.hz() * q.hw() - q.hz() * r.hw()));
|
||||
return ( (p.hx() * q.hw() - q.hx() * p.hw())
|
||||
* (r.hx() * q.hw() - q.hx() * r.hw())
|
||||
+ (p.hy() * q.hw() - q.hy() * p.hw())
|
||||
* (r.hy() * q.hw() - q.hy() * r.hw())
|
||||
+ (p.hz() * q.hw() - q.hz() * p.hw())
|
||||
* (r.hz() * q.hw() - q.hz() * r.hw()));
|
||||
}
|
||||
|
||||
template <class K>
|
||||
|
|
@ -93,9 +84,6 @@ wdot(const typename K::Point_3 &p,
|
|||
return wdot_tag(p, q, r, k, tag);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template <class K>
|
||||
typename K::Vector_3
|
||||
wcross(const typename K::Vector_3 &u,
|
||||
|
|
@ -103,13 +91,12 @@ wcross(const typename K::Vector_3 &u,
|
|||
const K&)
|
||||
{
|
||||
typedef typename K::Vector_3 Vector_3;
|
||||
return Vector_3(
|
||||
return Vector_3(
|
||||
u.hy()*v.hz() - u.hz()*v.hy(),
|
||||
u.hz()*v.hx() - u.hx()*v.hz(),
|
||||
u.hx()*v.hy() - u.hy()*v.hx());
|
||||
}
|
||||
|
||||
|
||||
template <class K>
|
||||
inline
|
||||
bool
|
||||
|
|
@ -117,8 +104,8 @@ is_acute_angle(const typename K::Vector_3 &u,
|
|||
const typename K::Vector_3 &v,
|
||||
const K& k)
|
||||
{
|
||||
typedef typename K::RT RT;
|
||||
return RT(wdot(u, v, k)) > RT(0) ;
|
||||
typedef typename K::RT RT;
|
||||
return RT(wdot(u, v, k)) > RT(0) ;
|
||||
}
|
||||
|
||||
template <class K>
|
||||
|
|
@ -128,8 +115,8 @@ is_straight_angle(const typename K::Vector_3 &u,
|
|||
const typename K::Vector_3 &v,
|
||||
const K& k)
|
||||
{
|
||||
typedef typename K::RT RT;
|
||||
return RT(wdot(u, v, k)) == RT(0) ;
|
||||
typedef typename K::RT RT;
|
||||
return RT(wdot(u, v, k)) == RT(0) ;
|
||||
}
|
||||
|
||||
template <class K>
|
||||
|
|
@ -139,8 +126,8 @@ is_obtuse_angle(const typename K::Vector_3 &u,
|
|||
const typename K::Vector_3 &v,
|
||||
const K& k)
|
||||
{
|
||||
typedef typename K::RT RT;
|
||||
return RT(wdot(u, v, k)) < RT(0) ;
|
||||
typedef typename K::RT RT;
|
||||
return RT(wdot(u, v, k)) < RT(0) ;
|
||||
}
|
||||
|
||||
template <class K>
|
||||
|
|
@ -151,8 +138,8 @@ is_acute_angle(const typename K::Point_3 &p,
|
|||
const typename K::Point_3 &r,
|
||||
const K& k)
|
||||
{
|
||||
typedef typename K::RT RT;
|
||||
return RT(wdot(p, q, r, k)) > RT(0) ;
|
||||
typedef typename K::RT RT;
|
||||
return RT(wdot(p, q, r, k)) > RT(0) ;
|
||||
}
|
||||
|
||||
template <class K>
|
||||
|
|
@ -163,8 +150,8 @@ is_straight_angle(const typename K::Point_3 &p,
|
|||
const typename K::Point_3 &r,
|
||||
const K& k)
|
||||
{
|
||||
typedef typename K::RT RT;
|
||||
return RT(wdot(p, q, r, k)) == RT(0) ;
|
||||
typedef typename K::RT RT;
|
||||
return RT(wdot(p, q, r, k)) == RT(0) ;
|
||||
}
|
||||
|
||||
template <class K>
|
||||
|
|
@ -173,25 +160,15 @@ bool
|
|||
is_obtuse_angle(const typename K::Point_3 &p,
|
||||
const typename K::Point_3 &q,
|
||||
const typename K::Point_3 &r,
|
||||
const K& k)
|
||||
const K& k)
|
||||
{
|
||||
typedef typename K::RT RT;
|
||||
return RT(wdot(p, q, r, k)) < RT(0) ;
|
||||
typedef typename K::RT RT;
|
||||
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>
|
||||
void
|
||||
squared_distance_to_plane_RT(const typename K::Vector_3 & normal,
|
||||
const typename K::Vector_3 & diff,
|
||||
squared_distance_to_plane_RT(const typename K::Vector_3& normal,
|
||||
const typename K::Vector_3& diff,
|
||||
typename K::RT& num,
|
||||
typename K::RT& den,
|
||||
const K& k)
|
||||
|
|
@ -206,8 +183,8 @@ squared_distance_to_plane_RT(const typename K::Vector_3 & normal,
|
|||
|
||||
template <class K>
|
||||
typename K::FT
|
||||
squared_distance_to_plane(const typename K::Vector_3 & normal,
|
||||
const typename K::Vector_3 & diff,
|
||||
squared_distance_to_plane(const typename K::Vector_3& normal,
|
||||
const typename K::Vector_3& diff,
|
||||
const K& k)
|
||||
{
|
||||
typedef typename K::RT RT;
|
||||
|
|
@ -219,8 +196,8 @@ squared_distance_to_plane(const typename K::Vector_3 & normal,
|
|||
|
||||
template <class K>
|
||||
void
|
||||
squared_distance_to_line_RT(const typename K::Vector_3 & dir,
|
||||
const typename K::Vector_3 & diff,
|
||||
squared_distance_to_line_RT(const typename K::Vector_3& dir,
|
||||
const typename K::Vector_3& diff,
|
||||
typename K::RT& num,
|
||||
typename K::RT& den,
|
||||
const K& k)
|
||||
|
|
@ -233,8 +210,8 @@ squared_distance_to_line_RT(const typename K::Vector_3 & dir,
|
|||
|
||||
template <class K>
|
||||
typename K::FT
|
||||
squared_distance_to_line(const typename K::Vector_3 & dir,
|
||||
const typename K::Vector_3 & diff,
|
||||
squared_distance_to_line(const typename K::Vector_3& dir,
|
||||
const typename K::Vector_3& diff,
|
||||
const K& k)
|
||||
{
|
||||
typedef typename K::RT RT;
|
||||
|
|
@ -271,7 +248,6 @@ same_direction_tag(const typename K::Vector_3 &u,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
template <class K>
|
||||
inline
|
||||
bool
|
||||
|
|
@ -299,7 +275,6 @@ same_direction_tag(const typename K::Vector_3 &u,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
template <class K>
|
||||
inline
|
||||
bool
|
||||
|
|
@ -312,70 +287,19 @@ same_direction(const typename K::Vector_3 &u,
|
|||
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 CGAL
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
#endif // CGAL_SQUARED_DISTANCE_UTILS_3_H
|
||||
|
|
@ -18,9 +18,31 @@
|
|||
#ifndef CGAL_DISTANCE_3_H
|
||||
#define CGAL_DISTANCE_3_H
|
||||
|
||||
#include <CGAL/squared_distance_3_0.h>
|
||||
#include <CGAL/squared_distance_3_1.h>
|
||||
#include <CGAL/squared_distance_3_2.h>
|
||||
#include <CGAL/squared_distance_3_3.h>
|
||||
#include <CGAL/Distance_3/Point_3_Point_3.h>
|
||||
#include <CGAL/Distance_3/Point_3_Weighted_point_3.h>
|
||||
#include <CGAL/Distance_3/Point_3_Segment_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,32 @@
|
|||
// 3D distance tests.
|
||||
|
||||
#ifdef NDEBUG
|
||||
#undef NDEBUG //this testsuite requires NDEBUG to be not defined
|
||||
#endif
|
||||
|
||||
#include <CGAL/Simple_cartesian.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 <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 <iostream>
|
||||
|
||||
const double epsilon = 0.001;
|
||||
|
||||
struct randomint {
|
||||
struct randomint
|
||||
{
|
||||
randomint() ;
|
||||
int get() const { return sequence[cur]; }
|
||||
int next() { cur = (cur+1)%11; return get();}
|
||||
int get() const { return sequence[cur]; }
|
||||
int next() {
|
||||
cur = (cur + 1) % 11;
|
||||
return get();
|
||||
}
|
||||
|
||||
private:
|
||||
int sequence[11];
|
||||
int cur;
|
||||
|
|
@ -40,43 +50,32 @@ inline randomint::randomint()
|
|||
|
||||
randomint ri;
|
||||
|
||||
inline double to_nt(int d)
|
||||
template <typename K>
|
||||
struct Test
|
||||
{
|
||||
return double(d);
|
||||
}
|
||||
|
||||
template < typename K >
|
||||
struct Test {
|
||||
|
||||
typedef typename K::RT RT;
|
||||
typedef typename K::FT FT;
|
||||
typedef CGAL::Point_3< K > P;
|
||||
typedef CGAL::Line_3< K > L;
|
||||
typedef CGAL::Segment_3< K > S;
|
||||
typedef CGAL::Ray_3< K > R;
|
||||
typedef CGAL::Triangle_3< K > T;
|
||||
typedef CGAL::Plane_3< K > Pl;
|
||||
typedef CGAL::Iso_cuboid_3< K > Cub;
|
||||
typedef CGAL::Tetrahedron_3< K > Tet;
|
||||
typedef typename K::Point_3 P;
|
||||
typedef typename K::Segment_3 S;
|
||||
typedef typename K::Vector_3 V;
|
||||
typedef typename K::Ray_3 R;
|
||||
typedef typename K::Line_3 L;
|
||||
typedef typename K::Triangle_3 T;
|
||||
typedef typename K::Plane_3 Pl;
|
||||
typedef typename K::Tetrahedron_3 Tet;
|
||||
typedef typename K::Iso_cuboid_3 Cub;
|
||||
|
||||
private:
|
||||
CGAL::Random& r;
|
||||
const double epsilon = 1e-14;
|
||||
int N = 1000;
|
||||
double m = 0, M = 1;
|
||||
|
||||
template < typename Type >
|
||||
bool approx_equal_nt(const Type &t1, const Type &t2)
|
||||
{
|
||||
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));
|
||||
}
|
||||
public:
|
||||
Test(CGAL::Random& r, const double epsilon) : r(r), epsilon(epsilon) { }
|
||||
|
||||
private:
|
||||
inline RT to_nt(int d) const { return RT(d); }
|
||||
|
||||
P p(int x, int y, int z)
|
||||
{
|
||||
|
|
@ -84,34 +83,119 @@ struct Test {
|
|||
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)
|
||||
{
|
||||
int w = ri.next();
|
||||
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()
|
||||
{
|
||||
std::cout << "Point - Point\n";
|
||||
check_squared_distance (p(0, 0, 0), p(0, 0, 0), 0);
|
||||
check_squared_distance (p(1, 1, 1), p(0, 0, 0), 3);
|
||||
std::cout << "Point - Point" << std::endl;
|
||||
check_squared_distance(p(0, 0, 0), p(0, 0, 0), 0);
|
||||
check_squared_distance(p(3, 5, 7), p(0, 0, 0), 83);
|
||||
}
|
||||
|
||||
void P_S()
|
||||
{
|
||||
// Note : the values are not verified by hand
|
||||
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)), 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);
|
||||
std::cout << "Point - Segment" << std::endl;
|
||||
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( 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);
|
||||
}
|
||||
|
||||
void P_T()
|
||||
{
|
||||
std::cout << "Point - Triangle\n";
|
||||
check_squared_distance (p(0, 1, 2), T(p(0, 0, 0), p( 2, 0, 0), p( 0, 2, 0)), 4);
|
||||
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);
|
||||
|
||||
T t(p(0,0,0), p(3,0,0), p(3,3,0));
|
||||
check_squared_distance (p(-1, -1, 0), t, 2);
|
||||
|
|
@ -136,150 +220,475 @@ struct Test {
|
|||
|
||||
void S_S()
|
||||
{
|
||||
std::cout << "Segment - Segment\n";
|
||||
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);
|
||||
check_squared_distance (S(p( 0, 0, 0), p( 5, 0, 0)), S(p( 1, 1, 2), p( 2, 1, 2)), 5);
|
||||
check_squared_distance (S(p( 5, 0, 0), p( 8, 0, 0)), S(p( 1, 1, 2), p( 2, 1, 2)), 14);
|
||||
check_squared_distance (S(p( 5, 0, 0), p( 0, 0, 0)), S(p( 1, 1, 2), p( 2, 1, 2)), 5);
|
||||
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);
|
||||
check_squared_distance (S(p( 0, 0, 0), p( 5, 0, 0)), S(p( 8, 1, 2), p( 6, 1, 2)), 6);
|
||||
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);
|
||||
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);
|
||||
check_squared_distance (S(p(-10,-13, 0), p( 0,10, 0)), S(p(10, 5,20), p( 70,-30,20)), 524.642);
|
||||
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);
|
||||
check_squared_distance (S(p( 3, 4, 0), p( 7, 7, 0)), S(p( 7, 0, 2), p( 6, 5, 2)), 5);
|
||||
check_squared_distance (S(p( -1, 1, 0), p( 3, 4, 0)), S(p( 7, 0, 2), p( 6, 5, 2)), 13.8462);
|
||||
std::cout << "Segment - Segment" << std::endl;
|
||||
|
||||
// coplanar segments (hardcoded)
|
||||
double z = std::sqrt(2.);
|
||||
P p0{-1, 0, z};
|
||||
P p1{ 1, 0, z};
|
||||
|
||||
// translations of (0, -1, z) -- (0, 1, z) to have all variations of x&y (<0, [0;1]; >1) in the code
|
||||
for(int j=-2;j<4; j+=2)
|
||||
{
|
||||
for(int k=-3;k<3; k+=2)
|
||||
{
|
||||
P p2{j, k, z};
|
||||
P p3{j, k+2, z};
|
||||
|
||||
// to explicit the expected distances
|
||||
if(j == -2 && k == -3)
|
||||
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()
|
||||
{
|
||||
// Note : the value is not verified by hand
|
||||
std::cout << "Point - Ray\n";
|
||||
check_squared_distance (p( -8, -7, 0), R(p(23, -27, 2), p( -17, 16, 2)), 86.3685);
|
||||
std::cout << "Point - Ray" << std::endl;
|
||||
check_squared_distance_with_bound(p( -8, -7, 0), R{p(23, -27, 2), p( -17, 16, 2)}, 86.368512613);
|
||||
}
|
||||
|
||||
void R_R()
|
||||
{
|
||||
// Note : the values are not verified by hand
|
||||
std::cout << "Ray - Ray\n";
|
||||
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 (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);
|
||||
std::cout << "Ray - Ray" << std::endl;
|
||||
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( 0, 0, 0), p( 1, 0, 0)}, R{p( 0, 0, 2), p( -1, 0, 2)}, 4);
|
||||
}
|
||||
|
||||
void S_R()
|
||||
{
|
||||
// Note : the values are not verified by hand
|
||||
std::cout << "Segment - Ray\n";
|
||||
check_squared_distance (S(p( 0, 0, 30), p( 0, 30, 30)), R(p(100, -100, 0), p( 200, 1, 0)), 20899.5);
|
||||
std::cout << "Segment - Ray" << std::endl;
|
||||
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()
|
||||
{
|
||||
// Note : the values are not verified by hand
|
||||
std::cout << "Ray - Line\n";
|
||||
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( 0, 0, 30), p( 0, 30, 30)), L(p(100, -100, 0), p( 200, 1, 0)), 20899.5);
|
||||
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);
|
||||
std::cout << "Ray - Line" << std::endl;
|
||||
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(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( 0, 0, 0), p( 1, 0, 0)}, L{p( 0, 0, 2), p( -1, 0, 2)}, 4);
|
||||
}
|
||||
|
||||
void P_L()
|
||||
{
|
||||
std::cout << "Point - Line\n";
|
||||
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);
|
||||
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, 0, 2), L{p( 0, 0, 0), p( 1, 2, 0)}, 4);
|
||||
}
|
||||
|
||||
void S_L()
|
||||
{
|
||||
// Note : the values are not verified by hand
|
||||
std::cout << "Segment - Line\n";
|
||||
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( 0, 0, 0), p( 1, 0, 0)), L(p( 0, 0, 2), p( -1, 0, 2)), 4);
|
||||
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(-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);
|
||||
}
|
||||
|
||||
void L_L()
|
||||
{
|
||||
// Note : the values are not verified by hand
|
||||
std::cout << "Line - Line\n";
|
||||
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( 0, 0, 0), p( 1, 0, 0)), L(p( 0, 0, 2), p( -1, 0, 2)), 4);
|
||||
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( 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);
|
||||
}
|
||||
|
||||
void P_Pl()
|
||||
{
|
||||
std::cout << "Point - Plane\n";
|
||||
check_squared_distance (p(2, 5, 3), Pl(0, 1, 0, 0), 25);
|
||||
std::cout << "Point - Plane" << std::endl;
|
||||
check_squared_distance(p(2, 5, 3), Pl(0, 1, 0, 0), 25);
|
||||
}
|
||||
|
||||
void S_Pl()
|
||||
{
|
||||
std::cout << "Segment - Plane\n";
|
||||
check_squared_distance (S(p(2, -3, 3), p( 3,-7, 4)), pl(0, 1, 0, 0), 9);
|
||||
std::cout << "Segment - Plane" << std::endl;
|
||||
check_squared_distance(S{p(2, -3, 3), p( 3,-7, 4)}, pl(0, 1, 0, 0), 9);
|
||||
}
|
||||
|
||||
void R_Pl()
|
||||
{
|
||||
std::cout << "Ray - Plane\n";
|
||||
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,-8, 4)), Pl(0, 1, 0, 0), 16);
|
||||
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), 0);
|
||||
check_squared_distance(R{p(2, -4, 3), p( 3,-8, 4)}, Pl(0, 1, 0, 0), 16);
|
||||
}
|
||||
|
||||
void L_Pl()
|
||||
{
|
||||
std::cout << "Line - Plane\n";
|
||||
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,-8, 4)), Pl(0, 1, 0, 0), 0);
|
||||
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), 0);
|
||||
check_squared_distance(L{p(2, -4, 3), p( 3,-8, 4)}, Pl(0, 1, 0, 0), 0);
|
||||
}
|
||||
|
||||
void Pl_Pl()
|
||||
{
|
||||
std::cout << "Plane - Plane\n";
|
||||
std::cout << "Plane - Plane" << std::endl;
|
||||
Pl p1(0, 1, 0, 0);
|
||||
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);
|
||||
check_squared_distance (p1,p2, 36);
|
||||
check_squared_distance (Pl(-2, 1, 1, 0), Pl(2, 1, 3, 0), 0);
|
||||
check_squared_distance(p1,p2, 36);
|
||||
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()
|
||||
{
|
||||
std::cout << "3D Distance tests\n";
|
||||
std::cout << "Kernel: " << typeid(K).name() << std::endl;
|
||||
|
||||
P_P();
|
||||
P_S();
|
||||
P_T();
|
||||
P_Tet();
|
||||
S_S();
|
||||
P_R();
|
||||
R_R();
|
||||
S_R();
|
||||
R_L();
|
||||
P_L();
|
||||
S_L();
|
||||
L_L();
|
||||
P_T();
|
||||
P_Pl();
|
||||
P_Tet();
|
||||
|
||||
S_S();
|
||||
S_R();
|
||||
S_L();
|
||||
S_Pl();
|
||||
|
||||
R_R();
|
||||
R_L();
|
||||
R_Pl();
|
||||
|
||||
L_L();
|
||||
L_Pl();
|
||||
|
||||
T_T();
|
||||
|
||||
Pl_Pl();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
Test< CGAL::Simple_cartesian<double> >().run();
|
||||
Test< CGAL::Simple_homogeneous<double> >().run();
|
||||
// TODO : test more kernels.
|
||||
std::cout.precision(17);
|
||||
std::cerr.precision(17);
|
||||
|
||||
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::Epeck_ft> >(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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,11 +17,11 @@
|
|||
#ifndef CGAL_INTERSECTIONS_2_CIRCLE_2_CIRCLE_2_H
|
||||
#define CGAL_INTERSECTIONS_2_CIRCLE_2_CIRCLE_2_H
|
||||
|
||||
#include <CGAL/Circle_2.h>
|
||||
#include <CGAL/squared_distance_2_1.h>
|
||||
|
||||
#include <CGAL/Distance_2/Point_2_Point_2.h>
|
||||
#include <CGAL/Intersection_traits_2.h>
|
||||
|
||||
#include <CGAL/Circle_2.h>
|
||||
|
||||
namespace CGAL {
|
||||
namespace Intersections {
|
||||
namespace internal {
|
||||
|
|
|
|||
|
|
@ -18,10 +18,11 @@
|
|||
#ifndef CGAL_INTERSECTIONS_2_CIRCLE_2_LINE_2_H
|
||||
#define CGAL_INTERSECTIONS_2_CIRCLE_2_LINE_2_H
|
||||
|
||||
#include <CGAL/Distance_2/Point_2_Line_2.h>
|
||||
#include <CGAL/Intersection_traits_2.h>
|
||||
|
||||
#include <CGAL/Circle_2.h>
|
||||
#include <CGAL/Line_2.h>
|
||||
#include <CGAL/squared_distance_2_1.h>
|
||||
#include <CGAL/Intersection_traits_2.h>
|
||||
|
||||
namespace CGAL {
|
||||
namespace Intersections {
|
||||
|
|
|
|||
|
|
@ -13,10 +13,11 @@
|
|||
#ifndef CGAL_INTERSECTIONS_2_CIRCLE_2_RAY_2_H
|
||||
#define CGAL_INTERSECTIONS_2_CIRCLE_2_RAY_2_H
|
||||
|
||||
#include <CGAL/Distance_2/Point_2_Ray_2.h>
|
||||
#include <CGAL/Intersection_traits_2.h>
|
||||
|
||||
#include <CGAL/Circle_2.h>
|
||||
#include <CGAL/Ray_2.h>
|
||||
#include <CGAL/squared_distance_2_1.h>
|
||||
#include <CGAL/Intersection_traits_2.h>
|
||||
|
||||
namespace CGAL {
|
||||
namespace Intersections {
|
||||
|
|
|
|||
|
|
@ -13,10 +13,11 @@
|
|||
#ifndef CGAL_INTERSECTIONS_2_CIRCLE_2_SEGMENT_2_H
|
||||
#define CGAL_INTERSECTIONS_2_CIRCLE_2_SEGMENT_2_H
|
||||
|
||||
#include <CGAL/Distance_2/Point_2_Segment_2.h>
|
||||
#include <CGAL/Intersection_traits_2.h>
|
||||
|
||||
#include <CGAL/Circle_2.h>
|
||||
#include <CGAL/Segment_2.h>
|
||||
#include <CGAL/squared_distance_2_1.h>
|
||||
#include <CGAL/Intersection_traits_2.h>
|
||||
|
||||
namespace CGAL {
|
||||
namespace Intersections {
|
||||
|
|
|
|||
|
|
@ -13,10 +13,12 @@
|
|||
#ifndef CGAL_INTERSECTIONS_2_CIRCLE_2_TRIANGLE_2_H
|
||||
#define CGAL_INTERSECTIONS_2_CIRCLE_2_TRIANGLE_2_H
|
||||
|
||||
#include <CGAL/Distance_2/Point_2_Point_2.h>
|
||||
#include <CGAL/Distance_2/Point_2_Triangle_2.h>
|
||||
#include <CGAL/Intersection_traits_2.h>
|
||||
|
||||
#include <CGAL/Circle_2.h>
|
||||
#include <CGAL/Triangle_2.h>
|
||||
#include <CGAL/squared_distance_2_1.h>
|
||||
#include <CGAL/Intersection_traits_2.h>
|
||||
|
||||
namespace CGAL {
|
||||
namespace Intersections {
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@
|
|||
#ifndef CGAL_INTERSECTIONS_2_INTERNAL_STRAIGHT_2_H
|
||||
#define CGAL_INTERSECTIONS_2_INTERNAL_STRAIGHT_2_H
|
||||
|
||||
#include <CGAL/Distance_2/internal/squared_distance_utils_2.h>
|
||||
#include <CGAL/Intersections_2/Line_2_Line_2.h>
|
||||
#include <CGAL/squared_distance_utils.h>
|
||||
#include <CGAL/Kernel/global_functions_internal_2.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include <CGAL/Intersections_2/Line_2_Line_2.h>
|
||||
#include <CGAL/Intersection_traits_2.h>
|
||||
#include <CGAL/Algebraic_structure_traits.h>
|
||||
#include <CGAL/Kernel/global_functions_2.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
|
|
|
|||
|
|
@ -30,8 +30,7 @@ In 2D, the types `Type1` and `Type2` can be any of the following:
|
|||
|
||||
as well as any combination of `Kernel::Point_2` and `Kernel::Weighted_point_2`
|
||||
|
||||
In 3D, the types `Type1` and `Type2` can be any of the
|
||||
following:
|
||||
In 3D, the types `Type1` and `Type2` can be any of the following:
|
||||
|
||||
- `Point_3`
|
||||
- `Line_3`
|
||||
|
|
@ -39,9 +38,12 @@ following:
|
|||
- `Segment_3`
|
||||
- `Plane_3`
|
||||
|
||||
as well as combinations `Point_3`/`Triangle_3`,
|
||||
and `Weighted_point_3`/`Triangle_3`, as well as `Point_3`/`Tetrahedron_3`,
|
||||
and `Weighted_point_3`/`Tetrahedron_3`
|
||||
as well as the following combinations:
|
||||
- `Point_3`/`Triangle_3`
|
||||
- `Point_3`/`Tetrahedron_3`
|
||||
- `Weighted_point_3`/`Triangle_3`
|
||||
- `Weighted_point_3`/`Tetrahedron_3`
|
||||
- `Triangle_3`/`Triangle_3`
|
||||
|
||||
\sa `compare_distance_to_point_grp`
|
||||
\sa `compare_signed_distance_to_line_grp`
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
#include <CGAL/license/Mesh_3.h>
|
||||
|
||||
#include <CGAL/Mesh_3/search_for_connected_components_in_labeled_image.h>
|
||||
#include <CGAL/Mesh_3/squared_distance_Point_3_Triangle_3.h>
|
||||
#include <CGAL/Distance_3/Point_3_Triangle_3.h>
|
||||
#include <CGAL/Labeled_mesh_domain_3.h>
|
||||
#include <CGAL/make_mesh_3.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
#include <CGAL/license/Mesh_3.h>
|
||||
|
||||
|
||||
#include <CGAL/squared_distance_3_2.h>
|
||||
#include <CGAL/Distance_3/Point_3_Triangle_3.h>
|
||||
|
||||
#endif // CGAL_SQUARED_DISTANCE_POINT_3_TRIANGLE_3_H
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
#include <CGAL/Homogeneous.h>
|
||||
#include <CGAL/Point_2.h>
|
||||
#include <CGAL/Intersections_2/Line_2_Line_2.h>
|
||||
#include <CGAL/squared_distance_2.h>
|
||||
#include <CGAL/Distance_2/Point_2_Point_2.h>
|
||||
#include <CGAL/number_utils.h>
|
||||
#include <CGAL/Nef_polynomial.h>
|
||||
#undef CGAL_NEF_DEBUG
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@
|
|||
#include <CGAL/basic.h>
|
||||
#include <CGAL/Unique_hash_map.h>
|
||||
#include <CGAL/Delaunay_triangulation_2.h>
|
||||
#include <CGAL/squared_distance_2_1.h>
|
||||
#include <CGAL/compare_vertices.h>
|
||||
#include <list>
|
||||
#include <queue>
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@
|
|||
#include <CGAL/basic.h>
|
||||
#include <CGAL/Unique_hash_map.h>
|
||||
#include <CGAL/Delaunay_triangulation_2.h>
|
||||
#include <CGAL/squared_distance_2_1.h>
|
||||
#include <CGAL/compare_vertices.h>
|
||||
#include <list>
|
||||
#include <queue>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
Algebraic_foundations
|
||||
Circulator
|
||||
Distance_2
|
||||
Filtered_kernel
|
||||
Hash_map
|
||||
Installation
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
#ifndef POLYHEDRON_DEMO_STATISTICS_HELPERS_H
|
||||
#define POLYHEDRON_DEMO_STATISTICS_HELPERS_H
|
||||
|
||||
#include <CGAL/squared_distance_3_0.h>
|
||||
#include <CGAL/Distance_3/Point_3_Point_3.h>
|
||||
#include <CGAL/Distance_3/Point_3_Line_3.h>
|
||||
#include <CGAL/Polygon_mesh_processing/repair.h>
|
||||
|
||||
#include <boost/accumulators/accumulators.hpp>
|
||||
|
|
|
|||
|
|
@ -15,10 +15,10 @@
|
|||
#include <CGAL/boost/graph/properties.h>
|
||||
#include <CGAL/boost/graph/graph_traits_Polyhedron_3.h>
|
||||
#include <CGAL/Unique_hash_map.h>
|
||||
#include <CGAL/squared_distance_2_1.h>
|
||||
#include <CGAL/number_utils.h>
|
||||
#include <memory>
|
||||
#include <CGAL/boost/graph/internal/Has_member_id.h>
|
||||
#include <CGAL/Distance_3/Point_3_Point_3.h>
|
||||
|
||||
#define CGAL_HDS_PARAM_ template < class Traits, class Items, class Alloc> class HDS
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue