Merge pull request #5617 from afabri/Nef_3-translation-GF

Nef_3: Add Aff_transformation_3::is_translation()
This commit is contained in:
Laurent Rineau 2021-05-18 18:14:17 +02:00
commit 4a2f016f6a
20 changed files with 398 additions and 31 deletions

View File

@ -165,6 +165,11 @@ public:
bool is_even() const { return this->Ptr()->is_even(); }
bool is_odd() const { return ! (this->Ptr()->is_even()); }
bool is_translation() const { return this->Ptr()->is_translation(); }
bool is_scaling() const { return this->Ptr()->is_scaling(); }
bool is_reflection() const { return this->Ptr()->is_reflection(); }
bool is_rotation() const { return this->Ptr()->is_rotation(); }
FT cartesian(int i, int j) const { return this->Ptr()->cartesian(i,j); }
FT homogeneous(int i, int j) const { return cartesian(i,j); }
FT m(int i, int j) const { return cartesian(i,j); }

View File

@ -143,14 +143,7 @@ public:
Plane_3
transform(const Plane_3& p) const
{
if (is_even())
return Plane_3(transform(p.point()),
transpose().inverse().transform(p.orthogonal_direction()));
else
return Plane_3(transform(p.point()),
- transpose().inverse().transform(p.orthogonal_direction()));
}
{ return this->Ptr()->transform(p); }
Plane_3
operator()(const Plane_3& p) const
@ -161,6 +154,10 @@ public:
bool is_even() const { return this->Ptr()->is_even(); }
bool is_odd() const { return ! (this->Ptr()->is_even()); }
bool is_translation() const { return this->Ptr()->is_translation(); }
bool is_scaling() const { return this->Ptr()->is_scaling(); }
FT cartesian(int i, int j) const { return this->Ptr()->cartesian(i,j); }
FT homogeneous(int i, int j) const { return cartesian(i,j); }
FT m(int i, int j) const { return cartesian(i,j); }

View File

@ -60,6 +60,11 @@ public:
virtual Aff_transformation_2 inverse() const = 0;
virtual bool is_even() const = 0;
virtual bool is_translation() const { return false; }
virtual bool is_scaling() const { return false; }
virtual bool is_rotation() const { return false; }
virtual bool is_reflection() const { return false; }
virtual FT cartesian(int i, int j) const = 0;
virtual std::ostream &print(std::ostream &os) const = 0;
};

View File

