1/*!
2 * \file ScaleTranslate.hpp
3 * \brief file ScaleTranslate.hpp
4 *
5 * Adapted from: WRATHScaleTranslate.hpp of WRATH:
6 *
7 * Copyright 2013 by Nomovok Ltd.
8 * Contact: info@nomovok.com
9 * This Source Code Form is subject to the
10 * terms of the Mozilla Public License, v. 2.0.
11 * If a copy of the MPL was not distributed with
12 * this file, You can obtain one at
13 * http://mozilla.org/MPL/2.0/.
14 *
15 * \author Kevin Rogovin <kevin.rogovin@nomovok.com>
16 * \author Kevin Rogovin <kevin.rogovin@gmail.com>
17 *
18 */
19
20
21
22
23#ifndef FASTUIDRAW_DEMO_SCALETRANSLATE_HPP
24#define FASTUIDRAW_DEMO_SCALETRANSLATE_HPP
25
26#include <cstdlib>
27#include <fastuidraw/util/util.hpp>
28#include <fastuidraw/util/vecN.hpp>
29#include <fastuidraw/util/math.hpp>
30#include <fastuidraw/util/matrix.hpp>
31#include <fastuidraw/painter/painter.hpp>
32
33/*!\class ScaleTranslate
34 A ScaleTranslate represents the composition
35 of a scaling and a translation, i.e.
36 \f[ f(x,y) = (sx,sy) + (A,B) \f]
37 where \f$ s \f$ =scale() and \f$ (A,B) \f$ =translation().
38 */
39template<typename T>
40class ScaleTranslate
41{
42public:
43 /*!
44 Ctor. Initialize a ScaleTranslate from a
45 scaling factor and translation
46 \param tr translation to use
47 \param s scaling factor to apply to both x-axis and y-axis,
48 _absolute_ value is stored, i.e. the sign of s
49 is ignored
50 */
51 ScaleTranslate(const fastuidraw::vecN<T, 2> &tr = fastuidraw::vecN<T, 2>(T(0), T(0)),
52 T s = T(1)):
53 m_scale(fastuidraw::t_abs(s)),
54 m_translation(tr)
55 {}
56
57 /*!
58 Ctor. Initialize a ScaleTranslate from a
59 scaling factor
60 \param s scaling factor to apply to both x-axis and y-axis,
61 _absolute_ value is stored, i.e. the sign of s
62 is ignored
63 */
64 ScaleTranslate(T s):
65 m_scale(fastuidraw::t_abs(s)),
66 m_translation(T(0), T(0))
67 {}
68
69 /*!
70 Returns the inverse transformation to this.
71 */
72 ScaleTranslate
73 inverse(void) const
74 {
75 ScaleTranslate r;
76
77 r.m_scale = T(1) / m_scale;
78 r.m_translation = -r.m_scale * m_translation;
79
80 return r;
81 }
82
83 /*!
84 Returns the translation of this
85 ScaleTranslate.
86 */
87 const fastuidraw::vecN<T, 2>&
88 translation(void) const
89 {
90 return m_translation;
91 }
92
93 /*!
94 Sets the translation of this.
95 \param tr value to set translation to.
96 */
97 ScaleTranslate&
98 translation(const fastuidraw::vecN<T, 2> &tr)
99 {
100 m_translation = tr;
101 return *this;
102 }
103
104 /*!
105 Sets the x-coordinate of the translation of this.
106 \param x value to set translation to.
107 */
108 ScaleTranslate&
109 translation_x(T x)
110 {
111 m_translation.x() = x;
112 return *this;
113 }
114
115 /*!
116 Sets the y-coordinate of the translation of this.
117 \param y value to set translation to.
118 */
119 ScaleTranslate&
120 translation_y(T y)
121 {
122 m_translation.y() = y;
123 return *this;
124 }
125
126 /*!
127 Returns the scale of this.
128 Scaling factor is _NEVER_
129 negative.
130 */
131 T
132 scale(void) const
133 {
134 return m_scale;
135 }
136
137 /*!
138 Sets the scale of this.
139 If a negative value is passed,
140 it's absolute value is used.
141 \param s value to set scale to.
142 */
143 ScaleTranslate&
144 scale(T s)
145 {
146 m_scale = fastuidraw::t_abs(s);
147 return *this;
148 }
149
150 /*!
151 Returns the value of applying the transformation to a point.
152 \param pt point to apply the transformation to.
153 */
154 fastuidraw::vecN<T, 2>
155 apply_to_point(const fastuidraw::vecN<T, 2> &pt) const
156 {
157 return scale() * pt + translation();
158 }
159
160 /*!
161 Returns the value of applying the inverse of the
162 transformation to a point.
163 \param pt point to apply the transformation to.
164 */
165 fastuidraw::vecN<T, 2>
166 apply_inverse_to_point(const fastuidraw::vecN<T, 2> &pt) const
167 {
168 return (pt - translation()) / scale();
169 }
170
171 /*!
172 Returns the transformation of this
173 ScaleTranslate as a 3x3 matrix
174 */
175 fastuidraw::matrix3x3<T>
176 matrix3(void) const
177 {
178 fastuidraw::matrix3x3<T> M;
179
180 M(0,0) = M(1,1) = scale();
181 M(0,2) = translation().x();
182 M(1,2) = translation().y();
183
184 return M;
185 }
186
187 void
188 concat_to_painter(const fastuidraw::reference_counted_ptr<fastuidraw::Painter> &p) const
189 {
190 p->translate(fastuidraw::vec2(m_translation));
191 p->scale(m_scale);
192 }
193
194 /*!
195 Computes the interpolation between
196 two ScaleTranslate objects.
197 \param a0 begin value of interpolation
198 \param a1 end value of interpolation
199 \param t interpolate, t=0 returns a0, t=1 returns a1
200 */
201 static
202 ScaleTranslate
203 interpolate(const ScaleTranslate &a0,
204 const ScaleTranslate &a1,
205 T t)
206 {
207 ScaleTranslate R;
208
209 R.translation( a0.translation() + t * (a1.translation()-a0.translation()) );
210 R.scale( a0.scale() + t * (a1.scale() - a0.scale()) );
211 return R;
212 }
213
214private:
215 T m_scale;
216 fastuidraw::vecN<T, 2> m_translation;
217};
218
219/*!
220 Compose two ScaleTranslate so that:
221 a*b.apply_to_point(p) "=" a.apply_to_point( b.apply_to_point(p)).
222 \param a left hand side of composition
223 \param b right hand side of composition
224 */
225template<typename T>
226ScaleTranslate<T>
227operator*(const ScaleTranslate<T> &a, const ScaleTranslate<T> &b)
228{
229 ScaleTranslate<T> c;
230
231 //
232 // c(p)= a( b(p) )
233 // = a.translation + a.scale*( b.scale*p + b.translation )
234 // = (a.translate + a.scale*b.translation) + (a.scale*b.scale)*p
235 //
236 //thus:
237 //
238 // c.scale=a.scale*b.scale
239 // c.translation= a.apply_to_point(b.translation)
240 c.scale( a.scale() * b.scale());
241 c.translation( a.apply_to_point(b.translation()) );
242
243 return c;
244}
245
246/*! @} */
247
248#endif
249