TuttleOFX  1
affine.hpp
Go to the documentation of this file.
00001 /*
00002   Copyright 2005-2007 Adobe Systems Incorporated
00003   Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt
00004   or a copy at http://opensource.adobe.com/licenses.html)
00005 */
00006 
00007 /*************************************************************************************************/
00008 
00009 #ifndef _TERRY_NUMERIC_AFFINE_HPP_
00010 #define _TERRY_NUMERIC_AFFINE_HPP_
00011 
00012 #include <boost/gil/utilities.hpp>     // point2
00013 
00014 ////////////////////////////////////////////////////////////////////////////////////////
00015 /// \file               
00016 /// \brief support for affine transformations
00017 /// \author Lubomir Bourdev and Hailin Jin \n
00018 ///         Adobe Systems Incorporated
00019 /// \date   2005-2007 \n September 21, 2006
00020 ///
00021 ////////////////////////////////////////////////////////////////////////////////////////
00022 
00023 namespace terry {
00024 
00025 using namespace boost::gil;
00026 
00027 ////////////////////////////////////////////////////////////////////////////////////////
00028 ///
00029 /// Simple matrix to do 2D affine transformations. It is actually 3x3 but the last column is [0 0 1]
00030 ///
00031 ////////////////////////////////////////////////////////////////////////////////////////
00032 template <typename T>
00033 class matrix3x2 {
00034 public:
00035     matrix3x2() : a(1), b(0), c(0), d(1), e(0), f(0) {}
00036     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) {}
00037     matrix3x2(const matrix3x2& mat) : a(mat.a), b(mat.b), c(mat.c), d(mat.d), e(mat.e), f(mat.f) {}
00038     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; }
00039 
00040     matrix3x2& operator*=(const matrix3x2& m)          { (*this) = (*this)*m; return *this; }
00041 
00042     static matrix3x2 get_rotate(T rads)                { T c=std::cos(rads); T s=std::sin(rads); return matrix3x2(c,s,-s,c,0,0); }
00043     static matrix3x2 get_translate(const point2<T>& t) { return matrix3x2(1  ,0,0,1  ,t.x,t.y); }
00044     static matrix3x2 get_translate(T x, T y)           { return matrix3x2(1  ,0,0,1  ,x,  y  ); }
00045     static matrix3x2 get_scale    (const point2<T>& s) { return matrix3x2(s.x,0,0,s.y,0  ,0  ); }
00046     static matrix3x2 get_scale    (T x, T y)           { return matrix3x2(x,  0,0,y,  0  ,0  ); }
00047     static matrix3x2 get_scale    (T s)                { return matrix3x2(s  ,0,0,s  ,0  ,0  ); }
00048 
00049     T a,b,c,d,e,f;
00050 };
00051 
00052 template <typename T> GIL_FORCEINLINE
00053 matrix3x2<T> operator*(const matrix3x2<T>& m1, const matrix3x2<T>& m2) {
00054     return matrix3x2<T>(
00055                 m1.a * m2.a + m1.b * m2.c,
00056                 m1.a * m2.b + m1.b * m2.d,
00057                 m1.c * m2.a + m1.d * m2.c,
00058                 m1.c * m2.b + m1.d * m2.d,
00059                 m1.e * m2.a + m1.f * m2.c + m2.e,
00060                 m1.e * m2.b + m1.f * m2.d + m2.f );
00061 }
00062 
00063 template <typename T, typename F> GIL_FORCEINLINE
00064 point2<F> operator*(const point2<T>& p, const matrix3x2<F>& m) {
00065     return point2<F>(m.a*p.x + m.c*p.y + m.e, m.b*p.x + m.d*p.y + m.f);
00066 }
00067 
00068 ////////////////////////////////////////////////////////////////////////////////////////
00069 /// Define affine mapping that transforms the source coordinates by the affine transformation
00070 ////////////////////////////////////////////////////////////////////////////////////////
00071 /*
00072 template <typename MapFn>
00073 concept MappingFunctionConcept {
00074     typename mapping_traits<MapFn>::result_type;   where PointNDConcept<result_type>;
00075 
00076     template <typename Domain> { where PointNDConcept<Domain> }
00077     result_type transform(MapFn&, const Domain& src); 
00078 };
00079 */
00080 
00081 template <typename T> struct mapping_traits;
00082 
00083 template <typename F>
00084 struct mapping_traits<matrix3x2<F> > {
00085     typedef point2<F> result_type;
00086 };
00087 
00088 template <typename F, typename F2> GIL_FORCEINLINE
00089 point2<F> transform(const matrix3x2<F>& mat, const point2<F2>& src) { return src * mat; }
00090 
00091 }
00092 
00093 #endif