@ -31,6 +31,7 @@ public:
typedef typename R::Point_3 Point_3;
typedef typename R::Vector_3 Vector_3;
typedef typename R::Direction_3 Direction_3;
typedef typename R::Plane_3 Plane_3;
typedef typename R::Aff_transformation_3 Aff_transformation_3;
virtual ~Aff_transformation_rep_baseC3(){}
@ -38,6 +39,7 @@ public:
virtual Point_3 transform(const Point_3 &p) const = 0;
virtual Vector_3 transform(const Vector_3 &v) const = 0;
virtual Direction_3 transform(const Direction_3 &d) const = 0;
virtual Plane_3 transform(const Plane_3& p) const = 0;
virtual Aff_transformation_3 operator*(
const Aff_transformation_rep_baseC3 &t) const = 0;
@ -54,6 +56,9 @@ public:
virtual Aff_transformation_3 inverse() const = 0;
virtual Aff_transformation_3 transpose() const = 0;
virtual bool is_even() const = 0;
virtual bool is_translation() const { return false; }
virtual bool is_scaling() const { return false; }
virtual FT cartesian(int i, int j) const = 0;
virtual std::ostream &print(std::ostream &os) const = 0;
};
@ -75,6 +80,7 @@ public:
typedef typename Transformation_base_3::Point_3 Point_3;
typedef typename Transformation_base_3::Vector_3 Vector_3;
typedef typename Transformation_base_3::Direction_3 Direction_3;
typedef typename Transformation_base_3::Plane_3 Plane_3;
typedef typename Transformation_base_3::
Aff_transformation_3 Aff_transformation_3;
@ -127,6 +133,17 @@ public:
t31 * v.x() + t32 * v.y() + t33 * v.z());
}
virtual Plane_3 transform(const Plane_3& p) const
{
if (is_even())
return Plane_3(transform(p.point()),
transpose().inverse().transform(p.orthogonal_direction()));
else
return Plane_3(transform(p.point()),
- transpose().inverse().transform(p.orthogonal_direction()));
}
// Note that Aff_transformation is not defined yet,
// so the following 6 functions have to be implemented
// outside class body
@ -144,6 +161,7 @@ public:
t31, t32, t33) == POSITIVE;
}
virtual FT cartesian(int i, int j) const
{
switch (i)

View File

@ -147,6 +147,11 @@ typedef typename CGAL::Line_2<R> Line_2;
return true;
}
virtual bool is_reflection() const
{
return true;
}
FT cartesian(int i, int j) const
{
switch (i)

View File

@ -139,11 +139,17 @@ public:
-sinus_*t.t21 + cosinus_*t.t22,
t.t23);
}
bool is_even() const
{
return true;
}
bool is_rotation() const
{
return true;
}
FT cartesian(int i, int j) const
{
switch (i)

View File

@ -120,6 +120,11 @@ public:
return true;
}
bool is_scaling() const
{
return true;
}
FT cartesian(int i, int j) const
{
if (i!=j) return FT(0);

View File

@ -34,6 +34,7 @@ public:
typedef typename Transformation_base_3::Point_3 Point_3;
typedef typename Transformation_base_3::Vector_3 Vector_3;
typedef typename Transformation_base_3::Direction_3 Direction_3;
typedef typename Transformation_base_3::Plane_3 Plane_3;
typedef typename Transformation_base_3::Aff_transformation_3
Aff_transformation_3;
@ -59,6 +60,12 @@ public:
return d;
}
virtual Plane_3 transform(const Plane_3 &p) const
{
// direction ( which is (p.a(), p.b(), p.c())) does not change
return Plane_3(p.a(),p.b(),p.c(), p.d()*scalefactor_);
}
virtual Aff_transformation_3 operator*(const Transformation_base_3 &t) const
{
return t.compose(*this);
@ -121,6 +128,11 @@ public:
return true;
}
virtual bool is_scaling() const
{
return true;
}
virtual FT cartesian(int i, int j) const
{
if (i!=j) return FT(0);

View File

@ -121,7 +121,12 @@ public:
return Aff_transformation_2(TRANSLATION, - translationvector_);
}
bool is_even() const
bool is_even() const
{
return true;
}
virtual bool is_translation() const
{
return true;
}

View File

