Merge pull request #1562 from afabri/Kernel_Compute_dihedral_angle-GF

Add doc of functor class and concept corresponding to dihedral_angle()
This commit is contained in:
Laurent Rineau 2016-10-20 09:48:05 +02:00
commit c6cf01c7f6
17 changed files with 136 additions and 94 deletions

View File

@ -48,8 +48,23 @@ Angle angle(const CGAL::Point_3<Kernel>& p,
const CGAL::Point_3<Kernel>& q, const CGAL::Point_3<Kernel>& q,
const CGAL::Point_3<Kernel>& r); const CGAL::Point_3<Kernel>& r);
/*!
returns an approximation of the signed dihedral angle in the tetrahedron `pqrs` of edge `pq`.
The sign is negative if `orientation(p,q,r,s)` is `CGAL::NEGATIVE` and positive otherwise.
The angle is given in degree.
\pre `p,q,r` and `p,q,s` are not collinear.
*/
template <typename Kernel>
Kernel::FT approximate_dihedral_angle(const CGAL::Point_3<Kernel>& p,
const CGAL::Point_3<Kernel>& q,
const CGAL::Point_3<Kernel>& r,
const CGAL::Point_3<Kernel>& s);
/// @} /// @}
/// \defgroup area_grp CGAL::area() /// \defgroup area_grp CGAL::area()
/// \ingroup kernel_global_function /// \ingroup kernel_global_function
/// @{ /// @{
@ -1690,14 +1705,6 @@ const CGAL::Vector_3<Kernel>& v,
const CGAL::Vector_3<Kernel>& w); const CGAL::Vector_3<Kernel>& w);
/// @} /// @}
/*!
returns the dihedral angle of .... between `-180` and `180` degree.
*/
template <typename Kernel>
Kernel::FT dihedral_angle(const CGAL::Point_3<Kernel>& p,
const CGAL::Point_3<Kernel>& q,
const CGAL::Point_3<Kernel>& r,
const CGAL::Point_3<Kernel>& s);
// This is there to keep the global functions in alphabetical order // This is there to keep the global functions in alphabetical order

View File

@ -1626,6 +1626,37 @@ public:
}; /* end Kernel::ComputeApproximateArea_3 */ }; /* end Kernel::ComputeApproximateArea_3 */
/*!
\ingroup PkgKernel23ConceptsFunctionObjects
\cgalConcept
\cgalRefines `AdaptableFunctor`
*/
class ComputeApproximateDihedralAngle_3 {
public:
/// \name Operations
/// A model of this concept must provide:
/// @{
/*!
returns an approximation of the signed dihedral angle in the tetrahedron `pqrs` of edge `pq`.
The sign is negative if `orientation(p,q,r,s)` is `CGAL::NEGATIVE` and positive otherwise.
The angle is given in degree.
\pre `p,q,r` and `p,q,s` are not collinear.
*/
Kernel::FT operator()(const Kernel::Point_3& p,
const Kernel::Point_3& q,
const Kernel::Point_3& r,
const Kernel::Point_3& s) const;
/// @}
}; /* end Kernel::ComputeApproximateDihedralAngle_3 */
/*! /*!
\ingroup PkgKernel23ConceptsFunctionObjects \ingroup PkgKernel23ConceptsFunctionObjects
\cgalConcept \cgalConcept
@ -1925,6 +1956,8 @@ public:
}; /* end Kernel::ComputeDeterminant_3 */ }; /* end Kernel::ComputeDeterminant_3 */
/*! /*!
\ingroup PkgKernel23ConceptsFunctionObjects \ingroup PkgKernel23ConceptsFunctionObjects
\cgalConcept \cgalConcept

View File

@ -1217,6 +1217,11 @@ public:
*/ */
typedef unspecified_type Compute_approximate_area_3; typedef unspecified_type Compute_approximate_area_3;
/*!
a model of `Kernel::ComputeApproximateDihedralAngle_3`
*/
typedef unspecified_type Compute_approximate_dihedral_angle_3;
/*! /*!
a model of `Kernel::ComputeDeterminant_3` a model of `Kernel::ComputeDeterminant_3`
*/ */

