/[gzz]/gzz/gfx/libcoords/Coords.cxx
ViewVC logotype

Diff of /gzz/gfx/libcoords/Coords.cxx

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.19 by tjl, Tue Oct 1 06:22:54 2002 UTC revision 1.20 by tjl, Tue Oct 1 07:55:44 2002 UTC
# Line 5  Line 5 
5  namespace Coords {  namespace Coords {
6      DBGVAR(dbg, "Coords.general");      DBGVAR(dbg, "Coords.general");
7    
8        // The (STL-like) concept of transform:
9        // enum { NParams = n };
10        // void tr(const ZPt &from, ZPt &to) const
11        // bool canPerformGL()
12        // bool performGL()
13        // float nonlinearity(const ZPt &p, float radius)
14        // void setParams(array/iterator i)
15        // typedef X InverseType;
16        //
17        // This approach is needed because inverse transforms and transforms need
18        // to call their parents at different points.
19        //
20        // XXX Nonlinearity is calculated wrong!
21        
22        template<class Transform> class TransformCoordSysBase : public CoordSys {
23        protected:
24            Transform t;
25        public:
26            TransformCoordSysBase() : t() { }
27            TransformCoordSysBase(const Transform &tr) : t(tr) { }
28            virtual void setParams(float *params) {
29                t.setParams(params);
30            }
31            bool canPerformGL() {
32                return t.canPerformGL() && super->canPerformGL();  
33            }
34        };
35    
36        template<class Transform> class InverseTransformCoordSys;
37    
38        template<class Transform> class TransformCoordSys : public TransformCoordSysBase<Transform> {
39        public:
40            virtual ZPt transform(const ZPt &p) const {
41                ZPt mp;
42                t.tr(p, mp);
43                return super->transform(mp);
44            }
45            virtual void vertex(const ZPt &p) const {
46                ZPt mp;
47                t.tr(p, mp);
48                super->vertex(mp);
49            }
50            virtual bool performGL() {
51                if(!super->performGL()) return false;
52                return t.performGL();
53            }
54    
55            virtual CoordSys *createInverse() {
56                CoordSys *sinv = super->createInverse();
57                typedef InverseTransformCoordSys<typename Transform::InverseType> Inv;
58                Inv *ret = new Inv(sinv, t);
59                ret->setOriginal(this);
60                return ret;
61            }
62    
63        };
64    
65        template<class Transform> class InverseTransformCoordSys : public TransformCoordSysBase<Transform> {
66        public:
67            template<class Original> InverseTransformCoordSys(CoordSys *s, Original &o) :
68                    TransformCoordSysBase<Transform>(o.inverseTransform()) {
69                super = s;
70            }
71    
72            virtual ZPt transform(const ZPt &p) const {
73                ZPt mp = super->transform(p);
74                ZPt res;
75                t.tr(mp, res);
76                return res;
77            }
78            virtual void vertex(const ZPt &p) const {
79                ZPt mp = transform(p);
80                glVertex3f(mp.x, mp.y, mp.z);
81            }
82            virtual bool performGL() {
83                if(!t.performGL()) return false;
84                return super->performGL();
85            }
86            void setOriginal(CoordSys *orig) { inverse = orig; }
87    
88        };
89    
90      class RootCoords : public CoordSys {      class RootCoords : public CoordSys {
91      public:      public:
92            virtual void setParams(float *params) { }
93          virtual ZPt transform(const ZPt &p) const {          virtual ZPt transform(const ZPt &p) const {
94              return p;              return p;
95          }          }
# Line 25  namespace Coords { Line 108  namespace Coords {
108      /** Affine coordinate system (in xy), offset in z.      /** Affine coordinate system (in xy), offset in z.
109       * Parameter layout: x, y, depth, xx, xy, yx, yy       * Parameter layout: x, y, depth, xx, xy, yx, yy
110       */       */
111      class AffineXYCoords : public CoordSys {      class AffineXYCoords {
112          float params[7];          float params[7];
113      public:      public:
114          enum { NParams = 7 };          enum { NParams = 7 };
115          virtual void setParams(float *params) {          template<class Ptr> void setParams(Ptr p) {
116              for(int i=0; i<7; i++)              for(int i=0; i<7; i++)
117                  this->params[i] = params[i];                  params[i] = p[i];
118          }          }
119          /** Perform the internal transformation of this          /** Perform the internal transformation of this
120           * coordsys.           * coordsys.
# Line 41  namespace Coords { Line 124  namespace Coords {
124              to.y = params[1] + from.x * params[5] + from.y * params[6];              to.y = params[1] + from.x * params[5] + from.y * params[6];
125              to.z = params[2] + from.z;              to.z = params[2] + from.z;
126          }          }
127          virtual ZPt transform(const ZPt &p) const {          bool canPerformGL() { return true; }
128              ZPt mp;          bool performGL() {
             tr(p, mp);  
             return super->transform(mp);  
         }  
         virtual void vertex(const ZPt &p) const {  
             ZPt mp;  
             tr(p, mp);  
             super->vertex(mp);  
         }  
         virtual bool canPerformGL() { return super->canPerformGL(); }  
         virtual bool performGL() {  
             if(!super->performGL()) return false;  
129              GLfloat matrix[16] = {              GLfloat matrix[16] = {
130                  params[3], params[5], 0, 0,                  params[3], params[5], 0, 0,
131                  params[4], params[6], 0, 0,                  params[4], params[6], 0, 0,
# Line 63  namespace Coords { Line 135  namespace Coords {
135              glMultMatrixf(matrix);              glMultMatrixf(matrix);
136              return true;              return true;
137          }          }
138          virtual float nonlinearity(const ZPt &p, float radius) {          float nonlinearity(const ZPt &p, float radius) {
139              float mult = 0.5 * (fabs(params[3]) + fabs(params[6]));              return 0;
             ZPt p2;  
             tr(p, p2);  
             return mult * super->nonlinearity(p2, mult * radius);  
140          }          }
141    
142      protected:          typedef AffineXYCoords InverseType;
143          virtual CoordSys *createInverse() {          AffineXYCoords inverseTransform() {
144              CoordSys *sup = super->createInverse();              AffineXYCoords inv;
             AffineXYCoords *inv = new AffineXYCoords();  
             inv->setSuper(sup);  
145              double det = params[3] * params[6] - params[4] * params[5];              double det = params[3] * params[6] - params[4] * params[5];
146              // XXX If det small, trouble!!              // XXX If det small, trouble!!
147              inv->params[3] = params[6] / det;              inv.params[3] = params[6] / det;
148              inv->params[4] = -params[4] / det;              inv.params[4] = -params[4] / det;
149              inv->params[5] = -params[5] / det;              inv.params[5] = -params[5] / det;
150              inv->params[6] = params[3] / det;              inv.params[6] = params[3] / det;
151    
152              inv->params[0] = -(params[0] * inv->params[3] +              inv.params[0] = -(params[0] * inv.params[3] +
153                                  params[1] * inv->params[4]);                                  params[1] * inv.params[4]);
154              inv->params[1] = -(params[0] * inv->params[5] +              inv.params[1] = -(params[0] * inv.params[5] +
155                                  params[1] * inv->params[6]);                                  params[1] * inv.params[6]);
156              inv->params[2] = -params[2];              inv.params[2] = -params[2];
157              return inv;              return inv;
158          }          }
159    
# Line 95  namespace Coords { Line 162  namespace Coords {
162      /** Rotation clockwise.      /** Rotation clockwise.
163       * Parameter layout: angle (degrees)       * Parameter layout: angle (degrees)
164       */       */
165      class RotateXYCoords : public CoordSys {      class RotateXYCoords {
166          float s, c;          float a, s, c;
167      public:      public:
168          enum { NParams = 1 };          enum { NParams = 1 };
169          virtual void setParams(float *params) {          template<class Ptr> void setParams(Ptr p) {
170              CoordSys::setParams(params);              a = p[0];
171              s = sin(params[0] * M_PI / 180);          }
172              c = cos(params[0] * M_PI / 180);          void angleWasSet() {
173                s = sin(a * M_PI / 180);
174                c = cos(a * M_PI / 180);
175          }          }
176          /** Perform the internal transformation of this          /** Perform the internal transformation of this
177           * coordsys.           * coordsys.
# Line 112  namespace Coords { Line 181  namespace Coords {
181              to.y = -s * from.x + c * from.y;              to.y = -s * from.x + c * from.y;
182              to.z = from.z;              to.z = from.z;
183          }          }
184          virtual ZPt transform(const ZPt &p) const {          bool canPerformGL() { return true; }
185              ZPt mp;          bool performGL() {
186              tr(p, mp);              glRotatef(a, 0, 0, 1);
187              return super->transform(mp);              return true;
188          }          }
189          virtual void vertex(const ZPt &p) const {          typedef RotateXYCoords InverseType;
190              ZPt mp;          RotateXYCoords inverseTransform() {
191              tr(p, mp);              RotateXYCoords inv;
192              super->vertex(mp);              inv.a = -a;
193                inv.angleWasSet();
194                return inv;
195          }          }
196          virtual bool canPerformGL() { return super->canPerformGL(); }          float nonlinearity(const ZPt &p, float radius) {
197          virtual bool performGL() {              return 0;
             if(!super->performGL()) return false;  
             glRotatef(params[0], 0, 0, 1);  
             return true;  
198          }          }
199      };      };
200    
201      /** Rotation around 3D vector.      /** Rotation around 3D vector.
202       * Params: x, y, z, angle       * Params: x, y, z, angle
203       */       */
204      class RotateXYZCoords : public CoordSys {      class RotateXYZCoords {
205          ZVec vec; float s, c;          ZVec vec; float a, s, c;
206      public:      public:
207          enum { NParams = 4 };          enum { NParams = 4 };
208          virtual void setParams(float *params) {          template<class Ptr> void setParams(Ptr p) {
209              CoordSys::setParams(params);              vec.x = p[0];
210              vec.x = params[0];              vec.y = p[1];
211              vec.y = params[1];              vec.z = p[2];
             vec.z = params[2];  
212              vec = vec.normalized();              vec = vec.normalized();
213                a = p[3];
214    
215                angleWasSet();
216    
217              s = sin(params[3] * M_PI / 180);          }
218              c = cos(params[3] * M_PI / 180);          void angleWasSet() {
219                s = sin(a * M_PI / 180);
220                c = cos(a * M_PI / 180);
221          }          }
222          /** Perform the internal transformation of this          /** Perform the internal transformation of this
223           * coordsys.           * coordsys.
# Line 159  namespace Coords { Line 231  namespace Coords {
231              ZVec ortho = para.crossp(vec).normalized();              ZVec ortho = para.crossp(vec).normalized();
232              to = ZPt( same * vec + paral * (c * para - s * ortho) );              to = ZPt( same * vec + paral * (c * para - s * ortho) );
233          }          }
234          virtual ZPt transform(const ZPt &p) const {          virtual bool canPerformGL() { return true; }
             ZPt mp;  
             tr(p, mp);  
             return super->transform(mp);  
         }  
         virtual void vertex(const ZPt &p) const {  
             ZPt mp;  
             tr(p, mp);  
             super->vertex(mp);  
         }  
         virtual bool canPerformGL() { return super->canPerformGL(); }  
235          virtual bool performGL() {          virtual bool performGL() {
236              if(!super->performGL()) return false;              glRotatef(a, vec.x, vec.y, vec.z);
             glRotatef(params[3], vec.x, vec.y, vec.z);  
237              return true;              return true;
238          }          }
239      } ;          typedef RotateXYZCoords InverseType;
240      ;          RotateXYZCoords inverseTransform() {
241                RotateXYZCoords inv;
242                inv.vec = vec;
243                inv.a = -a;
244                inv.angleWasSet();
245                return inv;
246            }
247            float nonlinearity(const ZPt &p, float radius) {
248                return 0;
249            }
250        };
251    
252      /** Scale.      /** Scale.
253       * Params: sx, sy, sz       * Params: sx, sy, sz
254       */       */
255      class ScaleXYZCoords : public CoordSys {      class ScaleXYZCoords {
256          ZVec vec;          ZVec vec;
257            friend class DistortCoords;
258      public:      public:
259          enum { NParams = 3 };          enum { NParams = 3 };
260          virtual void setParams(float *params) {          template<class Ptr> void setParams(Ptr p) {
261              CoordSys::setParams(params);              vec.x = p[0];
262              vec.x = params[0];              vec.y = p[1];
263              vec.y = params[1];              vec.z = p[2];
             vec.z = params[2];  
264          }          }
265          /** Perform the internal transformation of this          /** Perform the internal transformation of this
266           * coordsys.           * coordsys.
# Line 199  namespace Coords { Line 270  namespace Coords {
270              to.y = from.y * vec.y;              to.y = from.y * vec.y;
271              to.z = from.z * vec.z;              to.z = from.z * vec.z;
272          }          }
273          virtual ZPt transform(const ZPt &p) const {          virtual bool canPerformGL() { return true; }
             ZPt mp;  
             tr(p, mp);  
             return super->transform(mp);  
         }  
         virtual void vertex(const ZPt &p) const {  
             ZPt mp;  
             tr(p, mp);  
             super->vertex(mp);  
         }  
         virtual bool canPerformGL() { return super->canPerformGL(); }  
274          virtual bool performGL() {          virtual bool performGL() {
             if(!super->performGL()) return false;  
275              glScalef(vec.x, vec.y, vec.z);              glScalef(vec.x, vec.y, vec.z);
276              return true;              return true;
277          }          }
278            typedef ScaleXYZCoords InverseType;
279            ScaleXYZCoords inverseTransform() {
280                ScaleXYZCoords inv;
281                inv.vec.x = 1/vec.x; // XXX Numerical accuracy?
282                inv.vec.y = 1/vec.y;
283                inv.vec.z = 1/vec.z;
284                return inv;
285            }
286            float nonlinearity(const ZPt &p, float radius) {
287                return 0;
288            }
289      } ;      } ;
     ;  
290    
291    
292      /** Distorted coordinate system.      /** Distorted coordinate system.
# Line 224  namespace Coords { Line 294  namespace Coords {
294       * W and h give the width and height in the inside coordinate system       * W and h give the width and height in the inside coordinate system
295       * of the zoomed area.       * of the zoomed area.
296       */       */
297      class DistortCoords : public CoordSys {      class DistortCoords {
298          float x, y;          float x, y;
299          float w, h;          float w, h;
300          float mmin;          float mmin;
# Line 232  namespace Coords { Line 302  namespace Coords {
302          Fisheye::vector_mag_isotropic<Fisheye::scalar_mag_atan> distort;          Fisheye::vector_mag_isotropic<Fisheye::scalar_mag_atan> distort;
303      public:      public:
304          enum { NParams = 6 };          enum { NParams = 6 };
305          virtual void setParams(float *params) {          template<class Ptr> void setParams(Ptr p) {
306              CoordSys::setParams(params);              x = p[0];
307              x = params[0];              y = p[1];
308              y = params[1];              mmax = exp(p[2]);
309              mmax = exp(params[2]);              mmin = exp(p[3]);
310              mmin = exp(params[3]);              w = p[4];
311              w = params[4];              h = p[5];
             h = params[5];  
312              distort.f = Fisheye::scalar_mag_atan(mmax / mmin);              distort.f = Fisheye::scalar_mag_atan(mmax / mmin);
313          }          }
         virtual ZPt transform(const ZPt &p) const {  
             ZPt mp;  
             tr(p, mp);  
             return super->transform(mp);  
         }  
         virtual void vertex(const ZPt &p) const {  
             ZPt mp;  
             tr(p, mp);  
             super->vertex(mp);  
         }  
314          void tr(const ZPt &from, ZPt &to) const {          void tr(const ZPt &from, ZPt &to) const {
315              ZPt p = ZPt((from.x-x) / w, (from.y-y)/ h, from.z);              ZPt p = ZPt((from.x-x) / w, (from.y-y)/ h, from.z);
316              to = distort(p);              to = distort(p);
# Line 260  namespace Coords { Line 319  namespace Coords {
319              to.y *= mmin;              to.y *= mmin;
320              to.x += x; to.y += y;              to.x += x; to.y += y;
321          }          }
322          virtual float nonlinearity(const ZPt &p, float radius) {          typedef ScaleXYZCoords InverseType; // XXX !!!
323            ScaleXYZCoords inverseTransform() {
324                ScaleXYZCoords inv;
325                inv.vec = ZVec(1,1,1); // XXX!
326                return inv;
327            }
328            bool canPerformGL() { return false; }
329            bool performGL() { return false; }
330    
331            float nonlinearity(const ZPt &p, float radius) {
332              float wh = 0.5*(w+h);              float wh = 0.5*(w+h);
333              float dist = hypot((p.x-x)/w, (p.y-y)/h) - radius/wh;              float dist = hypot((p.x-x)/w, (p.y-y)/h) - radius/wh;
334              if(dist < 0) dist = 0;              if(dist < 0) dist = 0;
# Line 275  namespace Coords { Line 343  namespace Coords {
343      template<class C> class Factory : public SomeFactory {      template<class C> class Factory : public SomeFactory {
344      public:      public:
345          virtual int nparams() { return C::NParams; }          virtual int nparams() { return C::NParams; }
346          virtual CoordSys *create() { return new C(); }          virtual CoordSys *create() { return new TransformCoordSys<C>(); }
347      };      };
348    
349      extern SomeFactory* facs[];      extern SomeFactory* facs[];

Legend:
Removed from v.1.19  
changed lines
  Added in v.1.20

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26