Back to index

salome-med  6.5.0
InterpKernelGeo2DBounds.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D
00002 //
00003 // This library is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU Lesser General Public
00005 // License as published by the Free Software Foundation; either
00006 // version 2.1 of the License.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // Lesser General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU Lesser General Public
00014 // License along with this library; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00016 //
00017 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00018 //
00019 
00020 #include "InterpKernelGeo2DBounds.hxx"
00021 #include "InterpKernelException.hxx"
00022 #include "InterpKernelGeo2DEdgeArcCircle.hxx"
00023 #include "InterpKernelGeo2DNode.hxx"
00024 
00025 using namespace INTERP_KERNEL;
00026 
00027 const double& Bounds::operator[](int i) const
00028 {
00029   switch(i)
00030     {
00031     case 0:
00032       return _x_min;
00033     case 1:
00034       return _x_max;
00035     case 2:
00036       return _y_min;
00037     case 3:
00038       return _y_max;
00039     }
00040   throw Exception("internal error occurs !");
00041 }
00042 
00043 double &Bounds::operator[](int i)
00044 {
00045   switch(i)
00046     {
00047     case 0:
00048       return _x_min;
00049     case 1:
00050       return _x_max;
00051     case 2:
00052       return _y_min;
00053     case 3:
00054       return _y_max;
00055     }
00056   throw Exception("internal error occurs !");
00057 }
00058 
00059 double Bounds::getDiagonal() const
00060 {
00061   double a=_x_max-_x_min;
00062   double b=_y_max-_y_min;
00063   return sqrt(a*a+b*b);
00064 }
00065 
00069 void Bounds::applySimilarity(double xBary, double yBary, double dimChar)
00070 {
00071   _x_min=(_x_min-xBary)/dimChar;
00072   _x_max=(_x_max-xBary)/dimChar;
00073   _y_min=(_y_min-yBary)/dimChar;
00074   _y_max=(_y_max-yBary)/dimChar;
00075 }
00076 
00080 void Bounds::unApplySimilarity(double xBary, double yBary, double dimChar)
00081 {
00082   _x_min=_x_min*dimChar+xBary;
00083   _x_max=_x_max*dimChar+xBary;
00084   _y_min=_y_min*dimChar+yBary;
00085   _y_max=_y_max*dimChar+yBary;
00086 }
00087 
00088 void Bounds::getBarycenter(double& xBary, double& yBary) const
00089 {
00090   xBary=(_x_min+_x_max)/2.;
00091   yBary=(_y_max+_y_min)/2.;
00092 }
00093 
00094 void Bounds::prepareForAggregation()
00095 {
00096   _x_min=1e200; _x_max=-1e200; _y_min=1e200; _y_max=-1e200;
00097 }
00098 
00108 void Bounds::getInterceptedArc(const double *center, double radius, double& intrcptArcAngle0, double& intrcptArcDelta) const
00109 {
00110   double diag=getDiagonal();
00111   if(diag<2.*radius)
00112     {
00113       double v1[2],v2[2],w1[2],w2[2];
00114       v1[0]=_x_min-center[0]; v1[1]=_y_max-center[1]; v2[0]=_x_max-center[0]; v2[1]=_y_min-center[1];
00115       w1[0]=v1[0]; w1[1]=_y_min-center[1];           w2[0]=v2[0]; w2[1]=_y_max-center[1];
00116       double delta1=EdgeArcCircle::SafeAsin(v1[0]*v2[1]-v1[1]*v2[0]);
00117       double delta2=EdgeArcCircle::SafeAsin(w1[0]*w2[1]-w1[1]*w2[0]);
00118       double tmp;
00119       if(fabs(delta1)>fabs(delta2))
00120         {
00121           intrcptArcDelta=delta1;
00122           intrcptArcAngle0=EdgeArcCircle::GetAbsoluteAngle(v1,tmp);
00123         }
00124       else
00125         {
00126           intrcptArcDelta=delta2;
00127           intrcptArcAngle0=EdgeArcCircle::GetAbsoluteAngle(w1,tmp);
00128         }
00129     }
00130 }
00131 
00132 double Bounds::fitXForXFigD(double val, int res) const
00133 {
00134   double delta=std::max(_x_max-_x_min,_y_max-_y_min)/2.;
00135   double ret=val-(_x_max+_x_min)/2.+delta;
00136   delta=11.1375*res/(2.*delta);
00137   return ret*delta;
00138 }
00139 
00140 double Bounds::fitYForXFigD(double val, int res) const
00141 {
00142   double delta=std::max(_x_max-_x_min,_y_max-_y_min)/2.;
00143   double ret=(_y_max+_y_min)/2.-val+delta;
00144   delta=11.1375*res/(2.*delta);
00145   return ret*delta;
00146 }
00147 
00148 Bounds *Bounds::nearlyAmIIntersectingWith(const Bounds& other) const
00149 {
00150   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) 
00151       || (other._y_max < _y_min-QUADRATIC_PLANAR::_precision) )
00152     return 0;
00153   if( (other._x_min >= _x_max ) || (other._x_max <= _x_min) || (other._y_min >= _y_max) || (other._y_max <= _y_min) )
00154     return new Bounds(std::max(_x_min-QUADRATIC_PLANAR::_precision,other._x_min),
00155                       std::min(_x_max+QUADRATIC_PLANAR::_precision,other._x_max),
00156                       std::max(_y_min-QUADRATIC_PLANAR::_precision,other._y_min),
00157                       std::min(_y_max+QUADRATIC_PLANAR::_precision,other._y_max));//In approx cases.
00158   else
00159     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));
00160 }
00161 
00162 Bounds *Bounds::amIIntersectingWith(const Bounds& other) const
00163 {
00164   if( (other._x_min > _x_max) || (other._x_max < _x_min) || (other._y_min > _y_max) || (other._y_max < _y_min) )
00165     return 0;
00166   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));
00167 }
00168 
00169 Position Bounds::where(double x, double y) const
00170 {
00171   if((x>=_x_min && x<=_x_max) && (y>=_y_min && y<=_y_max))
00172     return IN;
00173   else
00174     return OUT;
00175 }
00176 
00177 Position Bounds::nearlyWhere(double x, double y) const
00178 {
00179   bool thinX=Node::areDoubleEquals(_x_min,_x_max);
00180   bool thinY=Node::areDoubleEquals(_y_min,_y_max);
00181   if(!thinX)
00182     {
00183       if((Node::areDoubleEquals(x,_x_min) || Node::areDoubleEquals(x,_x_max)) && ((y<_y_max+QUADRATIC_PLANAR::_precision) && (y>_y_min-QUADRATIC_PLANAR::_precision)))
00184         return ON_BOUNDARY_POS;
00185     }
00186   else
00187     if(!Node::areDoubleEquals(_x_min,x) && !Node::areDoubleEquals(_x_max,x))
00188       return OUT;
00189   if(!thinY)
00190     {
00191       if((Node::areDoubleEquals(y,_y_min) || Node::areDoubleEquals(y,_y_max)) && ((x<_x_max+QUADRATIC_PLANAR::_precision) && (x>_x_min-QUADRATIC_PLANAR::_precision)))
00192         return ON_BOUNDARY_POS;
00193     }
00194   else
00195     if(!Node::areDoubleEquals(_y_min,y) && !Node::areDoubleEquals(_y_max,y))
00196       return OUT;
00197   if(thinX && thinY)
00198     return ON_BOUNDARY_POS;
00199   if((x>=_x_min && x<=_x_max) && (y>=_y_min && y<=_y_max))
00200     return IN;
00201   else
00202     return OUT;
00203 }
00204 
00205 void Bounds::aggregate(const Bounds& other)
00206 {
00207   _x_min=std::min(_x_min,other._x_min); _x_max=std::max(_x_max,other._x_max);
00208   _y_min=std::min(_y_min,other._y_min); _y_max=std::max(_y_max,other._y_max);
00209 }