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