在体素空间上的正则表达式

时间:2011-09-21 20:22:59

标签: regex 3d pattern-matching voxel

有没有办法在3d体素网格中松散地描述一个对象(例如通过模式匹配有限自动机),就像我们可以用regexp松散地描述一维字符串中的模式一样?

假设我要描述一个“A”型体素的长方体,其下面由高度为3和宽度为5的“B”或“C”型体素组成,并将此描述与体素场匹配以找到模式的示例。我可以搜索精确的模型(类似Boyer-Moore-in-3D)但我需要为某些对象指定可变尺寸(如上述长方体的可变长度)。

2 个答案:

答案 0 :(得分:4)

正则表达式是表达有限(且仍然无限)语言集的语法的紧凑方式。使用正则表达式,您不需要告诉在哪里查找下一个符号,因为已知您正在处理字符串并迭代其字符,将它们作为语言的符号...但是在3D中你需要告诉他们要走的路。

您可以将其视为3D图灵机,即图灵机具有内部状态,可以读取3D"磁带"中的符号,因为我们只是验证让我们忽略写入磁带。然后,这个图灵机将走3D"磁带"也就是3D体素网格和读取体素作为符号,在读取每个符号后,图灵机的内部状态将根据某些定律改变。一旦执行结束,机器的最终状态就会告诉您它是否匹配。现在,Von Newman架构中的这些定律是对磁带数据作为指令的解释,但我们需要一种哈佛架构,即指令与数据分离。现在你想要的是一种描述图灵机的指令的方法。 [你可以把它想象成Logo的龟,但是在3D中。)

遵循正则表达式的精神,我们更喜欢一种类似于实际结构的语言。如果我们以文本为基础,它将是一种描述性语言(因为必要的语言并不比你最喜欢的图灵完整语言更好),它必须说(例如英语):

There is a voxel type A and then moving (x1, y1, z1) from that there is a voxel of type B or C and then moving (x2, y2, z3) from that there is a voxel type D

这描述了图灵机正在寻找什么,使用回溯算法测试它将按预期工作的所有潜在匹配。

请注意,我不知道体素的可能值集。也就是说,我不知道字母表。所以我只是说类型A,类型B,类型C和类型D作为例子,其中一个可能是没有体素的表示,其他可能是颜色或你正在使用的任何东西。根据需要可以存在多种类型的体素。如果体素的类型很复杂,则必须在那里插入它的描述。

我一直在考虑实际使用这种语言,而且很快出现的一个问题就是旋转,我必须确定在X轴上输入A的三个体素被认为是A型的三个体素相同Z轴,更好的是允许用语言来描述。

现在,如果体素是节点,则描述路径非常相似,我已经完成了一种语言来描述作为私有项目的一部分的2D路径(将它们存储在数据库中,如图...) ,它非常简单,它为每个方向保留一个字符,并使用一个数字作为步骤,例如:" 2d5l1u"。对3D做同样的事情并添加分组和匹配的方法就行了。为了解决旋转问题,有必要扩展方向以允许分离来表示匹配的替代配置。关于它如何工作的一些例子(我在EBNF或类似的情况下没有使用正式语法),这将变得更加清晰:

在X轴上匹配三个体素A的线:

(A1X){3}

在这里我插入匹配" A"通过运动" 1X",使用括号"("和")"用于分组和大括号" {"和"}"量化。这展开了:

A1XA1XA1X

最后一次" 1X"不会影响结果,所以它也可能是:

A1XA1XA

它清楚地说:匹配A型体素,在X上移动1并匹配A型体素,在X上移动1并匹配A型体素。

在X轴或Z轴上匹配三个体素A的线:

(A1X){3}|(A1Z){3}

替代:

(A1[X|Z]){3}

这里我使用括号" ["和"]"制作一个'类,它的位置告诉它是关于方向的,它只包括可能的轴,不要混淆:

[(A1X)|(A1Z)]{3}

这将匹配三个类型A的体素,但它们可能不在同一轴上,它们只能是连续的并且与它共享X轴或Z轴。

匹配一组3x3体素,在平面X,Y上输入a:

(((A1X){3})1Y){3}

这匹配X轴上的线和Y轴上的移动1以匹配另一个,依此类推。这意味着在对重复进行分组之后"([(A1X)] {16})"我们回溯到比赛开始执行以下动作的位置" 1Y"。展开它将是:

(A1XA1XA1X)1Y(A1XA1XA1X)1Y(A1XA1XA1X)1Y

查看剩下的括号,这些意味着回溯到比赛开始的地方。因此程序将检查组内部的内容以及何时完成它将返回到进入组之前的状态并继续执行。

匹配一对类型A的体素,由忽略类型的体素(在任何轴上)分隔:

A1(X|Y|Z).1(X|Y|Z)A1(X|Y|Z)

受正则表达式的影响,我们使用点"。"代表任何类型的体素。

我仍然没有决定使用负值是否比使用其他字母用于其他轴更好,我还认为数字1可以是可选的。正则表达式语法的其他部分,例如" +"," *"和"?"我必须更谨慎。执行" {"和"}"任何量化,直到证明没有歧义。

您可能已经注意到添加另一个移动方向或完全是另一个轴不会有问题,所以这个端口很好地说四个维度,如:

(A1[X|Y|Z|W]){3}

使用点"也可能是好的。"代表任何方向:

(A1.){3}

在未指定的情况下假设任何方向存在问题,并且该语言被定义为识别什么是方向并且基于表达式内部的位置将它们与体素类型区分开。所以"(A1B1){3}"不会映射到"(A1.B1。){3}"因为它需要" B"作为移动的方向,有可能通过末尾的尾随数字推断出含义,但我不知道它是否会是不明确的。

最后,这将匹配由A型体素组成的平面X,Y中的任何有效俄罗斯方块:

(A1[X|Y]){4}

如果我们假设世界只是二维的,并且我们允许忽略第一,那么它就会减少到:

(A.){4}

我对此很满意。然而,对于复杂的结构,您应该考虑更复杂,更紧凑和更易读的符号。

这就是我将正则表达式推广到两个,三个或更多维度的理论。

编辑:

如果体素的类型很复杂或引起歧义,我建议用尖括号编写#34;<"和">",例如,您可以使用原始体素数据的十六进制值:

(<0088FF>.){4}

答案 1 :(得分:2)

我对3D或体素知之甚少,但如果您可以使用标记将3D空间转换为一维表示,那么您可以在其上使用正则表达式。

简化示例:

对于蓝色脸,红脸,绿脸和其他3个我们不关心的立方体:

<object>
    <cube>
        <faces>
            <face orientation="up" color="blue">
                <border neighborOrient="west">
                <border neighborOrient="south">
            <face orientation="west" color="red">
            <face orientation="south" color="green">
            ...
        </faces>
    </cube>
</object>

您的正则表达式可以查找共享边框的同一个多维数据集中的面。正则表达式最适用于文本,因此您的第一步应该是找到一种方法来平整&#34;到文字。