opencascade Bnd_OBB源码学习 OBB包围盒

news/2024/9/20 23:08:12/文章来源:https://www.cnblogs.com/yzxxty/p/18423065

opencascade Bnd_OBB OBB包围盒

前言

类描述了定向包围盒(OBB),比轴对齐包围盒(AABB)更紧密地包围形状的体积。OBB由盒子的中心、轴以及三个维度的一半定义。与AABB相比,OBB在作为非干扰物体的排斥机制时可以更有效地使用。

方法

1. 空构造函数

//! 空构造函数
Bnd_OBB() : myIsAABox(Standard_False)
{myHDims[0] = myHDims[1] = myHDims[2] = -1.0;
}

2. 带有所有定义参数的构造函数

//! 使用所有定义参数的构造函数
Bnd_OBB(const gp_Pnt& theCenter,const gp_Dir& theXDirection,const gp_Dir& theYDirection,const gp_Dir& theZDirection,const Standard_Real theHXSize,const Standard_Real theHYSize,const Standard_Real theHZSize) : myCenter(theCenter.XYZ()),myIsAABox(Standard_False)
{myAxes[0] = theXDirection.XYZ();myAxes[1] = theYDirection.XYZ();myAxes[2] = theZDirection.XYZ();Standard_ASSERT_VOID(theHXSize >= 0.0, "X尺寸的负值");Standard_ASSERT_VOID(theHYSize >= 0.0, "Y尺寸的负值");Standard_ASSERT_VOID(theHZSize >= 0.0, "Z尺寸的负值");myHDims[0] = theHXSize;myHDims[1] = theHYSize;myHDims[2] = theHZSize;
}

3. 从 AABB 创建 OBB 的构造函数

//! 从 AABB 创建 OBB 的构造函数
Bnd_OBB(const Bnd_Box& theBox) : myIsAABox(Standard_True)
{if (theBox.IsVoid()){myHDims[0] = myHDims[1] = myHDims[2] = -1.0;myIsAABox = Standard_False;return;}Standard_Real aX1, aY1, aZ1, aX2, aY2, aZ2;theBox.Get(aX1, aY1, aZ1, aX2, aY2, aZ2);myAxes[0].SetCoord(1.0, 0.0, 0.0);myAxes[1].SetCoord(0.0, 1.0, 0.0);myAxes[2].SetCoord(0.0, 0.0, 1.0);myHDims[0] = 0.5 * (aX2 - aX1);myHDims[1] = 0.5 * (aY2 - aY1);myHDims[2] = 0.5 * (aZ2 - aZ1);myCenter.SetCoord(0.5 * (aX2 + aX1), 0.5 * (aY2 + aY1), 0.5 * (aZ2 + aZ1));
}

4. 重建 OBB

//! 创建覆盖所有点的新的 OBB。
//! 每个点的容差由 *theListOfTolerances 数组设置。
//! 如果数组不为空,则通过点的容差来扩大结果 Bnd_OBB。
//! <theIsOptimal> 标志定义了 OBB 的构建模式。
//! 构建最优盒子需要更多时间,但结果通常更紧凑。构建最优 OBB 时,会检查更多可能的轴。
Standard_EXPORT void ReBuild(const TColgp_Array1OfPnt& theListOfPoints,const TColStd_Array1OfReal *theListOfTolerances = 0,const Standard_Boolean theIsOptimal = Standard_False);

5. 设置 OBB 的中心

设置 OBB 的中心
void SetCenter(const gp_Pnt& theCenter)
{
myCenter = theCenter.XYZ();
}

6. 设置 X 组件

设置 OBB 的 X 组件 - 方向和尺寸
void SetXComponent(const gp_Dir& theXDirection,
const Standard_Real theHXSize)
{
Standard_ASSERT_VOID(theHXSize >= 0.0, "X尺寸的负值");

myAxes[0] = theXDirection.XYZ();
myHDims[0] = theHXSize;
}

7. 设置 Y 组件

//! 设置 OBB 的 Y 组件 - 方向和尺寸
void SetYComponent(const gp_Dir& theYDirection,
const Standard_Real theHYSize)
{
Standard_ASSERT_VOID(theHYSize >= 0.0, "Y尺寸的负值");

myAxes[1] = theYDirection.XYZ();
myHDims[1] = theHYSize;
}

8. 设置 Z 组件

