【问题标题】:Recognize pattern in 3D environment识别 3D 环境中的图案
【发布时间】:2016-01-27 21:24:52
【问题描述】:

我目前正在开发第三人称建筑游戏(作为学士学位论文)。我需要识别构造模式,因为我可以将相应的结构标记为某个建筑物(以便玩家可以开始使用该建筑物)。

我有以下规则:

  • 3种类型的积木(全部基于cube)(未来还会有更多类型)
  • 任何块都可以在每个轴上放大到 k 倍 (k = 20)
  • 块可以按任意轴旋转(但保持在 3D 网格中)

问题定义: 2x2 网格中的 4 个基本尺寸 (1,1,1) 的立方体应等于 1 框大小 (2,2,1),因此所有可能的变体(主要是旋转不同)都可以被评估为有效的模式构造。

我希望我的图案将达到基本尺寸的 30x30x30 倍数。

例如,我想识别这样的结构:(当前手动放置在关卡中 大小为 21x21x22,由多个对象构成。

作为一个限制,我将从确切的点开始边界模式搜索(让我们说 控制台 用于该结构)。电流限制常数约为基础立方体的 50x50x50 倍数。 (根据此处的答案,限额可能会有所变化。)

我搜索了 20 多个小时,结果只是从 2D 图像中识别 3D 结构或在 2D 中识别精确结构的论文。

我的问题是随着 K( 每个 X,Y,Z) 的增长,结构的数量呈指数增长,这应该被视为正确的模式构造。

问题:我应该使用什么算法(+启发式)?

以下 3 幅图像包含结构的可视化,它们被视为图像 4 中图案的正确变体,因此应该找到并接受它们。

所有这些都具有相同的最终形状(并且在相同的位置具有相同的材料)。我只将问题简化为 2D 形状,但在 3D 空间中扩展是显而易见的。

感谢您的所有回答/cmets。

【问题讨论】:

  • 您不清楚究竟是什么导致给定的构建结构与给定的模板匹配。很明显,细分模板的一些构建块不应该导致不匹配。 似乎拉伸“穿过”任何特定平面(想象切割世界,然后将两半分开,然后在原始接触点之间“填充”物质)不应导致不匹配 - - 正确的?如果您的模板是 U 形的,并且一个尖端而不是另一个已被拉伸怎么办?如果这会导致不匹配,那么我为您提供了一个有效的解决方案。
  • 只是一个愚蠢的问题:您是否必须使用图像识别(根据您的任务描述)?如果不是,我会直接使用向量形式的结构(无论如何你都需要存储它们),这比 2D->3D 模式匹配更少的工作和更快/更精确......你只需实现选择,拖放,对齐为您的原语...

标签: c++ algorithm 3d pattern-matching unreal-engine4


【解决方案1】:

如果每个轴可以缩放的构建块都可以细分为更小的 1x1x1 构建块,并且如果以下条件充分描述了构建结构是否应该与给定模板匹配:

  • 任意细分模板构建块不应导致不匹配
  • 任意“挤出”任何轴对齐的平面(想象在某个轴对齐的平面中切穿世界,然后将两半拉开,而新物质不断填充最初接触的点之间的间隙)不应该导致不匹配
  • 任何其他差异都会导致不匹配

那么应该可以在 O(b + t^2) 时间内有效地识别模板结构的构建实例,其中 b 是构建结构的体素体积,t 是(通常非常小;见下文)模板的体素体积。基本思想是将任何构建的结构转换为规范形式,其中任何“挤压范围”都被压缩为单个体素长度。

原子化然后规范化

首先,将构建结构中的所有构建块分解为等效的 1x1x1 构建块形式。下一步,压缩拉伸范围,本质上与从排序列表中消除重复的算法相同,但在 3D 中:

  • 对于每个轴 d(X、Y、Z):
    • 设置 j = 1。
    • 对于 i 从 1 到轴 d 中的最大坐标:
      • 已构建结构的平面体素“切片”在轴 d 上的坐标 i 处(例如,如果 d 是 Y,那么所有 x 和 z 的体素集 (x, i, z))是否与co-ord i-1 的前一个“切片”?
        • 如果不是,则将坐标 i 处的切片复制到坐标 j 处的切片之上,然后递增 j。

这将生成所有相邻切片都不同的构建结构的规范版本;通常这个版本会小得多,因为所有“长”特征都被折叠到长度 1。这里 j 的作用是指向我们可以放置下一个不同切片的最早位置。由于 j

一开始就应该对每个模板结构应用相同的规范化过程作为预处理。现在,这两种规范形式(模板和构建结构)可以直接通过蛮力逐个体素比较进行比较(基本上类似于strstr(),但在长方体中寻找长方体而不是字符串中的字符串)。此时也应尝试任何应被视为有效转换的旋转或翻转。

功能和注意事项

给定模板

X.X
XXX

它会识别例如以下为匹配项,

X.X
X.X   XXX  XX
X.X   XXXXXXX
XXX   XXXXXXX

但不是例如

X..
X.X
X.X
XXX

但如果你想检测这种具有不同长度的 U 形结构,你只需要提供一个额外的模板:

X..
X.X
XXX

此模板将匹配所有具有不同长度腿的 U 形结构(但不匹配具有等长腿的 U 形结构!)。根据您考虑的旋转,您可能还需要镜像。


AABB 相交的结构将无法正确处理。这些可以在前面的步骤中很容易地分开。


有趣的是,该算法能够识别包含多个连接组件的结构。比如模板

X.X.X

将识别一行(或列,如果允许旋转)中的三个大小相等的长方体。

【讨论】:

  • 对不起,我的问题在解释上并不复杂。我认为这并不能完全解决我的问题。从示例中可以看出,可接受的结构具有相同的尺寸。我只在构建该结构的部分有所不同。因此,例如,在中心,如果您使用 4 个立方体 (1,1,1),或 2 个立方体 (1,1,1) 和一个长方体 (2,1,1),则无关紧要,或者2 个长方体 (2,1,1) 或 i 个长方体 (2,2,2)。它们只是相同模式的不同构造,应该被接受。 (现在,如果将其扩展到整个示例形状,它应该会更清晰)。
  • 如果这就是你所需要的,那么它被算法的“将构建结构和模板中的所有内容转换为 1x1x1 块”部分所涵盖(即,你不需要折叠的部分挤压区域)。
  • 我也想过,但怕是慢得要死,就算是用C++写的。
  • 由于您决定的任何算法都必须在每种情况下都有效,包括模板和构建结构实际上完全由单独的 1x1x1 块组成的情况,我看不到这种规范化如何改变最坏情况的时间复杂度。
【解决方案2】:

我会编写一个函数来检查 1x1x1 区域是否具有特定形状(全块、半块 + 旋转、边缘块 + 旋转),然后以这种方式定义和检查模式。

【讨论】:

    猜你喜欢
    • 2011-10-08
    • 1970-01-01
    • 1970-01-01
    • 2021-11-01
    • 1970-01-01
    • 2011-03-16
    • 2014-02-18
    • 1970-01-01
    相关资源
    最近更新 更多