opencascade Bnd_Box源码学习 包围盒

opencascade Bnd_Box 包围盒

前言 描述一个三维空间中的包围盒

一个包围盒与坐标系的轴线平行。如果它是有限的,则由三个区间定义:

  • [Xmin, Xmax],
  • [Ymin, Ymax],
  • [Zmin, Zmax]。

一个包围盒在一个或多个方向上可能是无限的(即开放的)。它被称为:

  • OpenXmin 如果它在“X方向”的负方向上是无限的;
  • OpenXmax 如果它在“X方向”的正方向上是无限的;
  • OpenYmin 如果它在“Y方向”的负方向上是无限的;
  • OpenYmax 如果它在“Y方向”的正方向上是无限的;
  • OpenZmin 如果它在“Z方向”的负方向上是无限的;
  • OpenZmax 如果它在“Z方向”的正方向上是无限的;
  • WholeSpace 如果它在所有六个方向上都是无限的。在这种情况下,空间中的任何点都在包围盒内;
  • Void 如果它是空的。在这种情况下,包围盒内没有任何点。

一个包围盒由以下部分定义:

  • 六个边界(Xmin、Xmax、Ymin、Ymax、Zmin 和 Zmax),当包围盒是有限时,这些边界限制包围盒;
  • 八个标志(OpenXmin、OpenXmax、OpenYmin、OpenYmax、OpenZmin、OpenZmax、WholeSpace 和 Void),这些标志描述包围盒是否是无限的或空的;
  • 一个间隙,它在任何方向上包括在包围盒的有限边界的两侧。

方法

1

空构造函数
Bnd_B3f();

2

构造函数
Bnd_B3f(const gp_XYZ& theCenter, const gp_XYZ& theHSize);

3

返回 True 如果包围盒为空(未初始化)
Standard_Boolean IsVoid() const;

4

重置包围盒数据
void Clear();

5

通过一个点更新包围盒
Standard_EXPORT void Add (const gp_XYZ& thePnt);

6

通过一个点更新包围盒
void Add (const gp_Pnt& thePnt);

7

通过另一个包围盒更新包围盒
void Add (const Bnd_B3f& theBox);

8

查询下角点:(Center - HSize)。必须确保包围盒不是空的(请参见 IsVoid()),否则该方法返回不相关的结果。
gp_XYZ CornerMin() const;

9

查询上角点:(Center + HSize)。必须确保包围盒不是空的(请参见 IsVoid()),否则该方法返回不相关的结果。
gp_XYZ CornerMax() const;

10

查询对角线的平方。如果包围盒是空的(参见 IsVoid()),则返回一个非常大的实数值。
Standard_Real SquareExtent() const;

11

theDiff 的绝对值扩展包围盒
void Enlarge (const Standard_Real theDiff);

12

通过 theOtherBox 的内部限制包围盒。如果包围盒被限制,则返回 True,否则返回 False 表示包围盒不相交。
Standard_EXPORT Standard_Boolean Limit (const Bnd_B3f& theOtherBox);

13

使用给定的变换对包围盒进行变换。如果 theTrsf 包含旋转,则结果包围盒会更大。
Standard_NODISCARD Standard_EXPORT Bnd_B3f Transformed (const gp_Trsf& theTrsf) const;

14

检查给定点是否在包围盒内。如果点在包围盒外,则返回 True
Standard_Boolean IsOut (const gp_XYZ& thePnt) const;

15

检查一个球体是否与当前包围盒相交。如果包围盒完全在球体内,并且 IsSphereHollowTrue,则不会报告相交(否则该方法将报告相交)。
Standard_EXPORT Standard_Boolean IsOut (const gp_XYZ& theCenter, const Standard_Real theRadius, const Standard_Boolean isSphereHollow = Standard_False) const;

16

检查给定包围盒是否与当前包围盒相交。如果包围盒不相交,则返回 True
Standard_Boolean IsOut (const Bnd_B3f& theOtherBox) const;

17

检查给定的包围盒(经过给定的变换)是否与当前包围盒相交。如果包围盒不相交,则返回 True
Standard_EXPORT Standard_Boolean IsOut (const Bnd_B3f& theOtherBox, const gp_Trsf& theTrsf) const;

18

检查给定的直线是否与当前包围盒相交。如果不相交,则返回 TrueisRay==True 表示检查与正半轴的相交,theOverthickness 是对当前包围盒大小的额外加量(可能是负数)。如果为正,则可以视为直线 theLine 的厚度或沿 theLine 的圆柱体的半径。
Standard_EXPORT Standard_Boolean IsOut (const gp_Ax1& theLine, const Standard_Boolean isRay = Standard_False, const Standard_Real theOverthickness = 0.0) const;

19

检查给定平面是否与当前包围盒相交。如果不相交,则返回 True
Standard_EXPORT Standard_Boolean IsOut (const gp_Ax3& thePlane) const;

20

检查包围盒 this 是否在给定的包围盒 theBox 内。如果 this 包围盒完全在 theBox 内,则返回 True
Standard_Boolean IsIn (const Bnd_B3f& theBox) const;

21