设置 OBB 的 Z 组件 - 方向和尺寸
void SetZComponent(const gp_Dir& theZDirection,
const Standard_Real theHZSize)
{
Standard_ASSERT_VOID(theHZSize >= 0.0, "Z尺寸的负值");

myAxes[2] = theZDirection.XYZ();
myHDims[2] = theHZSize;
}

9. 获取局部坐标系

返回这个定向盒子的局部坐标系。
将其应用于轴对齐的盒子 ((-XHSize, -YHSize, -ZHSize), (XHSize, YHSize, ZHSize)) 将产生这个定向盒子。
gp_Ax3 Position() const { return gp_Ax3 (myCenter, ZDirection(), XDirection()); }

10. 获取中心点

返回 OBB 的中心
const gp_XYZ& Center() const
{
return myCenter;
}

11. 获取 X 方向

返回 OBB 的 X 方向
const gp_XYZ& XDirection() const
{
return myAxes[0];
}

12. 获取 Y 方向

返回 OBB 的 Y 方向
const gp_XYZ& YDirection() const
{
return myAxes[1];
}

13. 获取 Z 方向

返回 OBB 的 Z 方向
const gp_XYZ& ZDirection() const
{
return myAxes[2];
}

14. 获取 X 尺寸

返回 OBB 的 X 尺寸
Standard_Real XHSize() const
{
return myHDims[0];
}

15. 获取 Y 尺寸

返回 OBB 的 Y 尺寸
Standard_Real YHSize() const
{
return myHDims[1];
}

16. 获取 Z 尺寸

返回 OBB 的 Z 尺寸
Standard_Real ZHSize() const
{
return myHDims[2];
}

17. 检查盒子是否为空

检查盒子是否为空
Standard_Boolean IsVoid() const
{
return ((myHDims[0] < 0.0) || (myHDims[1] < 0.0) || (myHDims[2] < 0.0));
}

18. 清除盒子

清除这个盒子
void SetVoid()
{
myHDims[0] = myHDims[1] = myHDims[2] = -1.0;
myCenter = myAxes[0] = myAxes[1] = myAxes[2] = gp_XYZ();
myIsAABox = Standard_False;
}

19. 设置轴对齐盒子标志

设置轴对齐盒子的标志
void SetAABox(const Standard_Boolean& theFlag)
{
myIsAABox = theFlag;
}

20. 判断是否为轴对齐盒子

返回 TRUE 如果盒子是轴对齐的
Standard_Boolean IsAABox() const
{
return myIsAABox;
}

21. 扩大盒子

//! 用给定值扩大盒子
void Enlarge(const Standard_Real theGapAdd)
{
const Standard_Real aGap = Abs(theGapAdd);
myHDims[0] += aGap;
myHDims[1] += aGap;
myHDims[2] += aGap;
}

22. 获取顶点

返回盒子的顶点数组。
局部坐标的顶点取决于数组的索引:
Standard_Boolean GetVertex(gp_Pnt theP[8])

23. 获取平方对角线长度

返回这个盒子的平方对角线长度
Standard_Real SquareExtent() const
{
return 4.0 * (myHDims[0] * myHDims[0] +
myHDims[1] * myHDims[1] +
myHDims[2] * myHDims[2]);
}

24. 检查与另一个盒子的干扰

//! 检查这个盒子是否与另一个盒子不干扰
Standard_EXPORT Standard_Boolean IsOut(const Bnd_OBB& theOther) const;

25. 检查点是否在此盒子内

//! 检查点是否在这个盒子内
Standard_EXPORT Standard_Boolean IsOut(const gp_Pnt& theP) const;

26. 检查另一个盒子是否完全在此盒子内

检查另一个盒子是否完全在这个盒子内
Standard_EXPORT Standard_Boolean IsCompletelyInside(const Bnd_OBB& theOther) const;

27. 将另一个盒子添加到当前盒子中

重建当前盒子以包含所有之前的对象(包括另一个盒子)
Standard_EXPORT void Add(const Bnd_OBB& theOther);

28. 将点添加到当前盒子中

重建当前盒子以包含所有之前的对象(包括一个点)
Standard_EXPORT void Add(const gp_Pnt& theP);


