在3D空间中表示节点的最佳数据结构是什么?

时间:2009-02-13 16:26:05

标签: c++ data-structures stl map

...感谢阅读...

我还在学习绳索所以请原谅...... ;-)

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

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)完成查找,则映射是完美的容器。 有没有人建议如何解决这个特殊问题?

非常感谢! ASVP。

6 个答案:

答案 0 :(得分:6)

与任何“我应该用什么来表示这种结构”的问题一样,它确实依赖于你想如何与它互动

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

对于要保持要渲染的对象的东西,一个公共结构是Binary space Partitioning Tree,它允许有效地剔除绝对不被其他人看到或遮挡的对象。

编辑; 我错过了你通过浮点索引。这通常是一个坏主意(因为大多数标准映射中所需的准确性将导致与浮点行为的不稳定性相关的问题)。除非你真的想要这种行为

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

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

答案 1 :(得分:1)

您是否看过可用的几何库,我不是这个领域的专家,最近在boost邮件列表的预览期间听说过GTL

答案 2 :(得分:1)

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

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

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

答案 3 :(得分:0)

你究竟想做什么?

如果你有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 :(得分:0)

地图&lt;&gt;不行。 C ++关联容器在密钥相等的基础上工作,并且比较浮点数的相等性根本不起作用。

听起来你需要找到一个节点,给定x和y。最好的方法取决于你想要完成的任务。您是在尝试找到最近的节点,给定坐标,还是要计算非常靠近节点的坐标,然后需要找到节点?

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

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

如果你需要找到最近的节点,那就有点复杂了。我对此知之甚少,但是有几何算法的资源。

答案 5 :(得分:0)

杰瑞科击中了头上的钉子。 我使用两个参数来生成3D网格。这两个参数是圆柱坐标。一个是角度,第二个是沿轴的z。半径是一个常数,就像他的球体例子一样。我可以创建一个网格,但我需要更新它,执行更新的函数不会将id作为输入参数。 它通过使用那些参数p和r来获取“原始位置”。