View File

@ -288,6 +288,7 @@
- `Kernel::ComputeB_2` - `Kernel::ComputeB_2`
- `Kernel::ComputeC_2` - `Kernel::ComputeC_2`
- `Kernel::ComputeApproximateArea_3` - `Kernel::ComputeApproximateArea_3`
- `Kernel::ComputeApproximateDihedralAngle_3`
- `Kernel::ComputeApproximateSquaredLength_3` - `Kernel::ComputeApproximateSquaredLength_3`
- `Kernel::ComputeArea_2` - `Kernel::ComputeArea_2`
- `Kernel::ComputeArea_3` - `Kernel::ComputeArea_3`

View File

@ -344,30 +344,8 @@ namespace CommonKernelFunctors {
} }
}; };
template <typename K>
class Compute_area_3
{
typedef typename K::FT FT;
typedef typename K::Point_3 Point_3;
typedef typename K::Triangle_3 Triangle_3;
public:
typedef FT result_type;
FT
operator()( const Triangle_3& t ) const
{
return CGAL_NTS sqrt(K().compute_squared_area_3_object()(t));
}
FT
operator()( const Point_3& p, const Point_3& q, const Point_3& r ) const
{
return CGAL_NTS sqrt(K().compute_squared_area_3_object()(p, q, r));
}
};
template <typename K> template <typename K>
class Compute_dihedral_angle_3 class Compute_approximate_dihedral_angle_3
{ {
typedef typename K::Point_3 Point_3; typedef typename K::Point_3 Point_3;
public: public:
@ -401,6 +379,28 @@ namespace CommonKernelFunctors {
} }
}; };
template <typename K>
class Compute_area_3
{
typedef typename K::FT FT;
typedef typename K::Point_3 Point_3;
typedef typename K::Triangle_3 Triangle_3;
public:
typedef FT result_type;
FT
operator()( const Triangle_3& t ) const
{
return CGAL_NTS sqrt(K().compute_squared_area_3_object()(t));
}
FT
operator()( const Point_3& p, const Point_3& q, const Point_3& r ) const
{
return CGAL_NTS sqrt(K().compute_squared_area_3_object()(p, q, r));
}
};
template <typename K> template <typename K>
class Compute_squared_distance_2 class Compute_squared_distance_2
{ {

View File

@ -59,6 +59,17 @@ angle(const Point_3<K> &p, const Point_3<K> &q,
return internal::angle(p, q, r, s, K()); return internal::angle(p, q, r, s, K());
} }
template < class K >
inline
typename K::FT
approximate_dihedral_angle(const Point_3<K> &p,
const Point_3<K> &q,
const Point_3<K> &r,
const Point_3<K> &s)
{
return internal::approximate_dihedral_angle(p, q, r, s, K());
}
template < typename K > template < typename K >
inline inline
typename K::Boolean typename K::Boolean
@ -516,17 +527,6 @@ determinant(const Vector_3<K> &v0, const Vector_3<K> &v1,
return internal::determinant(v0, v1, v2, K()); return internal::determinant(v0, v1, v2, K());
} }
template < class K >
inline
typename K::FT
dihedral_angle(const Point_3<K> &p,
const Point_3<K> &q,
const Point_3<K> &r,
const Point_3<K> &s)
{
return internal::dihedral_angle(p, q, r, s, K());
}
template < class K > template < class K >
inline inline
typename K::Line_3 typename K::Line_3

View File