@ -34,6 +34,7 @@ public:
typedef typename Transformation_base_3::Point_3 Point_3;
typedef typename Transformation_base_3::Vector_3 Vector_3;
typedef typename Transformation_base_3::Direction_3 Direction_3;
typedef typename Transformation_base_3::Plane_3 Plane_3;
typedef typename Transformation_base_3::Aff_transformation_3
Aff_transformation_3;
@ -56,6 +57,15 @@ public:
return d;
}
virtual Plane_3 transform(const Plane_3 &p) const
{
// direction ( which is (p.a(), p.b(), p.c())) does not change
return Plane_3(p.a(),
p.b(),
p.c(),
p.d() - ( p.a()*translationvector_.x() + p.b()*translationvector_.y() + p.c()*translationvector_.z()));
}
virtual Aff_transformation_3 operator*(const Transformation_base_3 &t) const
{
return t.compose(*this);
@ -125,6 +135,11 @@ public:
return true;
}
virtual bool is_translation() const
{
return true;
}
virtual FT cartesian(int i, int j) const
{
if (j==i) return FT(1);

View File

@ -58,6 +58,11 @@ class Aff_transformation_rep_baseH2 : public Ref_counted_virtual
general_form() const = 0;
virtual bool is_even() const = 0;
virtual bool is_translation() const { return false; }
virtual bool is_scaling() const { return false; }
virtual bool is_reflection() const { return false; }
virtual bool is_rotation() const { return false; }
virtual RT homogeneous(int i, int j) const = 0;
virtual FT cartesian(int i, int j) const = 0;
};
@ -247,6 +252,10 @@ class Translation_repH2 : public Aff_transformation_rep_baseH2<R>
is_even() const
{ return true; }
virtual bool
is_translation() const
{ return true; }
virtual Aff_transformation_repH2<R>
general_form() const
{
@ -321,6 +330,11 @@ class Rotation_repH2 : public Aff_transformation_rep_baseH2<R>
{
return true;
}
virtual bool
is_rotation() const
{ return true; }
virtual Aff_transformation_repH2<R>
general_form() const
{
@ -392,6 +406,10 @@ class Scaling_repH2 : public Aff_transformation_rep_baseH2<R>
is_even() const
{ return true; }
virtual bool
is_scaling() const
{ return true; }
virtual Aff_transformation_repH2<R>
general_form() const
{
@ -456,6 +474,10 @@ class Reflection_repH2 : public Aff_transformation_rep_baseH2<R>
is_even() const
{ return false; }
virtual bool
is_reflection() const
{ return true; }
virtual Aff_transformation_repH2<R>
general_form() const
{
@ -576,6 +598,11 @@ public:
bool is_even() const;
bool is_odd() const;
bool is_translation() const;
bool is_scaling() const;
bool is_rotation() const;
bool is_reflection() const;
// Access functions for matrix form
FT cartesian(int i, int j) const;
RT homogeneous(int i, int j) const;
@ -739,6 +766,30 @@ Aff_transformationH2<R>::
is_odd() const
{ return ! is_even(); }
template < class R >
bool
Aff_transformationH2<R>::
is_translation() const
{ return this->Ptr()->is_translation(); }
template < class R >
bool
Aff_transformationH2<R>::
is_scaling() const
{ return this->Ptr()->is_scaling(); }
template < class R >
bool
Aff_transformationH2<R>::
is_rotation() const
{ return this->Ptr()->is_rotation(); }
template < class R >
bool
Aff_transformationH2<R>::
is_reflection() const
{ return this->Ptr()->is_reflection(); }
template < class R >
inline
typename Aff_transformationH2<R>::FT

View File

@ -82,11 +82,21 @@ public:
virtual bool
is_even() const = 0;
virtual bool
is_translation() const { return false; }
virtual bool
is_scaling() const { return false; }
virtual RT
homogeneous(int i, int j) const = 0;
virtual FT
cartesian(int i, int j) const = 0;
// this function has a default here as it is only used for "pure" scaling and translation
// and not for the other types (Identity and general case)
virtual Aff_transformation_3 compose(const Aff_transformation_rep_baseH3*) const { return Aff_transformation_3(); }
};
template < class R_ >
@ -221,6 +231,128 @@ public:
{ return (i==j) ? FT(1) : FT(0); }
};
template < class R >
class Scaling_repH3 : public Aff_transformation_rep_baseH3<R>
{
public:
typedef typename R::RT RT;
typedef typename R::FT FT;
typedef typename R::Point_3 Point_3;
typedef typename R::Vector_3 Vector_3;
typedef typename R::Direction_3 Direction_3;
typedef typename R::Plane_3 Plane_3;
typedef typename R::Aff_transformation_3 Aff_transformation_3;
typedef Aff_transformation_rep_baseH3<R> Base;
typedef Scaling_repH3<R> Self;
Scaling_repH3()
{}
Scaling_repH3(const RT& scaling_numerator,
const RT& scaling_denominator) :
_sf_num(scaling_numerator), _sf_den(scaling_denominator)
{
if ( scaling_denominator < RT(0) )
{
_sf_num = - _sf_num;
_sf_den = - _sf_den;
};
}
virtual ~Scaling_repH3()
{}
virtual Point_3
transform(const Point_3 & p) const
{
return Point_3( p.hx() * _sf_num,
p.hy() * _sf_num,
p.hz() * _sf_num,
p.hw() * _sf_den );
}
virtual Vector_3
transform(const Vector_3 & v) const
{
return Vector_3( v.hx() * _sf_num,
v.hy() * _sf_num,
v.hz() * _sf_num,
v.hw() * _sf_den );
}
virtual Direction_3
transform(const Direction_3 & d) const
{ return d; }
virtual Plane_3
transform(const Plane_3 & p) const
{
return Plane_3(p.a()*_sf_den, p.b()*_sf_den, p.c()*_sf_den, p.d()*_sf_num);
}
virtual Aff_transformation_3
inverse() const
{ return Aff_transformation_3(SCALING, _sf_den, _sf_num); }
virtual Aff_transformation_3
transpose() const
{ return Aff_transformation_3(SCALING, _sf_num, _sf_den); }
virtual bool
is_even() const
{ return true; }
virtual bool
is_scaling() const
{ return true; }
virtual Aff_transformation_repH3<R>
general_form() const
{
return
Aff_transformation_repH3<R>(_sf_num, RT(0) , RT(0) ,RT(0) ,
RT(0) , _sf_num, RT(0) ,RT(0) ,
RT(0) , RT(0) , _sf_num,RT(0) ,
_sf_den );
}
Aff_transformation_3 compose(const Base* aff) const
{
const Self* sr = dynamic_cast<const Self*>(aff);
return Aff_transformation_3(SCALING, _sf_num * sr->_sf_num, _sf_den * sr->_sf_den);
}
virtual RT homogeneous(int i, int j) const;
virtual FT cartesian(int i, int j) const;
private:
RT _sf_num;
RT _sf_den;
};
template < class R >
typename Scaling_repH3<R>::RT
Scaling_repH3<R>::
homogeneous(int i, int j) const
{
if(i!=j) return RT(0);
if (i==3) return _sf_den;
return _sf_num;
}
template <class R>
typename Scaling_repH3<R>::FT
Scaling_repH3<R>::
cartesian(int i, int j) const
{
if(i!=j) return FT(0);
if (i==3) return FT(1);
return FT(_sf_num) / FT(_sf_den);
}
template < class R_ >
class Translation_repH3 : public Aff_transformation_rep_baseH3<R_>
{
@ -231,6 +363,8 @@ class Translation_repH3 : public Aff_transformation_rep_baseH3<R_>
typedef typename R_::Direction_3 Direction_3;
typedef typename R_::Plane_3 Plane_3;
typedef typename R_::Aff_transformation_3 Aff_transformation_3;
typedef Aff_transformation_rep_baseH3<R_> Base;
typedef Translation_repH3<R_> Self;
public:
typedef R_ R;
@ -264,12 +398,21 @@ public:
virtual bool
is_even() const;
virtual bool
is_translation() const;
virtual RT
homogeneous(int i, int j) const ;
virtual FT
cartesian(int i, int j) const ;
Aff_transformation_3 compose(const Base* aff) const
{
const Self* sr = dynamic_cast<const Self*>(aff);
return Aff_transformation_3(TRANSLATION, tv + sr->tv);
}
friend class Aff_transformationH3<R>;
private:
@ -340,6 +483,12 @@ public:
bool
is_odd() const;
bool
is_scaling() const;
bool
is_translation() const;
FT
cartesian(int i, int j) const
{ return this->Ptr()->cartesian(i,j); }
@ -539,6 +688,7 @@ Aff_transformation_repH3<R>::is_even() const
t20, t21, t22 ) ) == POSITIVE );
}
template < class R >
CGAL_KERNEL_LARGE_INLINE
typename Aff_transformation_repH3<R>::RT
@ -693,6 +843,12 @@ bool
Translation_repH3<R>::is_even() const
{ return true; }
template < class R >
inline
bool
Translation_repH3<R>::is_translation() const
{ return true; }
template < class R >
CGAL_KERNEL_LARGE_INLINE
typename Translation_repH3<R>::RT
@ -800,11 +956,7 @@ CGAL_KERNEL_INLINE
Aff_transformationH3<R>::
Aff_transformationH3(const Scaling&, const RT& num, const RT& den)
{
const RT RT0(0);
initialize_with(Aff_transformation_repH3<R>(num, RT0, RT0, RT0,
RT0, num, RT0, RT0,
RT0, RT0, num, RT0,
den ));
initialize_with(Scaling_repH3<R>(num, den ));
}
template < class R >
@ -890,15 +1042,35 @@ bool
Aff_transformationH3<R>::is_odd() const
{ return ( ! (this->Ptr()->is_even() )); }
template < class R >
inline
bool
Aff_transformationH3<R>::is_scaling() const
{ return this->Ptr()->is_scaling(); }
template < class R >
inline
bool
Aff_transformationH3<R>::is_translation() const
{ return this->Ptr()->is_translation(); }
template < class R >
CGAL_KERNEL_INLINE
Aff_transformationH3<R>
operator*(const Aff_transformationH3<R>& left_argument,
const Aff_transformationH3<R>& right_argument )
{
return _general_transformation_composition(
left_argument.Ptr() ->general_form(),
right_argument.Ptr()->general_form() );
if(left_argument.is_scaling() && right_argument.is_scaling()){
return left_argument.Ptr()->compose(right_argument.Ptr());
}
if(left_argument.is_translation() && right_argument.is_translation()){
return left_argument.Ptr()->compose(right_argument.Ptr());
}
return _general_transformation_composition(left_argument.Ptr() ->general_form(),
right_argument.Ptr()->general_form() );
}
template < class R >

