我想表示多个三维矩形框的排列(可能在一个更大的盒子里......一个容器)。盒子的长度,宽度,高度和重量表示。
我现在的问题是,我如何有效地表示这些盒子的“位置”,以便我可以计算总体安排的一些属性:
我不需要有效地渲染,转换,旋转,显示......数据结构,我发现大多数解决方案都试图改进。
两种可能的方法:
我想到的第一种方法是包含所有方框的列表 和一个额外的给定位置(在x轴,y轴和z轴上) 3d空间。从这个基本方法,我可以计算所有属性 但是,要找到合适的位置是很困难的 一个新的盒子。我想我必须使用另一个表示法 找到合适的位置,然后将此表示转换为 被描述的那个。
另一个想法是将3d空间视为体素。放一个盒子 在空间内意味着分配代表的体素 空间盒子,这使得为盒子找到一个新的地方非常容易。 一旦建立了这个结构,就可以计算出这些属性 快速而简单,但在定义时我可能缺乏准确性 大体素。增加体素的数量会减慢体重 再次计算,需要更多的记忆。
我现在已经看了很长时间了,但是找不到我觉得合适的代表。
您是否有任何其他想法,或者您能指出我更好的解决方案,或者其中一种方法已经是一种好方法?
答案 0 :(得分:1)
在框内组织框,特别是如果你可以在整数空间中工作并将尺寸表示为体素,可以很好地适应八叉树。
https://en.wikipedia.org/wiki/Octree
虽然八叉树可以用作3D交互的空间划分方案 - 例如,为了快速找到最接近3D射线的大点云中的点,您可以使用八叉树作为起点用于组织数据。它不是最适合这个问题的,但它是一个很好的数据结构。
基本理念:
另见这个问题: Auto-balancing (or cheaply balanced) 3D datastructure
对于细分太多次的树,您可能很容易遇到内存问题。例如,一旦超过8 ^ 5个节点,您可能不喜欢有多少内存被咀嚼。传统使用八叉树的一个技巧是引入暂停条件,使得如果特定节点为空则不会被细分。
八叉树可能无法解决您的问题,但如果不是因为这个特殊问题,那么空间划分技术有一天会派上用场。
此外,对于八叉树,最基本的实现并未考虑对象可以跨越属于不同父节点的两个节点。为了在2D中表达这一点,想象两个正方形进一步细分为四个正方形:a,b,c,d和e,f,g,h:
a b e f
c d g h
虽然" d"和" g"彼此相邻,他们属于不同的父母方格,不知道"知道"他们是邻居。由于您的最小和最大坐标为" d"然而," g",它很简单,可以计算他们是否是邻居。
对于许多基本计算而言,您不需要将3D盒子表示为某种体素化的3D空间,而是用于衡量"坚固性" 3D数据网格是一种很好的方法。
如果记忆不是问题,那么你可以考虑一个类似下面的方案,假设你只需处理几十个盒子,并且(或许很奇怪)盒子可以重叠:
在遍历所有框及其尺寸之后,您将拥有一个3D空间,其中在每个体素中定义了存在/不存在,并且为每个框分配了唯一的ID(这可能会被证明是方便的)。
如果框不能重叠,因为它们代表刚性长方体或真正的纸板箱,那么您只需将每个体素的框索引指定为十进制值即可。
如果为了内存而定义整数空间但需要更高的精度,则可以使用单独的数据结构来跟踪盒子最外层体素的精度。因此,虽然对于某些处理,检查体素是否被占用(值> 0)可能就足够了,如果您需要精确地找到边缘,则可以:
分配完所有框后,您将遍历列表并使空体素更有意义。例如,可以为每个空体素分配指示到最近框的距离的值。例如,如果在空体素(x,y,z)处,如果任何方向上最近的框是10个体素距离,则可以使用负整数值-10(作为小数)。如果距离最近的盒子是10个体素,然后以那个空体素为中心,你可以打包另一个半宽= 9的盒子。
根据记忆力的限制和你的耐心,在每个空体素中,你可以计算到+ x,-x,+ y,-y,+ z和-z方向(也许是其他方向)到壁橱盒的距离)。
无论您的盒子是否与轴对齐,使用体素化3D方案都可以轻松计算"坚固性"或粗糙。一种简单的技术是想象总体积的每一侧都是深度图,或者是2D投影,其中每个像素"是盒子的距离。然后可以如下计算粗糙度:
您可以通过几种不同的方式计算粗糙度,具体取决于盒子是否完全填满空间。例如,让我们说有很多盒子填满空间,因为"看到"从XY侧,所有都在距离XY面10-20个体素的范围内。只需从表面的2D轮廓测量标准粗糙度,您就可以为3D表面开发几种粗糙度测量中的任何一种:
对于最后一个例子,想象两种情况:无论盒子占据什么空间,所有盒子都与封闭体积的XY面相距一距离D.这可以是0.0的粗糙度,因为距离没有变化,如果目标是(比方说)在框上放置大的平面物体,这是有用的。如果框之间的空间定义了粗糙度,"然后你可以执行如上所述的简单计算或近似某些物理特征:如果放在盒子上,布料会变形多少?
使用3D卷可以更容易地思考问题,并且(在我看来)将更容易调试。更复杂的方案也可以起作用。例如,每个框可以简单地是具有指向其他最接近的框的指针的数据结构,并且这些框可以布置在一些相当复杂的结构中。通过在单个超级体素内连接的空体素的替换的立方体区域,可以略微减小体素空间要求。"但这些技术都不像调试那么有趣。