@ -70,6 +70,17 @@ angle(const typename K::Point_3 &p,
return k.angle_3_object()(p, q, r, s); return k.angle_3_object()(p, q, r, s);
} }
template < class K >
inline
typename K::FT
approximate_dihedral_angle(const typename K::Point_3 &p,
const typename K::Point_3 &q,
const typename K::Point_3 &r,
const typename K::Point_3 &s, const K& k)
{
return k.compute_approximate_dihedral_angle_3_object()(p, q, r, s);
}
template < class K > template < class K >
inline inline
typename K::Boolean typename K::Boolean
@ -591,17 +602,6 @@ determinant(const typename K::Vector_3 &v0,
return k.compute_determinant_3_object()(v0, v1, v2); return k.compute_determinant_3_object()(v0, v1, v2);
} }
template < class K >
inline
typename K::FT
dihedral_angle(const typename K::Point_3 &p,
const typename K::Point_3 &q,
const typename K::Point_3 &r,
const typename K::Point_3 &s, const K& k)
{
return k.compute_dihedral_angle_3_object()(p, q, r, s);
}
template < class K > template < class K >
inline inline
typename K::Line_3 typename K::Line_3

View File

@ -162,6 +162,8 @@ CGAL_Kernel_cons(Compute_c_3,
compute_c_3_object) compute_c_3_object)
CGAL_Kernel_cons(Compute_d_3, CGAL_Kernel_cons(Compute_d_3,
compute_d_3_object) compute_d_3_object)
CGAL_Kernel_cons(Compute_approximate_dihedral_angle_3,
compute_approximate_dihedral_angle_3_object)
CGAL_Kernel_cons(Compute_approximate_area_3, CGAL_Kernel_cons(Compute_approximate_area_3,
compute_approximate_area_3_object) compute_approximate_area_3_object)
CGAL_Kernel_cons(Compute_approximate_squared_length_3, CGAL_Kernel_cons(Compute_approximate_squared_length_3,
@ -176,8 +178,6 @@ CGAL_Kernel_cons(Compute_determinant_2,
compute_determinant_2_object) compute_determinant_2_object)
CGAL_Kernel_cons(Compute_determinant_3, CGAL_Kernel_cons(Compute_determinant_3,
compute_determinant_3_object) compute_determinant_3_object)
CGAL_Kernel_cons(Compute_dihedral_angle_3,
compute_dihedral_angle_3_object)
CGAL_Kernel_cons(Compute_scalar_product_2, CGAL_Kernel_cons(Compute_scalar_product_2,
compute_scalar_product_2_object) compute_scalar_product_2_object)
CGAL_Kernel_cons(Compute_scalar_product_3, CGAL_Kernel_cons(Compute_scalar_product_3,

View File

@ -41,7 +41,7 @@ dihedral_angle(const typename K::Point_3& a,
K k = K()) K k = K())
{ {
// Now in the CGAL kernels // Now in the CGAL kernels
return k.compute_dihedral_angle_3_object()(a, b, c, d); return k.compute_approximate_dihedral_angle_3_object()(a, b, c, d);
} }

View File

@ -979,10 +979,10 @@ private:
const int k3, const int k3,
const Cell_handle& cell) const const Cell_handle& cell) const
{ {
return CGAL::abs(dihedral_angle(p, return CGAL::abs(approximate_dihedral_angle(p,
cell->vertex(k1)->point(), cell->vertex(k1)->point(),
cell->vertex(k2)->point(), cell->vertex(k2)->point(),
cell->vertex(k3)->point())); cell->vertex(k3)->point()));
} }
/** /**

View File

@ -248,14 +248,14 @@ private:
// check whether the edge is border // check whether the edge is border
if( (v0 + 1 == v1 || (v0 == n-1 && v1 == 0) ) && !Q.empty() ) { if( (v0 + 1 == v1 || (v0 == n-1 && v1 == 0) ) && !Q.empty() ) {
angle = 180 - CGAL::abs( angle = 180 - CGAL::abs(
to_double(CGAL::dihedral_angle(P[v0],P[v1],P[v_other],Q[v0])) ); to_double(CGAL::approximate_dihedral_angle(P[v0],P[v1],P[v_other],Q[v0])) );
} }
else { else {
if(e == 2) { continue; } if(e == 2) { continue; }
if(lambda.get(v0, v1) != -1){ if(lambda.get(v0, v1) != -1){
const Point_3& p01 = P[lambda.get(v0, v1)]; const Point_3& p01 = P[lambda.get(v0, v1)];
angle = 180 - CGAL::abs( angle = 180 - CGAL::abs(
to_double(CGAL::dihedral_angle(P[v0],P[v1],P[v_other],p01)) ); to_double(CGAL::approximate_dihedral_angle(P[v0],P[v1],P[v_other],p01)) );
} }
} }
ang_max = (std::max)(ang_max, angle); ang_max = (std::max)(ang_max, angle);

View File

@ -82,11 +82,11 @@ CGAL::internal::Weight_min_max_dihedral_and_area
Halfedge_handle edge_it = halfedge(*begin, poly); Halfedge_handle edge_it = halfedge(*begin, poly);
double ang_max = 0; double ang_max = 0;
for(int i = 0; i < 3; ++i) { for(int i = 0; i < 3; ++i) {
double angle = 180 - CGAL::abs( double angle = 180 -
CGAL::dihedral_angle(ppmap[target(edge_it,poly)], CGAL::abs(CGAL::approximate_dihedral_angle(ppmap[target(edge_it,poly)],
ppmap[source(edge_it,poly)], ppmap[source(edge_it,poly)],
ppmap[target(next(edge_it,poly),poly)], ppmap[target(next(edge_it,poly),poly)],
ppmap[target(next(opposite(edge_it,poly),poly),poly)]) ); ppmap[target(next(opposite(edge_it,poly),poly),poly)]) );
edge_it = next(edge_it,poly); edge_it = next(edge_it,poly);
ang_max = (std::max)(angle, ang_max); ang_max = (std::max)(angle, ang_max);
} }

View File

@ -85,10 +85,10 @@ CGAL::internal::Weight_min_max_dihedral_and_area
double ang_max = 0; double ang_max = 0;
for(int i = 0; i < 3; ++i) { for(int i = 0; i < 3; ++i) {
double angle = 180 - CGAL::abs( double angle = 180 - CGAL::abs(
CGAL::dihedral_angle(ppmap[target(edge_it,poly)], CGAL::approximate_dihedral_angle(ppmap[target(edge_it,poly)],
ppmap[source(edge_it,poly)], ppmap[source(edge_it,poly)],
ppmap[target(next(edge_it,poly),poly)], ppmap[target(next(edge_it,poly),poly)],
ppmap[target(next(opposite(edge_it,poly),poly),poly)]) ); ppmap[target(next(opposite(edge_it,poly),poly),poly)]) );
edge_it = next(edge_it,poly); edge_it = next(edge_it,poly);
ang_max = (std::max)(angle, ang_max); ang_max = (std::max)(angle, ang_max);
} }

View File

@ -13,7 +13,6 @@
#include <map> #include <map>
#include <vector> #include <vector>
#include <CGAL/gl.h> #include <CGAL/gl.h>
#include <CGAL/Mesh_3/dihedral_angle_3.h>
#include <CGAL/Three/Scene_interface.h> #include <CGAL/Three/Scene_interface.h>
#include <CGAL/Real_timer.h> #include <CGAL/Real_timer.h>
@ -562,32 +561,32 @@ create_histogram(const C3t3& c3t3, double& min_value, double& max_value)
const Point_3& p2 = cit->vertex(2)->point(); const Point_3& p2 = cit->vertex(2)->point();
const Point_3& p3 = cit->vertex(3)->point(); const Point_3& p3 = cit->vertex(3)->point();
double a = CGAL::to_double(CGAL::abs(CGAL::Mesh_3::dihedral_angle(p0, p1, p2, p3))); double a = CGAL::to_double(CGAL::abs(CGAL::approximate_dihedral_angle(p0, p1, p2, p3)));
histo[static_cast<int>(std::floor(a))] += 1; histo[static_cast<int>(std::floor(a))] += 1;
min_value = (std::min)(min_value, a); min_value = (std::min)(min_value, a);
max_value = (std::max)(max_value, a); max_value = (std::max)(max_value, a);
a = CGAL::to_double(CGAL::abs(CGAL::Mesh_3::dihedral_angle(p0, p2, p1, p3))); a = CGAL::to_double(CGAL::abs(CGAL::approximate_dihedral_angle(p0, p2, p1, p3)));
histo[static_cast<int>(std::floor(a))] += 1; histo[static_cast<int>(std::floor(a))] += 1;
min_value = (std::min)(min_value, a); min_value = (std::min)(min_value, a);
max_value = (std::max)(max_value, a); max_value = (std::max)(max_value, a);
a = CGAL::to_double(CGAL::abs(CGAL::Mesh_3::dihedral_angle(p0, p3, p1, p2))); a = CGAL::to_double(CGAL::abs(CGAL::approximate_dihedral_angle(p0, p3, p1, p2)));
histo[static_cast<int>(std::floor(a))] += 1; histo[static_cast<int>(std::floor(a))] += 1;
min_value = (std::min)(min_value, a); min_value = (std::min)(min_value, a);
max_value = (std::max)(max_value, a); max_value = (std::max)(max_value, a);
a = CGAL::to_double(CGAL::abs(CGAL::Mesh_3::dihedral_angle(p1, p2, p0, p3))); a = CGAL::to_double(CGAL::abs(CGAL::approximate_dihedral_angle(p1, p2, p0, p3)));
histo[static_cast<int>(std::floor(a))] += 1; histo[static_cast<int>(std::floor(a))] += 1;
min_value = (std::min)(min_value, a); min_value = (std::min)(min_value, a);
max_value = (std::max)(max_value, a); max_value = (std::max)(max_value, a);
a = CGAL::to_double(CGAL::abs(CGAL::Mesh_3::dihedral_angle(p1, p3, p0, p2))); a = CGAL::to_double(CGAL::abs(CGAL::approximate_dihedral_angle(p1, p3, p0, p2)));
histo[static_cast<int>(std::floor(a))] += 1; histo[static_cast<int>(std::floor(a))] += 1;
min_value = (std::min)(min_value, a); min_value = (std::min)(min_value, a);
max_value = (std::max)(max_value, a); max_value = (std::max)(max_value, a);
a = CGAL::to_double(CGAL::abs(CGAL::Mesh_3::dihedral_angle(p2, p3, p0, p1))); a = CGAL::to_double(CGAL::abs(CGAL::approximate_dihedral_angle(p2, p3, p0, p1)));
histo[static_cast<int>(std::floor(a))] += 1; histo[static_cast<int>(std::floor(a))] += 1;
min_value = (std::min)(min_value, a); min_value = (std::min)(min_value, a);
max_value = (std::max)(max_value, a); max_value = (std::max)(max_value, a);

View File

@ -752,10 +752,10 @@ detect_bubbles(FT border_angle) {
|| _shape->classify (f1) != Shape::REGULAR) || _shape->classify (f1) != Shape::REGULAR)
continue; continue;
double angle = CGAL::dihedral_angle (vedge.first->point (), double angle = CGAL::approximate_dihedral_angle (vedge.first->point (),
vedge.second->point (), vedge.second->point (),
c->vertex (i)->point (), c->vertex (i)->point (),
c->vertex ((i + (j+2)%3 + 1)%4)->point ()); c->vertex ((i + (j+2)%3 + 1)%4)->point ());
if (-border_angle < angle && angle < border_angle) if (-border_angle < angle && angle < border_angle)
{ {

View File

@ -326,7 +326,7 @@ private:
// As far as I check: if, say, dihedral angle is 5, this returns 175, // As far as I check: if, say, dihedral angle is 5, this returns 175,
// if dihedral angle is -5, this returns -175. // if dihedral angle is -5, this returns -175.
// Another words this function returns angle between planes. // Another words this function returns angle between planes.
double n_angle = to_double( ::CGAL::dihedral_angle(a, b, c, d) ); double n_angle = to_double( ::CGAL::approximate_dihedral_angle(a, b, c, d) );
n_angle /= 180.0; n_angle /= 180.0;
bool concave = n_angle > 0; bool concave = n_angle > 0;
double angle = 1 + ((concave ? -1 : +1) * n_angle); double angle = 1 + ((concave ? -1 : +1) * n_angle);

View File

@ -1,8 +1,6 @@
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <CGAL/Simple_cartesian.h> #include <CGAL/Simple_cartesian.h>
#include <CGAL/Polyhedron_3.h> #include <CGAL/Polyhedron_3.h>
#include <CGAL/IO/Polyhedron_iostream.h> #include <CGAL/IO/Polyhedron_iostream.h>
@ -13,7 +11,6 @@
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Midpoint_placement.h> #include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Midpoint_placement.h>
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Count_stop_predicate.h> #include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Count_stop_predicate.h>
#include <CGAL/Unique_hash_map.h> #include <CGAL/Unique_hash_map.h>
#include <CGAL/Mesh_3/dihedral_angle_3.h>
#include <CGAL/property_map.h> #include <CGAL/property_map.h>
#include <cmath> #include <cmath>
@ -106,10 +103,10 @@ int main( int argc, char** argv )
point(target(hd,surface_mesh),surface_mesh)); point(target(hd,surface_mesh),surface_mesh));
} }
else{ else{
double angle = CGAL::Mesh_3::dihedral_angle(point(target(opposite(hd,surface_mesh),surface_mesh),surface_mesh), double angle = CGAL::approximate_dihedral_angle(point(target(opposite(hd,surface_mesh),surface_mesh),surface_mesh),
point(target(hd,surface_mesh),surface_mesh), point(target(hd,surface_mesh),surface_mesh),
point(target(next(hd,surface_mesh),surface_mesh),surface_mesh), point(target(next(hd,surface_mesh),surface_mesh),surface_mesh),
point(target(next(opposite(hd,surface_mesh),surface_mesh),surface_mesh),surface_mesh)); point(target(next(opposite(hd,surface_mesh),surface_mesh),surface_mesh),surface_mesh));
if ( CGAL::abs(angle)<100 ){ if ( CGAL::abs(angle)<100 ){
++nb_sharp_edges; ++nb_sharp_edges;
constraint_hmap[*eb]=true; constraint_hmap[*eb]=true;
@ -152,10 +149,10 @@ int main( int argc, char** argv )
point(target(hd,surface_mesh),surface_mesh))); point(target(hd,surface_mesh),surface_mesh)));
} }
else{ else{
double angle = CGAL::Mesh_3::dihedral_angle(point(target(opposite(hd,surface_mesh),surface_mesh),surface_mesh), double angle = approximate_dihedral_angle(point(target(opposite(hd,surface_mesh),surface_mesh),surface_mesh),
point(target(hd,surface_mesh),surface_mesh), point(target(hd,surface_mesh),surface_mesh),
point(target(next(hd,surface_mesh),surface_mesh),surface_mesh), point(target(next(hd,surface_mesh),surface_mesh),surface_mesh),
point(target(next(opposite(hd,surface_mesh),surface_mesh),surface_mesh),surface_mesh)); point(target(next(opposite(hd,surface_mesh),surface_mesh),surface_mesh),surface_mesh));
if ( CGAL::abs(angle)<100 ){ if ( CGAL::abs(angle)<100 ){
--nb_sharp_edges; --nb_sharp_edges;
assert( assert(