dust3d/thirdparty/cgal/CGAL-5.1/include/CGAL/Cartesian/Reflection_rep_2.h

200 lines
5.8 KiB
C++

// Copyright (c) 2018
// 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: https://github.com/CGAL/cgal/blob/v5.1/Cartesian_kernel/include/CGAL/Cartesian/Reflection_rep_2.h $
// $Id: Reflection_rep_2.h 0779373 2020-03-26T13:31:46+01:00 Sébastien Loriot
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Maxime Gimeno
#ifndef CGAL_CARTESIAN_REFLECTION_REP_2_H
#define CGAL_CARTESIAN_REFLECTION_REP_2_H
#include <cmath>
namespace CGAL {
template < class R >
class Reflection_repC2: public Aff_transformation_rep_baseC2<R>
{
friend class Translation_repC2<R>;
friend class Rotation_repC2<R>;
friend class Scaling_repC2<R>;
friend class Aff_transformation_repC2<R>;
public:
typedef Aff_transformation_rep_baseC2<R> Aff_t_base;
typedef typename Aff_t_base::FT FT;
typedef typename Aff_t_base::Point_2 Point_2;
typedef typename Aff_t_base::Vector_2 Vector_2;
typedef typename Aff_t_base::Direction_2 Direction_2;
typedef typename CGAL::Line_2<R> Line_2;
typedef typename Aff_t_base::Aff_transformation_2 Aff_transformation_2;
typedef Aff_transformation_repC2<R> Transformation;
typedef Reflection_repC2<R> Reflection;
typedef Scaling_repC2<R> Scaling;
typedef Rotation_repC2<R> Rotation;
typedef Translation_repC2<R> Translation;
Reflection_repC2(const Line_2 &l)
{
if(l.a() == 0)
t = -Vector_2(0, l.c()/l.b());
else
t = -Vector_2(l.c()/l.a(),0);
Vector_2 l_to_v = l.to_vector();
FT scal = l_to_v.x(); //Projection of l_to_v on Ox. = |L|*cos(a)
FT det = l_to_v.y();// = |L|*sin(a)
sinus_ = 2*det*scal/l_to_v.squared_length(); //sin(2a) = 2*sin(a)*cos(a)
FT sq_cos = scal*scal/l_to_v.squared_length(); //cos(a)*cos(a)
cosinus_ = 2*sq_cos-1;
}
~Reflection_repC2()
{}
Point_2 transform(const Point_2 &p) const
{
return Point_2(
cosinus_*p.x()+sinus_*p.y()-cosinus_*t.x()-sinus_*t.y()+t.x(),
sinus_*p.x()-cosinus_*p.y()-sinus_*t.x()+cosinus_*t.y()+t.y());
}
Vector_2 transform(const Vector_2 &p) const
{
return Vector_2(
cosinus_*p.x()+sinus_*p.y()-cosinus_*t.x()-sinus_*t.y()+t.x(),
sinus_*p.x()-cosinus_*p.y()-sinus_*t.x()+cosinus_*t.y()+t.y());
}
Direction_2 transform(const Direction_2 &d) const
{
return transform(d.vector()).direction();
}
Aff_transformation_2 operator*(const Aff_t_base &t) const
{
return t.compose(*this);
}
Aff_transformation_2 compose(const Translation &tr) const
{
return Aff_transformation_2(cosinus_, sinus_, t13()+tr.translationvector_.x(),
sinus_, -cosinus_, t23()+tr.translationvector_.y());
}
Aff_transformation_2 compose(const Scaling &s) const
{
return Aff_transformation_2(s.scalefactor_ * cosinus_,
s.scalefactor_ * sinus_,
s.scalefactor_ * t13(),
s.scalefactor_ * sinus_,
-s.scalefactor_ * cosinus_,
s.scalefactor_ * t23());
}
Aff_transformation_2 compose(const Transformation &tr) const
{
return Aff_transformation_2(
tr.t11*cosinus_+tr.t12*sinus_,
tr.t11*sinus_-tr.t12*cosinus_,
tr.t11*t13()+tr.t12*t23()+tr.t13,
tr.t21*cosinus_+tr.t22*sinus_,
tr.t21*sinus_-tr.t22*cosinus_,
tr.t21*t13()+tr.t22*t23()+tr.t23);
}
Aff_transformation_2 compose(const Rotation &r) const
{
return Aff_transformation_2(
r.cosinus_*cosinus_-r.sinus_*sinus_,
r.cosinus_*sinus_+r.sinus_*cosinus_,
r.cosinus_*t13()
-r.sinus_*t23(),
r.sinus_*cosinus_+r.cosinus_*sinus_,
r.sinus_*sinus_-r.cosinus_*cosinus_,
r.sinus_*t13()
+r.cosinus_*t23());
}
Aff_transformation_2 compose(const Reflection &r) const
{
return Aff_transformation_2(
cosinus_*r.cosinus_+sinus_*r.sinus_,
r.cosinus_*sinus_-r.sinus_*cosinus_,
r.cosinus_*(t13()-r.t.x()) + r.sinus_*(t23()-r.t.y())+r.t.x(),
r.sinus_*cosinus_ - r.cosinus_*sinus_,
r.sinus_*sinus_+r.cosinus_*cosinus_,
r.sinus_*(t13()-r.t.x()) -r.cosinus_*(t23()-r.t.y())+r.t.y());
}
Aff_transformation_2 inverse() const
{
return Aff_transformation_2(cartesian(0,0), cartesian(0,1), cartesian(0,2),
cartesian(1,0), cartesian(1,1), cartesian(1,2));
}
bool is_even() const
{
return true;
}
FT cartesian(int i, int j) const
{
switch (i)
{
case 0: switch (j)
{
case 0: return cosinus_;
case 1: return sinus_;
default: return FT(0);
}
case 1: switch (j)
{
case 0: return sinus_;
case 1: return -cosinus_;
default: return FT(0);
}
case 2: switch (j)
{
case 0: return FT(0);
case 1: return FT(0);
default: return FT(1);
}
}
return FT(0);
}
std::ostream &print(std::ostream &os) const
{
os << "Aff_transformationC2(" << sinus_ << ", " << cosinus_ << "; "<< t <<")";
return os;
}
//convevience functions for composition
FT t13()const
{
return FT(-cosinus_*t.x()-sinus_*t.y()+t.x());
}
FT t23()const
{
return FT(-sinus_*t.x()+cosinus_*t.y()+t.y());
}
private:
Vector_2 t;
FT sinus_, cosinus_;
};
} //namespace CGAL
#endif // CGAL_CARTESIAN_REFLECTION_REP_2_H