Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
transforms.h
Go to the documentation of this file.
1/*
5 * Authors:
6 * ? <?@?.?>
7 * Krzysztof KosiƄski <tweenk.pl@gmail.com>
8 * Johan Engelen
9 *
10 * Copyright ?-2012 Authors
11 *
12 * This library is free software; you can redistribute it and/or
13 * modify it either under the terms of the GNU Lesser General Public
14 * License version 2.1 as published by the Free Software Foundation
15 * (the "LGPL") or, at your option, under the terms of the Mozilla
16 * Public License Version 1.1 (the "MPL"). If you do not alter this
17 * notice, a recipient may use your version of this file under either
18 * the MPL or the LGPL.
19 *
20 * You should have received a copy of the LGPL along with this library
21 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 * You should have received a copy of the MPL along with this library
24 * in the file COPYING-MPL-1.1
25 *
26 * The contents of this file are subject to the Mozilla Public License
27 * Version 1.1 (the "License"); you may not use this file except in
28 * compliance with the License. You may obtain a copy of the License at
29 * http://www.mozilla.org/MPL/
30 *
31 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
32 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
33 * the specific language governing rights and limitations.
34 */
35
36#ifndef LIB2GEOM_SEEN_TRANSFORMS_H
37#define LIB2GEOM_SEEN_TRANSFORMS_H
38
39#include <cmath>
40#include <2geom/forward.h>
41#include <2geom/affine.h>
42#include <2geom/angle.h>
43#include <boost/concept/assert.hpp>
44
45namespace Geom {
46
49template <typename T>
51 T t, t2;
54 bool bool_;
56 void constraints() {
57 m = t; //implicit conversion
58 m *= t;
59 m = m * t;
60 m = t * m;
61 p *= t;
62 p = p * t;
63 t *= t;
64 t = t * t;
65 t = pow(t, 3);
66 bool_ = (t == t);
67 bool_ = (t != t);
68 t = T::identity();
69 t = t.inverse();
70 bool_ = are_near(t, t2);
72 }
73};
74
77template <typename T>
79 : boost::equality_comparable< T
80 , boost::multipliable< T
81 > >
82{
83public:
84 template <typename T2>
85 Affine operator*(T2 const &t) const {
86 Affine ret(*static_cast<T const*>(this)); ret *= t; return ret;
87 }
88};
89
97template <typename T>
98T pow(T const &t, int n) {
99 BOOST_CONCEPT_ASSERT((TransformConcept<T>));
100 if (n == 0) return T::identity();
101 T result(T::identity());
102 T x(n < 0 ? t.inverse() : t);
103 if (n < 0) n = -n;
104 while ( n ) { // binary exponentiation - fast
105 if ( n & 1 ) { result *= x; --n; }
106 x *= x; n /= 2;
107 }
108 return result;
109}
110
114 : public TransformOperations< Translate >
115{
117public:
119 Translate() = default;
121 explicit Translate(Point const &p) : vec(p) {}
123 Translate(Coord x, Coord y) : vec(x, y) {}
124
125 operator Affine() const { return Affine(1, 0, 0, 1, vec[X], vec[Y]); }
126 Coord operator[](Dim2 dim) const { return vec[dim]; }
127 Coord operator[](unsigned dim) const { return vec[dim]; }
128 Translate &operator*=(Translate const &o) { vec += o.vec; return *this; }
129 bool operator==(Translate const &o) const { return vec == o.vec; }
130
131 Point vector() const { return vec; }
133 Translate inverse() const { return Translate(-vec); }
135 static Translate identity() { return {}; }
136
137 friend class Point;
138};
139
140inline bool are_near(Translate const &a, Translate const &b, Coord eps = EPSILON) {
141 return are_near(a[X], b[X], eps) && are_near(a[Y], b[Y], eps);
142}
143
148class Scale
149 : public TransformOperations< Scale >
150{
151 Point vec = { 1, 1 };
152public:
154 Scale() = default;
156 explicit Scale(Point const &p) : vec(p) {}
158 Scale(Coord x, Coord y) : vec(x, y) {}
160 explicit Scale(Coord s) : vec(s, s) {}
161 inline operator Affine() const { return Affine(vec[X], 0, 0, vec[Y], 0, 0); }
162
163 Coord operator[](Dim2 d) const { return vec[d]; }
164 Coord operator[](unsigned d) const { return vec[d]; }
165 //TODO: should we keep these mutators? add them to the other transforms?
166 Coord &operator[](Dim2 d) { return vec[d]; }
167 Coord &operator[](unsigned d) { return vec[d]; }
168 Scale &operator*=(Scale const &b) { vec[X] *= b[X]; vec[Y] *= b[Y]; return *this; }
169 bool operator==(Scale const &o) const { return vec == o.vec; }
170
171 Point vector() const { return vec; }
172 Scale inverse() const { return Scale(1./vec[0], 1./vec[1]); }
173 static Scale identity() { return {}; }
174
175 friend class Point;
176};
177
178inline bool are_near(Scale const &a, Scale const &b, Coord eps=EPSILON) {
179 return are_near(a[X], b[X], eps) && are_near(a[Y], b[Y], eps);
180}
181
186 : public TransformOperations< Rotate >
187{
188 Point vec = { 1, 0 };
189public:
191 Rotate() = default;
194 explicit Rotate(Coord theta) : vec(Point::polar(theta)) {}
196 explicit Rotate(Point const &p) : vec(p.normalized()) {}
198 explicit Rotate(Coord x, Coord y) : Rotate(Point(x, y)) {}
199 operator Affine() const { return Affine(vec[X], vec[Y], -vec[Y], vec[X], 0, 0); }
200
203 Point const &vector() const { return vec; }
204 Coord angle() const { return atan2(vec); }
205 Coord operator[](Dim2 dim) const { return vec[dim]; }
206 Coord operator[](unsigned dim) const { return vec[dim]; }
207 Rotate &operator*=(Rotate const &o) { vec *= o; return *this; }
208 bool operator==(Rotate const &o) const { return vec == o.vec; }
209 Rotate inverse() const {
210 Rotate r;
211 r.vec = Point(vec[X], -vec[Y]);
212 return r;
213 }
215 static Rotate identity() { return {}; }
218 static Rotate from_degrees(Coord deg) { return Rotate(rad_from_deg(deg)); }
219 static Affine around(Point const &p, Coord angle);
220
221 friend class Point;
222};
223
224inline bool are_near(Rotate const &a, Rotate const &b, Coord eps = EPSILON) {
225 return are_near(a[X], b[X], eps) && are_near(a[Y], b[Y], eps);
226}
227
231template <typename S>
233 : public TransformOperations<S>
234{
235protected:
236 Coord f = 0;
237 ShearBase() = default;
238 explicit ShearBase(Coord _f) : f(_f) {}
239public:
240 Coord factor() const { return f; }
241 void setFactor(Coord nf) { f = nf; }
242 S &operator*=(S const &s) { f += s.f; return static_cast<S &>(*this); }
243 bool operator==(ShearBase<S> const &s) const { return f == s.f; }
244 S inverse() const { return S(-f); }
245 static S identity() { return {}; }
246
247 friend class Point;
248 friend class Affine;
249};
250
256 : public ShearBase<HShear>
257{
258public:
259 HShear() = default;
260 explicit HShear(Coord h) : ShearBase<HShear>(h) {}
261 operator Affine() const { return Affine(1, 0, f, 1, 0, 0); }
262};
263
264inline bool are_near(HShear const &a, HShear const &b, Coord eps=EPSILON) {
265 return are_near(a.factor(), b.factor(), eps);
266}
267
273 : public ShearBase<VShear>
274{
275public:
276 VShear() = default;
277 explicit VShear(Coord h) : ShearBase<VShear>(h) {}
278 operator Affine() const { return Affine(1, f, 0, 1, 0, 0); }
279};
280
281inline bool are_near(VShear const &a, VShear const &b, Coord eps = EPSILON) {
282 return are_near(a.factor(), b.factor(), eps);
283}
284
290class Zoom
291 : public TransformOperations< Zoom >
292{
295public:
296 Zoom() = default;
298 explicit Zoom(Coord s) : _scale(s) {}
300 explicit Zoom(Point const &t) : _trans(t) {}
301 explicit Zoom(Translate const &t) : Zoom(t.vector()) {}
303 Zoom(Coord s, Point const &t) : _scale(s), _trans(t) {}
304 Zoom(Coord s, Translate const &t) : Zoom(s, t.vector()) {}
305
306 operator Affine() const {
307 return Affine(_scale, 0, 0, _scale, _trans[X] * _scale, _trans[Y] * _scale);
308 }
309 Zoom &operator*=(Zoom const &z) {
310 _trans += z._trans / _scale;
311 _scale *= z._scale;
312 return *this;
313 }
314 bool operator==(Zoom const &z) const { return _scale == z._scale && _trans == z._trans; }
315
316 Coord scale() const { return _scale; }
317 void setScale(Coord s) { _scale = s; }
318 Point translation() const { return _trans; }
319 void setTranslation(Point const &p) { _trans = p; }
320 Zoom inverse() const { return Zoom(1 / _scale, Translate(-_trans * _scale)); }
321 static Zoom identity() { return {}; }
322 static Zoom map_rect(Rect const &old_r, Rect const &new_r);
323
324 friend class Point;
325 friend class Affine;
326};
327
328inline bool are_near(Zoom const &a, Zoom const &b, Coord eps = EPSILON) {
329 return are_near(a.scale(), b.scale(), eps) &&
330 are_near(a.translation(), b.translation(), eps);
331}
332
335template<>
336inline Scale pow(Scale const &s, int n) {
337 return Scale(::pow(s[X], n), ::pow(s[Y], n));
338}
341template<>
342inline Translate pow(Translate const &t, int n) {
343 return Translate(t[X] * n, t[Y] * n);
344}
345
351Affine reflection(Point const & vector, Point const & origin);
352
353//TODO: decomposition of Affine into some finite combination of the above classes
354
355} // namespace Geom
356
357#endif // LIB2GEOM_SEEN_TRANSFORMS_H
358
359/*
360 Local Variables:
361 mode:c++
362 c-file-style:"stroustrup"
363 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
364 indent-tabs-mode:nil
365 fill-column:99
366 End:
367*/
368// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
Point origin
Definition aa.cpp:227
3x3 affine transformation matrix.
Various trigoniometric helper functions.
3x3 matrix representing an affine transformation.
Definition affine.h:70
Horizontal shearing.
Definition transforms.h:257
HShear(Coord h)
Definition transforms.h:260
HShear()=default
Two-dimensional point that doubles as a vector.
Definition point.h:66
Axis aligned, non-empty rectangle.
Definition rect.h:92
Rotation around the origin.
Definition transforms.h:187
Rotate & operator*=(Rotate const &o)
Definition transforms.h:207
static Affine around(Point const &p, Coord angle)
Coord operator[](unsigned dim) const
Definition transforms.h:206
static Rotate from_degrees(Coord deg)
Construct a rotation from its angle in degrees.
Definition transforms.h:218
Rotate(Coord theta)
Construct a rotation from its angle in radians.
Definition transforms.h:194
Rotate inverse() const
Definition transforms.h:209
Rotate(Point const &p)
Construct a rotation from its characteristic vector.
Definition transforms.h:196
static Rotate identity()
Get a zero-degree rotation.
Definition transforms.h:215
Coord angle() const
Definition transforms.h:204
bool operator==(Rotate const &o) const
Definition transforms.h:208
Rotate(Coord x, Coord y)
Construct a rotation from the coordinates of its characteristic vector.
Definition transforms.h:198
Coord operator[](Dim2 dim) const
Definition transforms.h:205
friend class Point
Definition transforms.h:221
Point const & vector() const
Get the characteristic vector of the rotation.
Definition transforms.h:203
Rotate()=default
Construct a zero-degree rotation.
Scaling from the origin.
Definition transforms.h:150
Scale()=default
Create a scaling that doesn't do anything.
Scale & operator*=(Scale const &b)
Definition transforms.h:168
Scale(Coord s)
Create an uniform scaling from a single scaling factor.
Definition transforms.h:160
Coord operator[](Dim2 d) const
Definition transforms.h:163
Scale inverse() const
Definition transforms.h:172
static Scale identity()
Definition transforms.h:173
Scale(Coord x, Coord y)
Create a scaling from two scaling factors.
Definition transforms.h:158
Coord operator[](unsigned d) const
Definition transforms.h:164
Point vector() const
Definition transforms.h:171
Scale pow(Scale const &s, int n)
Specialization of exponentiation for Scale.
Definition transforms.h:336
Scale(Point const &p)
Create a scaling from two scaling factors given as coordinates of a point.
Definition transforms.h:156
Coord & operator[](unsigned d)
Definition transforms.h:167
bool operator==(Scale const &o) const
Definition transforms.h:169
Coord & operator[](Dim2 d)
Definition transforms.h:166
Common base for shearing transforms.
Definition transforms.h:234
Coord factor() const
Definition transforms.h:240
void setFactor(Coord nf)
Definition transforms.h:241
ShearBase()=default
ShearBase(Coord _f)
Definition transforms.h:238
static S identity()
Definition transforms.h:245
bool operator==(ShearBase< S > const &s) const
Definition transforms.h:243
S inverse() const
Definition transforms.h:244
S & operator*=(S const &s)
Definition transforms.h:242
Base template for transforms.
Definition transforms.h:82
Affine operator*(T2 const &t) const
Definition transforms.h:85
Translation by a vector.
Definition transforms.h:115
bool operator==(Translate const &o) const
Definition transforms.h:129
Translate pow(Translate const &t, int n)
Specialization of exponentiation for Translate.
Definition transforms.h:342
static Translate identity()
Get a translation that doesn't do anything.
Definition transforms.h:135
Point vector() const
Definition transforms.h:131
Translate(Coord x, Coord y)
Construct a translation from its coordinates.
Definition transforms.h:123
Translate()=default
Create a translation that doesn't do anything.
Coord operator[](unsigned dim) const
Definition transforms.h:127
Translate(Point const &p)
Construct a translation from its vector.
Definition transforms.h:121
Translate inverse() const
Get the inverse translation.
Definition transforms.h:133
Translate & operator*=(Translate const &o)
Definition transforms.h:128
Coord operator[](Dim2 dim) const
Definition transforms.h:126
Vertical shearing.
Definition transforms.h:274
VShear(Coord h)
Definition transforms.h:277
VShear()=default
Combination of a translation and uniform scale.
Definition transforms.h:292
Zoom(Coord s, Point const &t)
Construct a zoom from a scaling factor and a translation.
Definition transforms.h:303
Zoom(Translate const &t)
Definition transforms.h:301
Zoom inverse() const
Definition transforms.h:320
Zoom(Coord s, Translate const &t)
Definition transforms.h:304
Zoom()=default
static Zoom identity()
Definition transforms.h:321
Zoom(Point const &t)
Construct a zoom from a translation.
Definition transforms.h:300
Coord scale() const
Definition transforms.h:316
bool operator==(Zoom const &z) const
Definition transforms.h:314
void setTranslation(Point const &p)
Definition transforms.h:319
static Zoom map_rect(Rect const &old_r, Rect const &new_r)
Zoom between rectangles.
Point translation() const
Definition transforms.h:318
friend class Affine
Definition transforms.h:325
Zoom(Coord s)
Construct a zoom from a scaling factor.
Definition transforms.h:298
void setScale(Coord s)
Definition transforms.h:317
Point _trans
Definition transforms.h:294
Coord _scale
Definition transforms.h:293
Zoom & operator*=(Zoom const &z)
Definition transforms.h:309
Css & result
Contains forward declarations of 2geom types.
Dim2
2D axis enumeration (X or Y).
Definition coord.h:48
double Coord
Floating point type used to store coordinates.
Definition coord.h:76
constexpr Coord EPSILON
Default "acceptably small" value.
Definition coord.h:84
@ Y
Definition coord.h:48
@ X
Definition coord.h:48
Affine reflection(Point const &vector, Point const &origin)
Reflects objects about line.
T pow(T const &t, int n)
Integer exponentiation for transforms.
Definition transforms.h:98
Various utility functions.
Definition affine.h:22
double atan2(Point const &p)
bool are_near(Affine const &a1, Affine const &a2, Coord eps=EPSILON)
Type requirements for transforms.
Definition transforms.h:50