File indexing completed on 2026-09-28 09:19:23
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
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
0031
0032 template <typename RealType>
0033 class Bnd_B2
0034 {
0035 public:
0036 DEFINE_STANDARD_ALLOC
0037
0038
0039 constexpr Bnd_B2() noexcept;
0040
0041
0042 constexpr Bnd_B2(const gp_XY& theCenter, const gp_XY& theHSize) noexcept;
0043
0044
0045 constexpr Bnd_B2(const std::array<RealType, 2>& theCenter,
0046 const std::array<RealType, 2>& theHSize) noexcept;
0047
0048
0049 constexpr bool IsVoid() const noexcept;
0050
0051
0052 void Clear() noexcept;
0053
0054
0055 void Add(const gp_XY& thePnt);
0056
0057
0058 void Add(const gp_Pnt2d& thePnt);
0059
0060
0061 void Add(const Bnd_B2<RealType>& theBox);
0062
0063
0064
0065
0066 gp_XY CornerMin() const noexcept;
0067
0068
0069
0070
0071 gp_XY CornerMax() const noexcept;
0072
0073
0074
0075 constexpr double SquareExtent() const noexcept;
0076
0077
0078 void Enlarge(const double theDiff) noexcept;
0079
0080
0081
0082
0083 bool Limit(const Bnd_B2<RealType>& theOtherBox);
0084
0085
0086
0087 [[nodiscard]] Bnd_B2<RealType> Transformed(const gp_Trsf2d& theTrsf) const;
0088
0089
0090
0091 constexpr bool IsOut(const gp_XY& thePnt) const noexcept;
0092
0093
0094
0095 bool IsOut(const gp_XY& theCenter,
0096 const double theRadius,
0097 const bool isCircleHollow = false) const;
0098
0099
0100
0101 constexpr bool IsOut(const Bnd_B2<RealType>& theOtherBox) const noexcept;
0102
0103
0104
0105
0106 bool IsOut(const Bnd_B2<RealType>& theOtherBox, const gp_Trsf2d& theTrsf) const;
0107
0108
0109
0110 bool IsOut(const gp_Ax2d& theLine) const;
0111
0112
0113
0114
0115 bool IsOut(const gp_XY& theP0, const gp_XY& theP1) const;
0116
0117
0118
0119 constexpr bool IsIn(const Bnd_B2<RealType>& theBox) const noexcept;
0120
0121
0122
0123
0124 bool IsIn(const Bnd_B2<RealType>& theBox, const gp_Trsf2d& theTrsf) const;
0125
0126
0127 void SetCenter(const gp_XY& theCenter) noexcept;
0128
0129
0130 void SetCenter(const std::array<RealType, 2>& theCenter) noexcept;
0131
0132
0133
0134 void SetHSize(const gp_XY& theHSize) noexcept;
0135
0136
0137
0138 void SetHSize(const std::array<RealType, 2>& theHSize) noexcept;
0139
0140
0141 constexpr const std::array<RealType, 2>& Center() const noexcept;
0142
0143
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
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
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;
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;
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;
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;
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
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
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
0495
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
0526
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
0547
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
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
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
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
0621
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
0640 using Bnd_B2d = Bnd_B2<double>;
0641
0642
0643 using Bnd_B2f = Bnd_B2<float>;
0644
0645 #endif