Back to home page

EIC code displayed by LXR

 
 

    


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 }