1 // Copyright (C) 2007-2016 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, or (at your option) any later version.
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
19 // Author : Anthony Geay (CEA/DEN)
21 #include "InterpKernelGeo2DBounds.hxx"
22 #include "InterpKernelException.hxx"
23 #include "InterpKernelGeo2DEdgeArcCircle.hxx"
24 #include "InterpKernelGeo2DNode.hxx"
26 using namespace INTERP_KERNEL;
28 const double& Bounds::operator[](int i) const
41 throw Exception("internal error occurs !");
44 double &Bounds::operator[](int i)
57 throw Exception("internal error occurs !");
60 double Bounds::getDiagonal() const
62 double a=_x_max-_x_min;
63 double b=_y_max-_y_min;
68 * See Node::applySimilarity to see signification of params.
70 void Bounds::applySimilarity(double xBary, double yBary, double dimChar)
72 _x_min=(_x_min-xBary)/dimChar;
73 _x_max=(_x_max-xBary)/dimChar;
74 _y_min=(_y_min-yBary)/dimChar;
75 _y_max=(_y_max-yBary)/dimChar;
79 * See Node::unApplySimilarity to see signification of params.
81 void Bounds::unApplySimilarity(double xBary, double yBary, double dimChar)
83 _x_min=_x_min*dimChar+xBary;
84 _x_max=_x_max*dimChar+xBary;
85 _y_min=_y_min*dimChar+yBary;
86 _y_max=_y_max*dimChar+yBary;
89 void Bounds::getBarycenter(double& xBary, double& yBary) const
91 xBary=(_x_min+_x_max)/2.;
92 yBary=(_y_max+_y_min)/2.;
95 void Bounds::prepareForAggregation()
97 _x_min=1e200; _x_max=-1e200; _y_min=1e200; _y_max=-1e200;
101 * Given an arc defined by 'center', 'radius' and 'intrcptArcDelta' in radian, returns (by outputs intrcptArcAngle0 and intrcptArcDelta)
102 * the intercepted angle of 'this' from 'center' point of view.
103 * If diagonal of 'this' is the same order of 2*radius, intrcptArcAngle0 and intrcptArcDelta remains unchanged.
104 * @param center IN parameter.
105 * @param radius IN parameter.
106 * @param [out] intrcptArcAngle0 OUT parameter.
107 * @param [out] intrcptArcDelta OUT parameter.
109 void Bounds::getInterceptedArc(const double *center, double radius, double& intrcptArcAngle0, double& intrcptArcDelta) const
111 double diag=getDiagonal();
114 double v1[2],v2[2],w1[2],w2[2];
115 v1[0]=_x_min-center[0]; v1[1]=_y_max-center[1]; v2[0]=_x_max-center[0]; v2[1]=_y_min-center[1];
116 w1[0]=v1[0]; w1[1]=_y_min-center[1]; w2[0]=v2[0]; w2[1]=_y_max-center[1];
117 double delta1=EdgeArcCircle::SafeAsin(v1[0]*v2[1]-v1[1]*v2[0]);
118 double delta2=EdgeArcCircle::SafeAsin(w1[0]*w2[1]-w1[1]*w2[0]);
120 if(fabs(delta1)>fabs(delta2))
122 intrcptArcDelta=delta1;
123 intrcptArcAngle0=EdgeArcCircle::GetAbsoluteAngle(v1,tmp);
127 intrcptArcDelta=delta2;
128 intrcptArcAngle0=EdgeArcCircle::GetAbsoluteAngle(w1,tmp);
133 double Bounds::fitXForXFigD(double val, int res) const
135 double delta=std::max(_x_max-_x_min,_y_max-_y_min)/2.;
136 double ret=val-(_x_max+_x_min)/2.+delta;
137 delta=11.1375*res/(2.*delta);
141 double Bounds::fitYForXFigD(double val, int res) const
143 double delta=std::max(_x_max-_x_min,_y_max-_y_min)/2.;
144 double ret=(_y_max+_y_min)/2.-val+delta;
145 delta=11.1375*res/(2.*delta);
149 Bounds *Bounds::nearlyAmIIntersectingWith(const Bounds& other) const
151 double eps = QuadraticPlanarPrecision::getPrecision();
152 if( (other._x_min > _x_max+eps) || (other._x_max < _x_min-eps) || (other._y_min > _y_max+eps)
153 || (other._y_max < _y_min-eps) )
155 if( (other._x_min >= _x_max ) || (other._x_max <= _x_min) || (other._y_min >= _y_max) || (other._y_max <= _y_min) )
157 return new Bounds(std::max(_x_min-eps,other._x_min),
158 std::min(_x_max+eps,other._x_max),
159 std::max(_y_min-eps,other._y_min),
160 std::min(_y_max+eps,other._y_max));//In approx cases.
163 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));
166 Bounds *Bounds::amIIntersectingWith(const Bounds& other) const
168 if( (other._x_min > _x_max) || (other._x_max < _x_min) || (other._y_min > _y_max) || (other._y_max < _y_min) )
170 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));
173 Position Bounds::where(double x, double y) const
175 if((x>=_x_min && x<=_x_max) && (y>=_y_min && y<=_y_max))
181 Position Bounds::nearlyWhere(double x, double y) const
183 bool thinX=Node::areDoubleEquals(_x_min,_x_max);
184 bool thinY=Node::areDoubleEquals(_y_min,_y_max);
187 if((Node::areDoubleEquals(x,_x_min) || Node::areDoubleEquals(x,_x_max)) && ((y<_y_max+QuadraticPlanarPrecision::getPrecision()) && (y>_y_min-QuadraticPlanarPrecision::getPrecision())))
188 return ON_BOUNDARY_POS;
191 if(!Node::areDoubleEquals(_x_min,x) && !Node::areDoubleEquals(_x_max,x))
195 if((Node::areDoubleEquals(y,_y_min) || Node::areDoubleEquals(y,_y_max)) && ((x<_x_max+QuadraticPlanarPrecision::getPrecision()) && (x>_x_min-QuadraticPlanarPrecision::getPrecision())))
196 return ON_BOUNDARY_POS;
199 if(!Node::areDoubleEquals(_y_min,y) && !Node::areDoubleEquals(_y_max,y))
202 return ON_BOUNDARY_POS;
203 if((x>=_x_min && x<=_x_max) && (y>=_y_min && y<=_y_max))
209 void Bounds::aggregate(const Bounds& other)
211 _x_min=std::min(_x_min,other._x_min); _x_max=std::max(_x_max,other._x_max);
212 _y_min=std::min(_y_min,other._y_min); _y_max=std::max(_y_max,other._y_max);