1 /**************************************************************************/
2 /*  Copyright 2012 Tim Day                                                */
3 /*                                                                        */
4 /*  This file is part of Evolvotron                                       */
5 /*                                                                        */
6 /*  Evolvotron is free software: you can redistribute it and/or modify    */
7 /*  it under the terms of the GNU General Public License as published by  */
8 /*  the Free Software Foundation, either version 3 of the License, or     */
9 /*  (at your option) any later version.                                   */
10 /*                                                                        */
11 /*  Evolvotron is distributed in the hope that it will be useful,         */
12 /*  but WITHOUT ANY WARRANTY; without even the implied warranty of        */
13 /*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         */
14 /*  GNU General Public License for more details.                          */
15 /*                                                                        */
16 /*  You should have received a copy of the GNU General Public License     */
17 /*  along with Evolvotron.  If not, see <http://www.gnu.org/licenses/>.   */
18 /**************************************************************************/
19 
20 /*! \file
21   \brief Interface for class Transform.
22 */
23 
24 #ifndef _transform_h_
25 #define _transform_h_
26 
27 #include "common.h"
28 
29 #include "xyz.h"
30 
31 //! Class representing 3d linear transforms.
32 /*! Not much functionality currently because is used mainly to pass info around for warp functionality
33  */
34 class Transform
35 {
36  public:
37   //! Default constructor.  NB Doesn't set up identity or anything.
38   Transform();
39 
40   //! Copy constructor.
41   Transform(const Transform&);
42 
43   //! Constructor specifying column vectors.
44   Transform(const XYZ& t,const XYZ& x,const XYZ& y,const XYZ& z);
45 
46   //! Constructor specifying column-wise elements.
47   Transform(const std::vector<real>& v,uint starting_element=0);
48 
49   //! virtual destructor in case of extension
50   virtual ~Transform();
51 
52   //@{
53   //! Accessor
translate()54   const XYZ& translate() const
55     {
56       return _translate;
57     }
basis_x()58   const XYZ& basis_x() const
59     {
60       return _basis_x;
61     }
basis_y()62   const XYZ& basis_y() const
63     {
64       return _basis_y;
65     }
basis_z()66   const XYZ& basis_z() const
67     {
68       return _basis_z;
69     }
70 
translate(const XYZ & t)71   void translate(const XYZ &t)
72      {
73        _translate=t;
74      }
basis_x(const XYZ & x)75   void basis_x(const XYZ &x)
76      {
77        _basis_x=x;
78      }
basis_y(const XYZ & y)79   void basis_y(const XYZ &y)
80      {
81        _basis_y=y;
82      }
basis_z(const XYZ & z)83   void basis_z(const XYZ &z)
84      {
85        _basis_z=z;
86      }
87   //@}
88 
89   //! Get column-wise element values as a vector
90   const std::vector<real> get_columns() const;
91 
92   //! Transform a point
93   const XYZ transformed(const XYZ& p) const;
94 
95   //! Transform a point with no translation
96   const XYZ transformed_no_translate(const XYZ& p) const;
97 
98   //! Concatenate transforms
99   Transform& concatenate_on_right(const Transform& t);
100 
101   //! Concatenate transforms
102   Transform& concatenate_on_left(const Transform& t);
103 
104  protected:
105   //@{
106   //! Translation component (column vector in matrix).
107   XYZ _translate;
108   XYZ _basis_x;
109   XYZ _basis_y;
110   XYZ _basis_z;
111 };
112 
113 inline const XYZ operator*(const Transform& t,const XYZ& p)
114 {
115   return
116      t.basis_x()*p.x()
117     +t.basis_y()*p.y()
118     +t.basis_z()*p.z()
119     +t.translate();
120 }
121 
122 inline std::ostream& operator<<(std::ostream& out,const Transform& t)
123 {
124   return out << t.translate() << ";" << t.basis_x() << "," << t.basis_y() << "," << t.basis_z();
125 }
126 
127 class TransformIdentity : public Transform
128 {
129  public:
TransformIdentity()130   TransformIdentity()
131     {
132       translate(XYZ(0.0,0.0,0.0));
133       basis_x(XYZ(1.0,0.0,0.0));
134       basis_y(XYZ(0.0,1.0,0.0));
135       basis_z(XYZ(0.0,0.0,1.0));
136     }
137 };
138 
139 class TransformTranslate : public Transform
140 {
141  public:
TransformTranslate(const XYZ & t)142   TransformTranslate(const XYZ& t)
143     {
144       translate(t);
145       basis_x(XYZ(1.0,0.0,0.0));
146       basis_y(XYZ(0.0,1.0,0.0));
147       basis_z(XYZ(0.0,0.0,1.0));
148     }
149 };
150 
151 class TransformScale : public Transform
152 {
153  public:
TransformScale(const XYZ & s)154   TransformScale(const XYZ& s)
155     {
156       translate(XYZ(0.0,0.0,0.0));
157       basis_x(XYZ(s.x(),0.0,0.0));
158       basis_y(XYZ(0.0,s.y(),0.0));
159       basis_z(XYZ(0.0,0.0,s.z()));
160     }
TransformScale(real s)161   TransformScale(real s)
162     {
163       translate(XYZ(0.0,0.0,0.0));
164       basis_x(XYZ(s,0.0,0.0));
165       basis_y(XYZ(0.0,s,0.0));
166       basis_z(XYZ(0.0,0.0,s));
167     }
168 };
169 
170 
171 class TransformRotateX : public Transform
172 {
173  public:
TransformRotateX(real a)174   TransformRotateX(real a)
175     {
176       const real sa=sin(a);
177       const real ca=cos(a);
178 
179       translate(XYZ(0.0,0.0,0.0));
180       basis_x(XYZ(1.0,0.0,0.0));
181       basis_y(XYZ(0.0, ca , sa ));
182       basis_z(XYZ(0.0,-sa , ca ));
183     }
184 };
185 
186 class TransformRotateY : public Transform
187 {
188  public:
TransformRotateY(real a)189   TransformRotateY(real a)
190     {
191       const real sa=sin(a);
192       const real ca=cos(a);
193 
194       translate(XYZ(0.0,0.0,0.0));
195       basis_x(XYZ( ca ,0.0,-sa ));
196       basis_y(XYZ(0.0,1.0,0.0));
197       basis_z(XYZ( sa ,0.0, ca ));
198     }
199 };
200 
201 class TransformRotateZ : public Transform
202 {
203  public:
TransformRotateZ(real a)204   TransformRotateZ(real a)
205     {
206       const real sa=sin(a);
207       const real ca=cos(a);
208 
209       translate(XYZ(0.0,0.0,0.0));
210       basis_x(XYZ( ca , sa ,0.0));
211       basis_y(XYZ(-sa , ca ,0.0));
212       basis_z(XYZ(0.0,0.0,1.0));
213     }
214 };
215 
216 #endif
217