我有一个3D模型,代表如下:
class Vertex
{
double x, y, z;
}
class Edge
{
Vertex *v1, *v2; // no particular order
Face *f1, *f2; // no particular order. f2 may be null.
}
class Face
{
List<Vertex*> vertices; // clockwise order
List<Edge*> edges; // clockwise order
}
class Model
{
List<Face*> faces;
List<Vertex*> vertices;
List<Edge*> edges;
}
当然,这可以转化为最方便的表达方式。
我想将这个模型拆分成几个断开的部分,沿着连接边的多个循环,然后创建新的面来封顶。一个循环的示例:
新面孔应该处于相同的位置,并且与它们与其他面孔的连接相同,但是对于这个例子,我将它们分开了。我怎么能这样做?
在其他断开的部分之间是否共享顶点并不重要。
由于每个边都恰好连接两个面,我尝试将每个边分别分成两个副本(每个面一个)。这确实根据需要分离了模型,但后来我找不到正确添加新面孔的方法。
这个问题是标记图形算法,因为这个问题似乎与图论有某种联系。
答案 0 :(得分:2)
class Edge
应该指向Face
和Vertex
而不是值。set
中使用某种List
代替class Model
。这有助于查找和删除内容,并确保没有重复项。pair<Model*, Model*> split_model( const Model* mx, const List<Edge*>& loop );
ma
和mb
。将loop
的边缘添加到每个边缘。loop
中挑选一条边。让我们调用附加到它的两个面fa
和fb
。 fa
添加到模型ma
。从fa
开始,按照fa
附加的所有边以及附加到这些边的所有边进行完整的图搜索,依此类推。必须遵循遇到的所有面和边并将其添加到模型ma
。如果遇到已经属于ma
的面孔或边缘,则不要遵循它们。特别是当遇到属于loop
的边缘时会发生这种情况,因此您永远不会越过边界。这样,您可以在一侧完整搜索所有边和面,最终得到一个完整的模型ma
。最后,添加一个代表切割的面。这里可以忽略顶点,但当然最后你可能想要添加属于你添加的面的所有顶点。fb
开始重复此步骤,以创建代表另一部分的模型mb
。