Warning, /include/opencascade/Bnd_B2x.gxx is written in an unsupported language. File is not indexed.
0001 // Created on: 2005-09-08
0002 // Created by: Alexander GRIGORIEV
0003 // Copyright (c) 2005-2014 OPEN CASCADE SAS
0004 //
0005 // This file is part of Open CASCADE Technology software library.
0006 //
0007 // This library is free software; you can redistribute it and/or modify it under
0008 // the terms of the GNU Lesser General Public License version 2.1 as published
0009 // by the Free Software Foundation, with special exception defined in the file
0010 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0011 // distribution for complete text of the license and disclaimer of any warranty.
0012 //
0013 // Alternatively, this file may be used under the terms of Open CASCADE
0014 // commercial license or contractual agreement.
0015
0016 inline Standard_Boolean _compareDist (const RealType aHSize[2],
0017 const RealType aDist[2])
0018 {
0019 return (Abs(aDist[0]) > aHSize[0] || Abs(aDist[1]) > aHSize[1]);
0020 }
0021
0022 inline Standard_Boolean _compareDistD (const gp_XY& aHSize, const gp_XY& aDist)
0023 {
0024 return (Abs(aDist.X()) > aHSize.X() || Abs(aDist.Y()) > aHSize.Y());
0025 }
0026
0027 //=======================================================================
0028 //function : Add
0029 //purpose : Update the box by a point
0030 //=======================================================================
0031
0032 void Bnd_B2x::Add (const gp_XY& thePnt) {
0033 if (IsVoid()) {
0034 myCenter[0] = RealType(thePnt.X());
0035 myCenter[1] = RealType(thePnt.Y());
0036 myHSize [0] = 0.;
0037 myHSize [1] = 0.;
0038 } else {
0039 const RealType aDiff[2] = {
0040 RealType(thePnt.X()) - myCenter[0],
0041 RealType(thePnt.Y()) - myCenter[1]
0042 };
0043 if (aDiff[0] > myHSize[0]) {
0044 const RealType aShift = (aDiff[0] - myHSize[0]) / 2;
0045 myCenter[0] += aShift;
0046 myHSize [0] += aShift;
0047 } else if (aDiff[0] < -myHSize[0]) {
0048 const RealType aShift = (aDiff[0] + myHSize[0]) / 2;
0049 myCenter[0] += aShift;
0050 myHSize [0] -= aShift;
0051 }
0052 if (aDiff[1] > myHSize[1]) {
0053 const RealType aShift = (aDiff[1] - myHSize[1]) / 2;
0054 myCenter[1] += aShift;
0055 myHSize [1] += aShift;
0056 } else if (aDiff[1] < -myHSize[1]) {
0057 const RealType aShift = (aDiff[1] + myHSize[1]) / 2;
0058 myCenter[1] += aShift;
0059 myHSize [1] -= aShift;
0060 }
0061 }
0062 }
0063
0064 //=======================================================================
0065 //function : Limit
0066 //purpose : limit the current box with the internals of theBox
0067 //=======================================================================
0068
0069 Standard_Boolean Bnd_B2x::Limit (const Bnd_B2x& theBox)
0070 {
0071 Standard_Boolean aResult (Standard_False);
0072 const RealType diffC[2] = {
0073 theBox.myCenter[0] - myCenter[0],
0074 theBox.myCenter[1] - myCenter[1]
0075 };
0076 const RealType sumH[2] = {
0077 theBox.myHSize[0] + myHSize[0],
0078 theBox.myHSize[1] + myHSize[1]
0079 };
0080 // check the condition IsOut
0081 if (_compareDist (sumH, diffC) == Standard_False) {
0082 const RealType diffH[2] = {
0083 theBox.myHSize[0] - myHSize[0],
0084 theBox.myHSize[1] - myHSize[1]
0085 };
0086 if (diffC[0] - diffH[0] > 0.) {
0087 const RealType aShift = (diffC[0] - diffH[0]) / 2; // positive
0088 myCenter[0] += aShift;
0089 myHSize [0] -= aShift;
0090 } else if (diffC[0] + diffH[0] < 0.) {
0091 const RealType aShift = (diffC[0] + diffH[0]) / 2; // negative
0092 myCenter[0] += aShift;
0093 myHSize [0] += aShift;
0094 }
0095 if (diffC[1] - diffH[1] > 0.) {
0096 const RealType aShift = (diffC[1] - diffH[1]) / 2; // positive
0097 myCenter[1] += aShift;
0098 myHSize [1] -= aShift;
0099 } else if (diffC[1] + diffH[1] < 0.) {
0100 const RealType aShift = (diffC[1] + diffH[1]) / 2; // negative
0101 myCenter[1] += aShift;
0102 myHSize [1] += aShift;
0103 }
0104 aResult = Standard_True;
0105 }
0106 return aResult;
0107 }
0108
0109 //=======================================================================
0110 //function : Transformed
0111 //purpose :
0112 //=======================================================================
0113
0114 Bnd_B2x Bnd_B2x::Transformed (const gp_Trsf2d& theTrsf) const
0115 {
0116 Bnd_B2x aResult;
0117 const gp_TrsfForm aForm = theTrsf.Form();
0118 const Standard_Real aScale = theTrsf.ScaleFactor();
0119 const Standard_Real aScaleAbs = Abs(aScale);
0120 if (aForm == gp_Identity)
0121 aResult = * this;
0122 else if (aForm== gp_Translation || aForm== gp_PntMirror || aForm== gp_Scale)
0123 {
0124 aResult.myCenter[0] =
0125 (RealType)(myCenter[0] * aScale + theTrsf.TranslationPart().X());
0126 aResult.myCenter[1] =
0127 (RealType)(myCenter[1] * aScale + theTrsf.TranslationPart().Y());
0128 aResult.myHSize[0] = (RealType)(myHSize[0] * aScaleAbs);
0129 aResult.myHSize[1] = (RealType)(myHSize[1] * aScaleAbs);
0130 } else {
0131 gp_XY aCenter ((Standard_Real)myCenter[0],
0132 (Standard_Real)myCenter[1]);
0133 theTrsf.Transforms (aCenter);
0134 aResult.myCenter[0] = (RealType)aCenter.X();
0135 aResult.myCenter[1] = (RealType)aCenter.Y();
0136
0137 const Standard_Real * aMat = &theTrsf.HVectorialPart().Value(1,1);
0138 aResult.myHSize[0] = (RealType)(aScaleAbs * (Abs(aMat[0]) * myHSize[0]+
0139 Abs(aMat[1]) * myHSize[1]));
0140 aResult.myHSize[1] = (RealType)(aScaleAbs * (Abs(aMat[2]) * myHSize[0]+
0141 Abs(aMat[3]) * myHSize[1]));
0142 }
0143 return aResult;
0144 }
0145
0146 //=======================================================================
0147 //function : IsOut
0148 //purpose : Intersection Box - Circle
0149 //=======================================================================
0150
0151 Standard_Boolean Bnd_B2x::IsOut (const gp_XY& theCenter,
0152 const Standard_Real theRadius,
0153 const Standard_Boolean isCircleHollow) const
0154 {
0155 Standard_Boolean aResult (Standard_True);
0156 if (isCircleHollow == Standard_False) {
0157 // vector from the center of the circle to the nearest box face
0158 const Standard_Real aDist[2] = {
0159 Abs(theCenter.X()-Standard_Real(myCenter[0])) - Standard_Real(myHSize[0]),
0160 Abs(theCenter.Y()-Standard_Real(myCenter[1])) - Standard_Real(myHSize[1])
0161 };
0162 Standard_Real aD (0.);
0163 if (aDist[0] > 0.)
0164 aD = aDist[0]*aDist[0];
0165 if (aDist[1] > 0.)
0166 aD += aDist[1]*aDist[1];
0167 aResult = (aD > theRadius*theRadius);
0168 } else {
0169 const Standard_Real aDistC[2] = {
0170 Abs(theCenter.X()-Standard_Real(myCenter[0])),
0171 Abs(theCenter.Y()-Standard_Real(myCenter[1]))
0172 };
0173 // vector from the center of the circle to the nearest box face
0174 Standard_Real aDist[2] = {
0175 aDistC[0] - Standard_Real(myHSize[0]),
0176 aDistC[1] - Standard_Real(myHSize[1])
0177 };
0178 Standard_Real aD (0.);
0179 if (aDist[0] > 0.)
0180 aD = aDist[0]*aDist[0];
0181 if (aDist[1] > 0.)
0182 aD += aDist[1]*aDist[1];
0183 if (aD < theRadius*theRadius) {
0184 // the box intersects the solid circle; check if it is completely
0185 // inside the circle (in such case return isOut==True)
0186 aDist[0] = aDistC[0] + Standard_Real(myHSize[0]);
0187 aDist[1] = aDistC[1] + Standard_Real(myHSize[1]);
0188 if (aDist[0]*aDist[0]+aDist[1]*aDist[1] > theRadius*theRadius)
0189 aResult = Standard_False;
0190 }
0191 }
0192 return aResult;
0193 }
0194
0195 //=======================================================================
0196 //function : IsOut
0197 //purpose : Intersection Box - transformed Box
0198 //=======================================================================
0199
0200 Standard_Boolean Bnd_B2x::IsOut (const Bnd_B2x& theBox,
0201 const gp_Trsf2d& theTrsf) const
0202 {
0203 Standard_Boolean aResult (Standard_False);
0204 const gp_TrsfForm aForm = theTrsf.Form();
0205 const Standard_Real aScale = theTrsf.ScaleFactor();
0206 const Standard_Real aScaleAbs = Abs(aScale);
0207 if (aForm == gp_Translation || aForm == gp_Identity ||
0208 aForm == gp_PntMirror || aForm == gp_Scale)
0209 {
0210 aResult =
0211 (Abs (RealType(theBox.myCenter[0]*aScale + theTrsf.TranslationPart().X())
0212 - myCenter[0])
0213 > RealType (theBox.myHSize[0]*aScaleAbs) + myHSize[0] ||
0214 Abs (RealType(theBox.myCenter[1]*aScale + theTrsf.TranslationPart().Y())
0215 - myCenter[1])
0216 > RealType (theBox.myHSize[1]*aScaleAbs) + myHSize[1]);
0217
0218 }
0219 else {
0220 // theBox is transformed and we check the resulting (enlarged) box against
0221 // 'this' box.
0222 const Standard_Real * aMat = &theTrsf.HVectorialPart().Value(1,1);
0223
0224 gp_XY aCenter ((Standard_Real)theBox.myCenter[0],
0225 (Standard_Real)theBox.myCenter[1]);
0226 theTrsf.Transforms (aCenter);
0227 const Standard_Real aDist[2] = {
0228 aCenter.X() - (Standard_Real)myCenter[0],
0229 aCenter.Y() - (Standard_Real)myCenter[1]
0230 };
0231 const Standard_Real aMatAbs[4] = {
0232 Abs(aMat[0]), Abs(aMat[1]), Abs(aMat[2]), Abs(aMat[3])
0233 };
0234 if (Abs(aDist[0]) > (aScaleAbs * (aMatAbs[0]*theBox.myHSize[0]+
0235 aMatAbs[1]*theBox.myHSize[1]) +
0236 (Standard_Real)myHSize[0]) ||
0237 Abs(aDist[1]) > (aScaleAbs * (aMatAbs[2]*theBox.myHSize[0]+
0238 aMatAbs[3]*theBox.myHSize[1]) +
0239 (Standard_Real)myHSize[1]))
0240 aResult = Standard_True;
0241
0242 else {
0243 // theBox is rotated, scaled and translated. We apply the reverse
0244 // translation and scaling then check against the rotated box 'this'
0245 if ((Abs(aMat[0]*aDist[0]+aMat[2]*aDist[1])
0246 > theBox.myHSize[0]*aScaleAbs + (aMatAbs[0]*myHSize[0] +
0247 aMatAbs[2]*myHSize[1])) ||
0248 (Abs(aMat[1]*aDist[0]+aMat[3]*aDist[1])
0249 > theBox.myHSize[1]*aScaleAbs + (aMatAbs[1]*myHSize[0] +
0250 aMatAbs[3]*myHSize[1])))
0251 aResult = Standard_True;
0252 }
0253 }
0254 return aResult;
0255 }
0256
0257 //=======================================================================
0258 //function : IsOut
0259 //purpose : Intersection Box - Line
0260 //=======================================================================
0261
0262 Standard_Boolean Bnd_B2x::IsOut (const gp_Ax2d& theLine) const
0263 {
0264 if (IsVoid())
0265 return Standard_True;
0266 // Intersect the line containing the segment.
0267 const Standard_Real aProd[3] = {
0268 theLine.Direction().XY() ^ (gp_XY (myCenter[0] - theLine.Location().X(),
0269 myCenter[1] - theLine.Location().Y())),
0270 theLine.Direction().X() * Standard_Real(myHSize[1]),
0271 theLine.Direction().Y() * Standard_Real(myHSize[0])
0272 };
0273 return (Abs(aProd[0]) > (Abs(aProd[1]) + Abs(aProd[2])));
0274 }
0275
0276 //=======================================================================
0277 //function : IsOut
0278 //purpose : Intersection Box - Segment
0279 //=======================================================================
0280
0281 Standard_Boolean Bnd_B2x::IsOut (const gp_XY& theP0, const gp_XY& theP1) const
0282 {
0283 Standard_Boolean aResult (Standard_True);
0284 if (IsVoid() == Standard_False)
0285 {
0286 // Intersect the line containing the segment.
0287 const gp_XY aSegDelta (theP1 - theP0);
0288 const Standard_Real aProd[3] = {
0289 aSegDelta ^ (gp_XY (myCenter[0], myCenter[1]) - theP0),
0290 aSegDelta.X() * Standard_Real(myHSize[1]),
0291 aSegDelta.Y() * Standard_Real(myHSize[0])
0292 };
0293 if (Abs(aProd[0]) < (Abs(aProd[1]) + Abs(aProd[2])))
0294 {
0295 // Intersection with line detected; check the segment as bounding box
0296 const gp_XY aHSeg (0.5 * aSegDelta.X(), 0.5 * aSegDelta.Y());
0297 const gp_XY aHSegAbs (Abs(aHSeg.X()), Abs(aHSeg.Y()));
0298 aResult = _compareDistD (gp_XY((Standard_Real)myHSize[0],
0299 (Standard_Real)myHSize[1]) + aHSegAbs,
0300 theP0 + aHSeg-gp_XY((Standard_Real)myCenter[0],
0301 (Standard_Real)myCenter[1]));
0302 }
0303 }
0304 return aResult;
0305 }
0306
0307 //=======================================================================
0308 //function : IsIn
0309 //purpose : Test the complete inclusion of this box in transformed theOtherBox
0310 //=======================================================================
0311
0312 Standard_Boolean Bnd_B2x::IsIn (const Bnd_B2x& theBox,
0313 const gp_Trsf2d& theTrsf) const
0314 {
0315 Standard_Boolean aResult (Standard_False);
0316 const gp_TrsfForm aForm = theTrsf.Form();
0317 const Standard_Real aScale = theTrsf.ScaleFactor();
0318 const Standard_Real aScaleAbs = Abs(aScale);
0319 if (aForm == gp_Translation || aForm == gp_Identity ||
0320 aForm == gp_PntMirror || aForm == gp_Scale)
0321 {
0322 aResult =
0323 (Abs (RealType(theBox.myCenter[0]*aScale + theTrsf.TranslationPart().X())
0324 - myCenter[0])
0325 < RealType (theBox.myHSize[0]*aScaleAbs) - myHSize[0] &&
0326 Abs (RealType(theBox.myCenter[1]*aScale + theTrsf.TranslationPart().Y())
0327 - myCenter[1])
0328 < RealType (theBox.myHSize[1]*aScaleAbs) - myHSize[1]);
0329
0330 } else {
0331 // theBox is rotated, scaled and translated. We apply the reverse
0332 // translation and scaling then check against the rotated box 'this'
0333 const Standard_Real * aMat = &theTrsf.HVectorialPart().Value(1,1);
0334 gp_XY aCenter ((Standard_Real)theBox.myCenter[0],
0335 (Standard_Real)theBox.myCenter[1]);
0336 theTrsf.Transforms (aCenter);
0337 const Standard_Real aDist[2] = {
0338 aCenter.X() - (Standard_Real)myCenter[0],
0339 aCenter.Y() - (Standard_Real)myCenter[1]
0340 };
0341 if ((Abs(aMat[0]*aDist[0]+aMat[2]*aDist[1])
0342 < theBox.myHSize[0]*aScaleAbs - (Abs(aMat[0])*myHSize[0] +
0343 Abs(aMat[2])*myHSize[1])) &&
0344 (Abs(aMat[1]*aDist[0]+aMat[3]*aDist[1])
0345 < theBox.myHSize[1]*aScaleAbs - (Abs(aMat[1])*myHSize[0] +
0346 Abs(aMat[3])*myHSize[1])))
0347 aResult = Standard_True;
0348 }
0349 return aResult;
0350 }