Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-28 09:19:23

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 #ifndef _Bnd_B2_HeaderFile
0017 #define _Bnd_B2_HeaderFile
0018 
0019 #include <Standard.hxx>
0020 #include <Standard_DefineAlloc.hxx>
0021 #include <Standard_Real.hxx>
0022 #include <Standard_ShortReal.hxx>
0023 #include <gp_XY.hxx>
0024 #include <gp_Pnt2d.hxx>
0025 #include <gp_Trsf2d.hxx>
0026 #include <gp_Ax2d.hxx>
0027 
0028 #include <array>
0029 
0030 //! Template class for 2D bounding box.
0031 //! This is a base template that is instantiated for double and float.
0032 template <typename RealType>
0033 class Bnd_B2
0034 {
0035 public:
0036   DEFINE_STANDARD_ALLOC
0037 
0038   //! Empty constructor.
0039   constexpr Bnd_B2() noexcept;
0040 
0041   //! Constructor.
0042   constexpr Bnd_B2(const gp_XY& theCenter, const gp_XY& theHSize) noexcept;
0043 
0044   //! Constructor.
0045   constexpr Bnd_B2(const std::array<RealType, 2>& theCenter,
0046                    const std::array<RealType, 2>& theHSize) noexcept;
0047 
0048   //! Returns True if the box is void (non-initialized).
0049   constexpr bool IsVoid() const noexcept;
0050 
0051   //! Reset the box data.
0052   void Clear() noexcept;
0053 
0054   //! Update the box by a point.
0055   void Add(const gp_XY& thePnt);
0056 
0057   //! Update the box by a point.
0058   void Add(const gp_Pnt2d& thePnt);
0059 
0060   //! Update the box by another box.
0061   void Add(const Bnd_B2<RealType>& theBox);
0062 
0063   //! Query a box corner: (Center - HSize). You must make sure that
0064   //! the box is NOT VOID (see IsVoid()), otherwise the method returns
0065   //! irrelevant result.
0066   gp_XY CornerMin() const noexcept;
0067 
0068   //! Query a box corner: (Center + HSize). You must make sure that
0069   //! the box is NOT VOID (see IsVoid()), otherwise the method returns
0070   //! irrelevant result.
0071   gp_XY CornerMax() const noexcept;
0072 
0073   //! Query the square diagonal. If the box is VOID (see method IsVoid())
0074   //! then a very big real value is returned.
0075   constexpr double SquareExtent() const noexcept;
0076 
0077   //! Extend the Box by the absolute value of theDiff.
0078   void Enlarge(const double theDiff) noexcept;
0079 
0080   //! Limit the Box by the internals of theOtherBox.
0081   //! Returns True if the limitation takes place, otherwise False
0082   //! indicating that the boxes do not intersect.
0083   bool Limit(const Bnd_B2<RealType>& theOtherBox);
0084 
0085   //! Transform the bounding box with the given transformation.
0086   //! The resulting box will be larger if theTrsf contains rotation.
0087   [[nodiscard]] Bnd_B2<RealType> Transformed(const gp_Trsf2d& theTrsf) const;
0088 
0089   //! Check the given point for the inclusion in the Box.
0090   //! Returns True if the point is outside.
0091   constexpr bool IsOut(const gp_XY& thePnt) const noexcept;
0092 
0093   //! Check a circle for the intersection with the current box.
0094   //! Returns True if there is no intersection between boxes.
0095   bool IsOut(const gp_XY& theCenter,
0096              const double theRadius,
0097              const bool   isCircleHollow = false) const;
0098 
0099   //! Check the given box for the intersection with the current box.
0100   //! Returns True if there is no intersection between boxes.
0101   constexpr bool IsOut(const Bnd_B2<RealType>& theOtherBox) const noexcept;
0102 
0103   //! Check the given box oriented by the given transformation
0104   //! for the intersection with the current box.
0105   //! Returns True if there is no intersection between boxes.
0106   bool IsOut(const Bnd_B2<RealType>& theOtherBox, const gp_Trsf2d& theTrsf) const;
0107 
0108   //! Check the given Line for the intersection with the current box.
0109   //! Returns True if there is no intersection.
0110   bool IsOut(const gp_Ax2d& theLine) const;
0111 
0112   //! Check the Segment defined by the couple of input points
0113   //! for the intersection with the current box.
0114   //! Returns True if there is no intersection.
0115   bool IsOut(const gp_XY& theP0, const gp_XY& theP1) const;
0116 
0117   //! Check that the box 'this' is inside the given box 'theBox'. Returns
0118   //! True if 'this' box is fully inside 'theBox'.
0119   constexpr bool IsIn(const Bnd_B2<RealType>& theBox) const noexcept;
0120 
0121   //! Check that the box 'this' is inside the given box 'theBox'
0122   //! transformed by 'theTrsf'. Returns True if 'this' box is fully
0123   //! inside the transformed 'theBox'.
0124   bool IsIn(const Bnd_B2<RealType>& theBox, const gp_Trsf2d& theTrsf) const;
0125 
0126   //! Set the Center coordinates
0127   void SetCenter(const gp_XY& theCenter) noexcept;
0128 
0129   //! Set the Center coordinates
0130   void SetCenter(const std::array<RealType, 2>& theCenter) noexcept;
0131 
0132   //! Set the HSize (half-diagonal) coordinates.
0133   //! All components of theHSize must be non-negative.
0134   void SetHSize(const gp_XY& theHSize) noexcept;
0135 
0136   //! Set the HSize (half-diagonal) coordinates.
0137   //! All components of theHSize must be non-negative.
0138   void SetHSize(const std::array<RealType, 2>& theHSize) noexcept;
0139 
0140   //! Get the Center coordinates
0141   constexpr const std::array<RealType, 2>& Center() const noexcept;
0142 
0143   //! Get the HSize (half-diagonal) coordinates
0144   constexpr const std::array<RealType, 2>& HSize() const noexcept;
0145 
0146 protected:
0147   static constexpr bool compareDist(const RealType aHSize[2], const RealType aDist[2]) noexcept
0148   {
0149     return (std::abs(aDist[0]) > aHSize[0] || std::abs(aDist[1]) > aHSize[1]);
0150   }
0151 
0152   static bool compareDistD(const gp_XY& aHSize, const gp_XY& aDist) noexcept
0153   {
0154     return (std::abs(aDist.X()) > aHSize.X() || std::abs(aDist.Y()) > aHSize.Y());
0155   }
0156 
0157   //! Constant representing a very large value for void box initialization
0158   static constexpr RealType THE_RealLast = RealType(1e30);
0159 
0160 private:
0161   std::array<RealType, 2> myCenter;
0162   std::array<RealType, 2> myHSize;
0163 };
0164 
0165 //=================================================================================================
0166 
0167 template <typename RealType>
0168 constexpr inline Bnd_B2<RealType>::Bnd_B2() noexcept
0169     : myCenter{THE_RealLast, THE_RealLast},
0170       myHSize{-THE_RealLast, -THE_RealLast}
0171 {
0172 }
0173 
0174 //=================================================================================================
0175 
0176 template <typename RealType>
0177 constexpr inline Bnd_B2<RealType>::Bnd_B2(const gp_XY& theCenter, const gp_XY& theHSize) noexcept
0178     : myCenter{RealType(theCenter.X()), RealType(theCenter.Y())},
0179       myHSize{RealType(theHSize.X()), RealType(theHSize.Y())}
0180 {
0181 }
0182 
0183 //=================================================================================================
0184 
0185 template <typename RealType>
0186 constexpr inline Bnd_B2<RealType>::Bnd_B2(const std::array<RealType, 2>& theCenter,
0187                                           const std::array<RealType, 2>& theHSize) noexcept
0188     : myCenter(theCenter),
0189       myHSize(theHSize)
0190 {
0191 }
0192 
0193 //=================================================================================================
0194 
0195 template <typename RealType>
0196 inline void Bnd_B2<RealType>::Clear() noexcept
0197 {
0198   myCenter[0] = THE_RealLast;
0199   myCenter[1] = THE_RealLast;
0200   myHSize[0]  = -THE_RealLast;
0201   myHSize[1]  = -THE_RealLast;
0202 }
0203 
0204 //=================================================================================================
0205 
0206 template <typename RealType>
0207 constexpr inline bool Bnd_B2<RealType>::IsVoid() const noexcept
0208 {
0209   return (myHSize[0] < -1e-5);
0210 }
0211 
0212 //=================================================================================================
0213 
0214 template <typename RealType>
0215 inline void Bnd_B2<RealType>::Add(const gp_Pnt2d& thePnt)
0216 {
0217   Add(thePnt.XY());
0218 }
0219 
0220 //=================================================================================================
0221 
0222 template <typename RealType>
0223 inline void Bnd_B2<RealType>::Add(const Bnd_B2<RealType>& theBox)
0224 {
0225   if (!theBox.IsVoid())
0226   {
0227     Add(theBox.CornerMin());
0228     Add(theBox.CornerMax());
0229   }
0230 }
0231 
0232 //=================================================================================================
0233 
0234 template <typename RealType>
0235 inline gp_XY Bnd_B2<RealType>::CornerMin() const noexcept
0236 {
0237   return gp_XY(myCenter[0] - myHSize[0], myCenter[1] - myHSize[1]);
0238 }
0239 
0240 //=================================================================================================
0241 
0242 template <typename RealType>
0243 inline gp_XY Bnd_B2<RealType>::CornerMax() const noexcept
0244 {
0245   return gp_XY(myCenter[0] + myHSize[0], myCenter[1] + myHSize[1]);
0246 }
0247 
0248 //=================================================================================================
0249 
0250 template <typename RealType>
0251 constexpr inline double Bnd_B2<RealType>::SquareExtent() const noexcept
0252 {
0253   return 4 * (myHSize[0] * myHSize[0] + myHSize[1] * myHSize[1]);
0254 }
0255 
0256 //=================================================================================================
0257 
0258 template <typename RealType>
0259 inline void Bnd_B2<RealType>::SetCenter(const gp_XY& theCenter) noexcept
0260 {
0261   myCenter[0] = RealType(theCenter.X());
0262   myCenter[1] = RealType(theCenter.Y());
0263 }
0264 
0265 //=================================================================================================
0266 
0267 template <typename RealType>
0268 inline void Bnd_B2<RealType>::SetHSize(const gp_XY& theHSize) noexcept
0269 {
0270   myHSize[0] = RealType(theHSize.X());
0271   myHSize[1] = RealType(theHSize.Y());
0272 }
0273 
0274 //=================================================================================================
0275 
0276 template <typename RealType>
0277 inline void Bnd_B2<RealType>::SetCenter(const std::array<RealType, 2>& theCenter) noexcept
0278 {
0279   myCenter = theCenter;
0280 }
0281 
0282 //=================================================================================================
0283 
0284 template <typename RealType>
0285 inline void Bnd_B2<RealType>::SetHSize(const std::array<RealType, 2>& theHSize) noexcept
0286 {
0287   myHSize = theHSize;
0288 }
0289 
0290 //=================================================================================================
0291 
0292 template <typename RealType>
0293 constexpr inline const std::array<RealType, 2>& Bnd_B2<RealType>::Center() const noexcept
0294 {
0295   return myCenter;
0296 }
0297 
0298 //=================================================================================================
0299 
0300 template <typename RealType>
0301 constexpr inline const std::array<RealType, 2>& Bnd_B2<RealType>::HSize() const noexcept
0302 {
0303   return myHSize;
0304 }
0305 
0306 //=================================================================================================
0307 
0308 template <typename RealType>
0309 inline void Bnd_B2<RealType>::Enlarge(const double aDiff) noexcept
0310 {
0311   const RealType aD = RealType(std::abs(aDiff));
0312   myHSize[0] += aD;
0313   myHSize[1] += aD;
0314 }
0315 
0316 //=================================================================================================
0317 
0318 template <typename RealType>
0319 constexpr inline bool Bnd_B2<RealType>::IsOut(const gp_XY& thePnt) const noexcept
0320 {
0321   return (std::abs(RealType(thePnt.X()) - myCenter[0]) > myHSize[0]
0322           || std::abs(RealType(thePnt.Y()) - myCenter[1]) > myHSize[1]);
0323 }
0324 
0325 //=================================================================================================
0326 
0327 template <typename RealType>
0328 constexpr inline bool Bnd_B2<RealType>::IsOut(const Bnd_B2<RealType>& theBox) const noexcept
0329 {
0330   return (std::abs(theBox.myCenter[0] - myCenter[0]) > theBox.myHSize[0] + myHSize[0]
0331           || std::abs(theBox.myCenter[1] - myCenter[1]) > theBox.myHSize[1] + myHSize[1]);
0332 }
0333 
0334 //=================================================================================================
0335 
0336 template <typename RealType>
0337 constexpr inline bool Bnd_B2<RealType>::IsIn(const Bnd_B2<RealType>& theBox) const noexcept
0338 {
0339   return (std::abs(theBox.myCenter[0] - myCenter[0]) < theBox.myHSize[0] - myHSize[0]
0340           && std::abs(theBox.myCenter[1] - myCenter[1]) < theBox.myHSize[1] - myHSize[1]);
0341 }
0342 
0343 //=================================================================================================
0344 
0345 template <typename RealType>
0346 void Bnd_B2<RealType>::Add(const gp_XY& thePnt)
0347 {
0348   if (IsVoid())
0349   {
0350     myCenter[0] = RealType(thePnt.X());
0351     myCenter[1] = RealType(thePnt.Y());
0352     myHSize[0]  = 0.;
0353     myHSize[1]  = 0.;
0354   }
0355   else
0356   {
0357     const RealType aDiff[2] = {RealType(thePnt.X()) - myCenter[0],
0358                                RealType(thePnt.Y()) - myCenter[1]};
0359     if (aDiff[0] > myHSize[0])
0360     {
0361       const RealType aShift = (aDiff[0] - myHSize[0]) / 2;
0362       myCenter[0] += aShift;
0363       myHSize[0] += aShift;
0364     }
0365     else if (aDiff[0] < -myHSize[0])
0366     {
0367       const RealType aShift = (aDiff[0] + myHSize[0]) / 2;
0368       myCenter[0] += aShift;
0369       myHSize[0] -= aShift;
0370     }
0371     if (aDiff[1] > myHSize[1])
0372     {
0373       const RealType aShift = (aDiff[1] - myHSize[1]) / 2;
0374       myCenter[1] += aShift;
0375       myHSize[1] += aShift;
0376     }
0377     else if (aDiff[1] < -myHSize[1])
0378     {
0379       const RealType aShift = (aDiff[1] + myHSize[1]) / 2;
0380       myCenter[1] += aShift;
0381       myHSize[1] -= aShift;
0382     }
0383   }
0384 }
0385 
0386 //=================================================================================================
0387 
0388 template <typename RealType>
0389 bool Bnd_B2<RealType>::Limit(const Bnd_B2<RealType>& theBox)
0390 {
0391   bool           aResult(false);
0392   const RealType diffC[2] = {theBox.myCenter[0] - myCenter[0], theBox.myCenter[1] - myCenter[1]};
0393   const RealType sumH[2]  = {theBox.myHSize[0] + myHSize[0], theBox.myHSize[1] + myHSize[1]};
0394   // check the condition IsOut
0395   if (!compareDist(sumH, diffC))
0396   {
0397     const RealType diffH[2] = {theBox.myHSize[0] - myHSize[0], theBox.myHSize[1] - myHSize[1]};
0398     if (diffC[0] - diffH[0] > 0.)
0399     {
0400       const RealType aShift = (diffC[0] - diffH[0]) / 2; // positive
0401       myCenter[0] += aShift;
0402       myHSize[0] -= aShift;
0403     }
0404     else if (diffC[0] + diffH[0] < 0.)
0405     {
0406       const RealType aShift = (diffC[0] + diffH[0]) / 2; // negative
0407       myCenter[0] += aShift;
0408       myHSize[0] += aShift;
0409     }
0410     if (diffC[1] - diffH[1] > 0.)
0411     {
0412       const RealType aShift = (diffC[1] - diffH[1]) / 2; // positive
0413       myCenter[1] += aShift;
0414       myHSize[1] -= aShift;
0415     }
0416     else if (diffC[1] + diffH[1] < 0.)
0417     {
0418       const RealType aShift = (diffC[1] + diffH[1]) / 2; // negative
0419       myCenter[1] += aShift;
0420       myHSize[1] += aShift;
0421     }
0422     aResult = true;
0423   }
0424   return aResult;
0425 }
0426 
0427 //=================================================================================================
0428 
0429 template <typename RealType>
0430 Bnd_B2<RealType> Bnd_B2<RealType>::Transformed(const gp_Trsf2d& theTrsf) const
0431 {
0432   Bnd_B2<RealType>  aResult;
0433   const gp_TrsfForm aForm     = theTrsf.Form();
0434   const double      aScale    = theTrsf.ScaleFactor();
0435   const double      aScaleAbs = std::abs(aScale);
0436   if (aForm == gp_Identity)
0437     aResult = *this;
0438   else if (aForm == gp_Translation || aForm == gp_PntMirror || aForm == gp_Scale)
0439   {
0440     aResult.myCenter[0] = (RealType)(myCenter[0] * aScale + theTrsf.TranslationPart().X());
0441     aResult.myCenter[1] = (RealType)(myCenter[1] * aScale + theTrsf.TranslationPart().Y());
0442     aResult.myHSize[0]  = (RealType)(myHSize[0] * aScaleAbs);
0443     aResult.myHSize[1]  = (RealType)(myHSize[1] * aScaleAbs);
0444   }
0445   else
0446   {
0447     gp_XY aCenter((double)myCenter[0], (double)myCenter[1]);
0448     theTrsf.Transforms(aCenter);
0449     aResult.myCenter[0] = (RealType)aCenter.X();
0450     aResult.myCenter[1] = (RealType)aCenter.Y();
0451 
0452     const double* aMat = &theTrsf.HVectorialPart().Value(1, 1);
0453     aResult.myHSize[0] =
0454       (RealType)(aScaleAbs * (std::abs(aMat[0]) * myHSize[0] + std::abs(aMat[1]) * myHSize[1]));
0455     aResult.myHSize[1] =
0456       (RealType)(aScaleAbs * (std::abs(aMat[2]) * myHSize[0] + std::abs(aMat[3]) * myHSize[1]));
0457   }
0458   return aResult;
0459 }
0460 
0461 //=================================================================================================
0462 
0463 template <typename RealType>
0464 bool Bnd_B2<RealType>::IsOut(const gp_XY& theCenter,
0465                              const double theRadius,
0466                              const bool   isCircleHollow) const
0467 {
0468   bool aResult(true);
0469   if (!isCircleHollow)
0470   {
0471     // vector from the center of the circle to the nearest box face
0472     const double aDist[2] = {std::abs(theCenter.X() - double(myCenter[0])) - double(myHSize[0]),
0473                              std::abs(theCenter.Y() - double(myCenter[1])) - double(myHSize[1])};
0474     double       aD(0.);
0475     if (aDist[0] > 0.)
0476       aD = aDist[0] * aDist[0];
0477     if (aDist[1] > 0.)
0478       aD += aDist[1] * aDist[1];
0479     aResult = (aD > theRadius * theRadius);
0480   }
0481   else
0482   {
0483     const double aDistC[2] = {std::abs(theCenter.X() - double(myCenter[0])),
0484                               std::abs(theCenter.Y() - double(myCenter[1]))};
0485     // vector from the center of the circle to the nearest box face
0486     double aDist[2] = {aDistC[0] - double(myHSize[0]), aDistC[1] - double(myHSize[1])};
0487     double aD(0.);
0488     if (aDist[0] > 0.)
0489       aD = aDist[0] * aDist[0];
0490     if (aDist[1] > 0.)
0491       aD += aDist[1] * aDist[1];
0492     if (aD < theRadius * theRadius)
0493     {
0494       // the box intersects the solid circle; check if it is completely
0495       // inside the circle (in such case return isOut==True)
0496       aDist[0] = aDistC[0] + double(myHSize[0]);
0497       aDist[1] = aDistC[1] + double(myHSize[1]);
0498       if (aDist[0] * aDist[0] + aDist[1] * aDist[1] > theRadius * theRadius)
0499         aResult = false;
0500     }
0501   }
0502   return aResult;
0503 }
0504 
0505 //=================================================================================================
0506 
0507 template <typename RealType>
0508 bool Bnd_B2<RealType>::IsOut(const Bnd_B2<RealType>& theBox, const gp_Trsf2d& theTrsf) const
0509 {
0510   bool              aResult(false);
0511   const gp_TrsfForm aForm     = theTrsf.Form();
0512   const double      aScale    = theTrsf.ScaleFactor();
0513   const double      aScaleAbs = std::abs(aScale);
0514   if (aForm == gp_Translation || aForm == gp_Identity || aForm == gp_PntMirror || aForm == gp_Scale)
0515   {
0516     aResult =
0517       (std::abs(RealType(theBox.myCenter[0] * aScale + theTrsf.TranslationPart().X()) - myCenter[0])
0518          > RealType(theBox.myHSize[0] * aScaleAbs) + myHSize[0]
0519        || std::abs(RealType(theBox.myCenter[1] * aScale + theTrsf.TranslationPart().Y())
0520                    - myCenter[1])
0521             > RealType(theBox.myHSize[1] * aScaleAbs) + myHSize[1]);
0522   }
0523   else
0524   {
0525     // theBox is transformed and we check the resulting (enlarged) box against
0526     // 'this' box.
0527     const double* aMat = &theTrsf.HVectorialPart().Value(1, 1);
0528 
0529     gp_XY aCenter((double)theBox.myCenter[0], (double)theBox.myCenter[1]);
0530     theTrsf.Transforms(aCenter);
0531     const double aDist[2] = {aCenter.X() - (double)myCenter[0], aCenter.Y() - (double)myCenter[1]};
0532     const double aMatAbs[4] = {std::abs(aMat[0]),
0533                                std::abs(aMat[1]),
0534                                std::abs(aMat[2]),
0535                                std::abs(aMat[3])};
0536     if (std::abs(aDist[0])
0537           > (aScaleAbs * (aMatAbs[0] * theBox.myHSize[0] + aMatAbs[1] * theBox.myHSize[1])
0538              + (double)myHSize[0])
0539         || std::abs(aDist[1])
0540              > (aScaleAbs * (aMatAbs[2] * theBox.myHSize[0] + aMatAbs[3] * theBox.myHSize[1])
0541                 + (double)myHSize[1]))
0542       aResult = true;
0543 
0544     else
0545     {
0546       // theBox is rotated, scaled and translated. We apply the reverse
0547       // translation and scaling then check against the rotated box 'this'
0548       if ((std::abs(aMat[0] * aDist[0] + aMat[2] * aDist[1])
0549            > theBox.myHSize[0] * aScaleAbs + (aMatAbs[0] * myHSize[0] + aMatAbs[2] * myHSize[1]))
0550           || (std::abs(aMat[1] * aDist[0] + aMat[3] * aDist[1])
0551               > theBox.myHSize[1] * aScaleAbs
0552                   + (aMatAbs[1] * myHSize[0] + aMatAbs[3] * myHSize[1])))
0553         aResult = true;
0554     }
0555   }
0556   return aResult;
0557 }
0558 
0559 //=================================================================================================
0560 
0561 template <typename RealType>
0562 bool Bnd_B2<RealType>::IsOut(const gp_Ax2d& theLine) const
0563 {
0564   if (IsVoid())
0565     return true;
0566   // Intersect the line containing the segment.
0567   const double aProd[3] = {
0568     theLine.Direction().XY()
0569       ^ (gp_XY(myCenter[0] - theLine.Location().X(), myCenter[1] - theLine.Location().Y())),
0570     theLine.Direction().X() * double(myHSize[1]),
0571     theLine.Direction().Y() * double(myHSize[0])};
0572   return (std::abs(aProd[0]) > (std::abs(aProd[1]) + std::abs(aProd[2])));
0573 }
0574 
0575 //=================================================================================================
0576 
0577 template <typename RealType>
0578 bool Bnd_B2<RealType>::IsOut(const gp_XY& theP0, const gp_XY& theP1) const
0579 {
0580   bool aResult(true);
0581   if (!IsVoid())
0582   {
0583     // Intersect the line containing the segment.
0584     const gp_XY  aSegDelta(theP1 - theP0);
0585     const double aProd[3] = {aSegDelta ^ (gp_XY(myCenter[0], myCenter[1]) - theP0),
0586                              aSegDelta.X() * double(myHSize[1]),
0587                              aSegDelta.Y() * double(myHSize[0])};
0588     if (std::abs(aProd[0]) < (std::abs(aProd[1]) + std::abs(aProd[2])))
0589     {
0590       // Intersection with line detected; check the segment as bounding box
0591       const gp_XY aHSeg(0.5 * aSegDelta.X(), 0.5 * aSegDelta.Y());
0592       const gp_XY aHSegAbs(std::abs(aHSeg.X()), std::abs(aHSeg.Y()));
0593       aResult = compareDistD(gp_XY((double)myHSize[0], (double)myHSize[1]) + aHSegAbs,
0594                              theP0 + aHSeg - gp_XY((double)myCenter[0], (double)myCenter[1]));
0595     }
0596   }
0597   return aResult;
0598 }
0599 
0600 //=================================================================================================
0601 
0602 template <typename RealType>
0603 bool Bnd_B2<RealType>::IsIn(const Bnd_B2<RealType>& theBox, const gp_Trsf2d& theTrsf) const
0604 {
0605   bool              aResult(false);
0606   const gp_TrsfForm aForm     = theTrsf.Form();
0607   const double      aScale    = theTrsf.ScaleFactor();
0608   const double      aScaleAbs = std::abs(aScale);
0609   if (aForm == gp_Translation || aForm == gp_Identity || aForm == gp_PntMirror || aForm == gp_Scale)
0610   {
0611     aResult =
0612       (std::abs(RealType(theBox.myCenter[0] * aScale + theTrsf.TranslationPart().X()) - myCenter[0])
0613          < RealType(theBox.myHSize[0] * aScaleAbs) - myHSize[0]
0614        && std::abs(RealType(theBox.myCenter[1] * aScale + theTrsf.TranslationPart().Y())
0615                    - myCenter[1])
0616             < RealType(theBox.myHSize[1] * aScaleAbs) - myHSize[1]);
0617   }
0618   else
0619   {
0620     // theBox is rotated, scaled and translated. We apply the reverse
0621     // translation and scaling then check against the rotated box 'this'
0622     const double* aMat = &theTrsf.HVectorialPart().Value(1, 1);
0623     gp_XY         aCenter((double)theBox.myCenter[0], (double)theBox.myCenter[1]);
0624     theTrsf.Transforms(aCenter);
0625     const double aDist[2] = {aCenter.X() - (double)myCenter[0], aCenter.Y() - (double)myCenter[1]};
0626     if ((std::abs(aMat[0] * aDist[0] + aMat[2] * aDist[1])
0627          < theBox.myHSize[0] * aScaleAbs
0628              - (std::abs(aMat[0]) * myHSize[0] + std::abs(aMat[2]) * myHSize[1]))
0629         && (std::abs(aMat[1] * aDist[0] + aMat[3] * aDist[1])
0630             < theBox.myHSize[1] * aScaleAbs
0631                 - (std::abs(aMat[1]) * myHSize[0] + std::abs(aMat[3]) * myHSize[1])))
0632       aResult = true;
0633   }
0634   return aResult;
0635 }
0636 
0637 //=================================================================================================
0638 
0639 //! 2D bounding box with double precision
0640 using Bnd_B2d = Bnd_B2<double>;
0641 
0642 //! 2D bounding box with single precision
0643 using Bnd_B2f = Bnd_B2<float>;
0644 
0645 #endif // _Bnd_B2_HeaderFile