mirror of https://github.com/CGAL/cgal
768 lines
23 KiB
C++
768 lines
23 KiB
C++
// ======================================================================
|
|
//
|
|
// Copyright (c) 1999 The CGAL Consortium
|
|
//
|
|
// This software and related documentation is part of an INTERNAL release
|
|
// of the Computational Geometry Algorithms Library (CGAL). It is not
|
|
// intended for general use.
|
|
//
|
|
// ----------------------------------------------------------------------
|
|
// release :
|
|
// release_date : 2000, October 15
|
|
//
|
|
// source : webS3/S3.lw
|
|
// file : include/CGAL/SimpleCartesian/Aff_transformationS3.h
|
|
// package : S3 (1.7)
|
|
// maintainer : Stefan Schirra <stschirr@mpi-sb.mpg.de>
|
|
// revision : 1.7
|
|
// revision_date : 15 Oct 2000
|
|
// author(s) : Stefan Schirra <Stefan.Schirra@@mpi-sb.mpg.de>
|
|
// based on code by
|
|
// Andreas Fabri and
|
|
// Herve Brönnimann
|
|
//
|
|
// coordinator : MPI, Saarbrücken
|
|
// ======================================================================
|
|
|
|
#ifndef CGAL_AFF_TRANSFORMATIONS3_H
|
|
#define CGAL_AFF_TRANSFORMATIONS3_H
|
|
|
|
#include <cmath>
|
|
#include <CGAL/Handle.h>
|
|
#include <CGAL/SimpleCartesian/simple_cartesian_classes.h>
|
|
#include <CGAL/determinant.h>
|
|
|
|
#ifdef CGAL_CFG_INCOMPLETE_TYPE_BUG_1
|
|
#define CGAL_NO_PLANE_TRANSFORM_IN_AT
|
|
#endif // CGAL_CFG_INCOMPLETE_TYPE_BUG_1
|
|
|
|
CGAL_BEGIN_NAMESPACE
|
|
|
|
template <class FT> class Aff_transformationS3;
|
|
template <class FT> class Aff_transformation_repS3;
|
|
template <class FT> class Translation_repS3;
|
|
template <class FT> class Scaling_repS3;
|
|
|
|
template <class FT>
|
|
Aff_transformationS3<FT>
|
|
_general_transformation_composition ( Aff_transformation_repS3<FT>& l,
|
|
Aff_transformation_repS3<FT>& r );
|
|
|
|
template <class FT>
|
|
Aff_transformationS3<FT>
|
|
operator*(const Aff_transformationS3<FT>& a, const Aff_transformationS3<FT>& b);
|
|
|
|
template <class FT>
|
|
std::ostream&
|
|
operator<< (std::ostream& os, Translation_repS3<FT>& t);
|
|
|
|
template <class FT>
|
|
std::ostream&
|
|
operator<< (std::ostream& os, Scaling_repS3<FT>& t);
|
|
|
|
template <class FT>
|
|
std::ostream&
|
|
operator<< (std::ostream& os, const Aff_transformationS3<FT>& t);
|
|
|
|
template < class FT >
|
|
class Aff_transformation_rep_baseS3 : public Rep
|
|
{
|
|
public:
|
|
virtual ~Aff_transformation_rep_baseS3(){}
|
|
|
|
virtual PointS3<FT> transform(const PointS3<FT>& p) const = 0;
|
|
virtual VectorS3<FT> transform(const VectorS3<FT>& v) const = 0;
|
|
virtual DirectionS3<FT> transform(const DirectionS3<FT>& d)
|
|
const = 0;
|
|
|
|
virtual Aff_transformationS3<FT> inverse() const = 0;
|
|
|
|
virtual Aff_transformationS3<FT> transpose() const = 0;
|
|
|
|
virtual bool is_even() const = 0;
|
|
virtual FT cartesian(int i, int j) const = 0;
|
|
virtual std::ostream& print(std::ostream& os) const = 0;
|
|
virtual Aff_transformationS3<FT> general_form() const = 0;
|
|
};
|
|
|
|
|
|
|
|
template < class FT >
|
|
class Aff_transformation_repS3 : public Aff_transformation_rep_baseS3<FT>
|
|
{
|
|
friend class Aff_transformationS3<FT>;
|
|
|
|
friend Aff_transformationS3<FT>
|
|
_general_transformation_composition CGAL_NULL_TMPL_ARGS(
|
|
Aff_transformation_repS3<FT>& l,
|
|
Aff_transformation_repS3<FT>& r );
|
|
friend Aff_transformationS3<FT> operator* CGAL_NULL_TMPL_ARGS
|
|
(const Aff_transformationS3<FT>& a,
|
|
const Aff_transformationS3<FT>& b);
|
|
|
|
public:
|
|
|
|
Aff_transformation_repS3()
|
|
{}
|
|
|
|
Aff_transformation_repS3( const FT& m11, const FT& m12, const FT& m13,
|
|
const FT& m21, const FT& m22, const FT& m23,
|
|
const FT& m31, const FT& m32, const FT& m33)
|
|
: t11(m11), t12(m12), t13(m13), t14(0),
|
|
t21(m21), t22(m22), t23(m23), t24(0),
|
|
t31(m31), t32(m32), t33(m33), t34(0)
|
|
{}
|
|
|
|
Aff_transformation_repS3( const FT& m11, const FT& m12,
|
|
const FT& m13,const FT& m14,
|
|
|
|
const FT& m21, const FT& m22,
|
|
const FT& m23, const FT& m24,
|
|
|
|
const FT& m31, const FT& m32,
|
|
const FT& m33, const FT& m34)
|
|
: t11(m11), t12(m12), t13(m13), t14(m14),
|
|
t21(m21), t22(m22), t23(m23), t24(m24),
|
|
t31(m31), t32(m32), t33(m33), t34(m34)
|
|
{}
|
|
|
|
~Aff_transformation_repS3()
|
|
{}
|
|
|
|
PointS3<FT> transform(const PointS3<FT>& p) const
|
|
{
|
|
return PointS3<FT>(t11 * p.x() + t12 * p.y() + t13 * p.z() + t14,
|
|
t21 * p.x() + t22 * p.y() + t23 * p.z() + t24,
|
|
t31 * p.x() + t32 * p.y() + t33 * p.z() + t34);
|
|
}
|
|
|
|
|
|
// note that a vector is not translated
|
|
VectorS3<FT> transform(const VectorS3<FT>& v) const
|
|
{
|
|
return VectorS3<FT>(t11 * v.x() + t12 * v.y() + t13 * v.z(),
|
|
t21 * v.x() + t22 * v.y() + t23 * v.z(),
|
|
t31 * v.x() + t32 * v.y() + t33 * v.z());
|
|
}
|
|
|
|
|
|
// note that a direction is not translated
|
|
DirectionS3<FT> transform(const DirectionS3<FT>& dir) const
|
|
{
|
|
VectorS3<FT> v = dir.vector();
|
|
return DirectionS3<FT>(t11 * v.x() + t12 * v.y() + t13 * v.z(),
|
|
t21 * v.x() + t22 * v.y() + t23 * v.z(),
|
|
t31 * v.x() + t32 * v.y() + t33 * v.z());
|
|
}
|
|
|
|
Aff_transformationS3<FT> inverse() const
|
|
{
|
|
return Aff_transformationS3<FT>(
|
|
det2x2_by_formula( t22, t23,
|
|
t32, t33), // i 11
|
|
|
|
- det2x2_by_formula( t12, t13,
|
|
t32, t33), // i 12
|
|
|
|
det2x2_by_formula( t12, t13,
|
|
t22, t23), // i 13
|
|
|
|
- det3x3_by_formula( t12, t13, t14,
|
|
t22, t23, t24, // i 14
|
|
t32, t33, t34 ),
|
|
|
|
- det2x2_by_formula( t21, t23,
|
|
t31, t33), // i 21
|
|
|
|
det2x2_by_formula( t11, t13,
|
|
t31, t33), // i 22
|
|
|
|
- det2x2_by_formula( t11, t13,
|
|
t21, t23), // i 23
|
|
|
|
det3x3_by_formula( t11, t13, t14,
|
|
t21, t23, t24, // i 24
|
|
t31, t33, t34 ),
|
|
|
|
det2x2_by_formula( t21, t22,
|
|
t31, t32), // i 31
|
|
|
|
- det2x2_by_formula( t11, t12,
|
|
t31, t32), // i 32
|
|
|
|
det2x2_by_formula( t11, t12,
|
|
t21, t22), // i 33
|
|
|
|
- det3x3_by_formula( t11, t12, t14,
|
|
t21, t22, t24, // i 34
|
|
t31, t32, t34 ),
|
|
|
|
det3x3_by_formula( t11, t12, t13,
|
|
t21, t22, t23, // i 44
|
|
t31, t32, t33 )
|
|
) ;
|
|
}
|
|
|
|
|
|
virtual Aff_transformationS3<FT> general_form() const
|
|
{
|
|
return Aff_transformationS3<FT>(t11, t12, t13, t14,
|
|
t21, t22, t23, t24,
|
|
t31, t32, t33, t34);
|
|
}
|
|
|
|
virtual Aff_transformationS3<FT> transpose() const
|
|
{
|
|
FT ft0(0);
|
|
return Aff_transformationS3<FT>( t11, t21, t31, ft0,
|
|
t12, t22, t32, ft0,
|
|
t13, t23, t33, ft0);
|
|
}
|
|
|
|
virtual bool is_even() const
|
|
{
|
|
return sign_of_determinant3x3(t11, t12, t13,
|
|
t21, t22, t23,
|
|
t31, t32, t33) == POSITIVE;
|
|
}
|
|
|
|
virtual FT cartesian(int i, int j) const
|
|
{
|
|
switch (i)
|
|
{
|
|
case 0: switch (j)
|
|
{
|
|
case 0: return t11;
|
|
case 1: return t12;
|
|
case 2: return t13;
|
|
case 3: return t14;
|
|
}
|
|
case 1: switch (j)
|
|
{
|
|
case 0: return t21;
|
|
case 1: return t22;
|
|
case 2: return t23;
|
|
case 3: return t24;
|
|
}
|
|
case 2: switch (j)
|
|
{
|
|
case 0: return t31;
|
|
case 1: return t32;
|
|
case 2: return t33;
|
|
case 3: return t34;
|
|
}
|
|
case 3: switch (j)
|
|
{
|
|
case 0: return FT(0);
|
|
case 1: return FT(0);
|
|
case 2: return FT(0);
|
|
case 3: return FT(1);
|
|
}
|
|
}
|
|
return FT(0);
|
|
}
|
|
|
|
|
|
std::ostream& print(std::ostream& os) const
|
|
{
|
|
os <<" "<< t11 <<' '<< t12 <<' '<< t13 <<' '<< t14 <<"\n";
|
|
os <<" "<< t21 <<' '<< t22 <<' '<< t23 <<' '<< t24 <<"\n";
|
|
os <<" "<< t31 <<' '<< t32 <<' '<< t33 <<' '<< t34 <<")\n";
|
|
|
|
return os;
|
|
}
|
|
private:
|
|
|
|
FT t11, t12, t13, t14;
|
|
FT t21, t22, t23, t24;
|
|
FT t31, t32, t33, t34;
|
|
|
|
};
|
|
|
|
template < class FT >
|
|
class Translation_repS3 : public Aff_transformation_rep_baseS3<FT>
|
|
{
|
|
friend std::ostream& operator<< CGAL_NULL_TMPL_ARGS(
|
|
std::ostream& os, Translation_repS3<FT>& t);
|
|
friend Aff_transformationS3<FT> operator* CGAL_NULL_TMPL_ARGS
|
|
(const Aff_transformationS3<FT>& a,
|
|
const Aff_transformationS3<FT>& b);
|
|
|
|
public:
|
|
Translation_repS3()
|
|
{}
|
|
|
|
Translation_repS3(const VectorS3<FT>& tv) :
|
|
translationvector(tv)
|
|
{}
|
|
|
|
~Translation_repS3()
|
|
{}
|
|
|
|
PointS3<FT> transform(const PointS3<FT>& p) const
|
|
{
|
|
return p + translationvector;
|
|
}
|
|
|
|
VectorS3<FT> transform(const VectorS3<FT>& v) const
|
|
{
|
|
return v;
|
|
}
|
|
|
|
DirectionS3<FT> transform(const DirectionS3<FT>& d) const
|
|
{
|
|
return d;
|
|
}
|
|
|
|
Aff_transformationS3<FT> inverse() const
|
|
{
|
|
return Aff_transformationS3<FT>(TRANSLATION, - translationvector);
|
|
}
|
|
|
|
Aff_transformationS3<FT> transpose() const
|
|
{
|
|
FT ft0(0), ft1(1);
|
|
|
|
return Aff_transformationS3<FT>(ft1, ft0, ft0, ft0,
|
|
ft0, ft1, ft0, ft0,
|
|
ft0, ft0, ft1, ft0);
|
|
}
|
|
|
|
Aff_transformationS3<FT> general_form() const
|
|
{
|
|
FT ft0(0), ft1(1);
|
|
|
|
return Aff_transformationS3<FT>(ft1, ft0, ft0, translationvector.x(),
|
|
ft0, ft1, ft0, translationvector.y(),
|
|
ft0, ft0, ft1, translationvector.z());
|
|
}
|
|
|
|
|
|
virtual bool is_even() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
virtual FT cartesian(int i, int j) const
|
|
{
|
|
if (j==i) return FT(1);
|
|
if (j==3) return translationvector[i];
|
|
return FT(0);
|
|
}
|
|
|
|
std::ostream& print(std::ostream& os) const
|
|
{
|
|
FT ft0(0), ft1(1);
|
|
os << " "<< ft1 <<' '<< ft0 <<' '<< ft0 <<' '
|
|
<< translationvector.x() << "\n";
|
|
|
|
os << " "<< ft0 <<' '<< ft1 <<' '<< ft0 <<' '
|
|
<< translationvector.y() << "\n";
|
|
|
|
os << " "<< ft0 <<' '<< ft0 <<' '<< ft1 <<' '
|
|
<< translationvector.z() << ")\n";
|
|
|
|
return os;
|
|
}
|
|
|
|
private:
|
|
VectorS3<FT> translationvector;
|
|
};
|
|
|
|
template < class FT >
|
|
class Scaling_repS3: public Aff_transformation_rep_baseS3<FT>
|
|
{
|
|
friend std::ostream& operator<< CGAL_NULL_TMPL_ARGS(
|
|
std::ostream& os, Scaling_repS3<FT>& t);
|
|
friend Aff_transformationS3<FT> operator* CGAL_NULL_TMPL_ARGS
|
|
(const Aff_transformationS3<FT>& a,
|
|
const Aff_transformationS3<FT>& b);
|
|
|
|
public:
|
|
Scaling_repS3()
|
|
{}
|
|
|
|
Scaling_repS3(const FT& s) :
|
|
scalefactor(s)
|
|
{}
|
|
|
|
~Scaling_repS3()
|
|
{}
|
|
|
|
PointS3<FT> transform(const PointS3<FT>& p) const
|
|
{
|
|
return PointS3<FT>(scalefactor * p.x(), scalefactor * p.y(),
|
|
scalefactor * p.z());
|
|
}
|
|
|
|
VectorS3<FT> transform(const VectorS3<FT>& v) const
|
|
{
|
|
return VectorS3<FT>(scalefactor * v.x(), scalefactor * v.y(),
|
|
scalefactor * v.z());
|
|
}
|
|
|
|
DirectionS3<FT> transform(const DirectionS3<FT>& d) const
|
|
{
|
|
return d;
|
|
}
|
|
|
|
Aff_transformationS3<FT> inverse() const
|
|
{
|
|
return Aff_transformationS3<FT>(SCALING, FT(1)/scalefactor);
|
|
}
|
|
|
|
Aff_transformationS3<FT> general_form() const
|
|
{
|
|
FT ft0(0);
|
|
|
|
return Aff_transformationS3<FT>(scalefactor, ft0, ft0,
|
|
ft0, scalefactor, ft0,
|
|
ft0, ft0, scalefactor);
|
|
}
|
|
|
|
Aff_transformationS3<FT> transpose() const
|
|
{
|
|
return general_form();
|
|
}
|
|
|
|
virtual bool is_even() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
virtual FT cartesian(int i, int j) const
|
|
{
|
|
if (i!=j) return FT(0);
|
|
if (i==3) return FT(1);
|
|
return scalefactor;
|
|
}
|
|
|
|
|
|
virtual std::ostream& print(std::ostream& os) const
|
|
{
|
|
FT ft0(0);
|
|
os << " "<< scalefactor <<' '<< ft0 <<' '<< ft0 << ' '
|
|
<< ft0 << "\n";
|
|
os << " "<< ft0 <<' '<< scalefactor <<' '<< ft0 << ' '
|
|
<< ft0 << "\n";
|
|
os << " "<< ft0 <<' '<< ft0 <<' '<< scalefactor <<' '
|
|
<< ft0 << ")\n";
|
|
|
|
return os;
|
|
}
|
|
|
|
private:
|
|
FT scalefactor;
|
|
};
|
|
|
|
|
|
template < class FT >
|
|
class Aff_transformationS3 : public Handle
|
|
{
|
|
friend std::ostream& operator<< CGAL_NULL_TMPL_ARGS(std::ostream& os,
|
|
const Aff_transformationS3<FT>& t);
|
|
|
|
friend Aff_transformationS3<FT>
|
|
_general_transformation_composition CGAL_NULL_TMPL_ARGS(
|
|
Aff_transformation_repS3<FT>& l,
|
|
Aff_transformation_repS3<FT>& r );
|
|
friend Aff_transformationS3<FT> operator* CGAL_NULL_TMPL_ARGS
|
|
(const Aff_transformationS3<FT>& a,
|
|
const Aff_transformationS3<FT>& b);
|
|
|
|
|
|
public:
|
|
// default constructor:
|
|
Aff_transformationS3();
|
|
|
|
// Identity
|
|
Aff_transformationS3(const Identity_transformation& );
|
|
|
|
|
|
// Translation:
|
|
Aff_transformationS3(const Translation,
|
|
const VectorS3<FT>& v);
|
|
|
|
// Scaling:
|
|
Aff_transformationS3(const Scaling,
|
|
const FT& s,
|
|
const FT& w = FT(1));
|
|
|
|
// General form:
|
|
Aff_transformationS3(const FT& m11, const FT& m12,
|
|
const FT& m13,
|
|
const FT& m21,
|
|
const FT& m22,
|
|
const FT& m23,
|
|
const FT& m31,
|
|
const FT& m32,
|
|
const FT& m33,
|
|
const FT& w= FT(1));
|
|
|
|
Aff_transformationS3(const FT& m11, const FT& m12,
|
|
const FT& m13, const FT& m14,
|
|
const FT& m21, const FT& m22,
|
|
const FT& m23, const FT& m24,
|
|
const FT& m31, const FT& m32,
|
|
const FT& m33, const FT& m34,
|
|
const FT& w = FT(1));
|
|
|
|
~Aff_transformationS3();
|
|
|
|
PointS3<FT> transform(const PointS3<FT>& p) const;
|
|
PointS3<FT> operator()(const PointS3<FT>& p) const;
|
|
|
|
VectorS3<FT> transform(const VectorS3<FT>& v) const;
|
|
VectorS3<FT> operator()(const VectorS3<FT>& v) const;
|
|
|
|
DirectionS3<FT> transform(const DirectionS3<FT>& d) const;
|
|
DirectionS3<FT> operator()(const DirectionS3<FT>& d) const;
|
|
|
|
|
|
#ifndef CGAL_NO_PLANE_TRANSFORM_IN_AT
|
|
PlaneS3<FT> transform(const PlaneS3<FT>& p) const;
|
|
PlaneS3<FT> operator()(const PlaneS3<FT>& p) const;
|
|
#endif // CGAL_NO_PLANE_TRANSFORM_IN_AT
|
|
|
|
Aff_transformationS3<FT> inverse() const;
|
|
Aff_transformationS3<FT> transpose() const;
|
|
Aff_transformationS3<FT> general_form() const;
|
|
bool is_even() const;
|
|
bool is_odd() const;
|
|
FT cartesian(int i, int j) const { return 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); }
|
|
FT hm(int i, int j) const { return cartesian(i,j); }
|
|
|
|
private:
|
|
Aff_transformation_rep_baseS3<FT>* ptr() const
|
|
{
|
|
return (Aff_transformation_rep_baseS3<FT>*)PTR;
|
|
}
|
|
};
|
|
|
|
template < class FT >
|
|
Aff_transformationS3<FT>::Aff_transformationS3()
|
|
{
|
|
FT ft1(1), ft0(0);
|
|
PTR = new Aff_transformation_repS3<FT>(ft1, ft0, ft0,
|
|
ft0, ft1, ft0,
|
|
ft0, ft0, ft1);
|
|
}
|
|
|
|
template < class FT >
|
|
Aff_transformationS3<FT>::Aff_transformationS3(const Identity_transformation& )
|
|
{
|
|
FT ft1(1), ft0(0);
|
|
PTR = new Aff_transformation_repS3<FT>(ft1, ft0, ft0,
|
|
ft0, ft1, ft0,
|
|
ft0, ft0, ft1);
|
|
}
|
|
|
|
template < class FT >
|
|
Aff_transformationS3<FT>::Aff_transformationS3(const Translation,
|
|
const VectorS3<FT>& v)
|
|
{
|
|
PTR = new Translation_repS3<FT>(v);
|
|
}
|
|
|
|
template < class FT >
|
|
Aff_transformationS3<FT>::Aff_transformationS3(const Scaling,
|
|
const FT& s,
|
|
const FT& w)
|
|
{
|
|
if (w != FT(1))
|
|
PTR = new Scaling_repS3<FT>(s/w);
|
|
else
|
|
PTR = new Scaling_repS3<FT>(s);
|
|
}
|
|
|
|
|
|
template < class FT >
|
|
Aff_transformationS3<FT>::Aff_transformationS3(const FT& m11, const FT& m12,
|
|
const FT& m13, const FT& m14,
|
|
const FT& m21, const FT& m22,
|
|
const FT& m23, const FT& m24,
|
|
const FT& m31, const FT& m32,
|
|
const FT& m33, const FT& m34,
|
|
const FT& w)
|
|
{
|
|
if (w != FT(1))
|
|
PTR = new Aff_transformation_repS3<FT>(m11/w, m12/w, m13/w, m14/w,
|
|
m21/w, m22/w, m23/w, m24/w,
|
|
m31/w, m32/w, m33/w, m34/w);
|
|
else
|
|
PTR = new Aff_transformation_repS3<FT>(m11, m12, m13, m14,
|
|
m21, m22, m23, m24,
|
|
m31, m32, m33, m34);
|
|
}
|
|
|
|
template < class FT >
|
|
Aff_transformationS3<FT>::Aff_transformationS3(
|
|
const FT& m11, const FT& m12, const FT& m13,
|
|
const FT& m21, const FT& m22, const FT& m23,
|
|
const FT& m31, const FT& m32, const FT& m33,
|
|
const FT& w)
|
|
{
|
|
if (w != FT(1))
|
|
PTR = new Aff_transformation_repS3<FT>(m11/w, m12/w, m13/w,
|
|
m21/w, m22/w, m23/w,
|
|
m31/w, m32/w, m33/w);
|
|
else
|
|
PTR = new Aff_transformation_repS3<FT>(m11, m12, m13,
|
|
m21, m22, m23,
|
|
m31, m32, m33);
|
|
}
|
|
|
|
template < class FT >
|
|
Aff_transformationS3<FT>::~Aff_transformationS3()
|
|
{}
|
|
template < class FT >
|
|
PointS3<FT> Aff_transformationS3<FT>::transform(const PointS3<FT>& p) const
|
|
{
|
|
return ptr()->transform(p);
|
|
}
|
|
|
|
template < class FT >
|
|
inline
|
|
PointS3<FT> Aff_transformationS3<FT>::operator()(const PointS3<FT>& p) const
|
|
{
|
|
return transform(p);
|
|
}
|
|
|
|
template < class FT >
|
|
inline
|
|
VectorS3<FT>
|
|
Aff_transformationS3<FT>::transform(const VectorS3<FT>& v) const
|
|
{
|
|
return ptr()->transform(v);
|
|
}
|
|
|
|
template < class FT >
|
|
inline
|
|
VectorS3<FT>
|
|
Aff_transformationS3<FT>::operator()(const VectorS3<FT>& v) const
|
|
{
|
|
return transform(v);
|
|
}
|
|
|
|
template < class FT >
|
|
inline
|
|
DirectionS3<FT>
|
|
Aff_transformationS3<FT>::transform(const DirectionS3<FT>& d) const
|
|
{
|
|
return ptr()->transform(d);
|
|
}
|
|
|
|
template < class FT >
|
|
inline
|
|
DirectionS3<FT>
|
|
Aff_transformationS3<FT>::operator()(const DirectionS3<FT>& d) const
|
|
{
|
|
return transform(d);
|
|
}
|
|
|
|
#ifndef CGAL_NO_PLANE_TRANSFORM_IN_AT
|
|
template < class FT >
|
|
inline
|
|
PlaneS3<FT>
|
|
Aff_transformationS3<FT>::transform(const PlaneS3<FT>& p) const
|
|
{
|
|
return p.transform(*this);
|
|
}
|
|
|
|
template < class FT >
|
|
inline
|
|
PlaneS3<FT>
|
|
Aff_transformationS3<FT>::operator()(const PlaneS3<FT>& p) const
|
|
{
|
|
return transform(p);
|
|
}
|
|
#endif // CGAL_NO_PLANE_TRANSFORM_IN_AT
|
|
|
|
template < class FT >
|
|
Aff_transformationS3<FT> Aff_transformationS3<FT>::inverse() const
|
|
{
|
|
return ptr()->inverse();
|
|
}
|
|
|
|
|
|
template < class FT >
|
|
Aff_transformationS3<FT> Aff_transformationS3<FT>::general_form() const
|
|
{
|
|
return ptr()->general_form();
|
|
}
|
|
|
|
template < class FT >
|
|
Aff_transformationS3<FT> Aff_transformationS3<FT>::transpose() const
|
|
{
|
|
return ptr()->transpose();
|
|
}
|
|
|
|
template < class FT >
|
|
bool Aff_transformationS3<FT>::is_even() const
|
|
{
|
|
return ptr()->is_even();
|
|
}
|
|
|
|
template < class FT >
|
|
bool Aff_transformationS3<FT>::is_odd() const
|
|
{
|
|
return ! (ptr()->is_even());
|
|
}
|
|
|
|
|
|
|
|
template < class FT >
|
|
Aff_transformationS3<FT>
|
|
_general_transformation_composition(Aff_transformation_repS3<FT>& l,
|
|
Aff_transformation_repS3<FT>& r )
|
|
{
|
|
return Aff_transformationS3<FT>(
|
|
l.t11*r.t11 + l.t12*r.t21 + l.t13*r.t31,
|
|
l.t11*r.t12 + l.t12*r.t22 + l.t13*r.t32,
|
|
l.t11*r.t13 + l.t12*r.t23 + l.t13*r.t33,
|
|
l.t11*r.t14 + l.t12*r.t24 + l.t13*r.t34 + l.t14,
|
|
|
|
l.t21*r.t11 + l.t22*r.t21 + l.t23*r.t31,
|
|
l.t21*r.t12 + l.t22*r.t22 + l.t23*r.t32,
|
|
l.t21*r.t13 + l.t22*r.t23 + l.t23*r.t33,
|
|
l.t21*r.t14 + l.t22*r.t24 + l.t23*r.t34 + l.t24,
|
|
|
|
l.t31*r.t11 + l.t32*r.t21 + l.t33*r.t31,
|
|
l.t31*r.t12 + l.t32*r.t22 + l.t33*r.t32,
|
|
l.t31*r.t13 + l.t32*r.t23 + l.t33*r.t33,
|
|
l.t31*r.t14 + l.t32*r.t24 + l.t33*r.t34 + l.t34);
|
|
}
|
|
|
|
|
|
// this is really quick and dirty. As in the 2D case the composition of
|
|
// translations or scalings should be a translation or a scaling
|
|
template < class FT >
|
|
Aff_transformationS3<FT> operator*(const Aff_transformationS3<FT>& a,
|
|
const Aff_transformationS3<FT>& b)
|
|
{
|
|
return _general_transformation_composition(
|
|
*(Aff_transformation_repS3<FT>*)(a.general_form().ptr()),
|
|
*(Aff_transformation_repS3<FT>*)(b.general_form().ptr()));
|
|
}
|
|
|
|
|
|
#ifndef CGAL_NO_OSTREAM_INSERT_AFF_TRANSFORMATIONS3
|
|
template < class FT >
|
|
std::ostream& operator<<(std::ostream& os, const Aff_transformationS3<FT>& t)
|
|
{
|
|
t.print(os);
|
|
return os;
|
|
}
|
|
#endif // CGAL_NO_OSTREAM_INSERT_AFF_TRANSFORMATIONS3
|
|
|
|
#ifndef CGAL_NO_ISTREAM_EXTRACT_AFF_TRANSFORMATIONS3
|
|
#endif // CGAL_NO_ISTREAM_EXTRACT_AFF_TRANSFORMATIONS3
|
|
|
|
|
|
|
|
CGAL_END_NAMESPACE
|
|
|
|
#endif // CGAL_AFF_TRANSFORMATIONS3_H
|