在 Unity 中查找一组 3D 点的定向边界框

2023-12-21

我有一组 3D 点,或者实际上是小球体,我需要使用 Unity 3D 将它们包围在尽可能小的 3D 框内。

在封闭框只能移动和缩放的情况下,解决方案非常简单,您只需迭代所有点并封装每个点即可。但我还需要找到盒子的最佳方向。

因此,为了用 ASCII 来说明问题,给出一个只有两点的基本 2D 场景:

Y
| * (0,1)
|
|
|
|               * (1,0)
-------------------- X

使用规则增长的边界框,您最终会得到一个非常大的封闭框,其中大部分为空白,而在这种情况下,我需要一个非常薄且绕 Z 轴旋转约 45 度的框。基本上只是一条连接两点的线。

但我永远不知道需要将多少点组合在一起。正如前面提到的,它必须以 3D 模式运行。

到目前为止,我只尝试了基本方法,即不旋转封装盒以获得最佳配合。结果确实离我需要的还很远。

我正在考虑一种基于遗传算法的强力方法,我生成大量随机框,然后简单地选择面积最小的框,同时仍包含所有点。然而,这太慢了。

GameObject go = points[0];
Bounds b = new Bounds(go.transform.position,go.transform.localScale);

for (int i=1;i<points.Count;i++)
{
    go = points[i];
    b.Encapsulate(new Bounds(go.transform.position, go.transform.localScale));
}

GameObject containingBox = Instantiate(boxPrefab);
containingBox.transform.position = b.center;
containingBox.transform.localScale = b.size;
containingBox.transform.rotation= Quaternion.Identity; //How to calculate?

嘿,我搜索了一下,发现了一个非常强大的库,它或多或少直接提供了您正在寻找的内容,甚至积极支持 Unity 类型:

几何3锐利 https://github.com/gradientspace/geometry3Sharp

Unity 项目的实现非常简单

  • 将项目下载为.zip
  • 解压文件夹geometry3Sharp-master进入你的Assets folder
  • 在Unity下ProjectSettings&右箭头;Player&右箭头;Other Settings&右箭头;Configuration&右箭头;Scripting Define Symbols insert

    G3_USING_UNITY;
    

    正如自述文件中所解释的那样:

    geometry3Sharp支持与Unity类型的透明转换。要启用此功能,请定义G3_USING_UNITY在您的 Unity 项目中,通过将此字符串添加到播放器设置中的脚本定义符号框中。

然后您可以简单地计算给定数组的定向边界框的边缘Vector3像这样的点:

using UnityEngine;
using g3;

public class Example : MonoBehaviour
{
    // Just for the demo I used Transforms so I can simply move them around in the scene
    public Transform[] transforms;

    private void OnDrawGizmos()
    {
        // First wehave to convert the Unity Vector3 array
        // into the g3 type g3.Vector3d
        var points3d = new Vector3d[transforms.Length];
        for (var i = 0; i < transforms.Length; i++)
        {
            // Thanks to the g3 library implictely casted from UnityEngine.Vector3 to g3.Vector3d
            points3d[i] = transforms[i].position;
        }

        // BOOM MAGIC!!!
        var orientedBoundingBox = new ContOrientedBox3(points3d);

        // Now just convert the information back to Unity Vector3 positions and axis
        // Since g3.Vector3d uses doubles but Unity Vector3 uses floats
        // we have to explicitly cast to Vector3
        var center = (Vector3)orientedBoundingBox.Box.Center;

        var axisX = (Vector3)orientedBoundingBox.Box.AxisX;
        var axisY = (Vector3)orientedBoundingBox.Box.AxisY;
        var axisZ = (Vector3)orientedBoundingBox.Box.AxisZ;
        var extends = (Vector3)orientedBoundingBox.Box.Extent;

        // Now we can simply calculate our 8 vertices of the bounding box
        var A = center - extends.z * axisZ - extends.x * axisX - axisY * extends.y;
        var B = center - extends.z * axisZ + extends.x * axisX - axisY * extends.y;
        var C = center - extends.z * axisZ + extends.x * axisX + axisY * extends.y;
        var D = center - extends.z * axisZ - extends.x * axisX + axisY * extends.y;

        var E = center + extends.z * axisZ - extends.x * axisX - axisY * extends.y;
        var F = center + extends.z * axisZ + extends.x * axisX - axisY * extends.y;
        var G = center + extends.z * axisZ + extends.x * axisX + axisY * extends.y;
        var H = center + extends.z * axisZ - extends.x * axisX + axisY * extends.y;

        // And finally visualize it
        Gizmos.DrawLine(A, B);
        Gizmos.DrawLine(B, C);
        Gizmos.DrawLine(C, D);
        Gizmos.DrawLine(D, A);

        Gizmos.DrawLine(E, F);
        Gizmos.DrawLine(F, G);
        Gizmos.DrawLine(G, H);
        Gizmos.DrawLine(H, E);

        Gizmos.DrawLine(A, E);
        Gizmos.DrawLine(B, F);
        Gizmos.DrawLine(D, H);
        Gizmos.DrawLine(C, G);

        // And Here we ca just be amazed ;)
    }
}

