【问题标题】:What is the best data structure for representing nodes in 3D space?在 3D 空间中表示节点的最佳数据结构是什么?
【发布时间】:2010-10-07 11:47:27
【问题描述】:

...感谢阅读...

我还在学习中,所以请原谅... ;-)

我正在编写一个在空间中网格化实体的函数。网格是通过使用“节点”类的对象完成的,每个节点由以下方式表示:

int id
double p
double r

最初我认为映射是可行的方法:使用映射我可以在“id”键和第二个键(指向节点对象的指针)之间建立关联。

类似这样的:

int nodeId;
Node *node;
std::map<int, Node *> NodeMap;

然后,当我创建节点时,我只需调用“new”运算符。例如,在 for 循环中,我执行以下操作:

node = new Node(i); // the node constructor sets the id to the value of i.

然后我将新节点添加到地图中:

NodeMap[i] = node;

但是....我意识到我需要在地图中进行查找,而不是通过第一个键(id)而是通过 p 和 r 参数(节点的坐标)。

换句话说,我需要在给定 p 和 r 值的情况下返回节点 id 的东西。 如果使用整数第一个键 (id) 完成查找,则地图是一个完美的容器。 有人对如何解决这个特定问题有建议吗?

非常感谢! 副总裁。

【问题讨论】:

  • p 和 r 代表什么 - 这不是 2D 空间,因为您只有 2 个坐标吗?

标签: c++ data-structures stl map


【解决方案1】:

与任何“我应该用什么来表示这个结构”问题一样,它确实取决于您希望如何与之交互

场景图在 3D 库中很常见,它们提供基于树的节点遍历,通常允许变换、交互和其他属性沿树向下级联。

对于保存要渲染的对象的通用结构是Binary space Partitioning Tree,它允许有效剔除绝对不可见或被其他对象遮挡的对象。

编辑; 我错过了您正在按浮点进行索引。这通常是个坏主意(因为大多数标准地图中要求的准确性会导致与浮点行为的不稳定性有关的问题)。除非你真的想要这种行为

在这种情况下,您需要有一些方法来处理它,例如:

  • 对您的域进行分块,以便您可以准确地指向其中的一小部分,并防止多个节点占用同一块空间。
  • 有一些方法来划分您的空间(可能需要自适应细分具有较高节点集中度的区域),以便在请求点 p,r 时,您会得到该区域中存在的一组(可能是空的)节点。

【讨论】:

    【解决方案2】:

    您是否查看过可用的几何库,我不是该领域的专家,最近在 boost 邮件列表的预览中听说了 GTL

    【讨论】:

    • 感谢您的建议。我会看看那个图书馆。
    【解决方案3】:

    你实际上想做什么?

    如果您有 2 个坐标表示 3d 位置,那么我假设它们是某个参数化函数的输入,该函数会产生 3 个顶点分量……如果是这种情况,那么节点实际上是做什么用的?在大多数情况下,这种参数化可用于直接生成网格。

    作为一个例子,考虑一个单位球体,它接受参数 u,v (0...2PI) 和 (0...PI) 并通过以下操作将它们转换为坐标:

    x = sin(u)*cos(v);
    y = sin(u)*sin(v);
    z = cos(u);
    

    这可用于通过在适当范围内改变 u 和 v 并合并任何重复的顶点来创建网格。例如取 u = 0, u = 0.1, v = 0 和 v = 0.1,您可以创建四个顶点 V(u,v),从而可以创建两个三角形。由于我假装这是一般情况而不是特殊情况,因此您必须执行诸如检查顶点是否重复并合并它们以及检查退化三角形并删除它们之类的操作。

    【讨论】:

      【解决方案4】:

      与查找问题无关,而是与您使用 new 创建的 Nodes 有关。如果地图拥有节点,就像您的情况一样,您可以简单地说:

      map <int, Node> mymap;     // map of Nodes, not pointers to Nodes
      ...
      myMap[i] = Node( whatever );
      

      这将大大简化您的内存管理。在 C++ 中,您应该尽可能避免使用 new 进行显式动态内存分配。

      【讨论】:

        【解决方案5】:

        地图不起作用。 C++ 关联容器在键相等的基础上工作,比较浮点数的相等性根本不起作用。

        听起来你需要找到一个节点,给定 x 和 y。最好的方法将取决于您要完成的工作。您是想在给定坐标的情况下找到最近的节点,还是要计算非常接近某个节点的坐标,然后您需要找到该节点?

        对于第二个,您可能会很好地对 x 或 y 坐标上的节点进行排序(我将假设 x),并进行二进制搜索以查找哪些节点的 x 坐标非常接近您的给定X。这通常会选择少量的节点,可以搜索到近似正确的 y。

        (当然,如果节点在某种可预测的网格中,您应该能够提供一些直接计算的方法,例如如果您有整数格点,则将 x 和 y 舍入到最接近的整数。)

        如果您需要找到最近的节点,那会有点复杂。我对此知之甚少,无法提供太大帮助,但有几何算法的资源。

        【讨论】:

          【解决方案6】:

          Jherico 一针见血。 我正在使用两个参数来生成 3D 网格。这两个参数是柱坐标。一个是角度,第二个是沿轴的 z。半径是一个常数,就像他的球体示例一样。我可以创建一个网格,但我需要更新它,并且执行更新的函数不会将 id 作为输入参数。 它通过使用这些参数 p 和 r 来获取“原始位置”。

          【讨论】:

          • 我 jericho 的回答是你想要的接受它然后删除这个答案(你可能希望整理你的问题以说明为什么他的回答对你来说是正确的)
          猜你喜欢
          • 1970-01-01
          • 2021-08-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-05-08
          相关资源
          最近更新 更多