Code

Merging from trunk
[inkscape.git] / src / 2geom / transforms.h
1 #ifndef SEEN_Geom_TRANSFORMS_H
2 #define SEEN_Geom_TRANSFORMS_H
4 #include <2geom/matrix.h>
5 #include <cmath>
7 namespace Geom {
9 template <typename T>
10 struct TransformConcept {
11     T t;
12     Matrix m;
13     Point p;
14     void constraints() {
15         m = t;  //implicit conversion
16         t = t.inverse();
17         p = p * t;
18         t = t * t;
19     }
20 };
23 class Rotate;
24 class Translate {
25   private:
26     Translate();
27     Point vec;
28   public:
29     explicit Translate(Point const &p) : vec(p) {}
30     explicit Translate(Coord const x, Coord const y) : vec(x, y) {}
31     inline operator Matrix() const { return Matrix(1, 0, 0, 1, vec[X], vec[Y]); }
33     inline Coord operator[](Dim2 const dim) const { return vec[dim]; }
34     inline Coord operator[](unsigned const dim) const { return vec[dim]; }
35     inline bool operator==(Translate const &o) const { return vec == o.vec; }
36     inline bool operator!=(Translate const &o) const { return vec != o.vec; }
38     inline Translate inverse() const { return Translate(-vec); }
40     friend Point operator*(Point const &v, Translate const &t);
41     inline Translate operator*(Translate const &b) const { return Translate(vec + b.vec); }
42     
43     friend Matrix operator*(Translate const &t, Rotate const &r);
44 };
46 inline Point operator*(Point const &v, Translate const &t) { return v + t.vec; }
48 class Scale {
49   private:
50     Point vec;
51     Scale();
52   public:
53     explicit Scale(Point const &p) : vec(p) {}
54     Scale(Coord const x, Coord const y) : vec(x, y) {}
55     explicit Scale(Coord const s) : vec(s, s) {}
56     inline operator Matrix() const { return Matrix(vec[X], 0, 0, vec[Y], 0, 0); }
58     inline Coord operator[](Dim2 const d) const { return vec[d]; }
59     inline Coord operator[](unsigned const d) const { return vec[d]; }
60     //TODO: should we keep these mutators? add them to the other transforms?
61     inline Coord &operator[](Dim2 const d) { return vec[d]; }
62     inline Coord &operator[](unsigned const d) { return vec[d]; }
63     inline bool operator==(Scale const &o) const { return vec == o.vec; }
64     inline bool operator!=(Scale const &o) const { return vec != o.vec; }
66     inline Scale inverse() const { return Scale(1./vec[0], 1./vec[1]); }
68     friend Point operator*(Point const &v, Translate const &t);
69     inline Scale operator*(Scale const &b) const { return Scale(vec[X]*b[X], vec[Y]*b[Y]); }
70 };
72 inline Point operator*(Point const &p, Scale const &s) { return Point(p[X] * s[X], p[Y] * s[Y]); }
74 /** Notionally an Geom::Matrix corresponding to rotation about the origin.
75     Behaves like Geom::Matrix for multiplication.
76 **/
77 class Rotate {
78   private:
79     Rotate() {}
80     Point vec;
81   public:    
82     explicit Rotate(Coord theta) : vec(std::cos(theta), std::sin(theta)) {}
83     Rotate(Point const &p) {Point v = p; v.normalize(); vec = v;} //TODO: UGLY!
84     explicit Rotate(Coord x, Coord y) { Rotate(Point(x, y)); }
85     inline operator Matrix() const { return Matrix(vec[X], vec[Y], -vec[Y], vec[X], 0, 0); }
87     inline Point vector() const { return vec; }
88     inline Coord operator[](Dim2 const dim) const { return vec[dim]; }
89     inline Coord operator[](unsigned const dim) const { return vec[dim]; }
90     inline bool operator==(Rotate const &o) const { return vec == o.vec; }
91     inline bool operator!=(Rotate const &o) const { return vec != o.vec; }
93     inline Rotate inverse() const {
94         Rotate r;
95         r.vec = Point(vec[X], -vec[Y]); 
96         return r;
97     }
98     static Rotate from_degrees(Coord deg) {
99         Coord rad = (deg / 180.0) * M_PI;
100         return Rotate(rad);
101     }
103     friend Point operator*(Point const &v, Rotate const &r);
104     inline Rotate operator*(Rotate const &b) const { return Rotate(vec * b); }
105 };
107 inline Point operator*(Point const &v, Rotate const &r) { return v ^ r.vec; }
109 Matrix operator*(Translate const &t, Scale const &s);
110 Matrix operator*(Translate const &t, Rotate const &r);
112 Matrix operator*(Scale const &s, Translate const &t);
113 Matrix operator*(Scale const &s, Matrix const &m);
115 Matrix operator*(Matrix const &m, Translate const &t);
116 Matrix operator*(Matrix const &m, Scale const &s);
117 Matrix operator*(Matrix const &m, Rotate const &r);
118 Matrix operator*(Matrix const &m1, Matrix const &m2);
120 Translate pow(Translate const &t, int n);
121 Scale pow(Scale const &t, int n);
122 Rotate pow(Rotate t, int n);
123 Matrix pow(Matrix t, int n);
125 //TODO: matrix to trans/scale/rotate
127 } /* namespace Geom */
130 #endif /* !SEEN_Geom_TRANSFORMS_H */
132 /*
133   Local Variables:
134   mode:c++
135   c-file-style:"stroustrup"
136   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
137   indent-tabs-mode:nil
138   fill-column:99
139   End:
140 */
141 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :