]> SALOME platform Git repositories - tools/medcoupling.git/blob - src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DBounds.cxx
Salome HOME
Merge from V6_main_20120808 08Aug12
[tools/medcoupling.git] / src / INTERP_KERNEL / Geometric2D / InterpKernelGeo2DBounds.cxx
1 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "InterpKernelGeo2DBounds.hxx"
21 #include "InterpKernelException.hxx"
22 #include "InterpKernelGeo2DEdgeArcCircle.hxx"
23 #include "InterpKernelGeo2DNode.hxx"
24
25 using namespace INTERP_KERNEL;
26
27 const double& Bounds::operator[](int i) const
28 {
29   switch(i)
30     {
31     case 0:
32       return _x_min;
33     case 1:
34       return _x_max;
35     case 2:
36       return _y_min;
37     case 3:
38       return _y_max;
39     }
40   throw Exception("internal error occurs !");
41 }
42
43 double &Bounds::operator[](int i)
44 {
45   switch(i)
46     {
47     case 0:
48       return _x_min;
49     case 1:
50       return _x_max;
51     case 2:
52       return _y_min;
53     case 3:
54       return _y_max;
55     }
56   throw Exception("internal error occurs !");
57 }
58
59 double Bounds::getDiagonal() const
60 {
61   double a=_x_max-_x_min;
62   double b=_y_max-_y_min;
63   return sqrt(a*a+b*b);
64 }
65
66 /*!
67  * See Node::applySimilarity to see signification of params.
68  */
69 void Bounds::applySimilarity(double xBary, double yBary, double dimChar)
70 {
71   _x_min=(_x_min-xBary)/dimChar;
72   _x_max=(_x_max-xBary)/dimChar;
73   _y_min=(_y_min-yBary)/dimChar;
74   _y_max=(_y_max-yBary)/dimChar;
75 }
76
77 /*!
78  * See Node::unApplySimilarity to see signification of params.
79  */
80 void Bounds::unApplySimilarity(double xBary, double yBary, double dimChar)
81 {
82   _x_min=_x_min*dimChar+xBary;
83   _x_max=_x_max*dimChar+xBary;
84   _y_min=_y_min*dimChar+yBary;
85   _y_max=_y_max*dimChar+yBary;
86 }
87
88 void Bounds::getBarycenter(double& xBary, double& yBary) const
89 {
90   xBary=(_x_min+_x_max)/2.;
91   yBary=(_y_max+_y_min)/2.;
92 }
93
94 void Bounds::prepareForAggregation()
95 {
96   _x_min=1e200; _x_max=-1e200; _y_min=1e200; _y_max=-1e200;
97 }
98
99 /*! 
100  * Given an arc defined by 'center', 'radius' and 'intrcptArcDelta' in radian, returns (by outputs intrcptArcAngle0 and intrcptArcDelta)
101  * the intercepted angle of 'this' from 'center' point of view.
102  * If diagonal of 'this' is the same order of 2*radius, intrcptArcAngle0 and intrcptArcDelta remains unchanged.
103  * @param center IN parameter.
104  * @param radius IN parameter.
105  * @param intrcptArcAngle0 OUT parameter.
106  * @param intrcptArcDelta IN/OUT parameter.
107  */
108 void Bounds::getInterceptedArc(const double *center, double radius, double& intrcptArcAngle0, double& intrcptArcDelta) const
109 {
110   double diag=getDiagonal();
111   if(diag<2.*radius)
112     {
113       double v1[2],v2[2],w1[2],w2[2];
114       v1[0]=_x_min-center[0]; v1[1]=_y_max-center[1]; v2[0]=_x_max-center[0]; v2[1]=_y_min-center[1];
115       w1[0]=v1[0]; w1[1]=_y_min-center[1];           w2[0]=v2[0]; w2[1]=_y_max-center[1];
116       double delta1=EdgeArcCircle::SafeAsin(v1[0]*v2[1]-v1[1]*v2[0]);
117       double delta2=EdgeArcCircle::SafeAsin(w1[0]*w2[1]-w1[1]*w2[0]);
118       double tmp;
119       if(fabs(delta1)>fabs(delta2))
120         {
121           intrcptArcDelta=delta1;
122           intrcptArcAngle0=EdgeArcCircle::GetAbsoluteAngle(v1,tmp);
123         }
124       else
125         {
126           intrcptArcDelta=delta2;
127           intrcptArcAngle0=EdgeArcCircle::GetAbsoluteAngle(w1,tmp);
128         }
129     }
130 }
131
132 double Bounds::fitXForXFigD(double val, int res) const
133 {
134   double delta=std::max(_x_max-_x_min,_y_max-_y_min)/2.;
135   double ret=val-(_x_max+_x_min)/2.+delta;
136   delta=11.1375*res/(2.*delta);
137   return ret*delta;
138 }
139
140 double Bounds::fitYForXFigD(double val, int res) const
141 {
142   double delta=std::max(_x_max-_x_min,_y_max-_y_min)/2.;
143   double ret=(_y_max+_y_min)/2.-val+delta;
144   delta=11.1375*res/(2.*delta);
145   return ret*delta;
146 }
147
148 Bounds *Bounds::nearlyAmIIntersectingWith(const Bounds& other) const
149 {
150   if( (other._x_min > _x_max+QUADRATIC_PLANAR::_precision) || (other._x_max < _x_min-QUADRATIC_PLANAR::_precision) || (other._y_min > _y_max+QUADRATIC_PLANAR::_precision) 
151       || (other._y_max < _y_min-QUADRATIC_PLANAR::_precision) )
152     return 0;
153   if( (other._x_min >= _x_max ) || (other._x_max <= _x_min) || (other._y_min >= _y_max) || (other._y_max <= _y_min) )
154     return new Bounds(std::max(_x_min-QUADRATIC_PLANAR::_precision,other._x_min),
155                       std::min(_x_max+QUADRATIC_PLANAR::_precision,other._x_max),
156                       std::max(_y_min-QUADRATIC_PLANAR::_precision,other._y_min),
157                       std::min(_y_max+QUADRATIC_PLANAR::_precision,other._y_max));//In approx cases.
158   else
159     return new Bounds(std::max(_x_min,other._x_min),std::min(_x_max,other._x_max),std::max(_y_min,other._y_min),std::min(_y_max,other._y_max));
160 }
161
162 Bounds *Bounds::amIIntersectingWith(const Bounds& other) const
163 {
164   if( (other._x_min > _x_max) || (other._x_max < _x_min) || (other._y_min > _y_max) || (other._y_max < _y_min) )
165     return 0;
166   return new Bounds(std::max(_x_min,other._x_min),std::min(_x_max,other._x_max),std::max(_y_min,other._y_min),std::min(_y_max,other._y_max));
167 }
168
169 Position Bounds::where(double x, double y) const
170 {
171   if((x>=_x_min && x<=_x_max) && (y>=_y_min && y<=_y_max))
172     return IN;
173   else
174     return OUT;
175 }
176
177 Position Bounds::nearlyWhere(double x, double y) const
178 {
179   bool thinX=Node::areDoubleEquals(_x_min,_x_max);
180   bool thinY=Node::areDoubleEquals(_y_min,_y_max);
181   if(!thinX)
182     {
183       if((Node::areDoubleEquals(x,_x_min) || Node::areDoubleEquals(x,_x_max)) && ((y<_y_max+QUADRATIC_PLANAR::_precision) && (y>_y_min-QUADRATIC_PLANAR::_precision)))
184         return ON_BOUNDARY_POS;
185     }
186   else
187     if(!Node::areDoubleEquals(_x_min,x) && !Node::areDoubleEquals(_x_max,x))
188       return OUT;
189   if(!thinY)
190     {
191       if((Node::areDoubleEquals(y,_y_min) || Node::areDoubleEquals(y,_y_max)) && ((x<_x_max+QUADRATIC_PLANAR::_precision) && (x>_x_min-QUADRATIC_PLANAR::_precision)))
192         return ON_BOUNDARY_POS;
193     }
194   else
195     if(!Node::areDoubleEquals(_y_min,y) && !Node::areDoubleEquals(_y_max,y))
196       return OUT;
197   if(thinX && thinY)
198     return ON_BOUNDARY_POS;
199   if((x>=_x_min && x<=_x_max) && (y>=_y_min && y<=_y_max))
200     return IN;
201   else
202     return OUT;
203 }
204
205 void Bounds::aggregate(const Bounds& other)
206 {
207   _x_min=std::min(_x_min,other._x_min); _x_max=std::max(_x_max,other._x_max);
208   _y_min=std::min(_y_min,other._y_min); _y_max=std::max(_y_max,other._y_max);
209 }