File indexing completed on 2025-01-18 09:37:00
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_GIL_EXTENSION_NUMERIC_AFFINE_HPP
0009 #define BOOST_GIL_EXTENSION_NUMERIC_AFFINE_HPP
0010
0011 #include <boost/gil/point.hpp>
0012
0013 namespace boost { namespace gil {
0014
0015
0016
0017
0018
0019
0020 template <typename T>
0021 class matrix3x2 {
0022 public:
0023 matrix3x2() : a(1), b(0), c(0), d(1), e(0), f(0) {}
0024 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) {}
0025 matrix3x2(const matrix3x2& mat) : a(mat.a), b(mat.b), c(mat.c), d(mat.d), e(mat.e), f(mat.f) {}
0026 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; }
0027
0028 matrix3x2& operator*=(const matrix3x2& m) { (*this) = (*this)*m; return *this; }
0029
0030 static matrix3x2 get_rotate(T rads) { T c=std::cos(rads); T s=std::sin(rads); return matrix3x2(c,s,-s,c,0,0); }
0031 static matrix3x2 get_translate(point<T> const& t)
0032 {
0033 return matrix3x2(1, 0, 0, 1, t.x, t.y);
0034 }
0035 static matrix3x2 get_translate(T x, T y) { return matrix3x2(1 ,0,0,1 ,x, y ); }
0036 static matrix3x2 get_scale(point<T> const& s)
0037 {
0038 return matrix3x2(s.x, 0, 0, s.y, 0, 0);
0039 }
0040 static matrix3x2 get_scale(T x, T y) { return matrix3x2(x, 0,0,y, 0 ,0 ); }
0041 static matrix3x2 get_scale(T s) { return matrix3x2(s ,0,0,s ,0 ,0 ); }
0042
0043 T a,b,c,d,e,f;
0044 };
0045
0046 template <typename T> BOOST_FORCEINLINE
0047 matrix3x2<T> operator*(const matrix3x2<T>& m1, const matrix3x2<T>& m2) {
0048 return matrix3x2<T>(
0049 m1.a * m2.a + m1.b * m2.c,
0050 m1.a * m2.b + m1.b * m2.d,
0051 m1.c * m2.a + m1.d * m2.c,
0052 m1.c * m2.b + m1.d * m2.d,
0053 m1.e * m2.a + m1.f * m2.c + m2.e,
0054 m1.e * m2.b + m1.f * m2.d + m2.f );
0055 }
0056
0057 template <typename T, typename F>
0058 BOOST_FORCEINLINE
0059 point<F> operator*(point<T> const& p, matrix3x2<F> const& m)
0060 {
0061 return { m.a*p.x + m.c*p.y + m.e, m.b*p.x + m.d*p.y + m.f };
0062 }
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077 template <typename T> struct mapping_traits;
0078
0079 template <typename F>
0080 struct mapping_traits<matrix3x2<F>>
0081 {
0082 using result_type = point<F>;
0083 };
0084
0085 template <typename F, typename F2>
0086 BOOST_FORCEINLINE
0087 point<F> transform(matrix3x2<F> const& mat, point<F2> const& src)
0088 {
0089 return src * mat;
0090 }
0091
0092
0093
0094
0095 template <typename T>
0096 boost::gil::matrix3x2<T> inverse(boost::gil::matrix3x2<T> m)
0097 {
0098 T const determinant = m.a * m.d - m.b * m.c;
0099
0100 boost::gil::matrix3x2<T> res;
0101 res.a = m.d / determinant;
0102 res.b = -m.b / determinant;
0103 res.c = -m.c / determinant;
0104 res.d = m.a / determinant;
0105 res.e = (m.c * m.f - m.d * m.e) / determinant;
0106 res.f = (m.b * m.e - m.a * m.f) / determinant;
0107
0108 return res;
0109 }
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119 template<typename T, typename F>
0120 boost::gil::matrix3x2<F> center_rotate(boost::gil::point<T> dims,F rads)
0121 {
0122 const F PI = F(3.141592653589793238);
0123 const F c_theta = std::abs(std::cos(rads));
0124 const F s_theta = std::abs(std::sin(rads));
0125
0126
0127 while(rads + PI < 0)
0128 {
0129 rads = rads + PI;
0130 }
0131
0132 while(rads > PI)
0133 {
0134 rads = rads - PI;
0135 }
0136
0137
0138 boost::gil::matrix3x2<F> rotate = boost::gil::matrix3x2<F>::get_rotate(rads);
0139
0140
0141 boost::gil::matrix3x2<F> translation(0,0,0,0,0,0);
0142 if(rads > 0)
0143 {
0144 translation.b = s_theta;
0145 }
0146 else
0147 {
0148 translation.c = s_theta;
0149 }
0150
0151 if(std::abs(rads) > PI/2)
0152 {
0153 translation.a = c_theta;
0154 translation.d = c_theta;
0155 }
0156
0157
0158 boost::gil::matrix3x2<F> translate =
0159 boost::gil::matrix3x2<F>::get_translate(-1 * dims * translation);
0160
0161
0162 boost::gil::matrix3x2<F> scale =
0163 boost::gil::matrix3x2<F>::get_scale(
0164 s_theta * dims.y / dims.x + c_theta ,
0165 s_theta * dims.x / dims.y + c_theta
0166 );
0167
0168 return scale * translate * rotate;
0169 }
0170
0171 }}
0172
0173 #endif