1 // Copyright (C) 2007-2012 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "InterpKernelGeo2DBounds.hxx"
21 #include "InterpKernelException.hxx"
22 #include "InterpKernelGeo2DEdgeArcCircle.hxx"
23 #include "InterpKernelGeo2DNode.hxx"
25 using namespace INTERP_KERNEL;
27 const double& Bounds::operator[](int i) const
40 throw Exception("internal error occurs !");
43 double &Bounds::operator[](int i)
56 throw Exception("internal error occurs !");
59 double Bounds::getDiagonal() const
61 double a=_x_max-_x_min;
62 double b=_y_max-_y_min;
67 * See Node::applySimilarity to see signification of params.
69 void Bounds::applySimilarity(double xBary, double yBary, double dimChar)
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;
78 * See Node::unApplySimilarity to see signification of params.
80 void Bounds::unApplySimilarity(double xBary, double yBary, double dimChar)
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;
88 void Bounds::getBarycenter(double& xBary, double& yBary) const
90 xBary=(_x_min+_x_max)/2.;
91 yBary=(_y_max+_y_min)/2.;
94 void Bounds::prepareForAggregation()
96 _x_min=1e200; _x_max=-1e200; _y_min=1e200; _y_max=-1e200;
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.
108 void Bounds::getInterceptedArc(const double *center, double radius, double& intrcptArcAngle0, double& intrcptArcDelta) const
110 double diag=getDiagonal();
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]);
119 if(fabs(delta1)>fabs(delta2))
121 intrcptArcDelta=delta1;
122 intrcptArcAngle0=EdgeArcCircle::GetAbsoluteAngle(v1,tmp);
126 intrcptArcDelta=delta2;
127 intrcptArcAngle0=EdgeArcCircle::GetAbsoluteAngle(w1,tmp);
132 double Bounds::fitXForXFigD(double val, int res) const
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);
140 double Bounds::fitYForXFigD(double val, int res) const
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);
148 Bounds *Bounds::nearlyAmIIntersectingWith(const Bounds& other) const
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) )
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.
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));
162 Bounds *Bounds::amIIntersectingWith(const Bounds& other) const
164 if( (other._x_min > _x_max) || (other._x_max < _x_min) || (other._y_min > _y_max) || (other._y_max < _y_min) )
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));
169 Position Bounds::where(double x, double y) const
171 if((x>=_x_min && x<=_x_max) && (y>=_y_min && y<=_y_max))
177 Position Bounds::nearlyWhere(double x, double y) const
179 bool thinX=Node::areDoubleEquals(_x_min,_x_max);
180 bool thinY=Node::areDoubleEquals(_y_min,_y_max);
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;
187 if(!Node::areDoubleEquals(_x_min,x) && !Node::areDoubleEquals(_x_max,x))
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;
195 if(!Node::areDoubleEquals(_y_min,y) && !Node::areDoubleEquals(_y_max,y))
198 return ON_BOUNDARY_POS;
199 if((x>=_x_min && x<=_x_max) && (y>=_y_min && y<=_y_max))
205 void Bounds::aggregate(const Bounds& other)
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);