soma-io 6.0.6
transformation.h
Go to the documentation of this file.
1/* This software and supporting documentation are distributed by
2 * Institut Federatif de Recherche 49
3 * CEA/NeuroSpin, Batiment 145,
4 * 91191 Gif-sur-Yvette cedex
5 * France
6 *
7 * This software is governed by the CeCILL-B license under
8 * French law and abiding by the rules of distribution of free software.
9 * You can use, modify and/or redistribute the software under the
10 * terms of the CeCILL-B license as circulated by CEA, CNRS
11 * and INRIA at the following URL "http://www.cecill.info".
12 *
13 * As a counterpart to the access to the source code and rights to copy,
14 * modify and redistribute granted by the license, users are provided only
15 * with a limited warranty and the software's author, the holder of the
16 * economic rights, and the successive licensors have only limited
17 * liability.
18 *
19 * In this respect, the user's attention is drawn to the risks associated
20 * with loading, using, modifying and/or developing or reproducing the
21 * software by the user in light of its specific status of free software,
22 * that may mean that it is complicated to manipulate, and that also
23 * therefore means that it is reserved for developers and experienced
24 * professionals having in-depth computer knowledge. Users are therefore
25 * encouraged to load and test the software's suitability as regards their
26 * requirements in conditions enabling the security of their systems and/or
27 * data to be ensured and, more generally, to use and operate it in the
28 * same conditions as regards security.
29 *
30 * The fact that you are presently reading this means that you have had
31 * knowledge of the CeCILL-B license and that you accept its terms.
32 */
33
34#ifndef SOMAIO_TRANSFORMATION_TRANSFORMATION_H
35#define SOMAIO_TRANSFORMATION_TRANSFORMATION_H
36/*
37 * These classes used to be in aimsdata, but they are used in Transformation
38 * classes, which are needed in IO, so they have been moved to soma-io
39 * in AIMS 4.7.
40 */
41
42#include <stdexcept>
43
45#include <cartobase/smart/rcptr.h>
46#include <cartobase/type/types.h>
47
48namespace soma
49{
50
57 class Transformation : public virtual carto::RCObject
58 {
59 public:
60 virtual ~Transformation();
61
62 virtual Transformation & operator = ( const Transformation & other );
63
75 virtual bool isIdentity() const
76 {
77 return false;
78 }
79
81 const carto::Object header() const { return _header; }
83
84 virtual std::vector<double>
85 transform( const std::vector<double> & pos ) const = 0;
86 virtual std::vector<float>
87 transform( const std::vector<float> & pos ) const;
88 virtual std::vector<int> transform( const std::vector<int> & pos ) const;
89
90 virtual std::vector<double>
91 transformVector( const std::vector<double> & pos ) const;
92 virtual std::vector<float>
93 transformVector( const std::vector<float> & pos ) const;
94 virtual std::vector<int>
95 transformVector( const std::vector<int> & pos ) const;
96
102 virtual bool invertible() const
103 {
104 return false;
105 };
106
112 virtual std::unique_ptr<Transformation> getInverse() const
113 {
114 throw std::logic_error("not implemented");
115 }
116
118 virtual bool isDirect() const = 0;
119
121 template <typename T>
122 static std::vector<T> vadd( const std::vector<T> & v1,
123 const std::vector<T> & v2 );
125 template <typename T>
126 static std::vector<T> vsub( const std::vector<T> & v1,
127 const std::vector<T> & v2 );
129 template <typename T>
130 static std::vector<T> vadd( const std::vector<T> & v1,
131 const T & v2 );
133 template <typename T>
134 static std::vector<T> vsub( const std::vector<T> & v1,
135 const T & v2 );
137 template <typename T>
138 static std::vector<T> vadd( const T & v1,
139 const std::vector<T> & v2 );
141 template <typename T>
142 static std::vector<T> vsub( const T & v1,
143 const std::vector<T> & v2 );
144
145 protected:
147
149 };
150
151
154 class Transformation3d : public virtual Transformation
155 {
156 public:
158
159 Point3dd transform( double x, double y, double z ) const;
160 Point3dd transform( const Point3dd & pos ) const;
161 Point3df transform( const Point3df & dir ) const;
162 Point3df transform( float x, float y, float z ) const;
163 Point3d transform( const Point3d & p ) const;
164 Point3di transform( const Point3di & p ) const;
165 Point3di transform( int x, int y, int z ) const;
166 virtual std::vector<double>
167 transform( const std::vector<double> & pos ) const;
168 virtual std::vector<float>
169 transform( const std::vector<float> & pos ) const;
170 virtual std::vector<int> transform( const std::vector<int> & pos ) const;
171
172 virtual std::vector<double>
173 transformVector( const std::vector<double> & pos ) const;
174 virtual std::vector<float>
175 transformVector( const std::vector<float> & pos ) const;
176 virtual std::vector<int>
177 transformVector( const std::vector<int> & pos ) const;
178
179 protected:
181
182 virtual Point3dd transformDouble( double x, double y, double z ) const = 0;
183 virtual Point3dd transformPoint3dd( const Point3dd & pos ) const;
184 virtual Point3df transformPoint3df( const Point3df & dir ) const;
185 virtual Point3d transformPoint3d( const Point3d & p ) const;
186 virtual Point3di transformPoint3di( const Point3di & p ) const;
187 virtual Point3df transformFloat( float x, float y, float z ) const;
188 virtual Point3di transformInt( int x, int y, int z ) const;
189 };
190
191
192 // --
193
194 inline std::vector<float>
195 Transformation::transform( const std::vector<float> & pos ) const
196 {
197 std::vector<double> tr
198 = transform( std::vector<double>( pos.begin(), pos.end() ) );
199 return std::vector<float>( tr.begin(), tr.end() );
200 }
201
202
203 inline std::vector<int>
204 Transformation::transform( const std::vector<int> & pos ) const
205 {
206 std::vector<double> tr
207 = transform( std::vector<double>( pos.begin(), pos.end() ) );
208 std::vector<int> itr( tr.size() );
209 for( size_t i=0; i<tr.size(); ++i )
210 itr[i] = int( rint( tr[i] ) );
211
212 return itr;
213 }
214
215
216 inline std::vector<double>
217 Transformation::transformVector( const std::vector<double> & pos ) const
218 {
219 std::vector<double> tr = transform( pos );
220 std::vector<double> tr0
221 = transform( std::vector<double>( pos.size(), 0. ) );
222 for( size_t i=0; i<tr.size(); ++i )
223 tr[i] -= tr0[i];
224 return tr;
225 }
226
227
228 inline std::vector<float>
229 Transformation::transformVector( const std::vector<float> & pos ) const
230 {
231 std::vector<double> tr
232 = transformVector( std::vector<double>( pos.begin(), pos.end() ) );
233 return std::vector<float>( tr.begin(), tr.end() );
234 }
235
236
237 inline std::vector<int>
238 Transformation::transformVector( const std::vector<int> & pos ) const
239 {
240 std::vector<double> tr
241 = transformVector( std::vector<double>( pos.begin(), pos.end() ) );
242 std::vector<int> itr( tr.size() );
243 for( size_t i=0; i<tr.size(); ++i )
244 itr[i] = int( rint( tr[i] ) );
245
246 return itr;
247 }
248
249
250 // --
251
252 inline Point3dd
253 Transformation3d::transform( double x, double y, double z ) const
254 {
255 return transformDouble( x, y, z );
256 }
257
258
259 inline Point3df
260 Transformation3d::transform( float x, float y, float z ) const
261 {
262 return transformFloat( x, y, z );
263 }
264
265
266 inline Point3di
267 Transformation3d::transform( int x, int y, int z ) const
268 {
269 return transformInt( x, y, z );
270 }
271
272
274 {
275 return transformPoint3df( pos );
276 }
277
278
279 inline Point3dd
281 {
282 return transformPoint3dd( pos );
283 }
284
285
286 inline Point3d
288 {
289 return transformPoint3d( pos );
290 }
291
292
293 inline Point3di
295 {
296 return transformPoint3di( pos );
297 }
298
299
300 inline Point3df
302 {
303 Point3dd transformed = transform( (double) pos[0], (double) pos[1],
304 (double) pos[2] );
305 return Point3df( (float) transformed[0], (float) transformed[1],
306 (float) transformed[2] );
307 }
308
309
310 inline Point3dd
312 {
313 return transform( pos[0], pos[1], pos[2] );
314 }
315
316
317 inline Point3df
318 Transformation3d::transformFloat( float x, float y, float z ) const
319 {
320 Point3dd transformed = transform( (double) x, (double) y, (double) z );
321 return Point3df( (float) transformed[0], (float) transformed[1],
322 (float) transformed[2] );
323 }
324
325
327 {
328 Point3dd transformed = transform( (double) p[0], (double) p[1],
329 (double) p[2] );
330 return Point3d( (int16_t) rint( transformed[0] ),
331 (int16_t) rint( transformed[1] ),
332 (int16_t) rint( transformed[2] ) );
333 }
334
335
336 inline Point3di
338 {
339 Point3dd transformed = transform( (double) p[0], (double) p[1],
340 (double) p[2] );
341 return Point3di( (int) rint( transformed[0] ),
342 (int) rint( transformed[1] ),
343 (int) rint( transformed[2] ) );
344 }
345
346
347 inline Point3di
348 Transformation3d::transformInt( int x, int y, int z ) const
349 {
350 Point3dd transformed = transform( (double) x, (double) y, (double) z );
351 return Point3di( (int) rint( transformed[0] ),
352 (int) rint( transformed[1] ),
353 (int) rint( transformed[2] ) );
354 }
355
356
357 inline std::vector<double>
358 Transformation3d::transform( const std::vector<double> & pos ) const
359 {
360 std::vector<double> tr = pos;
361 Point3dd p = transform( pos[0], pos[1], pos[2] );
362 tr[0] = p[0];
363 tr[1] = p[1];
364 tr[2] = p[2];
365 return tr;
366 }
367
368
369 inline std::vector<float>
370 Transformation3d::transform( const std::vector<float> & pos ) const
371 {
372 std::vector<float> tr = pos;
373 Point3df p = transform( pos[0], pos[1], pos[2] );
374 tr[0] = p[0];
375 tr[1] = p[1];
376 tr[2] = p[2];
377 return tr;
378 }
379
380
381 inline std::vector<int>
382 Transformation3d::transform( const std::vector<int> & pos ) const
383 {
384 std::vector<int> tr = pos;
385 Point3di p = transform( pos[0], pos[1], pos[2] );
386 tr[0] = p[0];
387 tr[1] = p[1];
388 tr[2] = p[2];
389 return tr;
390 }
391
392
393 inline std::vector<double>
394 Transformation3d::transformVector( const std::vector<double> & pos ) const
395 {
396 std::vector<double> tr = pos;
397 Point3dd p = transform( pos[0], pos[1], pos[2] )
398 - transform( Point3dd( 0., 0., 0. ) );
399 tr[0] = p[0];
400 tr[1] = p[1];
401 tr[2] = p[2];
402 return tr;
403 }
404
405
406 inline std::vector<float>
407 Transformation3d::transformVector( const std::vector<float> & pos ) const
408 {
409 std::vector<float> tr = pos;
410 Point3df p = transform( pos[0], pos[1], pos[2] )
411 - transform( Point3df( 0.f, 0.f, 0.f ) );
412 tr[0] = p[0];
413 tr[1] = p[1];
414 tr[2] = p[2];
415 return tr;
416 }
417
418
419 inline std::vector<int>
420 Transformation3d::transformVector( const std::vector<int> & pos ) const
421 {
422 std::vector<int> tr = pos;
423 Point3di p = transform( pos[0], pos[1], pos[2] )
424 - transform( Point3di( 0, 0, 0 ) );
425 tr[0] = p[0];
426 tr[1] = p[1];
427 tr[2] = p[2];
428 return tr;
429 }
430
431 // -- vector arithmetics
432
433 template <typename T>
434 inline
435 std::vector<T> Transformation::vadd( const std::vector<T> & v1,
436 const std::vector<T> & v2 )
437 {
438 size_t n1 = v1.size(), n2 = v2.size(), n3 = std::max( n1, n2 ),
439 n4 = std::min( n1, n2 ), i;
440 std::vector<T> res( n3, 0 );
441
442 for( i=0; i<n4; ++i )
443 res[i] = v1[i] + v2[i];
444 for( ; i<n1; ++i )
445 res[i] = v1[i];
446 for( ; i<n2; ++i )
447 res[i] = v2[i];
448 for( ; i<n3; ++i )
449 res[i] = 0;
450
451 return res;
452 }
453
454
455 template <typename T>
456 inline
457 std::vector<T> Transformation::vsub( const std::vector<T> & v1,
458 const std::vector<T> & v2 )
459 {
460 size_t n1 = v1.size(), n2 = v2.size(), n3 = std::max( n1, n2 ),
461 n4 = std::min( n1, n2 ), i;
462 std::vector<T> res( n3, 0 );
463
464 for( i=0; i<n4; ++i )
465 res[i] = v1[i] - v2[i];
466 for( ; i<n1; ++i )
467 res[i] = v1[i];
468 for( ; i<n2; ++i )
469 res[i] = -v2[i];
470 for( ; i<n3; ++i )
471 res[i] = 0;
472
473 return res;
474 }
475
476
477 template <typename T>
478 inline
479 std::vector<T> Transformation::vadd( const std::vector<T> & v1,
480 const T & v2 )
481 {
482 unsigned n1 = v1.size(), i;
483 std::vector<T> res( n1, 0 );
484
485 for( i=0; i<n1; ++i )
486 res[i] = v1[i] + v2;
487
488 return res;
489 }
490
491
492 template <typename T>
493 inline
494 std::vector<T> Transformation::vsub( const std::vector<T> & v1,
495 const T & v2 )
496 {
497 unsigned n1 = v1.size(), i;
498 std::vector<T> res( n1, 0 );
499
500 for( i=0; i<n1; ++i )
501 res[i] = v1[i] - v2;
502
503 return res;
504 }
505
506
507 template <typename T>
508 inline
509 std::vector<T> Transformation::vadd( const T & v1,
510 const std::vector<T> & v2 )
511 {
512 unsigned n1 = v2.size(), i;
513 std::vector<T> res( n1, 0 );
514
515 for( i=0; i<n1; ++i )
516 res[i] = v1 + v2[i];
517
518 return res;
519 }
520
521
522 template <typename T>
523 inline
524 std::vector<T> Transformation::vsub( const T & v1,
525 const std::vector<T> & v2 )
526 {
527 unsigned n1 = v2.size(), i;
528 std::vector<T> res( n1, 0 );
529
530 for( i=0; i<n1; ++i )
531 res[i] = v1 - v2[i];
532
533 return res;
534 }
535
536 // --
537
538 template <> inline std::string DataTypeCode<Transformation3d>::objectType()
539 {
540 return "Transformation3d";
541 }
542
543 template <> inline std::string DataTypeCode<Transformation3d>::dataType()
544 {
545 return "VOID";
546 }
547
548 template <> inline std::string DataTypeCode<Transformation3d>::name()
549 {
550 return "Transformation3d";
551 }
552
553}
554
555#endif
virtual Point3dd transformPoint3dd(const Point3dd &pos) const
virtual Point3d transformPoint3d(const Point3d &p) const
virtual std::vector< double > transformVector(const std::vector< double > &pos) const
Point3dd transform(double x, double y, double z) const
virtual Point3df transformPoint3df(const Point3df &dir) const
virtual Point3dd transformDouble(double x, double y, double z) const =0
virtual Point3df transformFloat(float x, float y, float z) const
virtual Point3di transformInt(int x, int y, int z) const
virtual Point3di transformPoint3di(const Point3di &p) const
virtual std::unique_ptr< Transformation > getInverse() const
Obtain the inverse transformation.
virtual std::vector< double > transformVector(const std::vector< double > &pos) const
static std::vector< T > vadd(const std::vector< T > &v1, const std::vector< T > &v2)
vector arithmetics, as convenience static functions
virtual std::vector< double > transform(const std::vector< double > &pos) const =0
virtual bool isDirect() const =0
true if the transformation is direct, false if it changes orientation
carto::Object header()
virtual bool isIdentity() const
Test if the transformation can safely be omitted.
void setHeader(carto::Object ph)
static std::vector< T > vsub(const std::vector< T > &v1, const std::vector< T > &v2)
vector arithmetics, as convenience static functions
virtual bool invertible() const
Test if the transformation can be inverted.
const carto::Object header() const
virtual ~Transformation()
AimsVector< float, 3 > Point3df
Definition vector.h:247
AimsVector< int16_t, 3 > Point3d
Definition vector.h:222
AimsVector< int32_t, 3 > Point3di
Definition vector.h:232
AimsVector< double, 3 > Point3dd
Definition vector.h:250