2 // Created: 08.09.05 19:37:06
3 // Author: Alexander GRIGORIEV
4 // Copyright: Open Cascade 2005
6 inline Standard_Boolean _compareDist (const RealType aHSize[2],
7 const RealType aDist[2])
9 return (Abs(aDist[0]) > aHSize[0] || Abs(aDist[1]) > aHSize[1]);
12 inline Standard_Boolean _compareDistD (const gp_XY& aHSize, const gp_XY& aDist)
14 return (Abs(aDist.X()) > aHSize.X() || Abs(aDist.Y()) > aHSize.Y());
17 //=======================================================================
19 //purpose : Update the box by a point
20 //=======================================================================
22 void Bnd_B2x::Add (const gp_XY& thePnt) {
24 myCenter[0] = RealType(thePnt.X());
25 myCenter[1] = RealType(thePnt.Y());
29 const RealType aDiff[2] = {
30 RealType(thePnt.X()) - myCenter[0],
31 RealType(thePnt.Y()) - myCenter[1]
33 if (aDiff[0] > myHSize[0]) {
34 const RealType aShift = (aDiff[0] - myHSize[0]) / 2;
35 myCenter[0] += aShift;
36 myHSize [0] += aShift;
37 } else if (aDiff[0] < -myHSize[0]) {
38 const RealType aShift = (aDiff[0] + myHSize[0]) / 2;
39 myCenter[0] += aShift;
40 myHSize [0] -= aShift;
42 if (aDiff[1] > myHSize[1]) {
43 const RealType aShift = (aDiff[1] - myHSize[1]) / 2;
44 myCenter[1] += aShift;
45 myHSize [1] += aShift;
46 } else if (aDiff[1] < -myHSize[1]) {
47 const RealType aShift = (aDiff[1] + myHSize[1]) / 2;
48 myCenter[1] += aShift;
49 myHSize [1] -= aShift;
54 //=======================================================================
56 //purpose : limit the current box with the internals of theBox
57 //=======================================================================
59 Standard_Boolean Bnd_B2x::Limit (const Bnd_B2x& theBox)
61 Standard_Boolean aResult (Standard_False);
62 const RealType diffC[2] = {
63 theBox.myCenter[0] - myCenter[0],
64 theBox.myCenter[1] - myCenter[1]
66 const RealType sumH[2] = {
67 theBox.myHSize[0] + myHSize[0],
68 theBox.myHSize[1] + myHSize[1]
70 // check the condition IsOut
71 if (_compareDist (sumH, diffC) == Standard_False) {
72 const RealType diffH[2] = {
73 theBox.myHSize[0] - myHSize[0],
74 theBox.myHSize[1] - myHSize[1]
76 if (diffC[0] - diffH[0] > 0.) {
77 const RealType aShift = (diffC[0] - diffH[0]) / 2; // positive
78 myCenter[0] += aShift;
79 myHSize [0] -= aShift;
80 } else if (diffC[0] + diffH[0] < 0.) {
81 const RealType aShift = (diffC[0] + diffH[0]) / 2; // negative
82 myCenter[0] += aShift;
83 myHSize [0] += aShift;
85 if (diffC[1] - diffH[1] > 0.) {
86 const RealType aShift = (diffC[1] - diffH[1]) / 2; // positive
87 myCenter[1] += aShift;
88 myHSize [1] -= aShift;
89 } else if (diffC[1] + diffH[1] < 0.) {
90 const RealType aShift = (diffC[1] + diffH[1]) / 2; // negative
91 myCenter[1] += aShift;
92 myHSize [1] += aShift;
94 aResult = Standard_True;
99 //=======================================================================
100 //function : Transformed
102 //=======================================================================
104 Bnd_B2x Bnd_B2x::Transformed (const gp_Trsf2d& theTrsf) const
107 const gp_TrsfForm aForm = theTrsf.Form();
108 const Standard_Real aScale = theTrsf.ScaleFactor();
109 const Standard_Real aScaleAbs = Abs(aScale);
110 if (aForm == gp_Identity)
112 else if (aForm== gp_Translation || aForm== gp_PntMirror || aForm== gp_Scale)
114 aResult.myCenter[0] =
115 (RealType)(myCenter[0] * aScale + theTrsf.TranslationPart().X());
116 aResult.myCenter[1] =
117 (RealType)(myCenter[1] * aScale + theTrsf.TranslationPart().Y());
118 aResult.myHSize[0] = (RealType)(myHSize[0] * aScaleAbs);
119 aResult.myHSize[1] = (RealType)(myHSize[1] * aScaleAbs);
121 gp_XY aCenter ((Standard_Real)myCenter[0],
122 (Standard_Real)myCenter[1]);
123 theTrsf.Transforms (aCenter);
124 aResult.myCenter[0] = (RealType)aCenter.X();
125 aResult.myCenter[1] = (RealType)aCenter.Y();
127 const Standard_Real * aMat = &theTrsf.HVectorialPart().Value(1,1);
128 aResult.myHSize[0] = (RealType)(aScaleAbs * (Abs(aMat[0]) * myHSize[0]+
129 Abs(aMat[1]) * myHSize[1]));
130 aResult.myHSize[1] = (RealType)(aScaleAbs * (Abs(aMat[2]) * myHSize[0]+
131 Abs(aMat[3]) * myHSize[1]));
136 //=======================================================================
138 //purpose : Intersection Box - Circle
139 //=======================================================================
141 Standard_Boolean Bnd_B2x::IsOut (const gp_XY& theCenter,
142 const Standard_Real theRadius,
143 const Standard_Boolean isCircleHollow) const
145 Standard_Boolean aResult (Standard_True);
146 if (isCircleHollow == Standard_False) {
147 // vector from the center of the circle to the nearest box face
148 const Standard_Real aDist[2] = {
149 Abs(theCenter.X()-Standard_Real(myCenter[0])) - Standard_Real(myHSize[0]),
150 Abs(theCenter.Y()-Standard_Real(myCenter[1])) - Standard_Real(myHSize[1])
152 Standard_Real aD (0.);
154 aD = aDist[0]*aDist[0];
156 aD += aDist[1]*aDist[1];
157 aResult = (aD > theRadius*theRadius);
159 const Standard_Real aDistC[2] = {
160 Abs(theCenter.X()-Standard_Real(myCenter[0])),
161 Abs(theCenter.Y()-Standard_Real(myCenter[1]))
163 // vector from the center of the circle to the nearest box face
164 Standard_Real aDist[2] = {
165 aDistC[0] - Standard_Real(myHSize[0]),
166 aDistC[1] - Standard_Real(myHSize[1])
168 Standard_Real aD (0.);
170 aD = aDist[0]*aDist[0];
172 aD += aDist[1]*aDist[1];
173 if (aD < theRadius*theRadius) {
174 // the box intersects the solid circle; check if it is completely
175 // inside the circle (in such case return isOut==True)
176 aDist[0] = aDistC[0] + Standard_Real(myHSize[0]);
177 aDist[1] = aDistC[1] + Standard_Real(myHSize[1]);
178 if (aDist[0]*aDist[0]+aDist[1]*aDist[1] > theRadius*theRadius)
179 aResult = Standard_False;
185 //=======================================================================
187 //purpose : Intersection Box - transformed Box
188 //=======================================================================
190 Standard_Boolean Bnd_B2x::IsOut (const Bnd_B2x& theBox,
191 const gp_Trsf2d& theTrsf) const
193 Standard_Boolean aResult (Standard_False);
194 const gp_TrsfForm aForm = theTrsf.Form();
195 const Standard_Real aScale = theTrsf.ScaleFactor();
196 const Standard_Real aScaleAbs = Abs(aScale);
197 if (aForm == gp_Translation || aForm == gp_Identity ||
198 aForm == gp_PntMirror || aForm == gp_Scale)
201 (Abs (RealType(theBox.myCenter[0]*aScale + theTrsf.TranslationPart().X())
203 > RealType (theBox.myHSize[0]*aScaleAbs) + myHSize[0] ||
204 Abs (RealType(theBox.myCenter[1]*aScale + theTrsf.TranslationPart().Y())
206 > RealType (theBox.myHSize[1]*aScaleAbs) + myHSize[1]);
210 // theBox is transformed and we check the resulting (enlarged) box against
212 const Standard_Real * aMat = &theTrsf.HVectorialPart().Value(1,1);
214 gp_XY aCenter ((Standard_Real)theBox.myCenter[0],
215 (Standard_Real)theBox.myCenter[1]);
216 theTrsf.Transforms (aCenter);
217 const Standard_Real aDist[2] = {
218 aCenter.X() - (Standard_Real)myCenter[0],
219 aCenter.Y() - (Standard_Real)myCenter[1]
221 const Standard_Real aMatAbs[4] = {
222 Abs(aMat[0]), Abs(aMat[1]), Abs(aMat[2]), Abs(aMat[3])
224 if (Abs(aDist[0]) > (aScaleAbs * (aMatAbs[0]*theBox.myHSize[0]+
225 aMatAbs[1]*theBox.myHSize[1]) +
226 (Standard_Real)myHSize[0]) ||
227 Abs(aDist[1]) > (aScaleAbs * (aMatAbs[2]*theBox.myHSize[0]+
228 aMatAbs[3]*theBox.myHSize[1]) +
229 (Standard_Real)myHSize[1]))
230 aResult = Standard_True;
233 // theBox is rotated, scaled and translated. We apply the reverse
234 // translation and scaling then check against the rotated box 'this'
235 if ((Abs(aMat[0]*aDist[0]+aMat[2]*aDist[1])
236 > theBox.myHSize[0]*aScaleAbs + (aMatAbs[0]*myHSize[0] +
237 aMatAbs[2]*myHSize[1])) ||
238 (Abs(aMat[1]*aDist[0]+aMat[3]*aDist[1])
239 > theBox.myHSize[1]*aScaleAbs + (aMatAbs[1]*myHSize[0] +
240 aMatAbs[3]*myHSize[1])))
241 aResult = Standard_True;
247 //=======================================================================
249 //purpose : Intersection Box - Line
250 //=======================================================================
252 Standard_Boolean Bnd_B2x::IsOut (const gp_Ax2d& theLine) const
255 return Standard_True;
256 // Intersect the line containing the segment.
257 const Standard_Real aProd[3] = {
258 theLine.Direction().XY() ^ (gp_XY (myCenter[0] - theLine.Location().X(),
259 myCenter[1] - theLine.Location().Y())),
260 theLine.Direction().X() * Standard_Real(myHSize[1]),
261 theLine.Direction().Y() * Standard_Real(myHSize[0])
263 return (Abs(aProd[0]) > (Abs(aProd[1]) + Abs(aProd[2])));
266 //=======================================================================
268 //purpose : Intersection Box - Segment
269 //=======================================================================
271 Standard_Boolean Bnd_B2x::IsOut (const gp_XY& theP0, const gp_XY& theP1) const
273 Standard_Boolean aResult (Standard_True);
274 if (IsVoid() == Standard_False)
276 // Intersect the line containing the segment.
277 const gp_XY aSegDelta (theP1 - theP0);
278 const Standard_Real aProd[3] = {
279 aSegDelta ^ (gp_XY (myCenter[0], myCenter[1]) - theP0),
280 aSegDelta.X() * Standard_Real(myHSize[1]),
281 aSegDelta.Y() * Standard_Real(myHSize[0])
283 if (Abs(aProd[0]) < (Abs(aProd[1]) + Abs(aProd[2])))
285 // Intersection with line detected; check the segment as bounding box
286 const gp_XY aHSeg (0.5 * aSegDelta.X(), 0.5 * aSegDelta.Y());
287 const gp_XY aHSegAbs (Abs(aHSeg.X()), Abs(aHSeg.Y()));
288 aResult = _compareDistD (gp_XY((Standard_Real)myHSize[0],
289 (Standard_Real)myHSize[1]) + aHSegAbs,
290 theP0 + aHSeg-gp_XY((Standard_Real)myCenter[0],
291 (Standard_Real)myCenter[1]));
297 //=======================================================================
299 //purpose : Test the complete inclusion of this box in transformed theOtherBox
300 //=======================================================================
302 Standard_Boolean Bnd_B2x::IsIn (const Bnd_B2x& theBox,
303 const gp_Trsf2d& theTrsf) const
305 Standard_Boolean aResult (Standard_False);
306 const gp_TrsfForm aForm = theTrsf.Form();
307 const Standard_Real aScale = theTrsf.ScaleFactor();
308 const Standard_Real aScaleAbs = Abs(aScale);
309 if (aForm == gp_Translation || aForm == gp_Identity ||
310 aForm == gp_PntMirror || aForm == gp_Scale)
313 (Abs (RealType(theBox.myCenter[0]*aScale + theTrsf.TranslationPart().X())
315 < RealType (theBox.myHSize[0]*aScaleAbs) - myHSize[0] &&
316 Abs (RealType(theBox.myCenter[1]*aScale + theTrsf.TranslationPart().Y())
318 < RealType (theBox.myHSize[1]*aScaleAbs) - myHSize[1]);
321 // theBox is rotated, scaled and translated. We apply the reverse
322 // translation and scaling then check against the rotated box 'this'
323 const Standard_Real * aMat = &theTrsf.HVectorialPart().Value(1,1);
324 gp_XY aCenter ((Standard_Real)theBox.myCenter[0],
325 (Standard_Real)theBox.myCenter[1]);
326 theTrsf.Transforms (aCenter);
327 const Standard_Real aDist[2] = {
328 aCenter.X() - (Standard_Real)myCenter[0],
329 aCenter.Y() - (Standard_Real)myCenter[1]
331 if ((Abs(aMat[0]*aDist[0]+aMat[2]*aDist[1])
332 < theBox.myHSize[0]*aScaleAbs - (Abs(aMat[0])*myHSize[0] +
333 Abs(aMat[2])*myHSize[1])) &&
334 (Abs(aMat[1]*aDist[0]+aMat[3]*aDist[1])
335 < theBox.myHSize[1]*aScaleAbs - (Abs(aMat[1])*myHSize[0] +
336 Abs(aMat[3])*myHSize[1])))
337 aResult = Standard_True;