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
检查一个球体是否与当前包围盒相交。如果包围盒完全在球体内,并且 IsSphereHollow
为 True
,则不会报告相交(否则该方法将报告相交)。
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
检查给定的直线是否与当前包围盒相交。如果不相交,则返回 True
。isRay==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;
}
代码解释
-
创建包围盒:
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();
-
扩展包围盒:
box.Enlarge(0.5);
-
查询扩展后的包围盒的对角线平方长度:
Standard_Real extent = box.SquareExtent();
-
检查两个包围盒是否相交:
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();
这些示例展示了如何使用 Bnd_Box
类创建和操作三维包围盒,包括设置包围盒的属性、更新包围盒、检查相交情况以及应用变换。