View File

@ -25,6 +25,10 @@ Release date: June 2021
A comprehensive list of the supported file formats is available in the Stream_support package [here](https://doc.cgal.org/5.3/Stream_support/index.html#IOstreamSupportedFormats); inversely, the following [page](https://doc.cgal.org/5.3/Stream_support/IOStreamSupportedFileFormats.html) can be used to find out which CGAL data structures can be used given a specific file format.
### [2D and 3D Linear Geometry Kernel](https://doc.cgal.org/5.3/Manual/packages.html#PkgKernel23)
- Added functions to the classes `Aff_transformation_2` and `Aff_transformation_3`, which enable to determine if they internally have a specialized representation.
### [Quadtrees, Octrees, and Orthtrees](https://doc.cgal.org/5.3/Manual/packages.html#PkgOrthree) (new package)
- This package implements a tree data structure in which each node

View File

@ -273,6 +273,26 @@ returns `true`, if the transformation is reflecting.
*/
bool is_odd() const;
/*!
returns `true`, if the object was constructed using the tag `CGAL::Scaling`, or is the result of the composition of only such scaling transformation objects.
*/
bool is_scaling() const;
/*!
returns `true`, if the object was constructed using the tag `CGAL::Translation`, or is the result of the composition of only such translation transformation objects.
*/
bool is_translation() const;
/*!
returns `true`, if the object was constructed using the tag `CGAL::Rotation`, or is the result of the composition of only such rotation transformation objects.
*/
bool is_rotation() const;
/*!
returns `true`, if the object was constructed using the tag `CGAL::Reflection`, or is the result of the composition of only such reflection transformation objects.
*/
bool is_reflection() const;
/// @}
/// \name Matrix Entry Access

View File

@ -199,6 +199,17 @@ returns `true`, if the transformation is reflecting.
*/
bool is_odd() const;
/*!
returns `true`, if the object was constructed using the tag `CGAL::Scaling`, or is the result of the composition of only such scaling transformation objects.
*/
bool is_scaling() const;
/*!
returns `true`, if the object was constructed using the tag `CGAL::Translation`, or is the result of the composition of only such translation transformation objects.
*/
bool is_translation() const;
/// @}
/// \name Matrix Entry Access

View File

@ -135,7 +135,9 @@ _test_cls_aff_transformation_2(const R& )
CGAL::Aff_transformation_2<R> rot3( CGAL::ROTATION, RT(3),RT(4),RT(5));
CGAL::Aff_transformation_2<R> refle(CGAL::REFLECTION, CGAL::Line_2<R>(
CGAL::Point_2<R>(1,3),
CGAL::Point_2<R>(2,1)));
CGAL::Aff_transformation_2<R> a[14];
@ -295,6 +297,34 @@ _test_cls_aff_transformation_2(const R& )
assert( rot3.is_even() );
assert( xrefl.is_odd() );
// translation
assert( translate.is_translation() );
assert( ! scale11.is_translation() );
assert( ! gtrans.is_translation() );
assert( ! rot90.is_translation() );
assert( ! refle.is_translation() );
// scaling
assert( scale11.is_scaling() );
assert( ! translate.is_scaling() );
assert( ! gscale.is_scaling() );
assert( ! rot90.is_scaling() );
assert( ! refle.is_scaling() );
// reflection
assert( ! scale11.is_reflection() );
assert( ! translate.is_reflection() );
assert( ! gscale.is_reflection() );
assert( ! rot90.is_reflection() );
assert( refle.is_reflection() );
// rotation
assert( ! scale11.is_rotation() );
assert( ! translate.is_rotation() );
assert( ! gscale.is_rotation() );
assert( rot90.is_rotation() );
assert( !refle.is_rotation() );
// rotation
assert( d0.transform( rot90 ) == d1 );
assert( d1.transform( rot90.inverse() ) == d0 );

View File

@ -151,6 +151,16 @@ _test_cls_aff_transformation_3(const R& )
assert( ident.is_even() );
assert( xrefl.is_odd() );
// translation
assert( translate.is_translation() );
assert( ! scale11.is_translation() );
assert( ! gtrans.is_translation() );
// scaling
assert( scale11.is_scaling() );
assert( ! translate.is_scaling() );
assert( ! gscale.is_scaling() );
CGAL::Aff_transformation_3<R> a[11];
std::cout << '.';
@ -261,7 +271,7 @@ _test_cls_aff_transformation_3(const R& )
assert( vec.transform(translate) == vec.transform(gtrans) );
assert( dir.transform(translate) == dir.transform(gtrans) );
assert( pnt.transform(translate) == pnt.transform(gtrans) );
assert( pla.transform(translate) == pla.transform(gtrans) );
assert( pla.transform(translate) == pla.transform(gtrans) || nonexact );
// xrefl
tdir = d0.transform(xrefl);

View File

@ -579,4 +579,3 @@ the `Object_handle` can represent a `Vertex_const_handle`, a
*/
} /* namespace CGAL */

