Moka libraries
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
inequation.hh
Go to the documentation of this file.
1 /*
2  * lib-spamod : Visualisation des objets en discret.
3  * Copyright (C) 2004, Moka Team, Université de Poitiers, Laboratoire SIC
4  * http://www.sic.sp2mi.univ-poitiers.fr/
5  * Copyright (C) 2009, Guillaume Damiand, CNRS, LIRIS,
6  * guillaume.damiand@liris.cnrs.fr, http://liris.cnrs.fr/
7  *
8  * This file is part of lib-spamod
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU Lesser General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with this program. If not, see <http://www.gnu.org/licenses/>.
22  */
23 
24 /******************************************************************************
25  * Fichier : Inequation.h *
26  * Auteur : DEXET Martine *
27  *----------------------------------------------------------------------------*
28  * Ce fichier contient la sp�cification de la classe Inequation. Cette *
29  * classe permet de repr�senter une in�quation de la forme ax+by+cz <= w (ou *
30  * ax+by+cz < w. La variable "used" alpha de plus �t� ajout�e pour les besoins du *
31  * programme. *
32  * *
33  *****************************************************************************/
34 
35 
36 #ifndef INEQUATION_H
37 #define INEQUATION_H
38 
39 #include <cassert>
40 #include "vertex.hh"
41 
42 
43 
44 /******************************************************************************
45  * Classe Inequation *
46  *****************************************************************************/
47 
48 class Inequation {
49 
50  public:
51 
52  // Constructeurs.
53  Inequation();
54  Inequation(float pa, float pb, float pc, float pw);
55 
56  // M�thodes permettant la lecture des variables de la classe.
57  float GetA() const;
58  float GetB() const;
59  float GetC() const;
60  float GetW() const;
61  bool Is_Strict() const;
62  bool Is_Used() const;
63 
64  // M�thode calculant la dimension d'une in�quation.
65  int Get_Dim() const;
66 
67  // M�thodes permettant l'�criture de variable dans la classe.
68  void SetA(float pa);
69  void SetB(float pb);
70  void SetC(float pc);
71  void SetW(float pw);
72  void SetAbcw(float pa, float pb, float pc, float pw);
73  void Set_Strict();
74  void Unset_Strict();
75  void Set_Used();
76  void Set_Unused();
77 
78  // M�thode permettant de savoir si un point de rep�re 3D v�rifie
79  // l'in�quation.
80  bool Test_Point (CVertex const & pt) const;
81 
82  // M�thode permettant de savoir si un point de rep�re 3D v�rifie
83  // l'�quation ax+by+cz = w.
84  bool Test_Point_Eq (CVertex const & pt) const;
85 
86  // M�thode calculant le point d'intersection de trois �quations du rep�re 3D.
87  CVertex* Intersec (Inequation const & i1, Inequation const & i2);
88 
89  // Op�rateur d'�galit� entre deux in�quations.
90  bool operator == (Inequation i) const;
91 
92  // Op�rateur de diff�rence entre deux in�quations.
93  bool operator != (Inequation i) const;
94 
95  // Op�rateur de transfert << et >>.
96  friend std::ostream& operator << (std::ostream& s, Inequation const & i);
97  friend Inequation& operator >> (std::ostream& s, Inequation & i);
98 
99 
100  private:
101 
102  // Variables repr�sentant les param�tres de l'in�quation.
103  float alpha, b, c, w;
104 
105  // Variable indiquant si une in�quation est stricte ou non.
106  bool strict;
107 
108  // Variable indiquant si l'in�quation est visible ou non.
109  bool used;
110 };
111 
112 /******************************************************************************
113  * Fichier : Inequation.inl *
114  * Auteur : DEXET Martine *
115  *----------------------------------------------------------------------------*
116  * Ce fichier contient l'impl�mentation des m�thodes de la classe Inequation.*
117  * *
118  *****************************************************************************/
119 
120 
121 #include <cmath>
122 #include "definition.hh"
123 
124 
125 
126 // Constructeurs.
127 inline
129  :alpha(0), b(0), c(0), w(0), strict(false), used(true)
130 {}
131 
132 inline
133 Inequation::Inequation(float pa, float pb, float pc, float pw)
134  :alpha(pa), b(pb), c(pc), w(pw), strict(false), used(true)
135 {}
136 
137 
138 // M�thodes permettant la lecture des variables de la classe.
139 inline
140 float Inequation::GetA() const
141 {
142  return alpha;
143 }
144 
145 inline
146 float Inequation::GetB() const
147 {
148  return b;
149 }
150 
151 inline
152 float Inequation::GetC() const
153 {
154  return c;
155 }
156 
157 inline
158 float Inequation::GetW() const
159 {
160  return w;
161 }
162 
163 inline
165 {
166  return strict;
167 }
168 
169 inline
171 {
172  return used;
173 }
174 
175 
176 // M�thode calculant la dimension d'une in�quation.
177 inline
179 {
180  if(fabs(alpha)>EPS && fabs(b)>EPS && fabs(c)>EPS)
181  return 3;
182 
183  else
184  if ((fabs(alpha)>EPS && fabs(b)>EPS)||
185  (fabs(alpha)>EPS && fabs(c)>EPS)||
186  (fabs(b)>EPS && fabs(c)>EPS))
187  return 2;
188 
189  else
190  if(fabs(alpha)>EPS || fabs(b)>EPS || fabs(c)>EPS)
191  return 1;
192 
193  else
194  return 0;
195 }
196 
197 
198 // M�thodes permettant l'�criture de variable dans la classe.
199 inline
200 void Inequation::SetA(float pa)
201 {
202  alpha=pa;
203 }
204 
205 inline
206 void Inequation::SetB(float pb)
207 {
208  b=pb;
209 }
210 
211 inline
212 void Inequation::SetC(float pc)
213 {
214  c=pc;
215 }
216 
217 inline
218 void Inequation::SetW(float pw)
219 {
220  w=pw;
221 }
222 
223 inline
224 void Inequation::SetAbcw(float pa, float pb, float pc, float pw)
225 {
226  alpha=pa;
227  b=pb;
228  c=pc;
229  w=pw;
230 }
231 
232 inline
234 {
235  strict = true;
236 }
237 
238 inline
240 {
241  strict = false;
242 }
243 
244 inline
246 {
247  used = true;
248 }
249 
250 inline
252 {
253  used = false;
254 }
255 
256 
257 // Méthode permettant de savoir si un point de rep�re 3D v�rifie
258 // l'inéquation.
259 inline
260 bool Inequation::Test_Point (CVertex const & pt) const
261 {
262  if (strict)
263  {
264  if (alpha*pt.getX() + b*pt.getY() + c*pt.getZ() < w)
265  return true;
266  else
267  return false;
268  }
269  else
270  {
271  if (alpha*pt.getX() + b*pt.getY() + c*pt.getZ() <= w + EPS)
272  return true;
273  else
274  return false;
275  }
276 }
277 
278 
279 // M�thode permettant de savoir si un point de rep�re 3D v�rifie
280 // l'�quation ax+by+cz = w.
281 inline
282 bool Inequation::Test_Point_Eq (CVertex const & pt) const
283 {
284  if (fabs(alpha*pt.getX() + b*pt.getY() + c*pt.getZ() - w) <= EPS)
285  return true;
286 
287  else
288  return false;
289 }
290 
291 
292 // M�thode calculant le point d'intersection de trois �quations du rep�re 3D.
293 inline
294 CVertex* Inequation::Intersec (Inequation const & i1, Inequation const & i2)
295 {
296  float const epsilon = 0.0001;
297 
298  float mat[3][4] = {{alpha, b, c, w},
299  {i1.alpha, i1.b, i1.c, i1.w},
300  {i2.alpha, i2.b, i2.c, i2.w}};
301  int nbZeros;
302  float coef1, coef2;
303 
304  for (int i=0; i<3; i++)
305  for (int j=0; j<4; j++)
306  if (fabs(mat[i][j]) < epsilon)
307  mat[i][j] = 0.0;
308 
309  // Comptage du nombre de 0 dans la premiere colonne.
310  nbZeros = 0;
311  for (int i=0; i<3; i++)
312  if (mat[i][0] == 0.0)
313  nbZeros++;
314 
315  // Il n y alpha pas de 0 dans la premiere colonne.
316  if (nbZeros == 0)
317  {
318  coef1 = mat[0][0];
319  coef2 = mat[1][0];
320 
321  // Elimination du 1er 0.
322  for (int i=0; i<4; i++)
323  mat[0][i] = mat[0][i]*coef2 - mat[1][i]*coef1;
324 
325  coef1 = mat[2][0];
326 
327  // Elimination du 2ieme 0.
328  for (int i=0; i<4; i++)
329  mat[1][i] = mat[1][i]*coef1 - mat[2][i]*coef2;
330  }
331 
332  // Il y alpha un 0 dans la premiere colonne.
333  else
334  if (nbZeros == 1)
335  {
336  if (mat[0][0] == 0.0)
337  {
338  coef1 = mat[1][0];
339  coef2 = mat[2][0];
340 
341  for (int i=0; i<4; i++)
342  mat[1][i] = mat[1][i]*coef2 - mat[2][i]*coef1;
343  }
344 
345  else
346  if (mat[1][0] == 0.0)
347  {
348  coef1 = mat[0][0];
349  coef2 = mat[2][0];
350 
351  for (int i=0; i<4; i++)
352  mat[0][i] = mat[0][i]*coef2 - mat[2][i]*coef1;
353  }
354 
355  else
356  {
357  coef1 = mat[0][0];
358  coef2 = mat[1][0];
359 
360  for (int i=0; i<4; i++)
361  mat[0][i] = mat[0][i]*coef2 - mat[1][i]*coef1;
362  }
363  }
364 
365  // Comptage du nombre de 0 dans la deuxieme colonne.
366  nbZeros = 0;
367 
368  for (int i=0; i<3; i++)
369  if (mat[i][1] == 0.0)
370  nbZeros++;
371 
372  // Il n y alpha pas de 0 dans la deuxieme colonne.
373  if (nbZeros == 0)
374  {
375  if (mat[0][0] == 0.0)
376  {
377  coef1 = mat[0][1];
378 
379  if (mat[1][0] == 0.0)
380  {
381  coef2 = mat[1][1];
382 
383  for (int i=1; i<4; i++)
384  mat[1][i] = mat[1][i]*coef1 - mat[0][i]*coef2;
385 
386  coef2 = mat[2][1];
387 
388  for (int i=0; i<4; i++)
389  mat[2][i] = mat[2][i]*coef1 - mat[0][i]*coef2;
390  }
391 
392  else
393  {
394  coef2 = mat[2][1];
395 
396  for (int i=1; i<4; i++)
397  mat[2][i] = mat[2][i]*coef1 - mat[0][i]*coef2;
398 
399  coef2 = mat[1][1];
400 
401  for (int i=0; i<4; i++)
402  mat[1][i] = mat[1][i]*coef1 - mat[0][i]*coef2;
403  }
404  }
405 
406  else
407  {
408  coef1 = mat[0][1];
409  coef2 = mat[1][1];
410 
411  for (int i=0; i<4; i++)
412  mat[0][i] = mat[0][i]*coef2 - mat[1][i]*coef1;
413 
414  coef1 = mat[2][1];
415 
416  for (int i=1; i<4; i++)
417  mat[1][i] = mat[1][i]*coef1 - mat[2][i]*coef2;
418  }
419  }
420 
421  // Il y alpha un 0 dans la deuxieme colonne.
422  else
423  if (nbZeros == 1)
424  {
425  if (mat[0][1] == 0.0)
426  {
427  if (mat[0][0] == 0.0)
428  {
429  coef1 = mat[1][1];
430  coef2 = mat[2][1];
431 
432  if (mat[1][0] == 0.0)
433  {
434  for (int i=0; i<4; i++)
435  mat[2][i] = mat[2][i]*coef1 - mat[1][i]*coef2;
436  }
437 
438  else
439  {
440  for (int i=0; i<4; i++)
441  mat[1][i] = mat[1][i]*coef2 - mat[2][i]*coef1;
442  }
443  }
444 
445  else
446  {
447  coef1 = mat[2][1];
448  coef2 = mat[1][1];
449 
450  for (int i=1; i<4; i++)
451  mat[1][i] = mat[1][i]*coef1 - mat[2][i]*coef2;
452  }
453  }
454 
455  else
456  if (mat[1][1] == 0.0)
457  {
458  if (mat[1][0] == 0.0)
459  {
460  coef1 = mat[0][1];
461  coef2 = mat[2][1];
462 
463  if (mat[0][0] == 0.0)
464  {
465  for (int i=0; i<4; i++)
466  mat[2][i] = mat[2][i]*coef1 - mat[0][i]*coef2;
467  }
468 
469  else
470  {
471  for (int i=0; i<4; i++)
472  mat[0][i] = mat[0][i]*coef2 - mat[2][i]*coef1;
473  }
474  }
475 
476  else
477  {
478  coef1 = mat[0][1];
479  coef2 = mat[2][1];
480 
481  for (int i=1; i<4; i++)
482  mat[0][i] = mat[0][i]*coef2 - mat[2][i]*coef1;
483  }
484  }
485 
486  else
487  {
488  if (mat[2][0] == 0.0)
489  {
490  coef1 = mat[0][1];
491  coef2 = mat[1][1];
492 
493  if (mat[0][0] == 0.0)
494  {
495  for (int i=0; i<4; i++)
496  mat[1][i] = mat[1][i]*coef1 - mat[0][i]*coef2;
497  }
498 
499  else
500  {
501  for (int i=0; i<4; i++)
502  mat[0][i] = mat[0][i]*coef2 - mat[1][i]*coef1;
503  }
504  }
505 
506  else
507  {
508  coef1 = mat[0][1];
509  coef2 = mat[1][1];
510 
511  for (int i=1; i<4; i++)
512  mat[0][i] = mat[0][i]*coef2 - mat[1][i]*coef1;
513  }
514  }
515  }
516 
517  // Comptage du nombre de 0 dans la troisieme colonne.
518  nbZeros = 0;
519 
520  for (int i=0; i<3; i++)
521  if (mat[i][2] == 0.0)
522  nbZeros++;
523 
524  // Il n y alpha pas de 0 dans la troisieme colonne.
525  if (nbZeros == 0)
526  {
527  if (mat[0][0] == 0.0 && mat[0][1] == 0.0)
528  {
529  coef1 = mat[0][2];
530  coef2 = mat[1][2];
531 
532  for (int i=0; i<4; i++)
533  mat[1][i] = mat[1][i]*coef1 - mat[0][i]*coef2;
534 
535  coef2 = mat[2][2];
536 
537  for (int i=0; i<4; i++)
538  mat[2][i] = mat[2][i]*coef1 - mat[0][i]*coef2;
539  }
540 
541  else
542  if (mat[1][0] == 0.0 && mat[1][1] == 0.0)
543  {
544  coef1 = mat[1][2];
545  coef2 = mat[0][2];
546 
547  for (int i=0; i<4; i++)
548  mat[0][i] = mat[0][i]*coef1 - mat[1][i]*coef2;
549 
550  coef2 = mat[2][2];
551 
552  for (int i=0; i<4; i++)
553  mat[2][i] = mat[2][i]*coef1 - mat[1][i]*coef2;
554  }
555 
556  else
557  {
558  coef1 = mat[2][2];
559  coef2 = mat[0][2];
560 
561  for (int i=0; i<4; i++)
562  mat[0][i] = mat[0][i]*coef1 - mat[2][i]*coef2;
563 
564  coef2 = mat[1][2];
565 
566  for (int i=0; i<4; i++)
567  mat[1][i] = mat[1][i]*coef1 - mat[2][i]*coef2;
568  }
569  }
570 
571  else
572  if (nbZeros == 1)
573  {
574  if (mat[0][2] == 0.0)
575  {
576  coef1 = mat[2][2];
577  coef2 = mat[1][2];
578 
579  if (mat[1][0] == 0.0 && mat[1][1] == 0.0)
580  {
581  for (int i=0; i<4; i++)
582  mat[2][i] = mat[2][i]*coef2 - mat[1][i]*coef1;
583  }
584 
585  else
586  {
587  for (int i=0; i<4; i++)
588  mat[1][i] = mat[1][i]*coef1 - mat[2][i]*coef2;
589  }
590  }
591 
592  else
593  if (mat[1][2] == 0.0)
594  {
595  coef1 = mat[0][2];
596  coef2 = mat[2][2];
597 
598  if (mat[0][0] == 0.0 && mat[0][1] == 0.0)
599  {
600  for (int i=0; i<4; i++)
601  mat[2][i] = mat[2][i]*coef1 - mat[0][i]*coef2;
602  }
603 
604  else
605  {
606  for (int i=0; i<4; i++)
607  mat[0][i] = mat[0][i]*coef2 - mat[2][i]*coef1;
608  }
609  }
610 
611  else
612  {
613  coef1 = mat[0][2];
614  coef2 = mat[1][2];
615 
616  if (mat[0][0] == 0.0 && mat[0][1] == 0.0)
617  {
618  for (int i=0; i<4; i++)
619  mat[1][i] = mat[1][i]*coef1 - mat[0][i]*coef2;
620  }
621 
622  else
623  {
624  for (int i=0; i<4; i++)
625  mat[0][i] = mat[0][i]*coef2 - mat[1][i]*coef1;
626  }
627  }
628  }
629 
630  float x, y, z;
631 
632  if (mat[0][0] != 0.0)
633  x = mat[0][3] / mat[0][0];
634 
635  else
636  if (mat[1][0] != 0.0)
637  x = mat[1][3] / mat[1][0];
638 
639  else
640  x = mat[2][3] / mat[2][0];
641 
642  if (mat[0][1] != 0.0)
643  y = mat[0][3] / mat[0][1];
644 
645  else
646  if (mat[1][1] != 0.0)
647  y = mat[1][3] / mat[1][1];
648 
649  else
650  y = mat[2][3] / mat[2][1];
651 
652  if (mat[0][2] != 0.0)
653  z = mat[0][3] / mat[0][2];
654 
655  else
656  if (mat[1][2] != 0.0)
657  z = mat[1][3] / mat[1][2];
658 
659  else
660  z = mat[2][3] / mat[2][2];
661 
662  return new CVertex (x, y, z);
663 }
664 
665 
666 // Op�rateur d'�galit� entre deux in�quations.
667 inline
669 {
670  bool change = false;
671 
672  if (alpha != 0.0 && i.alpha != 0.0)
673  {
674  i.b = (i.b * alpha)/i.alpha;
675  i.c = (i.c * alpha)/i.alpha;
676  i.w = (i.w * alpha)/i.alpha;
677  change = true;
678  }
679  else
680  if (alpha != 0.0 || i.alpha != 0.0)
681  return false;
682 
683  if (b != 0.0 && i.b != 0.0)
684  {
685  if (change && fabs(b - i.b) > EPS)
686  return false;
687  else
688  if (fabs(b - i.b) > EPS)
689  {
690  i.c = (i.c * b)/i.b;
691  i.w = (i.w * b)/i.b;
692  }
693  }
694  else
695  if (b != 0.0 || i.b != 0.0)
696  return false;
697 
698  if (c != 0.0 && i.c != 0.0)
699  {
700  if (change && fabs(c - i.c) > EPS)
701  return false;
702  else
703  if (fabs(c - i.c) > EPS)
704  {
705  i.w = (i.w * c)/i.c;
706  }
707  }
708  else
709  if (c != 0.0 || i.c != 0.0)
710  return false;
711 
712  if (fabs(w - i.w) > EPS)
713  return false;
714 
715  return true;
716 }
717 
718 
719 // Op�rateur de diff�rence entre deux in�quations.
720 inline
722 {
723  return !(*this == i);
724 }
725 
726 
727 // Op�rateur de transfert << et >>.
728 inline
729 std::ostream& operator << (std::ostream& s, Inequation const & i)
730 {
731  s << i.GetA() << "\t"
732  << i.GetB() << "\t"
733  << i.GetC() << "\t\t"
734  << i.Is_Strict();
735 
736  s << "\t\t" << i.GetW() << "\t\t" << i.Is_Used() << std::endl;
737 
738  return s;
739 }
740 
741 inline
742 Inequation& operator >> (std::istream& s, Inequation & i)
743 {
744  float alpha, b, c, w;
745  bool strict, used;
746 
747  s >> alpha >> b >> c >> strict >> w >> used;
748 
749  i.SetA(alpha);
750  i.SetB(b);
751  i.SetC(c);
752  i.SetW(w);
753 
754  if (strict)
755  i.Set_Strict();
756 
757  else
758  i.Unset_Strict();
759 
760  if (used)
761  i.Set_Used();
762 
763  else
764  i.Set_Unused();
765 
766  return i;
767 }
768 
769 #endif