]> Creatis software - creaMaracasVisu.git/blob - lib/maracasVisuLib/src/kernel/include/marVector.cpp
7f92f0a9ef0125dbebedf9aea59c80c9c2d55d81
[creaMaracasVisu.git] / lib / maracasVisuLib / src / kernel / include / marVector.cpp
1 // marVector.cpp: implementation of the marVector class.
2 //
3 //////////////////////////////////////////////////////////////////////
4 #include "marVector.h"
5 #include <assert.h>
6 #include <math.h>
7
8
9 //////////////////////////////////////////////////////////////////////
10 // Constructeurs
11 //////////////////////////////////////////////////////////////////////
12 marVector::marVector(size_t s)
13         :shallowCopy(false)
14 {
15         if (s!=0)
16         {
17                 _data=new double[s];
18                 _size=s;
19         }
20         else
21         {
22                 _data=NULL;
23                 _size=0;
24                 assert(false);
25         }
26 }
27
28 marVector::marVector(const marVector &v)
29         :shallowCopy(false)
30 {
31         _size=v._size;
32         _data=new double[_size];
33         int i;
34         for (i=0;i<_size;i++)
35         {
36                 _data[i]=v._data[i];
37         }
38 }
39
40 marVector::marVector(double*v,size_t s)
41         :shallowCopy(true)
42 {
43         if (s!=0)
44         {
45                 _size=s;
46                 _data=v;
47 // PS ->                _data=new double[_size];
48 // PS ->                for (int i=0;i<_size;i++)
49 // PS ->                {
50 // PS ->                        _data[i]=v[i];
51 // PS ->                }
52                 
53         }
54         else
55         {
56                 _data=NULL;
57                 _size=0;
58                 assert(false);
59         }
60         
61 }
62
63 //////////////////////////////////////////////////////////////////////
64 // Destructeur
65 //////////////////////////////////////////////////////////////////////
66 marVector::~marVector()
67 {
68         if (!shallowCopy) 
69         {
70                 delete _data;
71         }
72         else
73         {
74                 _data=NULL;
75         }
76 }
77
78 //////////////////////////////////////////////////////////////////////
79 // Opérateurs
80 //////////////////////////////////////////////////////////////////////
81 // ---------------------------------------------------------------------
82 /*Affichage*/
83 std::ostream& operator<<(std::ostream& os,const marVector& v)
84 {
85         int i;
86     for(i=0;i < v.size();i++) 
87         {
88                 os << " " << v(i);
89         }
90         os <<"\n";
91     return(os);
92 }
93
94 // ---------------------------------------------------------------------
95 /*Casting*/
96 marVector::operator double*() const 
97
98         return(_data);
99 }
100
101 // ---------------------------------------------------------------------
102 /*Indexation*/
103 double& marVector::operator()(size_t i) 
104
105         return(_data[i]);
106 }
107
108 const double& marVector::operator()(size_t i) const
109 {
110         return(_data[i]);
111 }
112
113 // ---------------------------------------------------------------------
114 /*Affectation*/
115 marVector& marVector::operator=(const marVector& o)
116 {
117         _size=o._size;
118         if (!(_data==NULL)&&(!shallowCopy))
119         {
120                 delete _data;
121         }
122         shallowCopy=false;
123         _data=new double[_size];
124         int i;
125         for (i=0;i<_size;i++)
126         {
127                 _data[i]=o._data[i];
128         }
129         return (*this);
130 }
131
132 marVector& marVector::operator=(double o)
133 {
134         if (_size!=0)
135         {
136                 if (!(_data==NULL)&&(!shallowCopy))
137                 {
138                         delete _data;
139                 }
140                 shallowCopy=false;
141                 _data=new double[_size];
142                 int i;
143                 for (i=0;i<_size;i++)
144                 {
145                         _data[i]=o;
146                 }
147         }
148         else
149         {
150                 assert(false);
151         }
152         return (*this);
153 }
154
155 marVector& marVector::operator=(double*o)
156 {
157         if (_size!=0)
158         {
159                 if (!(_data==NULL)&&(!shallowCopy))
160                 {
161                         delete _data;
162                 }
163                 shallowCopy=false;
164                 _data=new double[_size];
165                 int i;
166                 for (i=0;i<_size;i++)
167                 {
168                         _data[i]=o[i];
169                 }
170         }
171         else
172         {
173                 assert(false);
174         }
175         return (*this);
176 }
177
178 // ---------------------------------------------------------------------
179 /*Comparaison*/
180 bool marVector::operator==(const marVector& o) const
181 {
182     bool equal=true;
183         
184     if(_size!=o._size)
185         {
186                 return(false);
187         }
188         
189         int i;
190         for(i=0;i<_size && equal;i++)
191         {
192                 equal=equal && (_data[i]==o._data[i]); 
193         }
194     return(equal);
195 }
196
197 bool marVector::operator!=(const marVector& o) const
198 {
199         return(!((*this)==o));
200 }
201
202 // ---------------------------------------------------------------------
203 /*Addition*/
204 marVector marVector::operator+(const marVector& o)
205 {
206         marVector result(*this);
207         size_t s=result._size;
208         
209         if ((o._size!=s) || (s==0))
210         {
211                 assert(false);
212         }
213         else 
214         {
215                 for (int i=0;i < s;i++)
216                 {
217                         result._data[i] +=o._data[i];
218                 }
219         }
220         return result;
221 }
222
223 marVector marVector::operator+(double o)
224 {
225         marVector result(*this);
226         size_t s=result._size;
227         
228         if (s==0)
229         {
230                 assert(false);
231         }
232         else 
233         {
234                 for (int i=0;i < s;i++)
235                 {
236                         result._data[i] +=o;
237                 }
238         }
239         return result;
240 }
241
242 marVector marVector::operator+(double*o)
243 {
244         marVector result(*this);
245         size_t s=result._size;
246         
247         if (s==0)
248         {
249                 assert(false);
250         }
251         else 
252         {
253                 for (int i=0;i < s;i++)
254                 {
255                         result._data[i] +=o[i];
256                 }
257         }
258         return result;
259 }
260
261 // ---------------------------------------------------------------------
262 /*Addition + Affectation*/
263 marVector& marVector::operator+=(const marVector& o)
264 {
265         if ((o._size!=_size) || (_size==0))
266         {
267                 assert(false);          
268         }
269         else 
270         {
271                 for (int i=0;i < _size;i++)
272                 {
273                         _data[i] +=o._data[i];
274                 }
275         }
276         return (*this);
277 }
278
279 marVector& marVector::operator+=(double o)
280 {
281         if (_size==0)
282         {
283                 assert(false);  
284         }
285         else 
286         {
287                 for (int i=0;i < _size;i++)
288                 {
289                         _data[i] +=o;
290                 }
291         }
292     return(*this);
293 }
294
295 marVector& marVector::operator+=(double*o)
296 {
297         if (_size==0)
298         {
299                 assert(false);          
300         }
301         else 
302         {
303                 for (int i=0;i < _size;i++)
304                 {
305                         _data[i] +=o[i];
306                 }
307         }
308     return(*this);
309 }
310
311 // ---------------------------------------------------------------------
312 /*Soustraction*/
313 marVector marVector::operator-(const marVector& o)
314 {
315         marVector result(*this);
316         size_t s=result._size;
317         
318         if ((o._size !=s) || (s==0))
319         {
320                 assert(false);          
321         }
322         else 
323         {
324                 for (int i=0;i < s;i++)
325                 {
326                         result._data[i] -=o._data[i];
327                 }
328         }
329         return result;
330 }
331
332 marVector marVector::operator-(double o)
333 {
334         marVector result(*this);
335         size_t s=result._size;
336         
337         if (s==0)
338         {
339                 assert(false);  
340         }
341         else 
342         {
343                 for (int i=0;i < s;i++)
344                 {
345                         result._data[i] -=o;
346                 }
347         }
348         return result;
349 }
350
351 marVector marVector::operator-(double*o)
352 {
353         marVector result(*this);
354         size_t s=result._size;
355         
356         if (s==0)
357         {
358                 assert(false);          
359         }
360         else 
361         {
362                 for (int i=0;i < s;i++)
363                 {
364                         result._data[i] -=o[i];
365                 }
366         }
367         return result;
368 }
369
370 // ---------------------------------------------------------------------
371 /*Sooustraction + Affection*/
372 marVector& marVector::operator-=(const marVector& o)
373 {
374         if ((o._size!=_size) || (_size==0))
375         {
376                 assert(false);          
377         }
378         else 
379         {
380                 for (int i=0;i < _size;i++)
381                 {
382                         _data[i] -=o._data[i];
383                 }
384         }
385         return (*this);
386 }
387
388 marVector& marVector::operator-=(double o)
389 {
390         if (_size==0)
391         {
392                 assert(false);  
393         }
394         else 
395         {
396                 for (int i=0;i < _size;i++)
397                 {
398                         _data[i] -=o;
399                 }
400         }
401     return(*this);
402 }
403
404 marVector& marVector::operator-=(double*o)
405 {
406         if (_size==0)
407         {
408                 assert(false);          
409         }
410         else 
411         {
412                 for (int i=0;i < _size;i++)
413                 {
414                         _data[i] -=o[i];
415                 }
416         }
417     return(*this);
418 }
419
420 // ---------------------------------------------------------------------
421 /*Multiplication (produit scalaire)*/
422 marVector marVector::operator*(double o)
423 {
424         marVector result(*this);
425         size_t s=result._size;
426         
427         if (s==0)
428         {
429                 assert(false);  
430         }
431         else 
432         {
433                 for (int i=0;i < s;i++)
434                 {
435                         result._data[i]*=o;
436                 }
437         }
438         return result;
439 }
440
441 // ---------------------------------------------------------------------
442 /*Multiplication (produit scalaire) + Affectation*/
443 marVector& marVector::operator*=(double o)
444 {
445         if (_size==0)
446         {
447                 assert(false);  
448         }
449         else 
450         {
451                 for (int i=0;i < _size;i++)
452                 {
453                         _data[i]*=o;
454                 }
455         }
456     return(*this);
457 }
458
459 // ---------------------------------------------------------------------
460 /*Division (division scalaire)*/
461 marVector marVector::operator/(double o)
462 {
463         marVector result(*this);
464         size_t s=result._size;
465         
466         if (s==0)
467         {
468                 assert(false);  
469         }
470         else 
471         {
472                 for (int i=0;i < s;i++)
473                 {
474                         result._data[i] /=o;
475                 }
476         }
477         return result;
478 }
479
480 // ---------------------------------------------------------------------
481 /*Division (division scalaire) + Affectation*/
482 marVector& marVector::operator/=(double o)
483 {
484         if (_size==0)
485         {
486                 assert(false);  
487         }
488         else 
489         {
490                 for (int i=0;i < _size;i++)
491                 {
492                         _data[i] /=o;
493                 }
494         }
495     return(*this);
496 }
497
498 //////////////////////////////////////////////////////////////////////
499 // Opérations
500 //////////////////////////////////////////////////////////////////////
501 // ---------------------------------------------------------------------
502 /*Produit scalaire*/
503 double marVector::dot(const marVector& o)
504 {
505     double result;
506         if ((_size!=o._size) || (_size==0))
507         {
508                 assert(false); 
509         }
510         else
511         {
512                 result=0.0;
513                 for (int i=0;i<_size;i++)
514                 {
515                         result+=(_data[i]*o._data[i]);
516                 }
517         }
518         return result;
519 }
520
521 double marVector::dot(double*o)
522 {
523     double result;
524         if (_size==0)
525         {
526                 assert(false); 
527         }
528         else
529         {
530                 result=0.0;
531                 for (int i=0;i<_size;i++)
532                 {
533                         result+=(_data[i]*o[i]);
534                 }
535         }
536         return result;
537 }
538
539 // ---------------------------------------------------------------------
540 /*Produit vectoriel*/
541 marVector marVector::cross(const marVector& o)
542 {
543     marVector result(*this);
544         if ((o._size!=_size) || (_size!=3))
545         {
546                 assert(false); 
547         }
548         else
549         {
550                 double S,s;
551                 
552                 // 1st element
553                 S=_data[1]*o._data[2];
554                 s=_data[2]*o._data[1];
555                 result._data[0]=S - s;
556                 
557                 // 2nd element
558                 S=_data[2]*o._data[0];
559                 s=_data[0]*o._data[2];
560                 result._data[1]=S - s;
561                 
562                 // 3rd element
563                 S=_data[0]*o._data[1];
564                 s=_data[1]*o._data[0];
565                 result._data[2]=S - s;
566         }
567     return(result);    
568 }
569
570 marVector marVector::cross(double*o)
571 {
572     marVector result(*this);
573         if (_size!=3)
574         {
575                 assert(false); 
576         }
577         else
578         {
579                 double S,s;
580                 
581                 // 1st element
582                 S=_data[1]*o[2];
583                 s=_data[2]*o[1];
584                 result._data[0]=S - s;
585                 
586                 // 2nd element
587                 S=_data[2]*o[0];
588                 s=_data[0]*o[2];
589                 result._data[1]=S - s;
590                 
591                 // 3rd element
592                 S=_data[0]*o[1];
593                 s=_data[1]*o[0];
594                 result._data[2]=S - s;
595         }
596     return(result);
597 }
598
599 int marVector::scross(const marVector& o)
600 {
601         if ((o._size!=_size) && (_size!=3))
602         {
603                 return (1);
604         }
605         else
606         {
607                 *this=cross(o);
608                 return(0);
609         } 
610 }
611
612 int marVector::scross(double*o)
613 {
614         if (_size!=3)
615         {
616                 return (1);
617         }
618         else
619         {
620                 *this=cross(o);
621                 return(0);
622         } 
623 }
624
625 // ---------------------------------------------------------------------
626 /*Norme euclidienne*/
627 double marVector::norm2()
628 // Calcule la norme euclidienne du vecteur 
629 // en utilisant l'agorithme de Blue
630 {
631         
632         double norme2=0.0;
633         if (_size==0)
634         {
635                 assert(false);
636         }
637         else
638         {
639                 const double seuil1=pow( 2., 154. ),seuil2=1/seuil1;
640                 double n1=0; /* les sommes partielles */
641                 double n2=0;
642                 double n3=0;
643                 double n4;
644                 int i;
645                 for ( i=0; i<_size; i++ ) 
646                 {
647                         double x=_data[i];      /* x=abs(vecteur[i]) */
648                         
649                         if (x<0) 
650                         { 
651                                 x=-x;
652                         }
653                         /* sommation par classe */
654                         if ( x > seuil1 ) 
655                         {
656                                 x *=seuil2;
657                                 n1 +=x*x;
658                         } 
659                         else if ( x < seuil2 ) 
660                         {
661                                 x  *=seuil1;
662                                 n2 +=x*x;
663                         } 
664                         else
665                         {
666                                 n3 +=x*x;
667                         }
668                 }
669                 
670                 n3=sqrt(n3);
671                 if (n1>0)
672                 {
673                         n4=seuil1 * sqrt(n1);
674                 }
675                 else
676                 {
677                         n4=seuil2 * sqrt(n2);
678                 }
679                 
680 // EED 
681 /*
682                 if (n3 < n4) 
683                 {
684                         n3 /=n4;
685                         norme2=n4 * sqrt( 1 + n3*n3 );
686                 } 
687                 else 
688                 {
689                         n4 /=n3;
690                         norme2=n3 * sqrt( 1 + n4*n4 );
691                 }
692 */
693                 norme2=n3;
694         }
695         return norme2;
696 }
697
698 // ---------------------------------------------------------------------
699 /*Normalisation*/
700 marVector marVector::normalize( )
701 {
702         marVector result=marVector(*this);
703         result *= (1/result.norm2());
704         return result;
705 }
706
707 int marVector::snormalize( )
708 {
709         (*this)*=(1/this->norm2());
710         return(0);
711 }// renvoie 0 si OK, 1 sinon
712
713 //////////////////////////////////////////////////////////////////////
714 // Méthodes
715 //////////////////////////////////////////////////////////////////////
716
717 size_t marVector::size() const
718 {
719         return _size;
720 }