• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2005-2007 Adobe Systems Incorporated
3 //
4 // Distributed under the Boost Software License, Version 1.0
5 // See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt
7 //
8 #ifndef BOOST_GIL_EXTENSION_NUMERIC_AFFINE_HPP
9 #define BOOST_GIL_EXTENSION_NUMERIC_AFFINE_HPP
10 
11 #include <boost/gil/point.hpp>
12 
13 namespace boost { namespace gil {
14 
15 ////////////////////////////////////////////////////////////////////////////////////////
16 ///
17 /// Simple matrix to do 2D affine transformations. It is actually 3x3 but the last column is [0 0 1]
18 ///
19 ////////////////////////////////////////////////////////////////////////////////////////
20 template <typename T>
21 class matrix3x2 {
22 public:
matrix3x2()23     matrix3x2() : a(1), b(0), c(0), d(1), e(0), f(0) {}
matrix3x2(T A,T B,T C,T D,T E,T F)24     matrix3x2(T A, T B, T C, T D, T E, T F) : a(A),b(B),c(C),d(D),e(E),f(F) {}
matrix3x2(const matrix3x2 & mat)25     matrix3x2(const matrix3x2& mat) : a(mat.a), b(mat.b), c(mat.c), d(mat.d), e(mat.e), f(mat.f) {}
operator =(const matrix3x2 & m)26     matrix3x2& operator=(const matrix3x2& m)           { a=m.a; b=m.b; c=m.c; d=m.d; e=m.e; f=m.f; return *this; }
27 
operator *=(const matrix3x2 & m)28     matrix3x2& operator*=(const matrix3x2& m)          { (*this) = (*this)*m; return *this; }
29 
get_rotate(T rads)30     static matrix3x2 get_rotate(T rads)                { T c=std::cos(rads); T s=std::sin(rads); return matrix3x2(c,s,-s,c,0,0); }
get_translate(point<T> const & t)31     static matrix3x2 get_translate(point<T> const& t)
32     {
33         return matrix3x2(1, 0, 0, 1, t.x, t.y);
34     }
get_translate(T x,T y)35     static matrix3x2 get_translate(T x, T y)           { return matrix3x2(1  ,0,0,1  ,x,  y  ); }
get_scale(point<T> const & s)36     static matrix3x2 get_scale(point<T> const& s)
37     {
38         return matrix3x2(s.x, 0, 0, s.y, 0, 0);
39     }
get_scale(T x,T y)40     static matrix3x2 get_scale(T x, T y)           { return matrix3x2(x,  0,0,y,  0  ,0  ); }
get_scale(T s)41     static matrix3x2 get_scale(T s)                { return matrix3x2(s  ,0,0,s  ,0  ,0  ); }
42 
43     T a,b,c,d,e,f;
44 };
45 
46 template <typename T> BOOST_FORCEINLINE
operator *(const matrix3x2<T> & m1,const matrix3x2<T> & m2)47 matrix3x2<T> operator*(const matrix3x2<T>& m1, const matrix3x2<T>& m2) {
48     return matrix3x2<T>(
49                 m1.a * m2.a + m1.b * m2.c,
50                 m1.a * m2.b + m1.b * m2.d,
51                 m1.c * m2.a + m1.d * m2.c,
52                 m1.c * m2.b + m1.d * m2.d,
53                 m1.e * m2.a + m1.f * m2.c + m2.e,
54                 m1.e * m2.b + m1.f * m2.d + m2.f );
55 }
56 
57 template <typename T, typename F>
58 BOOST_FORCEINLINE
operator *(point<T> const & p,matrix3x2<F> const & m)59 point<F> operator*(point<T> const& p, matrix3x2<F> const& m)
60 {
61     return { m.a*p.x + m.c*p.y + m.e, m.b*p.x + m.d*p.y + m.f };
62 }
63 
64 ////////////////////////////////////////////////////////////////////////////////////////
65 /// Define affine mapping that transforms the source coordinates by the affine transformation
66 ////////////////////////////////////////////////////////////////////////////////////////
67 /*
68 template <typename MapFn>
69 concept MappingFunctionConcept {
70     typename mapping_traits<MapFn>::result_type;   where PointNDConcept<result_type>;
71 
72     template <typename Domain> { where PointNDConcept<Domain> }
73     result_type transform(MapFn&, const Domain& src);
74 };
75 */
76 
77 template <typename T> struct mapping_traits;
78 
79 template <typename F>
80 struct mapping_traits<matrix3x2<F>>
81 {
82     using result_type =  point<F>;
83 };
84 
85 template <typename F, typename F2>
86 BOOST_FORCEINLINE
transform(matrix3x2<F> const & mat,point<F2> const & src)87 point<F> transform(matrix3x2<F> const& mat, point<F2> const& src)
88 {
89     return src * mat;
90 }
91 
92 }} // namespace boost::gil
93 
94 #endif
95