View File

@ -4,11 +4,7 @@
#include <CGAL/IO/Nef_polyhedron_iostream_3.h>
//instead of
//typedef CGAL::Extended_homogeneous<CGAL::Exact_integer> Kernel;
// workaround for VC++
struct Kernel : public CGAL::Extended_homogeneous<CGAL::Exact_integer> {};
typedef CGAL::Extended_homogeneous<CGAL::Exact_integer> Kernel;
typedef CGAL::Nef_polyhedron_3<Kernel> Nef_polyhedron;
typedef Nef_polyhedron::Plane_3 Plane_3;
typedef Nef_polyhedron::Vector_3 Vector_3;
@ -22,10 +18,7 @@ int main() {
0,0,-1,
0,1,0,
1);
Aff_transformation_3 scale(3,0,0,
0,3,0,
0,0,3,
2);
Aff_transformation_3 scale(CGAL::SCALING, 3, 2);
N.transform(transl);
CGAL_assertion(N == Nef_polyhedron(Plane_3(0,1,0,-7)));

View File

@ -1710,6 +1710,8 @@ protected:
bool ninety = is_90degree_rotation(aff);
bool scale = is_scaling(aff);
bool translate = aff.is_translation();
Vertex_iterator vi;
CGAL_forall_vertices( vi, snc()) {
@ -1726,8 +1728,10 @@ protected:
vertex_list.push_back(vi);
} else {
vi->point() = vi->point().transform( aff);
SM_decorator sdeco(&*vi);
sdeco.transform( linear);
if(! translate){
SM_decorator sdeco(&*vi);
sdeco.transform( linear);
}
}
}