我认为这可以通过将对象切片,移除不需要的部分,然后通过合并面将剩余的部分重新粘合在一起来相当容易地解决。
假设您将对象建模为完全链接的图
- 一个顶点列表,每个顶点都有一个边列表
- 边列表,每条边都引用两个顶点和两个面
- 面列表,每个面都有一个边列表
只要您小心维护和操作此图,它就会包含快速剪切和合并对象所需的所有信息。
您可以使用此答案中描述的算法来计算剪切产生的新面。
所以:您对算法的输入是切割平面列表和对象列表 - 最初只有一个。对于每个切割平面,将列表对象中的每个对象一分为二,然后将它们放回列表中。添加的两个面(每个新对象上一个)应保持对生成它们的切割平面的引用。对于被平面切成两半的面,请记住生成的两个新面应继承此参考(如果存在)。新对象应该记录它们位于平面的哪一侧(只是一个布尔值,意思是“保留”或“丢弃”)——这些记录也应该随着对象的进一步细分而保留。
完成所有切割后,您将获得一个对象列表,每个对象都有一个记录列表,详细说明它们位于切割平面的哪一侧。找到所有这些记录都“丢弃”的对象并将它们扔掉。
我们现在必须把这些物体粘在一起。
首先简单地合并对象图 - 只需将所有顶点、边和面列表组合到一个对象中。我们现在检查由同一切割平面创建的两个面:
- 如果两个面相同(即:它们共享同一组顶点),则可以删除两个面和所有关联的边。
- 如果一个面的顶点集大于另一个面,则删除较小的面和所有共享边。
您现在应该有一个合并的对象,但有一些无关的顶点。简单地遍历顶点并删除那些只有两条关联边的顶点。
这是切割如何工作的示例:
:
a---1-:---b
| : |
2 X : 3
| : |
| : |
c---4-:---d
:
:s
我们从一个对象开始(?表示未显示的某些边缘或面):
verts:
a:1,2,?
b:1,3,?
c:2,4,?
d:3,4,?
edges:
1:a,b X,?
2:a,c X,?
3:b,d X,?
4:c,d X,?
faces:
X:1,2,3,4
?:...
当我们用平面 s 切割时,我们最终得到两个对象:
a--1--e-7-b
| | |
2 X 5 Y 3
| 6 |
| | |
c--4--f-8-d
verts: verts:
a:1,2,? e:1,5,6,7
e:1,5,6,7 b:3,7,?
c:2,4,? d:3,8,?
f:4,5,6,8 f:4,5,6,8
edges: edges:
1:a,e X,? 3:b,d Y,?
2:a,c X,? 6:e,f Y,W
4:c,f X,? 7:e,b Y,?
5:e,f X,V 8:f,d Y,?
faces: faces:
X:1,2,3,4 Y:3,6,7,8
V:5,... W:6,...
?:... ?:...
我们添加了顶点 e 和 f、边 5 和 6,以及面 V 和 W。请注意,边 5 和 6 是不同的对象,它们共享相同的顶点,但在不同的面之间。
当我们将这两个对象重新合并在一起时,我们首先简单地合并两个对象图:
verts:
a:1,2,?
b:3,7,?
c:2,4,?
d:3,8,?
e:1,5,6,7
f:4,5,6,8
edges:
1:a,e X,?
2:a,c X,?
3:b,d Y,?
4:c,f X,?
5:e,f X,V
6:e,f Y,W
7:e,b Y,?
8:f,d Y,?
faces:
X:1,2,3,4
Y:3,6,7,8
V:5,...
W:6,...
?:...
我们可以看到面 V 和 W 是由相同的切割平面产生的并且具有相同的顶点集,因此可以将它们与关联的边一起删除。与一对重合边相关联的两个未移除的面被合并。
a--1--e-7-b
| |
2 X 3
| |
| |
c--4--f-8-d
verts:
a:1,2,?
b:3,7,?
c:2,4,?
d:3,8,?
e:1,7
f:4,8
edges:
1:a,e X,?
2:a,c X,?
3:b,d X,?
4:c,f X,?
7:e,b X,?
8:f,d X,?
faces:
X:1,2,3,4,7,8
?:...
然后我们可以删除只有两条关联边的顶点,并合并这些边:
verts:
a:1,2,?
b:1,3,?
c:2,4,?
d:3,8,?
edges:
1:a,e X,?
2:a,c X,?
3:b,d Y,?
4:c,d X,?
faces:
X:1,2,3,4
Y:3,6,7,8
?:...
合并这些对象怎么样?
a--1--e
| 5
2 X g-3-b
| 6 |
| 9 Y 7
c--4--f-8-d
verts: verts:
a:1,2,? g:3,5,6,?
e:1,5,? b:3,7,?
c:2,4,? d:7,8,?
f:4,6,8,9,? f:4,6,8,9,?
edges: edges:
1:a,e X,? 3:b,g Y,?
2:a,c X,? 9:f,g Y,W
4:c,f X,? 7:b,d Y,?
5:e,g X,V,? 8:f,d Y,?
6:f,g X,V
faces: faces:
X:1,2,4,5,6 Y:3,7,8,9
V:5,6,... W:9,...
?:... ?:...
我们合并:
verts:
a:1,2,?
b:3,7,?
e:1,5,?
c:2,4,?
d:7,8,?
f:4,6,8,9,?
g:3,5,6,9,?
edges:
1:a,e X,?
2:a,c X,?
3:b,g Y,?
4:c,f X,?
5:e,g X,V,?
6:f,g X,V
7:b,d Y,?
8:f,d Y,?
9:f,g Y,W
faces:
X:1,2,4,5,6
Y:3,6,7,8
V:5,6,...
W:9,...
?:...
并检查面 V 和 W,因为它们是由同一剖切面创建的。这次他们的顶点集是不同的。去掉小脸。在这两个面上,找到具有相同顶点的边并将它们删除:
a--1--e
| 5
2 X g-3-b
| |
| 7
c--4--f-8-d
verts:
a:1,2,?
b:3,7,?
e:1,5,?
c:2,4,?
d:7,8,?
f:4,8
g:3,5,?
edges:
1:a,e X,?
2:a,c X,?
3:b,g X,?
4:c,f X,?
5:e,g X,V,?
7:b,d X,?
8:f,d X,?
faces:
X:1,2,3,4,5,7,8
V:5,...
?:...
我们现在可以删除只有两条入射边的无用顶点:
a--1--e
| 5
2 X g-3-b
| |
| 7
c----4----d
verts:
a:1,2,?
b:3,7,?
e:1,5,?
c:2,4,?
d:4,7,?
g:3,5,?
edges:
1:a,e X,?
2:a,c X,?
3:b,g Y,?
4:c,d X,?
5:e,g X,?
7:b,d X,?
faces:
X:1,2,3,4,5,7
V:5,...
?:...
呸!希望这可以帮助...