mirror of https://github.com/CGAL/cgal
959 lines
26 KiB
C++
959 lines
26 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, August 16
|
|
//
|
|
// source : webS2/S2.lw
|
|
// file : include/CGAL/SimpleCartesian/Aff_transformationS2.h
|
|
// package : S2 (1.7)
|
|
// maintainer : Stefan Schirra <stschirr@mpi-sb.mpg.de>
|
|
// revision : 1.6
|
|
// revision_date : 27 Jun 2000
|
|
// author(s) : Stefan Schirra
|
|
// based on code by
|
|
// Andreas Fabri and
|
|
// Herve Brönnimann
|
|
//
|
|
// coordinator : MPI, Saarbrücken
|
|
// ======================================================================
|
|
|
|
|
|
#ifndef CGAL_AFF_TRANSFORMATIONS2_H
|
|
#define CGAL_AFF_TRANSFORMATIONS2_H
|
|
|
|
#include <CGAL/config.h>
|
|
#include <cmath>
|
|
#include <CGAL/rational_rotation.h>
|
|
#include <CGAL/Handle.h>
|
|
#include <CGAL/SimpleCartesian/simple_cartesian_classes.h>
|
|
#include <CGAL/determinant.h>
|
|
|
|
#if defined(CGAL_CFG_INCOMPLETE_TYPE_BUG_1) && \
|
|
!defined(CGAL_NO_LINE_TRANSFORM_IN_AT)
|
|
#define CGAL_NO_LINE_TRANSFORM_IN_AT
|
|
#endif // CGAL_CFG_INCOMPLETE_TYPE_BUG_1
|
|
|
|
|
|
CGAL_BEGIN_NAMESPACE
|
|
|
|
template < class FT >
|
|
class Translation_repS2;
|
|
|
|
template < class FT >
|
|
class Rotation_repS2;
|
|
|
|
template < class FT >
|
|
class Scaling_repS2;
|
|
|
|
template < class FT >
|
|
class Aff_transformation_repS2;
|
|
|
|
|
|
template < class FT >
|
|
class Aff_transformation_rep_baseS2 : public Rep
|
|
{
|
|
public:
|
|
virtual ~Aff_transformation_rep_baseS2() {}
|
|
|
|
virtual PointS2<FT>
|
|
transform(const PointS2<FT>& p) const = 0;
|
|
|
|
virtual VectorS2<FT>
|
|
transform(const VectorS2<FT>& v) const = 0;
|
|
|
|
virtual DirectionS2<FT>
|
|
transform(const DirectionS2<FT>& d) const=0;
|
|
|
|
#ifdef CGAL_CFG_INCOMPLETE_TYPE_BUG_3
|
|
virtual Aff_transformationS2<FT>
|
|
general_form() const = 0;
|
|
#else
|
|
virtual Aff_transformationS2<FT>
|
|
operator*( const Aff_transformation_rep_baseS2<FT>& t) = 0;
|
|
|
|
virtual Aff_transformationS2<FT>
|
|
compose( const Translation_repS2<FT>& t) const = 0;
|
|
|
|
virtual Aff_transformationS2<FT>
|
|
compose( const Rotation_repS2<FT>& t) const = 0;
|
|
|
|
virtual Aff_transformationS2<FT>
|
|
compose( const Scaling_repS2<FT>& t) const = 0;
|
|
|
|
virtual Aff_transformationS2<FT>
|
|
compose( const Aff_transformation_repS2<FT>& t) const = 0;
|
|
#endif // CGAL_CFG_INCOMPLETE_TYPE_BUG_3
|
|
virtual Aff_transformationS2<FT>
|
|
inverse() const = 0;
|
|
|
|
virtual bool
|
|
is_even() const = 0;
|
|
|
|
virtual FT
|
|
cartesian(int i, int j) const = 0;
|
|
|
|
};
|
|
|
|
|
|
template < class FT >
|
|
class Aff_transformation_repS2 : public Aff_transformation_rep_baseS2<FT>
|
|
{
|
|
friend class Translation_repS2<FT>;
|
|
friend class Rotation_repS2<FT>;
|
|
friend class Scaling_repS2<FT>;
|
|
friend class Aff_transformationS2<FT>;
|
|
|
|
public:
|
|
|
|
Aff_transformation_repS2()
|
|
{}
|
|
|
|
Aff_transformation_repS2( const FT& m11, const FT& m12,
|
|
const FT& m21, const FT& m22)
|
|
: t11(m11), t12(m12), t13(0),
|
|
t21(m21), t22(m22), t23(0)
|
|
{}
|
|
|
|
Aff_transformation_repS2( const FT& m11, const FT& m12, const FT& m13,
|
|
const FT& m21, const FT& m22, const FT& m23)
|
|
: t11(m11), t12(m12), t13(m13),
|
|
t21(m21), t22(m22), t23(m23)
|
|
{}
|
|
|
|
~Aff_transformation_repS2()
|
|
{}
|
|
|
|
PointS2<FT> transform(const PointS2<FT>& p) const
|
|
{
|
|
return PointS2<FT>(t11 * p.x() + t12 * p.y() + t13,
|
|
t21 * p.x() + t22 * p.y() + t23);
|
|
}
|
|
|
|
|
|
// note that a vector is not translated
|
|
VectorS2<FT> transform(const VectorS2<FT>& v) const
|
|
{
|
|
return VectorS2<FT>(t11 * v.x() + t12 * v.y(),
|
|
t21 * v.x() + t22 * v.y());
|
|
}
|
|
|
|
|
|
// note that a direction is not translated
|
|
DirectionS2<FT> transform(const DirectionS2<FT>& dir) const
|
|
{
|
|
VectorS2<FT> v = dir.vector();
|
|
return DirectionS2<FT>(t11 * v.x() + t12 * v.y(),
|
|
t21 * v.x() + t22 * v.y());
|
|
}
|
|
|
|
Aff_transformationS2<FT> inverse() const
|
|
{
|
|
FT det = FT(1) / (t11 * t22 - t12 * t21);
|
|
|
|
return Aff_transformationS2<FT>(
|
|
det * t22, det * (-t12), det * (t12*t23-t13*t22),
|
|
det * (-t21), det * t11 , det * (t13*t21-t11*t23));
|
|
}
|
|
|
|
#ifdef CGAL_CFG_INCOMPLETE_TYPE_BUG_3
|
|
|
|
Aff_transformationS2<FT> general_form() const
|
|
{
|
|
return Aff_transformationS2<FT>(t11, t12, t13,
|
|
t21, t22, t23);
|
|
}
|
|
|
|
#else
|
|
Aff_transformationS2<FT> operator*(
|
|
const Aff_transformation_rep_baseS2<FT>& t)
|
|
{
|
|
return t.compose(*this);
|
|
}
|
|
|
|
Aff_transformationS2<FT> compose( const Translation_repS2<FT>& t) const
|
|
{
|
|
return Aff_transformationS2<FT>(t11,
|
|
t12,
|
|
t13 + t._translationvector.x(),
|
|
t21,
|
|
t22,
|
|
t23 + t._translationvector.y());
|
|
}
|
|
|
|
virtual Aff_transformationS2<FT> compose( const Rotation_repS2<FT>& t) const
|
|
{
|
|
return Aff_transformationS2<FT>(t._cosinus*t11 - t._sinus*t21,
|
|
t._cosinus*t12 - t._sinus*t22,
|
|
t._cosinus*t13 - t._sinus*t23,
|
|
t._sinus*t11 + t._cosinus*t21,
|
|
t._sinus*t12 + t._cosinus*t22,
|
|
t._sinus*t13 + t._cosinus*t23);
|
|
}
|
|
|
|
virtual Aff_transformationS2<FT> compose( const Scaling_repS2<FT>& t) const
|
|
{
|
|
return Aff_transformationS2<FT>(t._scalefactor * t11,
|
|
t._scalefactor * t12,
|
|
t._scalefactor * t13,
|
|
t._scalefactor * t21,
|
|
t._scalefactor * t22,
|
|
t._scalefactor * t23);
|
|
}
|
|
|
|
virtual Aff_transformationS2<FT> compose(
|
|
const Aff_transformation_repS2<FT>& t) const
|
|
{
|
|
return Aff_transformationS2<FT>(t.t11*t11 + t.t12*t21,
|
|
t.t11*t12 + t.t12*t22,
|
|
t.t11*t13 + t.t12*t23 + t.t13,
|
|
t.t21*t11 + t.t22*t21,
|
|
t.t21*t12 + t.t22*t22,
|
|
t.t21*t13 + t.t22*t23 + t.t23 );
|
|
}
|
|
#endif // CGAL_CFG_INCOMPLETE_TYPE_BUG_3
|
|
|
|
virtual bool is_even() const
|
|
{
|
|
return sign_of_determinant2x2(t11, t12, t21, t22) == 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 1: switch (j)
|
|
{
|
|
case 0: return t21;
|
|
case 1: return t22;
|
|
case 2: return t23;
|
|
}
|
|
case 2: switch (j)
|
|
{
|
|
case 0: return FT(0);
|
|
case 1: return FT(0);
|
|
case 2: return FT(1);
|
|
}
|
|
}
|
|
return FT(0);
|
|
}
|
|
|
|
virtual std::ostream& print(std::ostream &os) const
|
|
{
|
|
os << "Aff_transformationS2(" << t11 << " " << t12 << " " << t13 << std::endl;
|
|
os << " " << t21 << " " << t22 << " " << t23 << ")";
|
|
return os;
|
|
}
|
|
|
|
private:
|
|
FT t11, t12, t13;
|
|
FT t21, t22, t23;
|
|
};
|
|
|
|
template < class FT >
|
|
class Translation_repS2 : public Aff_transformation_rep_baseS2<FT>
|
|
{
|
|
friend class Aff_transformation_repS2<FT>;
|
|
friend class Rotation_repS2<FT>;
|
|
friend class Scaling_repS2<FT>;
|
|
public:
|
|
Translation_repS2()
|
|
{}
|
|
|
|
Translation_repS2(const VectorS2<FT>& tv) : _translationvector(tv)
|
|
{}
|
|
|
|
~Translation_repS2()
|
|
{}
|
|
|
|
PointS2<FT>
|
|
transform(const PointS2<FT>& p) const
|
|
{ return p + _translationvector; }
|
|
|
|
VectorS2<FT>
|
|
transform(const VectorS2<FT>& v) const
|
|
{ return v; }
|
|
|
|
DirectionS2<FT>
|
|
transform(const DirectionS2<FT>& d) const
|
|
{ return d; }
|
|
|
|
#ifdef CGAL_CFG_INCOMPLETE_TYPE_BUG_3
|
|
|
|
Aff_transformationS2<FT> general_form() const
|
|
{
|
|
return Aff_transformationS2<FT>(FT(1), FT(0), _translationvector.x(),
|
|
FT(0), FT(1), _translationvector.y());
|
|
}
|
|
|
|
#else
|
|
Aff_transformationS2<FT> operator*(
|
|
const Aff_transformation_rep_baseS2<FT>& t)
|
|
{
|
|
return t.compose(*this);
|
|
}
|
|
|
|
Aff_transformationS2<FT> compose(
|
|
const Translation_repS2<FT>& t) const
|
|
{
|
|
return Aff_transformationS2<FT>(TRANSLATION,
|
|
_translationvector +
|
|
t._translationvector);
|
|
}
|
|
|
|
virtual Aff_transformationS2<FT> compose(
|
|
const Rotation_repS2<FT>& t) const
|
|
{
|
|
return Aff_transformationS2<FT>(t._cosinus,
|
|
-t._sinus,
|
|
t._cosinus*_translationvector.x() -
|
|
t._sinus*_translationvector.y(),
|
|
|
|
t._sinus,
|
|
t._cosinus,
|
|
t._sinus*_translationvector.x() +
|
|
t._cosinus*_translationvector.y());
|
|
}
|
|
|
|
virtual Aff_transformationS2<FT> compose(
|
|
const Scaling_repS2<FT>& t) const
|
|
{
|
|
return Aff_transformationS2<FT>(t._scalefactor,
|
|
FT(0),
|
|
t._scalefactor*_translationvector.x(),
|
|
|
|
FT(0),
|
|
t._scalefactor,
|
|
t._scalefactor*_translationvector.y());
|
|
}
|
|
|
|
virtual Aff_transformationS2<FT> compose(
|
|
const Aff_transformation_repS2<FT>& t) const
|
|
{
|
|
return Aff_transformationS2<FT>(t.t11,
|
|
t.t12,
|
|
t.t11 * _translationvector.x()
|
|
+ t.t12 * _translationvector.y()
|
|
+ t.t13,
|
|
|
|
t.t21,
|
|
t.t22,
|
|
t.t21 * _translationvector.x()
|
|
+ t.t22*_translationvector.y()
|
|
+ t.t23);
|
|
}
|
|
#endif // CGAL_CFG_INCOMPLETE_TYPE_BUG_3
|
|
|
|
Aff_transformationS2<FT> inverse() const
|
|
{
|
|
return Aff_transformationS2<FT>(TRANSLATION,
|
|
- _translationvector);
|
|
}
|
|
|
|
virtual bool is_even() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
virtual FT cartesian(int i, int j) const
|
|
{
|
|
if (j==i) return FT(1);
|
|
if (j==2) return _translationvector[i];
|
|
return FT(0);
|
|
}
|
|
|
|
virtual std::ostream& print(std::ostream &os) const
|
|
{
|
|
os << "Aff_transformationS2(VectorS2(" << _translationvector.x() << ", "
|
|
<< _translationvector.y() << "))";
|
|
return os;
|
|
}
|
|
|
|
private:
|
|
VectorS2<FT> _translationvector;
|
|
};
|
|
|
|
template < class FT >
|
|
class Rotation_repS2: public Aff_transformation_rep_baseS2<FT>
|
|
{
|
|
friend class Aff_transformation_repS2<FT>;
|
|
friend class Translation_repS2<FT>;
|
|
friend class Scaling_repS2<FT>;
|
|
public:
|
|
Rotation_repS2()
|
|
{}
|
|
|
|
Rotation_repS2(const FT& sinus, const FT &cosinus)
|
|
: _sinus(sinus), _cosinus(cosinus)
|
|
{}
|
|
|
|
Rotation_repS2(const DirectionS2<FT>& d,
|
|
const FT& eps_num,
|
|
const FT& eps_den = FT(1))
|
|
{
|
|
FT sin_num;
|
|
FT cos_num;
|
|
FT denom;
|
|
|
|
rational_rotation_approximation(d.vector().x(),
|
|
d.vector().y(),
|
|
sin_num,
|
|
cos_num,
|
|
denom,
|
|
eps_num,
|
|
eps_den);
|
|
_sinus = sin_num/denom;
|
|
_cosinus = cos_num/denom;
|
|
}
|
|
|
|
~Rotation_repS2()
|
|
{}
|
|
|
|
PointS2<FT> transform(const PointS2<FT>& p) const
|
|
{
|
|
return PointS2<FT>(_cosinus * p.x() - _sinus * p.y(),
|
|
_sinus * p.x() + _cosinus * p.y());
|
|
}
|
|
|
|
VectorS2<FT> transform(const VectorS2<FT>& v) const
|
|
{
|
|
return VectorS2<FT>(_cosinus * v.x() - _sinus * v.y(),
|
|
_sinus * v.x() + _cosinus * v.y());
|
|
}
|
|
|
|
DirectionS2<FT> transform(const DirectionS2<FT>& d) const
|
|
{
|
|
VectorS2<FT> v = d.vector();
|
|
return DirectionS2<FT>(_cosinus * v.x() - _sinus * v.y(),
|
|
_sinus * v.x() + _cosinus * v.y());
|
|
}
|
|
|
|
Aff_transformationS2<FT> inverse() const
|
|
{
|
|
return Aff_transformationS2<FT>(ROTATION,
|
|
- _sinus, _cosinus, FT(1));
|
|
}
|
|
#ifdef CGAL_CFG_INCOMPLETE_TYPE_BUG_3
|
|
|
|
Aff_transformationS2<FT> general_form() const
|
|
{
|
|
return Aff_transformationS2<FT>(_cosinus, - _sinus, FT(0),
|
|
_sinus, _cosinus, FT(0));
|
|
}
|
|
|
|
#else
|
|
|
|
Aff_transformationS2<FT> operator*(
|
|
const Aff_transformation_rep_baseS2<FT>& t)
|
|
{
|
|
return t.compose(*this);
|
|
}
|
|
|
|
Aff_transformationS2<FT> compose(
|
|
const Translation_repS2<FT>& t) const
|
|
{
|
|
return Aff_transformationS2<FT>(_cosinus,
|
|
-_sinus,
|
|
t._translationvector.x(),
|
|
|
|
_sinus,
|
|
_cosinus,
|
|
t._translationvector.y());
|
|
}
|
|
|
|
|
|
virtual Aff_transformationS2<FT> compose(
|
|
const Rotation_repS2<FT>& t) const
|
|
{
|
|
return Aff_transformationS2<FT>(ROTATION,
|
|
t._sinus*_cosinus + t._cosinus*_sinus,
|
|
t._cosinus*_cosinus-t._sinus*_sinus );
|
|
}
|
|
|
|
virtual Aff_transformationS2<FT> compose(
|
|
const Scaling_repS2<FT>& t) const
|
|
{
|
|
return Aff_transformationS2<FT>(t._scalefactor*_cosinus,
|
|
t._scalefactor*-_sinus,
|
|
|
|
t._scalefactor*_sinus,
|
|
t._scalefactor*_cosinus);
|
|
}
|
|
|
|
virtual Aff_transformationS2<FT> compose(
|
|
const Aff_transformation_repS2<FT>& t) const
|
|
{
|
|
return Aff_transformationS2<FT>(_cosinus*t.t11 + _sinus*t.t12,
|
|
-_sinus*t.t11 + _cosinus*t.t12,
|
|
t.t13,
|
|
|
|
_cosinus*t.t21 + _sinus*t.t22,
|
|
-_sinus*t.t21 + _cosinus*t.t22,
|
|
t.t23);
|
|
}
|
|
#endif // CGAL_CFG_INCOMPLETE_TYPE_BUG_3
|
|
|
|
virtual bool is_even() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
virtual FT cartesian(int i, int j) const
|
|
{
|
|
switch (i)
|
|
{
|
|
case 0: switch (j)
|
|
{
|
|
case 0: return _cosinus;
|
|
case 1: return -_sinus;
|
|
case 2: return FT(0);
|
|
}
|
|
case 1: switch (j)
|
|
{
|
|
case 0: return _sinus;
|
|
case 1: return _cosinus;
|
|
case 2: return FT(0);
|
|
}
|
|
case 2: switch (j)
|
|
{
|
|
case 0: return FT(0);
|
|
case 1: return FT(0);
|
|
case 2: return FT(1);
|
|
}
|
|
}
|
|
return FT(0);
|
|
}
|
|
|
|
virtual std::ostream& print(std::ostream &os) const
|
|
{
|
|
os << "Aff_transformationS2(" << _sinus << ", " << _cosinus << ")";
|
|
return os;
|
|
}
|
|
|
|
private:
|
|
FT _sinus;
|
|
FT _cosinus;
|
|
};
|
|
|
|
template < class FT >
|
|
class Scaling_repS2: public Aff_transformation_rep_baseS2<FT>
|
|
{
|
|
friend class Aff_transformation_repS2<FT>;
|
|
friend class Rotation_repS2<FT>;
|
|
friend class Translation_repS2<FT>;
|
|
|
|
public:
|
|
Scaling_repS2()
|
|
{}
|
|
|
|
Scaling_repS2(const FT& scalefactor) :
|
|
_scalefactor(scalefactor)
|
|
{}
|
|
|
|
~Scaling_repS2()
|
|
{}
|
|
|
|
PointS2<FT> transform(const PointS2<FT>& p) const
|
|
{
|
|
return PointS2<FT>(_scalefactor * p.x(), _scalefactor * p.y());
|
|
}
|
|
|
|
VectorS2<FT> transform(const VectorS2<FT>& p) const
|
|
{
|
|
return VectorS2<FT>(_scalefactor * p.x(), _scalefactor * p.y());
|
|
}
|
|
|
|
DirectionS2<FT> transform(const DirectionS2<FT>& d) const
|
|
{
|
|
return d;
|
|
}
|
|
|
|
#ifdef CGAL_CFG_INCOMPLETE_TYPE_BUG_3
|
|
|
|
Aff_transformationS2<FT> general_form() const
|
|
{
|
|
return Aff_transformationS2<FT>(_scalefactor, FT(0), FT(0),
|
|
FT(0), _scalefactor, FT(0));
|
|
}
|
|
|
|
#else
|
|
Aff_transformationS2<FT> operator*(
|
|
const Aff_transformation_rep_baseS2<FT>& t)
|
|
{
|
|
return t.compose(*this);
|
|
}
|
|
|
|
Aff_transformationS2<FT> compose(const Translation_repS2<FT>& t) const
|
|
{
|
|
FT ft0(0);
|
|
|
|
return Aff_transformationS2<FT>(_scalefactor,
|
|
ft0,
|
|
t._translationvector.x(),
|
|
|
|
ft0,
|
|
_scalefactor,
|
|
t._translationvector.y());
|
|
}
|
|
|
|
virtual Aff_transformationS2<FT> compose(const Rotation_repS2<FT>& t) const
|
|
{
|
|
return Aff_transformationS2<FT>(_scalefactor * t._cosinus,
|
|
_scalefactor * -t._sinus,
|
|
|
|
_scalefactor * t._sinus,
|
|
_scalefactor * t._cosinus);
|
|
}
|
|
|
|
virtual Aff_transformationS2<FT> compose(const Scaling_repS2<FT>& t) const
|
|
{
|
|
return Aff_transformationS2<FT>(SCALING, _scalefactor*t._scalefactor);
|
|
}
|
|
|
|
virtual Aff_transformationS2<FT> compose(
|
|
const Aff_transformation_repS2<FT>& t) const
|
|
{
|
|
return Aff_transformationS2<FT>(_scalefactor * t.t11,
|
|
_scalefactor * t.t12,
|
|
t.t13,
|
|
|
|
_scalefactor * t.t21,
|
|
_scalefactor * t.t22,
|
|
t.t23);
|
|
}
|
|
#endif // CGAL_CFG_INCOMPLETE_TYPE_BUG_3
|
|
|
|
Aff_transformationS2<FT> inverse() const
|
|
{
|
|
return Aff_transformationS2<FT>(SCALING, FT(1)/_scalefactor);
|
|
}
|
|
|
|
virtual bool is_even() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
virtual FT cartesian(int i, int j) const
|
|
{
|
|
if (i!=j) return FT(0);
|
|
return (i==2) ? FT(1) : _scalefactor;
|
|
}
|
|
|
|
virtual std::ostream& print(std::ostream &os) const
|
|
{
|
|
os << "Aff_transformationS2(" << _scalefactor << ")";
|
|
return os;
|
|
}
|
|
|
|
private:
|
|
FT _scalefactor;
|
|
};
|
|
|
|
|
|
template < class FT >
|
|
class Aff_transformationS2 : public Handle
|
|
{
|
|
|
|
|
|
public:
|
|
Aff_transformationS2();
|
|
|
|
Aff_transformationS2(const Identity_transformation& );
|
|
|
|
Aff_transformationS2(const Aff_transformationS2<FT>& t);
|
|
|
|
// Translation:
|
|
Aff_transformationS2(const Translation,
|
|
const VectorS2<FT>& v);
|
|
|
|
// Rational Rotation:
|
|
Aff_transformationS2(const Rotation,
|
|
const DirectionS2<FT>& d,
|
|
const FT& num,
|
|
const FT& den = FT(1));
|
|
|
|
Aff_transformationS2(const Rotation,
|
|
const FT& sine_rho,
|
|
const FT& cosine_rho,
|
|
const FT& hw = FT(1));
|
|
|
|
// Scaling:
|
|
Aff_transformationS2(const Scaling,
|
|
const FT& s,
|
|
const FT& w = FT(1));
|
|
|
|
// The general case:
|
|
Aff_transformationS2(const FT& m11,
|
|
const FT& m12,
|
|
const FT& m13,
|
|
const FT& m21,
|
|
const FT& m22,
|
|
const FT& m23,
|
|
const FT& w = FT(1));
|
|
|
|
Aff_transformationS2(const FT& m11, const FT & m12,
|
|
const FT& m21, const FT & m22,
|
|
const FT& w = FT(1));
|
|
|
|
~Aff_transformationS2();
|
|
|
|
PointS2<FT> transform(const PointS2<FT>& p) const;
|
|
PointS2<FT> operator()(const PointS2<FT>& p) const;
|
|
|
|
VectorS2<FT> transform(const VectorS2<FT>& p) const;
|
|
VectorS2<FT> operator()(const VectorS2<FT>& p) const;
|
|
|
|
DirectionS2<FT> transform(const DirectionS2<FT>& d) const;
|
|
DirectionS2<FT> operator()(const DirectionS2<FT>& d) const;
|
|
|
|
#ifndef CGAL_NO_LINE_TRANSFORM_IN_AT
|
|
LineS2<FT> transform(const LineS2<FT>& l) const;
|
|
LineS2<FT> operator()(const LineS2<FT>& l) const;
|
|
#endif // CGAL_NO_LINE_TRANSFORM_IN_AT
|
|
|
|
Aff_transformationS2<FT> inverse() const;
|
|
|
|
bool is_even() const { return ptr()->is_even(); }
|
|
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); }
|
|
|
|
#ifdef CGAL_CFG_INCOMPLETE_TYPE_BUG_3
|
|
|
|
Aff_transformationS2<FT> general_form() const
|
|
{
|
|
return ptr()->general_form();
|
|
}
|
|
|
|
|
|
Aff_transformationS2<FT> operator*(const Aff_transformationS2<FT>& t) const
|
|
{
|
|
Aff_transformationS2<FT> tt1 = general_form(), tt2 = t.general_form();
|
|
Aff_transformation_repS2<FT> *t1 = (Aff_transformation_repS2<FT>*)tt1.ptr();
|
|
|
|
Aff_transformation_repS2<FT> *t2 = (Aff_transformation_repS2<FT>*)tt2.ptr();
|
|
|
|
return Aff_transformationS2<FT>(
|
|
t1->t11*t2->t11 + t1->t12*t2->t21,
|
|
t1->t11*t2->t12 + t1->t12*t2->t22,
|
|
t1->t11*t2->t13 + t1->t12*t2->t23 + t1->t13,
|
|
|
|
t1->t21*t2->t11 + t1->t22*t2->t21,
|
|
t1->t21*t2->t12 + t1->t22*t2->t22,
|
|
t1->t21*t2->t13 + t1->t22*t2->t23 + t1->t23 );
|
|
}
|
|
|
|
#else
|
|
|
|
Aff_transformationS2<FT> operator*(const Aff_transformationS2<FT>& t) const
|
|
{
|
|
return (*ptr()) * (*t.ptr());
|
|
}
|
|
|
|
#endif // CGAL_CFG_INCOMPLETE_TYPE_BUG_3
|
|
|
|
std::ostream & print(std::ostream &os) const;
|
|
|
|
private:
|
|
Aff_transformation_rep_baseS2<FT>* ptr() const
|
|
{
|
|
return (Aff_transformation_rep_baseS2<FT>*)PTR;
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template < class FT >
|
|
Aff_transformationS2<FT>::Aff_transformationS2()
|
|
{ PTR = new Aff_transformation_repS2<FT>(FT(1), FT(0), FT(0), FT(1)); }
|
|
|
|
template < class FT >
|
|
Aff_transformationS2<FT>::Aff_transformationS2(const Identity_transformation& )
|
|
{ PTR = new Aff_transformation_repS2<FT>(FT(1), FT(0), FT(0), FT(1)); }
|
|
|
|
template < class FT >
|
|
Aff_transformationS2<FT>::Aff_transformationS2( const Aff_transformationS2<FT>& t)
|
|
: Handle(t)
|
|
{}
|
|
|
|
|
|
template < class FT >
|
|
Aff_transformationS2<FT>::Aff_transformationS2(const FT& m11,
|
|
const FT& m12,
|
|
const FT& m21,
|
|
const FT& m22,
|
|
const FT& w)
|
|
{
|
|
if (w != FT(1))
|
|
PTR = new Aff_transformation_repS2<FT>(m11/w, m12/w, m21/w, m22/w);
|
|
else
|
|
PTR = new Aff_transformation_repS2<FT>(m11, m12, m21, m22);
|
|
}
|
|
|
|
template < class FT >
|
|
Aff_transformationS2<FT>::Aff_transformationS2(const Translation,
|
|
const VectorS2<FT>& v)
|
|
{ PTR = new Translation_repS2<FT>(v); }
|
|
|
|
template < class FT >
|
|
Aff_transformationS2<FT>::Aff_transformationS2(const Rotation,
|
|
const DirectionS2<FT>& d,
|
|
const FT& num,
|
|
const FT& den)
|
|
{ PTR = new Rotation_repS2<FT>(d, num, den); }
|
|
|
|
|
|
template < class FT >
|
|
Aff_transformationS2<FT>::Aff_transformationS2(const Rotation,
|
|
const FT& sine,
|
|
const FT &cosine,
|
|
const FT &w)
|
|
{
|
|
if (w != FT(1))
|
|
PTR = new Rotation_repS2<FT>(sine/w, cosine/w);
|
|
else
|
|
PTR = new Rotation_repS2<FT>(sine, cosine);
|
|
}
|
|
|
|
template < class FT >
|
|
Aff_transformationS2<FT>::Aff_transformationS2(const Scaling,
|
|
const FT& s,
|
|
const FT& w)
|
|
{
|
|
if (w != FT(1))
|
|
PTR = new Scaling_repS2<FT>(s/w);
|
|
else
|
|
PTR = new Scaling_repS2<FT>(s);
|
|
}
|
|
|
|
|
|
|
|
template < class FT >
|
|
Aff_transformationS2<FT>::Aff_transformationS2(
|
|
const FT& m11, const FT & m12, const FT & m13,
|
|
const FT& m21, const FT & m22, const FT & m23,
|
|
const FT& w)
|
|
{
|
|
if (w != FT(1))
|
|
PTR = new Aff_transformation_repS2<FT>(m11/w, m12/w, m13/w,
|
|
m21/w, m22/w, m23/w);
|
|
else
|
|
PTR = new Aff_transformation_repS2<FT>(m11, m12, m13,
|
|
m21, m22, m23);
|
|
}
|
|
|
|
template < class FT >
|
|
Aff_transformationS2<FT>::~Aff_transformationS2()
|
|
{}
|
|
|
|
|
|
template < class FT >
|
|
PointS2<FT>
|
|
Aff_transformationS2<FT>::transform(const PointS2<FT>& p) const
|
|
{ return ptr()->transform(p); }
|
|
|
|
template < class FT >
|
|
inline
|
|
PointS2<FT>
|
|
Aff_transformationS2<FT>::operator()(const PointS2<FT>& p) const
|
|
{ return transform(p); }
|
|
|
|
template < class FT >
|
|
VectorS2<FT>
|
|
Aff_transformationS2<FT>::transform(const VectorS2<FT>& p) const
|
|
{ return ptr()->transform(p); }
|
|
|
|
template < class FT >
|
|
inline
|
|
VectorS2<FT>
|
|
Aff_transformationS2<FT>::operator()(const VectorS2<FT>& p) const
|
|
{ return transform(p); }
|
|
|
|
template < class FT >
|
|
DirectionS2<FT>
|
|
Aff_transformationS2<FT>::transform(const DirectionS2<FT>& d) const
|
|
{ return ptr()->transform(d); }
|
|
|
|
template < class FT >
|
|
inline
|
|
DirectionS2<FT>
|
|
Aff_transformationS2<FT>::operator()(const DirectionS2<FT>& d) const
|
|
{ return transform(d); }
|
|
|
|
#ifndef CGAL_NO_LINE_TRANSFORM_IN_AT
|
|
template < class FT >
|
|
inline
|
|
LineS2<FT>
|
|
Aff_transformationS2<FT>::transform(const LineS2<FT>& l) const
|
|
{
|
|
return LineS2<FT>(ptr()->transform(l.point(0)),
|
|
ptr()->transform(l.direction()));
|
|
}
|
|
|
|
template < class FT >
|
|
inline
|
|
LineS2<FT>
|
|
Aff_transformationS2<FT>::operator()(const LineS2<FT>& l) const
|
|
{ return transform(l); }
|
|
#endif // CGAL_NO_LINE_TRANSFORM_IN_AT
|
|
|
|
template < class FT >
|
|
Aff_transformationS2<FT>
|
|
Aff_transformationS2<FT>::inverse() const
|
|
{
|
|
return ptr()->inverse();
|
|
}
|
|
|
|
|
|
template < class FT >
|
|
bool
|
|
Aff_transformationS2<FT>::is_odd() const
|
|
{
|
|
return ! (ptr()->is_even());
|
|
}
|
|
|
|
|
|
template < class FT >
|
|
std::ostream&
|
|
Aff_transformationS2<FT>::print(std::ostream& os) const
|
|
{
|
|
ptr()->print(os);
|
|
return os;
|
|
}
|
|
|
|
|
|
#ifndef CGAL_NO_OSTREAM_INSERT_AFF_TRANSFORMATIONS2
|
|
template < class FT >
|
|
std::ostream&
|
|
operator<<(std::ostream& os, const Aff_transformationS2<FT>& t)
|
|
{
|
|
t.print(os);
|
|
return os;
|
|
}
|
|
#endif // CGAL_NO_OSTREAM_INSERT_AFF_TRANSFORMATIONS2
|
|
|
|
#ifndef CGAL_NO_ISTREAM_EXTRACT_AFF_TRANSFORMATIONS2
|
|
#endif // CGAL_NO_ISTREAM_EXTRACT_AFF_TRANSFORMATIONS2
|
|
|
|
|
|
|
|
CGAL_END_NAMESPACE
|
|
|
|
#endif // CGAL_AFF_TRANSFORMATIONS2_H
|