00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #ifndef INEQUATION_H
00037 #define INEQUATION_H
00038
00039 #include <cassert>
00040 #include "vertex.hh"
00041
00042
00043
00044
00045
00046
00047
00048 class Inequation {
00049
00050 public:
00051
00052
00053 Inequation();
00054 Inequation(float pa, float pb, float pc, float pw);
00055
00056
00057 float GetA() const;
00058 float GetB() const;
00059 float GetC() const;
00060 float GetW() const;
00061 bool Is_Strict() const;
00062 bool Is_Used() const;
00063
00064
00065 int Get_Dim() const;
00066
00067
00068 void SetA(float pa);
00069 void SetB(float pb);
00070 void SetC(float pc);
00071 void SetW(float pw);
00072 void SetAbcw(float pa, float pb, float pc, float pw);
00073 void Set_Strict();
00074 void Unset_Strict();
00075 void Set_Used();
00076 void Set_Unused();
00077
00078
00079
00080 bool Test_Point (CVertex const & pt) const;
00081
00082
00083
00084 bool Test_Point_Eq (CVertex const & pt) const;
00085
00086
00087 CVertex* Intersec (Inequation const & i1, Inequation const & i2);
00088
00089
00090 bool operator == (Inequation i) const;
00091
00092
00093 bool operator != (Inequation i) const;
00094
00095
00096 friend std::ostream& operator << (std::ostream& s, Inequation const & i);
00097 friend Inequation& operator >> (std::ostream& s, Inequation & i);
00098
00099
00100 private:
00101
00102
00103 float alpha, b, c, w;
00104
00105
00106 bool strict;
00107
00108
00109 bool used;
00110 };
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 #include <cmath>
00122 #include "definition.hh"
00123
00124
00125
00126
00127 inline
00128 Inequation::Inequation()
00129 :alpha(0), b(0), c(0), w(0), strict(false), used(true)
00130 {}
00131
00132 inline
00133 Inequation::Inequation(float pa, float pb, float pc, float pw)
00134 :alpha(pa), b(pb), c(pc), w(pw), strict(false), used(true)
00135 {}
00136
00137
00138
00139 inline
00140 float Inequation::GetA() const
00141 {
00142 return alpha;
00143 }
00144
00145 inline
00146 float Inequation::GetB() const
00147 {
00148 return b;
00149 }
00150
00151 inline
00152 float Inequation::GetC() const
00153 {
00154 return c;
00155 }
00156
00157 inline
00158 float Inequation::GetW() const
00159 {
00160 return w;
00161 }
00162
00163 inline
00164 bool Inequation::Is_Strict() const
00165 {
00166 return strict;
00167 }
00168
00169 inline
00170 bool Inequation::Is_Used() const
00171 {
00172 return used;
00173 }
00174
00175
00176
00177 inline
00178 int Inequation::Get_Dim() const
00179 {
00180 if(fabs(alpha)>EPS && fabs(b)>EPS && fabs(c)>EPS)
00181 return 3;
00182
00183 else
00184 if ((fabs(alpha)>EPS && fabs(b)>EPS)||
00185 (fabs(alpha)>EPS && fabs(c)>EPS)||
00186 (fabs(b)>EPS && fabs(c)>EPS))
00187 return 2;
00188
00189 else
00190 if(fabs(alpha)>EPS || fabs(b)>EPS || fabs(c)>EPS)
00191 return 1;
00192
00193 else
00194 return 0;
00195 }
00196
00197
00198
00199 inline
00200 void Inequation::SetA(float pa)
00201 {
00202 alpha=pa;
00203 }
00204
00205 inline
00206 void Inequation::SetB(float pb)
00207 {
00208 b=pb;
00209 }
00210
00211 inline
00212 void Inequation::SetC(float pc)
00213 {
00214 c=pc;
00215 }
00216
00217 inline
00218 void Inequation::SetW(float pw)
00219 {
00220 w=pw;
00221 }
00222
00223 inline
00224 void Inequation::SetAbcw(float pa, float pb, float pc, float pw)
00225 {
00226 alpha=pa;
00227 b=pb;
00228 c=pc;
00229 w=pw;
00230 }
00231
00232 inline
00233 void Inequation::Set_Strict()
00234 {
00235 strict = true;
00236 }
00237
00238 inline
00239 void Inequation::Unset_Strict()
00240 {
00241 strict = false;
00242 }
00243
00244 inline
00245 void Inequation::Set_Used()
00246 {
00247 used = true;
00248 }
00249
00250 inline
00251 void Inequation::Set_Unused()
00252 {
00253 used = false;
00254 }
00255
00256
00257
00258
00259 inline
00260 bool Inequation::Test_Point (CVertex const & pt) const
00261 {
00262 if (strict)
00263 {
00264 if (alpha*pt.getX() + b*pt.getY() + c*pt.getZ() < w)
00265 return true;
00266 else
00267 return false;
00268 }
00269 else
00270 {
00271 if (alpha*pt.getX() + b*pt.getY() + c*pt.getZ() <= w + EPS)
00272 return true;
00273 else
00274 return false;
00275 }
00276 }
00277
00278
00279
00280
00281 inline
00282 bool Inequation::Test_Point_Eq (CVertex const & pt) const
00283 {
00284 if (fabs(alpha*pt.getX() + b*pt.getY() + c*pt.getZ() - w) <= EPS)
00285 return true;
00286
00287 else
00288 return false;
00289 }
00290
00291
00292
00293 inline
00294 CVertex* Inequation::Intersec (Inequation const & i1, Inequation const & i2)
00295 {
00296 float const epsilon = 0.0001;
00297
00298 float mat[3][4] = {{alpha, b, c, w},
00299 {i1.alpha, i1.b, i1.c, i1.w},
00300 {i2.alpha, i2.b, i2.c, i2.w}};
00301 int nbZeros;
00302 float coef1, coef2;
00303
00304 for (int i=0; i<3; i++)
00305 for (int j=0; j<4; j++)
00306 if (fabs(mat[i][j]) < epsilon)
00307 mat[i][j] = 0.0;
00308
00309
00310 nbZeros = 0;
00311 for (int i=0; i<3; i++)
00312 if (mat[i][0] == 0.0)
00313 nbZeros++;
00314
00315
00316 if (nbZeros == 0)
00317 {
00318 coef1 = mat[0][0];
00319 coef2 = mat[1][0];
00320
00321
00322 for (int i=0; i<4; i++)
00323 mat[0][i] = mat[0][i]*coef2 - mat[1][i]*coef1;
00324
00325 coef1 = mat[2][0];
00326
00327
00328 for (int i=0; i<4; i++)
00329 mat[1][i] = mat[1][i]*coef1 - mat[2][i]*coef2;
00330 }
00331
00332
00333 else
00334 if (nbZeros == 1)
00335 {
00336 if (mat[0][0] == 0.0)
00337 {
00338 coef1 = mat[1][0];
00339 coef2 = mat[2][0];
00340
00341 for (int i=0; i<4; i++)
00342 mat[1][i] = mat[1][i]*coef2 - mat[2][i]*coef1;
00343 }
00344
00345 else
00346 if (mat[1][0] == 0.0)
00347 {
00348 coef1 = mat[0][0];
00349 coef2 = mat[2][0];
00350
00351 for (int i=0; i<4; i++)
00352 mat[0][i] = mat[0][i]*coef2 - mat[2][i]*coef1;
00353 }
00354
00355 else
00356 {
00357 coef1 = mat[0][0];
00358 coef2 = mat[1][0];
00359
00360 for (int i=0; i<4; i++)
00361 mat[0][i] = mat[0][i]*coef2 - mat[1][i]*coef1;
00362 }
00363 }
00364
00365
00366 nbZeros = 0;
00367
00368 for (int i=0; i<3; i++)
00369 if (mat[i][1] == 0.0)
00370 nbZeros++;
00371
00372
00373 if (nbZeros == 0)
00374 {
00375 if (mat[0][0] == 0.0)
00376 {
00377 coef1 = mat[0][1];
00378
00379 if (mat[1][0] == 0.0)
00380 {
00381 coef2 = mat[1][1];
00382
00383 for (int i=1; i<4; i++)
00384 mat[1][i] = mat[1][i]*coef1 - mat[0][i]*coef2;
00385
00386 coef2 = mat[2][1];
00387
00388 for (int i=0; i<4; i++)
00389 mat[2][i] = mat[2][i]*coef1 - mat[0][i]*coef2;
00390 }
00391
00392 else
00393 {
00394 coef2 = mat[2][1];
00395
00396 for (int i=1; i<4; i++)
00397 mat[2][i] = mat[2][i]*coef1 - mat[0][i]*coef2;
00398
00399 coef2 = mat[1][1];
00400
00401 for (int i=0; i<4; i++)
00402 mat[1][i] = mat[1][i]*coef1 - mat[0][i]*coef2;
00403 }
00404 }
00405
00406 else
00407 {
00408 coef1 = mat[0][1];
00409 coef2 = mat[1][1];
00410
00411 for (int i=0; i<4; i++)
00412 mat[0][i] = mat[0][i]*coef2 - mat[1][i]*coef1;
00413
00414 coef1 = mat[2][1];
00415
00416 for (int i=1; i<4; i++)
00417 mat[1][i] = mat[1][i]*coef1 - mat[2][i]*coef2;
00418 }
00419 }
00420
00421
00422 else
00423 if (nbZeros == 1)
00424 {
00425 if (mat[0][1] == 0.0)
00426 {
00427 if (mat[0][0] == 0.0)
00428 {
00429 coef1 = mat[1][1];
00430 coef2 = mat[2][1];
00431
00432 if (mat[1][0] == 0.0)
00433 {
00434 for (int i=0; i<4; i++)
00435 mat[2][i] = mat[2][i]*coef1 - mat[1][i]*coef2;
00436 }
00437
00438 else
00439 {
00440 for (int i=0; i<4; i++)
00441 mat[1][i] = mat[1][i]*coef2 - mat[2][i]*coef1;
00442 }
00443 }
00444
00445 else
00446 {
00447 coef1 = mat[2][1];
00448 coef2 = mat[1][1];
00449
00450 for (int i=1; i<4; i++)
00451 mat[1][i] = mat[1][i]*coef1 - mat[2][i]*coef2;
00452 }
00453 }
00454
00455 else
00456 if (mat[1][1] == 0.0)
00457 {
00458 if (mat[1][0] == 0.0)
00459 {
00460 coef1 = mat[0][1];
00461 coef2 = mat[2][1];
00462
00463 if (mat[0][0] == 0.0)
00464 {
00465 for (int i=0; i<4; i++)
00466 mat[2][i] = mat[2][i]*coef1 - mat[0][i]*coef2;
00467 }
00468
00469 else
00470 {
00471 for (int i=0; i<4; i++)
00472 mat[0][i] = mat[0][i]*coef2 - mat[2][i]*coef1;
00473 }
00474 }
00475
00476 else
00477 {
00478 coef1 = mat[0][1];
00479 coef2 = mat[2][1];
00480
00481 for (int i=1; i<4; i++)
00482 mat[0][i] = mat[0][i]*coef2 - mat[2][i]*coef1;
00483 }
00484 }
00485
00486 else
00487 {
00488 if (mat[2][0] == 0.0)
00489 {
00490 coef1 = mat[0][1];
00491 coef2 = mat[1][1];
00492
00493 if (mat[0][0] == 0.0)
00494 {
00495 for (int i=0; i<4; i++)
00496 mat[1][i] = mat[1][i]*coef1 - mat[0][i]*coef2;
00497 }
00498
00499 else
00500 {
00501 for (int i=0; i<4; i++)
00502 mat[0][i] = mat[0][i]*coef2 - mat[1][i]*coef1;
00503 }
00504 }
00505
00506 else
00507 {
00508 coef1 = mat[0][1];
00509 coef2 = mat[1][1];
00510
00511 for (int i=1; i<4; i++)
00512 mat[0][i] = mat[0][i]*coef2 - mat[1][i]*coef1;
00513 }
00514 }
00515 }
00516
00517
00518 nbZeros = 0;
00519
00520 for (int i=0; i<3; i++)
00521 if (mat[i][2] == 0.0)
00522 nbZeros++;
00523
00524
00525 if (nbZeros == 0)
00526 {
00527 if (mat[0][0] == 0.0 && mat[0][1] == 0.0)
00528 {
00529 coef1 = mat[0][2];
00530 coef2 = mat[1][2];
00531
00532 for (int i=0; i<4; i++)
00533 mat[1][i] = mat[1][i]*coef1 - mat[0][i]*coef2;
00534
00535 coef2 = mat[2][2];
00536
00537 for (int i=0; i<4; i++)
00538 mat[2][i] = mat[2][i]*coef1 - mat[0][i]*coef2;
00539 }
00540
00541 else
00542 if (mat[1][0] == 0.0 && mat[1][1] == 0.0)
00543 {
00544 coef1 = mat[1][2];
00545 coef2 = mat[0][2];
00546
00547 for (int i=0; i<4; i++)
00548 mat[0][i] = mat[0][i]*coef1 - mat[1][i]*coef2;
00549
00550 coef2 = mat[2][2];
00551
00552 for (int i=0; i<4; i++)
00553 mat[2][i] = mat[2][i]*coef1 - mat[1][i]*coef2;
00554 }
00555
00556 else
00557 {
00558 coef1 = mat[2][2];
00559 coef2 = mat[0][2];
00560
00561 for (int i=0; i<4; i++)
00562 mat[0][i] = mat[0][i]*coef1 - mat[2][i]*coef2;
00563
00564 coef2 = mat[1][2];
00565
00566 for (int i=0; i<4; i++)
00567 mat[1][i] = mat[1][i]*coef1 - mat[2][i]*coef2;
00568 }
00569 }
00570
00571 else
00572 if (nbZeros == 1)
00573 {
00574 if (mat[0][2] == 0.0)
00575 {
00576 coef1 = mat[2][2];
00577 coef2 = mat[1][2];
00578
00579 if (mat[1][0] == 0.0 && mat[1][1] == 0.0)
00580 {
00581 for (int i=0; i<4; i++)
00582 mat[2][i] = mat[2][i]*coef2 - mat[1][i]*coef1;
00583 }
00584
00585 else
00586 {
00587 for (int i=0; i<4; i++)
00588 mat[1][i] = mat[1][i]*coef1 - mat[2][i]*coef2;
00589 }
00590 }
00591
00592 else
00593 if (mat[1][2] == 0.0)
00594 {
00595 coef1 = mat[0][2];
00596 coef2 = mat[2][2];
00597
00598 if (mat[0][0] == 0.0 && mat[0][1] == 0.0)
00599 {
00600 for (int i=0; i<4; i++)
00601 mat[2][i] = mat[2][i]*coef1 - mat[0][i]*coef2;
00602 }
00603
00604 else
00605 {
00606 for (int i=0; i<4; i++)
00607 mat[0][i] = mat[0][i]*coef2 - mat[2][i]*coef1;
00608 }
00609 }
00610
00611 else
00612 {
00613 coef1 = mat[0][2];
00614 coef2 = mat[1][2];
00615
00616 if (mat[0][0] == 0.0 && mat[0][1] == 0.0)
00617 {
00618 for (int i=0; i<4; i++)
00619 mat[1][i] = mat[1][i]*coef1 - mat[0][i]*coef2;
00620 }
00621
00622 else
00623 {
00624 for (int i=0; i<4; i++)
00625 mat[0][i] = mat[0][i]*coef2 - mat[1][i]*coef1;
00626 }
00627 }
00628 }
00629
00630 float x, y, z;
00631
00632 if (mat[0][0] != 0.0)
00633 x = mat[0][3] / mat[0][0];
00634
00635 else
00636 if (mat[1][0] != 0.0)
00637 x = mat[1][3] / mat[1][0];
00638
00639 else
00640 x = mat[2][3] / mat[2][0];
00641
00642 if (mat[0][1] != 0.0)
00643 y = mat[0][3] / mat[0][1];
00644
00645 else
00646 if (mat[1][1] != 0.0)
00647 y = mat[1][3] / mat[1][1];
00648
00649 else
00650 y = mat[2][3] / mat[2][1];
00651
00652 if (mat[0][2] != 0.0)
00653 z = mat[0][3] / mat[0][2];
00654
00655 else
00656 if (mat[1][2] != 0.0)
00657 z = mat[1][3] / mat[1][2];
00658
00659 else
00660 z = mat[2][3] / mat[2][2];
00661
00662 return new CVertex (x, y, z);
00663 }
00664
00665
00666
00667 inline
00668 bool Inequation::operator == (Inequation i) const
00669 {
00670 bool change = false;
00671
00672 if (alpha != 0.0 && i.alpha != 0.0)
00673 {
00674 i.b = (i.b * alpha)/i.alpha;
00675 i.c = (i.c * alpha)/i.alpha;
00676 i.w = (i.w * alpha)/i.alpha;
00677 change = true;
00678 }
00679 else
00680 if (alpha != 0.0 || i.alpha != 0.0)
00681 return false;
00682
00683 if (b != 0.0 && i.b != 0.0)
00684 {
00685 if (change && fabs(b - i.b) > EPS)
00686 return false;
00687 else
00688 if (fabs(b - i.b) > EPS)
00689 {
00690 i.c = (i.c * b)/i.b;
00691 i.w = (i.w * b)/i.b;
00692 }
00693 }
00694 else
00695 if (b != 0.0 || i.b != 0.0)
00696 return false;
00697
00698 if (c != 0.0 && i.c != 0.0)
00699 {
00700 if (change && fabs(c - i.c) > EPS)
00701 return false;
00702 else
00703 if (fabs(c - i.c) > EPS)
00704 {
00705 i.w = (i.w * c)/i.c;
00706 }
00707 }
00708 else
00709 if (c != 0.0 || i.c != 0.0)
00710 return false;
00711
00712 if (fabs(w - i.w) > EPS)
00713 return false;
00714
00715 return true;
00716 }
00717
00718
00719
00720 inline
00721 bool Inequation::operator != (Inequation i) const
00722 {
00723 return !(*this == i);
00724 }
00725
00726
00727
00728 inline
00729 std::ostream& operator << (std::ostream& s, Inequation const & i)
00730 {
00731 s << i.GetA() << "\t"
00732 << i.GetB() << "\t"
00733 << i.GetC() << "\t\t"
00734 << i.Is_Strict();
00735
00736 s << "\t\t" << i.GetW() << "\t\t" << i.Is_Used() << std::endl;
00737
00738 return s;
00739 }
00740
00741 inline
00742 Inequation& operator >> (std::istream& s, Inequation & i)
00743 {
00744 float alpha, b, c, w;
00745 bool strict, used;
00746
00747 s >> alpha >> b >> c >> strict >> w >> used;
00748
00749 i.SetA(alpha);
00750 i.SetB(b);
00751 i.SetC(c);
00752 i.SetW(w);
00753
00754 if (strict)
00755 i.Set_Strict();
00756
00757 else
00758 i.Unset_Strict();
00759
00760 if (used)
00761 i.Set_Used();
00762
00763 else
00764 i.Set_Unused();
00765
00766 return i;
00767 }
00768
00769 #endif