1 #ifndef SEEN_Geom_TRANSFORMS_H
2 #define SEEN_Geom_TRANSFORMS_H
4 #include "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); }
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 Coord operator[](Dim2 const dim) const { return vec[dim]; }
88 inline Coord operator[](unsigned const dim) const { return vec[dim]; }
89 inline bool operator==(Rotate const &o) const { return vec == o.vec; }
90 inline bool operator!=(Rotate const &o) const { return vec != o.vec; }
92 Rotate inverse() const { return Rotate( Point(vec[X], -vec[Y]) ); }
93 static Rotate from_degrees(Coord deg) {
94 Coord rad = (deg / 180.0) * M_PI;
95 return Rotate(rad);
96 }
98 friend Point operator*(Point const &v, Rotate const &r);
99 inline Rotate operator*(Rotate const &b) const { return Rotate(vec * b); }
100 };
102 inline Point operator*(Point const &v, Rotate const &r) { return v ^ r.vec; }
104 Matrix operator*(Translate const &t, Scale const &s);
105 Matrix operator*(Translate const &t, Rotate const &r);
107 Matrix operator*(Scale const &s, Translate const &t);
108 Matrix operator*(Scale const &s, Matrix const &m);
110 Matrix operator*(Matrix const &m, Translate const &t);
111 Matrix operator*(Matrix const &m, Scale const &s);
112 Matrix operator*(Matrix const &m, Rotate const &r);
113 Matrix operator*(Matrix const &m1, Matrix const &m2);
115 //TODO: matrix to trans/scale/rotate
117 } /* namespace Geom */
120 #endif /* !SEEN_Geom_TRANSFORMS_H */
122 /*
123 Local Variables:
124 mode:c++
125 c-file-style:"stroustrup"
126 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
127 indent-tabs-mode:nil
128 fill-column:99
129 End:
130 */
131 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :