1 // Created on: 2005-09-08
2 // Created by: Alexander GRIGORIEV
3 // Copyright (c) 2005-2012 OPEN CASCADE SAS
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
21 inline Standard_Boolean _compareDist (const RealType aHSize[3],
22 const RealType aDist [3])
24 return (Abs(aDist[0]) > aHSize[0] ||
25 Abs(aDist[1]) > aHSize[1] ||
26 Abs(aDist[2]) > aHSize[2]);
29 inline Standard_Boolean _compareDistD (const gp_XYZ& aHSize,const gp_XYZ& aDist)
31 return (Abs(aDist.X()) > aHSize.X() ||
32 Abs(aDist.Y()) > aHSize.Y() ||
33 Abs(aDist.Z()) > aHSize.Z());
36 //=======================================================================
38 //purpose : Update the box by a point
39 //=======================================================================
41 void Bnd_B3x::Add (const gp_XYZ& thePnt) {
43 myCenter[0] = RealType(thePnt.X());
44 myCenter[1] = RealType(thePnt.Y());
45 myCenter[2] = RealType(thePnt.Z());
50 const RealType aDiff[3] = {
51 RealType(thePnt.X()) - myCenter[0],
52 RealType(thePnt.Y()) - myCenter[1],
53 RealType(thePnt.Z()) - myCenter[2]
55 if (aDiff[0] > myHSize[0]) {
56 const RealType aShift = (aDiff[0] - myHSize[0]) / 2;
57 myCenter[0] += aShift;
58 myHSize [0] += aShift;
59 } else if (aDiff[0] < -myHSize[0]) {
60 const RealType aShift = (aDiff[0] + myHSize[0]) / 2;
61 myCenter[0] += aShift;
62 myHSize [0] -= aShift;
64 if (aDiff[1] > myHSize[1]) {
65 const RealType aShift = (aDiff[1] - myHSize[1]) / 2;
68 } else if (aDiff[1] < -myHSize[1]) {
69 const RealType aShift = (aDiff[1] + myHSize[1]) / 2;
70 myCenter[1] += aShift;
71 myHSize [1] -= aShift;
73 if (aDiff[2] > myHSize[2]) {
74 const RealType aShift = (aDiff[2] - myHSize[2]) / 2;
77 } else if (aDiff[2] < -myHSize[2]) {
78 const RealType aShift = (aDiff[2] + myHSize[2]) / 2;
79 myCenter[2] += aShift;
80 myHSize [2] -= aShift;
85 //=======================================================================
87 //purpose : limit the current box with the internals of theBox
88 //=======================================================================
90 Standard_Boolean Bnd_B3x::Limit (const Bnd_B3x& theBox)
92 Standard_Boolean aResult (Standard_False);
93 const RealType diffC[3] = {
94 theBox.myCenter[0] - myCenter[0],
95 theBox.myCenter[1] - myCenter[1],
96 theBox.myCenter[2] - myCenter[2]
98 const RealType sumH[3] = {
99 theBox.myHSize[0] + myHSize[0],
100 theBox.myHSize[1] + myHSize[1],
101 theBox.myHSize[2] + myHSize[2]
103 // check the condition IsOut
104 if (_compareDist (sumH, diffC) == Standard_False) {
105 const RealType diffH[3] = {
106 theBox.myHSize[0] - myHSize[0],
107 theBox.myHSize[1] - myHSize[1],
108 theBox.myHSize[2] - myHSize[2]
110 if (diffC[0] - diffH[0] > 0.) {
111 const RealType aShift = (diffC[0] - diffH[0]) / 2; // positive
112 myCenter[0] += aShift;
113 myHSize [0] -= aShift;
114 } else if (diffC[0] + diffH[0] < 0.) {
115 const RealType aShift = (diffC[0] + diffH[0]) / 2; // negative
116 myCenter[0] += aShift;
117 myHSize [0] += aShift;
119 if (diffC[1] - diffH[1] > 0.) {
120 const RealType aShift = (diffC[1] - diffH[1]) / 2; // positive
121 myCenter[1] += aShift;
122 myHSize [1] -= aShift;
123 } else if (diffC[1] + diffH[1] < 0.) {
124 const RealType aShift = (diffC[1] + diffH[1]) / 2; // negative
125 myCenter[1] += aShift;
126 myHSize [1] += aShift;
128 if (diffC[2] - diffH[2] > 0.) {
129 const RealType aShift = (diffC[2] - diffH[2]) / 2; // positive
130 myCenter[2] += aShift;
131 myHSize [2] -= aShift;
132 } else if (diffC[2] + diffH[2] < 0.) {
133 const RealType aShift = (diffC[2] + diffH[2]) / 2; // negative
134 myCenter[2] += aShift;
135 myHSize [2] += aShift;
137 aResult = Standard_True;
142 //=======================================================================
143 //function : Transformed
145 //=======================================================================
147 Bnd_B3x Bnd_B3x::Transformed (const gp_Trsf& theTrsf) const
150 const gp_TrsfForm aForm = theTrsf.Form();
151 const Standard_Real aScale = theTrsf.ScaleFactor();
152 const Standard_Real aScaleAbs = Abs(aScale);
153 if (aForm == gp_Identity)
155 else if (aForm== gp_Translation || aForm== gp_PntMirror || aForm== gp_Scale)
157 aResult.myCenter[0] =
158 (RealType)(myCenter[0] * aScale + theTrsf.TranslationPart().X());
159 aResult.myCenter[1] =
160 (RealType)(myCenter[1] * aScale + theTrsf.TranslationPart().Y());
161 aResult.myCenter[2] =
162 (RealType)(myCenter[2] * aScale + theTrsf.TranslationPart().Z());
163 aResult.myHSize[0] = (RealType)(myHSize[0] * aScaleAbs);
164 aResult.myHSize[1] = (RealType)(myHSize[1] * aScaleAbs);
165 aResult.myHSize[2] = (RealType)(myHSize[2] * aScaleAbs);
167 gp_XYZ aCenter ((Standard_Real)myCenter[0],
168 (Standard_Real)myCenter[1],
169 (Standard_Real)myCenter[2]);
170 theTrsf.Transforms (aCenter);
171 aResult.myCenter[0] = (RealType)aCenter.X();
172 aResult.myCenter[1] = (RealType)aCenter.Y();
173 aResult.myCenter[2] = (RealType)aCenter.Z();
175 const Standard_Real * aMat = &theTrsf.HVectorialPart().Value(1,1);
176 aResult.myHSize[0] = (RealType)(aScaleAbs * (Abs(aMat[0]) * myHSize[0]+
177 Abs(aMat[1]) * myHSize[1]+
178 Abs(aMat[2]) * myHSize[2]));
179 aResult.myHSize[1] = (RealType)(aScaleAbs * (Abs(aMat[3]) * myHSize[0]+
180 Abs(aMat[4]) * myHSize[1]+
181 Abs(aMat[5]) * myHSize[2]));
182 aResult.myHSize[2] = (RealType)(aScaleAbs * (Abs(aMat[6]) * myHSize[0]+
183 Abs(aMat[7]) * myHSize[1]+
184 Abs(aMat[8]) * myHSize[2]));
189 //=======================================================================
191 //purpose : Intersection Box - Sphere
192 //=======================================================================
194 Standard_Boolean Bnd_B3x::IsOut (const gp_XYZ& theCenter,
195 const Standard_Real theRadius,
196 const Standard_Boolean isSphereHollow) const
198 Standard_Boolean aResult (Standard_True);
199 if (isSphereHollow == Standard_False) {
200 // vector from the center of the sphere to the nearest box face
201 const Standard_Real aDist[3] = {
202 Abs(theCenter.X()-Standard_Real(myCenter[0])) - Standard_Real(myHSize[0]),
203 Abs(theCenter.Y()-Standard_Real(myCenter[1])) - Standard_Real(myHSize[1]),
204 Abs(theCenter.Z()-Standard_Real(myCenter[2])) - Standard_Real(myHSize[2])
206 Standard_Real aD (0.);
208 aD = aDist[0]*aDist[0];
210 aD += aDist[1]*aDist[1];
212 aD += aDist[2]*aDist[2];
213 aResult = (aD > theRadius*theRadius);
215 const Standard_Real aDistC[3] = {
216 Abs(theCenter.X()-Standard_Real(myCenter[0])),
217 Abs(theCenter.Y()-Standard_Real(myCenter[1])),
218 Abs(theCenter.Z()-Standard_Real(myCenter[2]))
220 // vector from the center of the sphere to the nearest box face
221 Standard_Real aDist[3] = {
222 aDistC[0] - Standard_Real(myHSize[0]),
223 aDistC[1] - Standard_Real(myHSize[1]),
224 aDistC[2] - Standard_Real(myHSize[2])
226 Standard_Real aD (0.);
228 aD = aDist[0]*aDist[0];
230 aD += aDist[1]*aDist[1];
232 aD += aDist[2]*aDist[2];
233 if (aD < theRadius*theRadius) {
234 // the box intersects the solid sphere; check if it is completely
235 // inside the circle (in such case return isOut==True)
236 aDist[0] = aDistC[0] + Standard_Real(myHSize[0]);
237 aDist[1] = aDistC[1] + Standard_Real(myHSize[1]);
238 aDist[2] = aDistC[2] + Standard_Real(myHSize[2]);
239 if (aDist[0]*aDist[0]+aDist[1]*aDist[1]+aDist[2]*aDist[2]
240 > theRadius*theRadius)
241 aResult = Standard_False;
247 //=======================================================================
249 //purpose : Intersection Box - transformed Box
250 //=======================================================================
252 Standard_Boolean Bnd_B3x::IsOut (const Bnd_B3x& theBox,
253 const gp_Trsf& theTrsf) const
255 Standard_Boolean aResult (Standard_False);
256 const gp_TrsfForm aForm = theTrsf.Form();
257 const Standard_Real aScale = theTrsf.ScaleFactor();
258 const Standard_Real aScaleAbs = Abs(aScale);
259 if (aForm == gp_Translation || aForm == gp_Identity ||
260 aForm == gp_PntMirror || aForm == gp_Scale)
263 (Abs (RealType(theBox.myCenter[0]*aScale + theTrsf.TranslationPart().X())
265 > RealType (theBox.myHSize[0]*aScaleAbs) + myHSize[0] ||
266 Abs (RealType(theBox.myCenter[1]*aScale + theTrsf.TranslationPart().Y())
268 > RealType (theBox.myHSize[1]*aScaleAbs) + myHSize[1] ||
269 Abs (RealType(theBox.myCenter[2]*aScale + theTrsf.TranslationPart().Y())
271 > RealType (theBox.myHSize[2]*aScaleAbs) + myHSize[2]);
275 // theBox is transformed and we check the resulting (enlarged) box against
277 const Standard_Real * aMat = &theTrsf.HVectorialPart().Value(1,1);
279 gp_XYZ aCenter ((Standard_Real)theBox.myCenter[0],
280 (Standard_Real)theBox.myCenter[1],
281 (Standard_Real)theBox.myCenter[2]);
282 theTrsf.Transforms (aCenter);
283 const Standard_Real aDist[3] = {
284 aCenter.X() - (Standard_Real)myCenter[0],
285 aCenter.Y() - (Standard_Real)myCenter[1],
286 aCenter.Z() - (Standard_Real)myCenter[2]
288 const Standard_Real aMatAbs[9] = {
289 Abs(aMat[0]), Abs(aMat[1]), Abs(aMat[2]), Abs(aMat[3]), Abs(aMat[4]),
290 Abs(aMat[5]), Abs(aMat[6]), Abs(aMat[7]), Abs(aMat[8])
292 if (Abs(aDist[0]) > (aScaleAbs*(aMatAbs[0]*theBox.myHSize[0]+
293 aMatAbs[1]*theBox.myHSize[1]+
294 aMatAbs[2]*theBox.myHSize[2]) +
295 (Standard_Real)myHSize[0]) ||
296 Abs(aDist[1]) > (aScaleAbs*(aMatAbs[3]*theBox.myHSize[0]+
297 aMatAbs[4]*theBox.myHSize[1]+
298 aMatAbs[5]*theBox.myHSize[2]) +
299 (Standard_Real)myHSize[1]) ||
300 Abs(aDist[2]) > (aScaleAbs*(aMatAbs[6]*theBox.myHSize[0]+
301 aMatAbs[7]*theBox.myHSize[1]+
302 aMatAbs[8]*theBox.myHSize[2]) +
303 (Standard_Real)myHSize[2]))
304 aResult = Standard_True;
307 // theBox is rotated, scaled and translated. We apply the reverse
308 // translation and scaling then check against the rotated box 'this'
309 if ((Abs(aMat[0]*aDist[0]+aMat[3]*aDist[1]+aMat[6]*aDist[2])
310 > theBox.myHSize[0]*aScaleAbs + (aMatAbs[0]*myHSize[0] +
311 aMatAbs[3]*myHSize[1] +
312 aMatAbs[6]*myHSize[2])) ||
313 (Abs(aMat[1]*aDist[0]+aMat[4]*aDist[1]+aMat[7]*aDist[2])
314 > theBox.myHSize[1]*aScaleAbs + (aMatAbs[1]*myHSize[0] +
315 aMatAbs[4]*myHSize[1] +
316 aMatAbs[7]*myHSize[2])) ||
317 (Abs(aMat[2]*aDist[0]+aMat[5]*aDist[1]+aMat[8]*aDist[2])
318 > theBox.myHSize[2]*aScaleAbs + (aMatAbs[2]*myHSize[0] +
319 aMatAbs[5]*myHSize[1] +
320 aMatAbs[8]*myHSize[2])))
321 aResult = Standard_True;
327 //=======================================================================
330 //=======================================================================
332 Standard_Boolean Bnd_B3x::IsOut (const gp_Ax3& thePlane) const
335 return Standard_True;
336 const gp_XYZ& anOrigin = thePlane.Location().XYZ();
337 const gp_XYZ& aDir = thePlane.Direction().XYZ();
338 const gp_XYZ aBoxCenter ((Standard_Real)myCenter[0],
339 (Standard_Real)myCenter[1],
340 (Standard_Real)myCenter[2]);
341 const Standard_Real aDist0 = (aBoxCenter - anOrigin) * aDir;
342 // Find the signed distances from two opposite corners of the box to the plane
343 // If the distances are not the same sign, then the plane crosses the box
344 const Standard_Real aDist1 = // proj of HSize on aDir
345 Standard_Real(myHSize[0]) * Abs(aDir.X()) +
346 Standard_Real(myHSize[1]) * Abs(aDir.Y()) +
347 Standard_Real(myHSize[2]) * Abs(aDir.Z());
348 return ((aDist0 + aDist1) * (aDist0 - aDist1) > 0.);
351 //=======================================================================
354 //=======================================================================
356 Standard_Boolean Bnd_B3x::IsOut (const gp_Ax1& theLine,
357 const Standard_Boolean isRay,
358 const Standard_Real theOverthickness) const
360 const Standard_Real aRes = gp::Resolution() * 100.;
362 return Standard_True;
364 anInter0[2] = {-RealLast(), RealLast()},
365 anInter1[2] = {-RealLast(), RealLast()};
366 const gp_XYZ& aDir = theLine.Direction().XYZ();
367 const gp_XYZ aDiff ((Standard_Real)myCenter[0] - theLine.Location().X(),
368 (Standard_Real)myCenter[1] - theLine.Location().Y(),
369 (Standard_Real)myCenter[2] - theLine.Location().Z());
371 // Find the parameter interval in X dimention
372 Standard_Real aHSize = (Standard_Real)myHSize[0]+theOverthickness;
373 if (aDir.X() > aRes) {
374 anInter0[0]= (aDiff.X() - aHSize) / aDir.X();
375 anInter0[1]= (aDiff.X() + aHSize) / aDir.X();
376 } else if (aDir.X() < -aRes) {
377 anInter0[0]= (aDiff.X() + aHSize) / aDir.X();
378 anInter0[1]= (aDiff.X() - aHSize) / aDir.X();
380 // the line is orthogonal to OX axis. Test for inclusion in box limits
381 if (Abs(aDiff.X()) > aHSize)
382 return Standard_True;
384 // Find the parameter interval in Y dimention
385 aHSize = (Standard_Real)myHSize[1]+theOverthickness;
386 if (aDir.Y() > aRes) {
387 anInter1[0]= (aDiff.Y() - aHSize) / aDir.Y();
388 anInter1[1]= (aDiff.Y() + aHSize) / aDir.Y();
389 } else if (aDir.Y() < -aRes) {
390 anInter1[0]= (aDiff.Y() + aHSize) / aDir.Y();
391 anInter1[1]= (aDiff.Y() - aHSize) / aDir.Y();
393 // the line is orthogonal to OY axis. Test for inclusion in box limits
394 if (Abs(aDiff.Y()) > aHSize)
395 return Standard_True;
397 // Intersect Y-interval with X-interval
398 if (anInter0[0] > (anInter1[1] + aRes) || anInter0[1] < (anInter1[0] - aRes))
399 return Standard_True;
400 if (anInter1[0] > anInter0[0])
401 anInter0[0] = anInter1[0];
402 if (anInter1[1] < anInter0[1])
403 anInter0[1] = anInter1[1];
404 if (isRay && anInter0[1] < -aRes)
405 return Standard_True;
407 // Find the parameter interval in Z dimention
408 aHSize = (Standard_Real)myHSize[2]+theOverthickness;
409 if (aDir.Z() > aRes) {
410 anInter1[0]= (aDiff.Z() - aHSize) / aDir.Z();
411 anInter1[1]= (aDiff.Z() + aHSize) / aDir.Z();
412 } else if (aDir.Z() < -aRes) {
413 anInter1[0]= (aDiff.Z() + aHSize) / aDir.Z();
414 anInter1[1]= (aDiff.Z() - aHSize) / aDir.Z();
416 // the line is orthogonal to OZ axis. Test for inclusion in box limits
417 return (Abs(aDiff.Z()) > aHSize);
418 if (isRay && anInter1[1] < -aRes)
419 return Standard_True;
421 return (anInter0[0] > (anInter1[1]+aRes) || anInter0[1] < (anInter1[0]-aRes));
424 //=======================================================================
426 //purpose : Test the complete inclusion of this box in transformed theOtherBox
427 //=======================================================================
429 Standard_Boolean Bnd_B3x::IsIn (const Bnd_B3x& theBox,
430 const gp_Trsf& theTrsf) const
432 Standard_Boolean aResult (Standard_False);
433 const gp_TrsfForm aForm = theTrsf.Form();
434 const Standard_Real aScale = theTrsf.ScaleFactor();
435 const Standard_Real aScaleAbs = Abs(aScale);
436 if (aForm == gp_Translation || aForm == gp_Identity ||
437 aForm == gp_PntMirror || aForm == gp_Scale)
440 (Abs (RealType(theBox.myCenter[0]*aScale + theTrsf.TranslationPart().X())
442 < RealType (theBox.myHSize[0]*aScaleAbs) - myHSize[0] &&
443 Abs (RealType(theBox.myCenter[1]*aScale + theTrsf.TranslationPart().Y())
445 < RealType (theBox.myHSize[1]*aScaleAbs) - myHSize[1] &&
446 Abs (RealType(theBox.myCenter[2]*aScale + theTrsf.TranslationPart().Y())
448 < RealType (theBox.myHSize[2]*aScaleAbs) - myHSize[2]);
451 // theBox is rotated, scaled and translated. We apply the reverse
452 // translation and scaling then check against the rotated box 'this'
453 const Standard_Real * aMat = &theTrsf.HVectorialPart().Value(1,1);
454 gp_XYZ aCenter ((Standard_Real)theBox.myCenter[0],
455 (Standard_Real)theBox.myCenter[1],
456 (Standard_Real)theBox.myCenter[2]);
457 theTrsf.Transforms (aCenter);
458 const Standard_Real aDist[3] = {
459 aCenter.X() - (Standard_Real)myCenter[0],
460 aCenter.Y() - (Standard_Real)myCenter[1],
461 aCenter.Z() - (Standard_Real)myCenter[2]
463 if ((Abs(aMat[0]*aDist[0]+aMat[3]*aDist[1]+aMat[6]*aDist[2])
464 < theBox.myHSize[0]*aScaleAbs - (Abs(aMat[0])*myHSize[0] +
465 Abs(aMat[3])*myHSize[1] +
466 Abs(aMat[6])*myHSize[2])) &&
467 (Abs(aMat[1]*aDist[0]+aMat[4]*aDist[1]+aMat[7]*aDist[2])
468 < theBox.myHSize[1]*aScaleAbs - (Abs(aMat[1])*myHSize[0] +
469 Abs(aMat[4])*myHSize[1] +
470 Abs(aMat[7])*myHSize[2])) &&
471 (Abs(aMat[2]*aDist[0]+aMat[5]*aDist[1]+aMat[8]*aDist[2])
472 < theBox.myHSize[2]*aScaleAbs - (Abs(aMat[2])*myHSize[0] +
473 Abs(aMat[5])*myHSize[1] +
474 Abs(aMat[8])*myHSize[2])))
475 aResult = Standard_True;