当然还有类似的东西

orientedBoundingBox.Box.Contains(Vector3d)

用于确定给定点是否位于该框中。


只因为鲁兹姆问:

当然,您可以稍微更改上面的脚本以仅使用实际的网格顶点:

public MeshFilter[] meshFilters;

private void OnDrawGizmos()
{
    var vertices = new List<Vector3>();
    foreach (var meshFilter in meshFilters)
    {
        // have to multiply the vertices' positions
        // with the lossyScale and add it to the transform.position 
        vertices.AddRange(meshFilter.sharedMesh.vertices.Select(vertex => meshFilter.transform.position + Vector3.Scale(vertex, meshFilter.transform.lossyScale)));
    }

    var points3d = new Vector3d[vertices.Count];

    for (var i = 0; i < vertices.Count; i++)
    {
        points3d[i] = vertices[i];
    }

    // ...
    // From here the code is the same as above

看起来基本一样

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Unity 中查找一组 3D 点的定向边界框 的相关文章

  • 为什么这个 Web api 控制器不并发?

    我有一个 Web API 控制器 里面有以下方法 public string Tester Thread Sleep 2000 return OK 当我调用它 10 次 使用 Fiddler 时 我预计所有 10 次调用都会在大约 2 秒后
  • Exit() 时是否调用基本对象析构函数?

    我意识到这个问题已经出现过几次 但我试图获得上述问题的明确答案 但我不断遇到相互矛盾的信息 我需要知道的是 当我使用 exit 时 基本类对象是否被破坏 我知道需要删除动态内存 但我的意思更像是 include
  • 如何在 VC++ CString 中验证有效的整数和浮点数

    有人可以告诉我一种有效的方法来验证 CString 对象中存在的数字是有效整数还是浮点数吗 Use tcstol http msdn microsoft com en us library w4z2wdyc aspx and tcstod
  • 将类对象放置在向量中?

    我注意到我可以将一个类放置在一个向量中 这是我的程序 我收到以下错误 out blackjack exe blackjack obj blackjack obj error LNK2019 unresolved external symbo
  • 如何在类文件中使用 Url.Action() ?

    如何在 MVC 项目的类文件中使用 Url Action Like namespace 3harf public class myFunction public static void CheckUserAdminPanelPermissi
  • 按扩展名过滤搜索文件返回太多结果

    我正在开发一个 C 控制台应用程序 它必须管理 Windows 操作系统上的文件 我需要获取具有特定扩展名的文件名 列表 我找到了很多解决方案 最建议的是以下一种 HANDLE hFind WIN32 FIND DATA data hFin
  • 强制初始化模板类的静态数据成员

    关于模板类的静态数据成员未初始化存在一些问题 不幸的是 这些都没有能够帮助我解决我的具体问题的答案 我有一个模板类 它有一个静态数据成员 必须为特定类型显式实例化 即必须专门化 如果不是这种情况 使用不同的模板函数应该会导致链接器错误 这是
  • 语音识别编程问题入门

    所以 你们可能都看过 钢铁侠 其中托尼与一个名为贾维斯的人工智能系统进行交互 演示剪辑here http www youtube com watch v Go8zsh1Ev6Y 抱歉 这是广告 我非常熟悉 C C 和 Visual Basi
  • 在 C# 中检查 PowerShell 执行策略的最佳方法是什么?

    当你跑步时Get ExecutionPolicy在 PowerShell 中 它得到有效的执行政策 https learn microsoft com en us powershell module microsoft powershell
  • 如何将AVFrame转换为glTexImage2D使用的纹理?

    如您所知 AVFrame 有 2 个属性 pFrame gt data pFrame gt linesize 当我从视频 sdcard test mp4 android平台 读取帧后 并将其转换为RGB AVFrame副 img conve
  • 不可变类与结构

    以下是类与 C 中的结构的唯一区别 如果我错了 请纠正我 类变量是引用 而结构变量是值 因此在赋值和参数传递中复制结构的整个值 类变量是存储在堆栈上的指针 指向堆上的内存 而结构变量作为值存储在堆上 假设我有一个不可变的结构 该结构的字段一
  • 模板外部链接?谁能解释一下吗?

    模板名称具有链接 3 5 非成员函数模板可以有内部链接 任何其他模板名称应具有外部链接 从具有内部链接的模板生成的实体与在其他翻译单元中生成的所有实体不同 我知道使用关键字的外部链接 extern C EX extern C templat
  • C++ - 多维数组

    处理多维数组时 是否可以为数组分配两种不同的变量类型 例如你有数组int example i j 有可能吗i and j是两种完全不同的变量类型 例如 int 和 string 听起来您正在寻找 std vector
  • 将二变量 std::function 转换为单变量 std::function

    我有一个函数 它获取两个值 x 和 y 并返回结果 std function lt double double double gt mult double x double y return x y 现在我想得到一个常量 y 的单变量函数
  • 将 Lambda 表达式树与 IEnumerable 结合使用

    我一直在尝试了解有关使用 Lamba 表达式树的更多信息 因此我创建了一个简单的示例 这是代码 如果作为 C 程序粘贴到 LINQPad 中 它可以工作 void Main IEnumerable
  • 代码中的.net Access Forms身份验证“超时”值

    我正在向我的应用程序添加注销过期警报 并希望从我的代码访问我的 web config 表单身份验证 超时 值 我有什么办法可以做到这一点吗 我认为您可以从 FormsAuthentication 静态类方法中读取它 这比直接读取 web c
  • 如何在 sql azure 上运行 aspnet_regsql? [复制]

    这个问题在这里已经有答案了 可能的重复 将 ASP NET 成员资格数据库迁移到 SQL Azure https stackoverflow com questions 10140774 migrating asp net membersh
  • 无法将字符串文字分配给装箱的 std::string 向量

    这是我的类型系统的简化版本 include
  • 为什么空循环使用如此多的处理器时间?

    如果我的代码中有一个空的 while 循环 例如 while true 它将把处理器的使用率提高到大约 25 但是 如果我执行以下操作 while true Sleep 1 它只会使用大约1 那么这是为什么呢 更新 感谢所有精彩的回复 但我
  • 当用户更改 Windows 中的语言键盘布局时如何通知?

    I want to show a message to user when the user changes the language keyboard layout of Windows for example from EN to FR

随机推荐

  • 从https页面转到http页面时是否发送HTTP标头Referer?

    经过几次测试后 我开始得出这样的结论 当用户从 https 页面单击到 http 页面时 浏览器不会发送 Referer HTTP 标头 这是出于什么安全原因 是在标准中的某个地方定义的吗 The HTTP RFC http www w3
  • 大数字的 NumberFormatter 问题

    我尝试使用此代码将字符串转换为数字 反之亦然 此代码必须打印相同的输出 但其输出不正确 谁能帮我 let formatter NumberFormatter NumberFormatter formatter locale Locale i
  • 如何在十亿像素位图上实现平移/缩放?

    在我的项目中 我使用来自高分辨率扫描仪的 未压缩的 16 位灰度 十亿像素图像来进行测量 由于这些位图无法加载到内存中 主要是由于内存碎片 我正在使用图块 以及光盘上的图块 TIFF 看StackOverflow 主题 https stac
  • ASP.NET MVC 2 并列为隐藏值?

    Hi 我有一个包含列表的 View 类 该列表解释了用户已上传的可用文件 使用 html 助手呈现 为了在提交时维护此数据 我在视图中添加了以下内容 我希望 mode ModelView Files 列表将返回到提交操作 但事实并非如此 是
  • 在浏览器中模拟linux终端

    我读过 Fabrice Bellard 在浏览器中模拟 Linux 的内容 Fabrice Bellard 的 Javascript Linux 模拟器如何工作 https stackoverflow com questions 60304
  • 如何编写Python表达式来过滤掉某些字符串

    有一个由多个数字组成的字符串 例如 12 03 5 897 7 10 74 0 103 12 05 6 4 1 8 98 我想用Python正则表达式仅输出那些带有 ONLY 的数字single dot 例如 12 03 and 5 897
  • 三字母组在 C++ 中仍然有效吗?

    我们都知道历史好奇心 https stackoverflow com a 1234618 560648那是二合字母和三合字母 http en wikipedia org wiki Digraphs and trigraphs 但随着近年来
  • 通过C#检索CRM中所有帐户的列表?

    我正在尝试从 CRM 2011 检索所有帐户记录 以便我可以使用 ForEach 循环循环浏览它们并填充下拉列表 我正在读这篇文章 检索实体列表 https stackoverflow com questions 7409091 retri
  • ARM TrustZone 的安全/正常世界与操作系统的内核/用户模式或 x86 的 Ring0/1/2/3?

    我读了这样的文档TrustZone 安全白皮书 http infocenter arm com help topic com arm doc prd29 genc 009492c PRD29 GENC 009492C trustzone s
  • 加密数据作为字符串

    我对加密和 C 语言很陌生 所以这可能是一个明显的问题 但我找不到解决问题的方法 我正在 C 上制作一个应用程序 并在 Linux 中使用 openssl 进行加密 我从这个 url 获得了一个 C 代码示例 该代码允许使用 SHA 加密和
  • 如何使用 dockerfile 在 aws sagemaker 中运行 python 文件

    我有一个 python 代码和一个经过预先训练的模型 并且有一个 model pkl 文件与我在代码所在的同一目录中 现在我必须运行它或将其部署到 aws sagemaker 但没有得到任何解决方案由于aws sagemaker仅支持两个命
  • Html5 拖放到 svg 元素上

    我正在尝试遵循 html5 拖放教程here http www html5rocks com tutorials dnd basics 我无法得到dragstart要注册的事件rect元素 如果我将事件从draggable to mouse
  • Java进程内存使用量不断增加

    前提条件 具有 16 GB RAM 的电脑 Ubuntu 16 10 x64 上安装了 JDK 1 8 x 一个基于 Spring 的标准 Web 应用程序 部署在 Tomcat 8 5 x 上 Tomcat 配置了以下参数 CATALIN
  • Python/Django 时间戳,包括毫秒

    我需要按以下格式打印 并传递给外部 API 当前日期时间 DD MM YYYY HH MM SS SSS 最后 3 个SSS表示毫秒 我知道如何使用 Python 打印当前的日期时间 最多微秒 strftime http docs pyth
  • 检查 CalledProcessError 的输出

    我正在使用 python 子进程模块中的 subprocess check output 来执行 ping 命令 我是这样做的 output subprocess check output ping c 2 W 2 1 1 1 1 它引发
  • 如何正确配置 NSFetchedResultsController

    我将 NSFetchedResultsController 放入我的代码中 这样我就可以对表视图数据进行很好的自动分段 所以我正在运行测试以确保一切正常 我的持久存储中有一个 Book 实体 我将首先以旧方式执行获取 然后尝试使用 NSFe
  • Django Admin:根据先前的字段值填充字段

    我在 django admin 中有一个模型如下 ChoiceA on false on false on true on true ChoiceB always always never never id models CharField
  • SAFESEH:NO 选项的实际作用

    我正在尝试使用boost asio spawn功能就像在example http www boost org doc libs 1 55 0 doc html boost asio example cpp03 spawn echo serv
  • 使用 Javascript 向用户发送 HTTP 附件(打开浏览器的“另存为...”对话框)

    我是网络开发的新手 所以如果这个问题很菜鸟 我深表歉意 我想在 Javascript 中请求时向用户提供服务器硬盘上的文件 即发送 HTTP 附件以触发浏览器的 另存为 对话框 用户单击页面上的按钮 服务器根据他 她的一些帐户设置 和其他参
  • 在 Unity 中查找一组 3D 点的定向边界框

    我有一组 3D 点 或者实际上是小球体 我需要使用 Unity 3D 将它们包围在尽可能小的 3D 框内 在封闭框只能移动和缩放的情况下 解决方案非常简单 您只需迭代所有点并封装每个点即可 但我还需要找到盒子的最佳方向 因此 为了用 ASC