#### 29. 将内容输出到流中
```cpp
//! 将当前对象的内容输出到流中
Standard_EXPORT void DumpJson(Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;

下面是一个使用 OpenCascade Bnd_OBB 类的简单示例。这个示例展示了如何创建一个 Bnd_OBB 对象,设置它的属性,以及如何使用它的一些功能。

示例代码

#include <gp_Pnt.hxx>
#include <gp_Dir.hxx>
#include <Bnd_OBB.hxx>
#include <Bnd_Box.hxx>
#include <TColgp_Array1OfPnt.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <Standard_Real.hxx>
#include <Standard_Boolean.hxx>
#include <Standard_OStream.hxx>
#include <iostream>int main() {// 示例 1: 使用中心点、方向向量和尺寸创建一个 Bnd_OBB 对象gp_Pnt center(0.0, 0.0, 0.0);  // 中心点gp_Dir xDir(1.0, 0.0, 0.0);    // X 方向gp_Dir yDir(0.0, 1.0, 0.0);    // Y 方向gp_Dir zDir(0.0, 0.0, 1.0);    // Z 方向Standard_Real xSize = 10.0;     // X 尺寸Standard_Real ySize = 5.0;      // Y 尺寸Standard_Real zSize = 2.0;      // Z 尺寸// 创建 Bnd_OBB 对象Bnd_OBB obb(center, xDir, yDir, zDir, xSize, ySize, zSize);// 输出 OBB 的中心点和方向std::cout << "Center: (" << obb.Center().X() << ", " << obb.Center().Y() << ", " << obb.Center().Z() << ")\n";std::cout << "X Direction: (" << obb.XDirection().X() << ", " << obb.XDirection().Y() << ", " << obb.XDirection().Z() << ")\n";std::cout << "Y Direction: (" << obb.YDirection().X() << ", " << obb.YDirection().Y() << ", " << obb.YDirection().Z() << ")\n";std::cout << "Z Direction: (" << obb.ZDirection().X() << ", " << obb.ZDirection().Y() << ", " << obb.ZDirection().Z() << ")\n";// 输出 OBB 的尺寸std::cout << "X Size: " << obb.XHSize() << "\n";std::cout << "Y Size: " << obb.YHSize() << "\n";std::cout << "Z Size: " << obb.ZHSize() << "\n";// 获取并输出 OBB 的顶点gp_Pnt vertices[8];if (obb.GetVertex(vertices)) {std::cout << "Vertices:\n";for (int i = 0; i < 8; ++i) {std::cout << "Vertex " << i << ": (" << vertices[i].X() << ", " << vertices[i].Y() << ", " << vertices[i].Z() << ")\n";}} else {std::cout << "Failed to get vertices.\n";}// 示例 2: 从 AABB 创建 OBBBnd_Box aabb;aabb.Add(gp_Pnt(-5.0, -2.5, -1.0));aabb.Add(gp_Pnt(5.0, 2.5, 1.0));Bnd_OBB obbFromAABB(aabb);// 输出从 AABB 创建的 OBB 的中心点和尺寸std::cout << "Center from AABB: (" << obbFromAABB.Center().X() << ", " << obbFromAABB.Center().Y() << ", " << obbFromAABB.Center().Z() << ")\n";std::cout << "X Size from AABB: " << obbFromAABB.XHSize() << "\n";std::cout << "Y Size from AABB: " << obbFromAABB.YHSize() << "\n";std::cout << "Z Size from AABB: " << obbFromAABB.ZHSize() << "\n";return 0;
}

代码说明

  1. 创建 Bnd_OBB 对象

    • 使用中心点 (gp_Pnt)、方向向量 (gp_Dir) 和尺寸 (Standard_Real) 创建一个 Bnd_OBB 对象。
    • 使用 SetCenterSetXComponentSetYComponentSetZComponent 方法可以设置 Bnd_OBB 对象的属性。
  2. 获取 Bnd_OBB 的属性

    • 通过 Center()XDirection()YDirection()ZDirection() 获取中心点和方向向量。
    • 使用 XHSize()YHSize()ZHSize() 获取尺寸。
    • GetVertex 方法用于获取 OBB 的 8 个顶点。
  3. 从 AABB 创建 Bnd_OBB 对象

    • 创建一个 Bnd_Box 对象并添加点。
    • Bnd_Box 创建 Bnd_OBB 对象并获取其属性。

注意事项

  • 确保在构建程序时正确链接 OpenCascade 库。
  • 调用 GetVertex 时,检查返回值以确认操作成功。

这个示例涵盖了 Bnd_OBB 类的一些基本用法,包括创建对象、设置属性、获取信息和从 Bnd_Box 创建 Bnd_OBB
参考
参考

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/800775.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Scala安装与环境配置详解教程

本文参考来源: http://mengmianren.com/zhihuishu2020/641069.htmlScala运行在java的JVM之上,因此需要先安装Java运行环境 一、JDK8的下载和安装及环境变量配置 使用的jdk版本是:jdk-8u191-windows-i586.exe https://pan.baidu.com/s/1RNNb7lcqKHC_2h0iiTlqFg?pwd=9t5e 提取…

day2-2

今天进行了一次小测验,仍与基础的增删改查有关。 题目的要求是通过Java写出一个建议系统,能够历遍输出各个数据,能够添加,删除,修改数据,能够根据编号查找到对应的数据。程序如下该程序能够完成这些要求,也具有一定的健全性。

大学C++程序设计课程开发指南——开发环境搭建

前言 由于某些大学程序设计课程仍然在使用VC6.0这一上古工具,不太适合学生与现代开发生产接轨,并且也有可能出现兼容问题等,故编写此文,仅供参考。 使用 Visual Studio 在介绍Visual Studio(此后简称VS)前,先给大家介绍这一工具的发展。 其前身正是VC6.0(全称Visual C++…

LLM DATASET

大模型的能力来源 https://arxiv.org/pdf/2402.18041 大模型合规来源 https://arxiv.org/html/2402.12193v2 大模型的罪恶检测来源 https://www.kaggle.com/datasets/odins0n/ucf-crime-dataset/data code math https://github.com/mlabonne/llm-datasetsMath & LogicLLMs …

2024-9-20

ArrayList类 获取元素

在链接与运行地址不同时gdb的调试方法

搭建一个链接和运行不同的环境 SECTIONS {. = 0xffff000000080000,/* . = 0x80000, */.text.boot : { *(.text.boot) }.text : { *(.text) }.rodata : { *(.rodata) }..... }-s还可以看到符号都链接到高地址去了但是elf文件中有详细的地址信息,如果后续qemu加载的是elf的话就会…

排队论——随机服务系统仿真精解

排队论作为研究随机服务系统的重要工具,专门研究系统中客户到达、排队、服务和离开的过程。排队论的核心目的是通过数学建模和分析,研究系统的性能指标,如平均等待时间、队列长度、系统的吞吐量等。虽然排队论提供了强大的数学工具来分析随机服务系统,但在许多复杂的实际问…

opencascade Adaptor3d_Curve源码学习

opencascade Adaptor3d_Curve 前言用于几何算法工作的3D曲线的根类。 适配曲线是曲线提供的服务与使用该曲线的算法所需服务之间的接口。 提供了两个派生具体类:GeomAdaptor_Curve,用于Geom包中的曲线 Adaptor3d_CurveOnSurface,用于Geom包中表面上的曲线。 用于评估BSpline…

IDEA 换了电脑,如何导入和导出配置?

前言 我们在使用IDEA开发时,经常会设置各种各样的配置,时间一长,就会有很多个性化的东西。用起来也越来越顺手。不过这里可能会有个问题,那就是哪一天我们要换个电脑了,或者想安装新版本的IDEA时,又得重新配置下来。这复杂度堪比重装系统后的各种安装软件。那么,我们有没…

csp2024 游寄

不知不觉中,学OI已经一年了啊 day -\(\infty\) 打了一场模拟赛 喜提历史最好成绩:颓颓颓 day -6 做了一下去年的初赛 喜提57.5(SD分数线76 尸体不好了/tu day -5 又是模拟赛,达到历史最差成绩:不会打表导致的(确信 咋办啊有点慌。。。。。 day -4 开始去b站搜视频,搞初赛…

搭建免费的图床

当我们想创建一个小型的web应用时,如果图片资源放在服务器上,会影响带宽(也就是加载速度),尤其一些新手创业项目购买的服务器资源非常有限。这个时候如果还把图片资源放在服务器上会导致网页加载的非常缓慢。 这个时候就需要用的图片服务器。图片服务器有以下几种自己搭建…

结对作业

结对项目 这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/CSGrade22-34/ 这个作业要求在哪里 https://edu.cnblogs.com/campus/gdgy/CSGrade22-34/homework/13230 这个作业的目标 结对项目——实现一个自动生成小学四则运算题目的命令行程序 项目成员 本次结对项目…