检查包围盒 this 是否在经过 theTrsf 变换的包围盒 theBox 内。如果 this 包围盒完全在变换后的 theBox 内,则返回 True
Standard_EXPORT Standard_Boolean IsIn (const Bnd_B3f& theBox, const gp_Trsf& theTrsf) const;

22

设置中心坐标
void SetCenter (const gp_XYZ& theCenter);

23

设置 HSize(半对角线)坐标。所有 HSize 的分量必须是非负的。
void SetHSize (const gp_XYZ& theHSize);
Bnd_Box 是 OpenCascade 中用于表示三维包围盒的类。下面是一些使用 Bnd_Box 类的示例,包括如何创建包围盒、更新包围盒、查询包围盒等操作的示例代码。

示例代码

#include <Bnd_Box.hxx>
#include <gp_Pnt.hxx>
#include <gp_XYZ.hxx>
#include <iostream>

int main() {
    // 创建一个空的包围盒
    Bnd_Box box;

    // 创建一个中心点和半对角线大小
    gp_XYZ center(0.0, 0.0, 0.0);
    gp_XYZ halfSize(1.0, 1.0, 1.0);

    // 设置包围盒的中心和半对角线
    box.SetCenter(center);
    box.SetHSize(halfSize);

    // 添加一个点到包围盒
    gp_Pnt point(0.5, 0.5, 0.5);
    box.Add(point);

    // 查询包围盒的下角和上角
    gp_XYZ minCorner = box.CornerMin();
    gp_XYZ maxCorner = box.CornerMax();

    std::cout << "Min Corner: (" << minCorner.X() << ", " << minCorner.Y() << ", " << minCorner.Z() << ")\n";
    std::cout << "Max Corner: (" << maxCorner.X() << ", " << maxCorner.Y() << ", " << maxCorner.Z() << ")\n";

    // 扩展包围盒
    box.Enlarge(0.5);

    // 查询扩展后的包围盒的对角线平方长度
    Standard_Real extent = box.SquareExtent();
    std::cout << "Square Extent: " << extent << "\n";

    // 创建另一个包围盒
    Bnd_Box anotherBox;
    anotherBox.SetCenter(gp_XYZ(2.0, 2.0, 2.0));
    anotherBox.SetHSize(gp_XYZ(1.0, 1.0, 1.0));

    // 检查两个包围盒是否相交
    if (box.IsOut(anotherBox)) {
        std::cout << "The boxes do not intersect.\n";
    } else {
        std::cout << "The boxes intersect.\n";
    }

    // 创建一个变换
    gp_Trsf transform;
    transform.SetRotation(gp_Ax1(gp_Pnt(0,0,0), gp_Dir(1,1,1)), M_PI/4);

    // 变换包围盒
    Bnd_Box transformedBox = box.Transformed(transform);

    // 查询变换后的包围盒的下角和上角
    gp_XYZ transformedMin = transformedBox.CornerMin();
    gp_XYZ transformedMax = transformedBox.CornerMax();

    std::cout << "Transformed Min Corner: (" << transformedMin.X() << ", " << transformedMin.Y() << ", " << transformedMin.Z() << ")\n";
    std::cout << "Transformed Max Corner: (" << transformedMax.X() << ", " << transformedMax.Y() << ", " << transformedMax.Z() << ")\n";

    return 0;
}

代码解释

  1. 创建包围盒Bnd_Box box; 创建了一个空的包围盒。

  2. 设置包围盒的中心和半对角线

    gp_XYZ center(0.0, 0.0, 0.0);
    gp_XYZ halfSize(1.0, 1.0, 1.0);
    box.SetCenter(center);
    box.SetHSize(halfSize);
    
  3. 添加点到包围盒

    gp_Pnt point(0.5, 0.5, 0.5);
    box.Add(point);
    
  4. 查询包围盒的下角和上角

    gp_XYZ minCorner = box.CornerMin();
    gp_XYZ maxCorner = box.CornerMax();
    
  5. 扩展包围盒

    box.Enlarge(0.5);
    
  6. 查询扩展后的包围盒的对角线平方长度

    Standard_Real extent = box.SquareExtent();
    
  7. 检查两个包围盒是否相交

    Bnd_Box anotherBox;
    anotherBox.SetCenter(gp_XYZ(2.0, 2.0, 2.0));
    anotherBox.SetHSize(gp_XYZ(1.0, 1.0, 1.0));
    
    if (box.IsOut(anotherBox)) {
        std::cout << "The boxes do not intersect.\n";
    } else {
        std::cout << "The boxes intersect.\n";
    }
    
  8. 变换包围盒

    gp_Trsf transform;
    transform.SetRotation(gp_Ax1(gp_Pnt(0,0,0), gp_Dir(1,1,1)), M_PI/4);
    Bnd_Box transformedBox = box.Transformed(transform);
    
  9. 查询变换后的包围盒的下角和上角

    gp_XYZ transformedMin = transformedBox.CornerMin();
    gp_XYZ transformedMax = transformedBox.CornerMax();
    

这些示例展示了如何使用 Bnd_Box 类创建和操作三维包围盒,包括设置包围盒的属性、更新包围盒、检查相交情况以及应用变换。

参考
参考