具有给出三角形网格的连通分量的函数的奇怪错误
Weird bug with a function that gives the connected component of a triangular mesh
我正在尝试在 C++
中编写一个函数,该函数为我提供了三角形网格的连通分量。
我有一个自定义的 class,它可以对 3D 三角形网格进行建模。
我的目标是获得一个 std::vector<Mesh2d>
,每个组件都包含我的网格的一个连接组件。
class Mesh2d{
std::vector<R3>* node_ptr;
std::vector<Elt2d> elt;
public:
Mesh2d(){};
Mesh2d(std::vector<R3>& node){}
void Load(const string& filename){}
void PushBack(const Elt2d& e){}
std::vector<Elt2d>::iterator begin(){}
std::vector<Elt2d>::iterator end(){}
std::vector<int> Num(const int& j) const {}
void Plot(string filename) const {}
const Elt2d& operator[](const int& j) const {}
std::vector<Elt2d> const GetElt() const {}
void GetBoundary(Mesh& mesh){}
friend std::vector<Elt2d> adj(Elt2d e, Mesh2d mesh){}
friend int find_index(Elt2d e,Mesh2d mesh){}
friend void DFS(int j , std::vector<bool> visited, Mesh2d boundary, std::vector<Mesh2d> ConnectedComponents, int n){
visited[j] = true;
std::cout<<"visited = " << visited << std::endl;
ConnectedComponents[n].PushBack(boundary[j]);
Elt2d e = boundary[j];
std::vector<Elt2d> neighbor = adj(e,boundary);
for(int i = 0; i<neighbor.size(); ++i){
// std::cout<<"i = " << i << std::endl;
int p = find_index(neighbor[i], boundary);
if(visited[p] == false){
DFS(p, visited, boundary, ConnectedComponents, n);
}
}
}
std::vector<Mesh2d> Boundary(Mesh mesh){
Mesh2d boundary;
boundary.GetBoundary(mesh);
std::vector<Mesh2d> ConnectedComponents;
std::vector<bool> visited(boundary.NbElt(),false);
std::vector<bool> True(boundary.NbElt(),true);
int k = 0;
for(int j = 0; j<boundary.NbElt(); ++j){
ConnectedComponents.resize(k+1);
std::cout<<"j =" << j << std::endl;
Elt2d e = boundary[j];
if(visited[j]==false){
DFS(j, visited, boundary, ConnectedComponents,k);
ConnectedComponents[k].PushBack(boundary[j]);
std::cout<< "NbCC = " << ConnectedComponents.size() << std::endl;
}
++k;
std::cout<<"k = " << k << std::endl;
}
return ConnectedComponents;
}
};
其中 R3
和 Elt2d
是自定义的 class,表示 3D 向量和三角形。
我的问题是两个函数 DFS
和 Boundary
,我正在使用深度优先搜索算法来探索我的网格(以三角形作为节点)。但是我遇到了一个奇怪的错误,我的向量 visited
将其某些值更改为 false
。如果我为一个小网格打印我的 visited
矢量,我得到这个:
visited = 1 1 1 1 1 1 1 1 1 1 1 1
visited = 1 1 1 1 0 1 1 1 1 1 1 1
visited = 1 1 1 1 1 1 1 1 1 1 1 1
visited = 1 1 1 1 0 0 1 1 1 1 0 1
visited = 1 1 1 1 1 0 1 1 1 1 0 1
visited = 1 1 1 1 1 1 1 1 1 1 0 1
visited = 1 1 1 1 1 1 1 1 1 1 1 1
visited = 1 1 1 1 1 0 1 1 1 1 1 1
visited = 1 1 1 1 1 1 1 1 1 1 1 1
visited = 1 1 1 1 0 1 1 1 1 1 0 1
visited = 1 1 1 1 1 1 1 1 1 1 0 1
visited = 1 1 1 1 1 1 1 1 1 1 1 1
visited = 1 1 1 1 0 1 1 1 1 1 1 1
visited = 1 1 1 1 1 1 1 1 1 1 1 1
visited = 1 1 1 1 0 0 1 1 1 1 1 1
visited = 1 1 1 1 1 0 1 1 1 1 1 1
visited = 1 1 1 1 1 1 1 1 1 1 1 1
visited = 1 1 1 1 0 1 1 1 1 1 1 1
visited = 1 1 1 1 1 1 1 1 1 1 1 1
visited = 1 1 1 1 0 0 1 1 1 0 1 1
visited = 1 1 1 1 1 0 1 1 1 0 1 1
visited = 1 1 1 1 1 1 1 1 1 0 1 1
visited = 1 1 1 1 1 1 1 1 1 1 1 1
visited = 1 1 1 1 1 0 1 1 1 1 1 1
我完全不知道为什么会这样。
请记住,我是 C++
的初学者,我的代码的某些部分(或大部分)看起来很傻。
任何帮助将不胜感激
您正在按值传递 visited
:
void DFS(int j, std::vector<bool> visited, Mesh2d boundary, std::vector<Mesh2d> ConnectedComponents, int n)
这意味着每次调用 DFS
函数时都会复制此向量,并且不会更改原始向量的值。您观察到当您从函数中 return 时值“恢复”。
改为通过引用传递向量:
void DFS(int j, std::vector<bool> &visited, Mesh2d &boundary, std::vector<Mesh2d> &ConnectedComponents, int n)
修改其余代码,您永远不会通过引用传递“重”对象。那至少是低效的。
我正在尝试在 C++
中编写一个函数,该函数为我提供了三角形网格的连通分量。
我有一个自定义的 class,它可以对 3D 三角形网格进行建模。
我的目标是获得一个 std::vector<Mesh2d>
,每个组件都包含我的网格的一个连接组件。
class Mesh2d{
std::vector<R3>* node_ptr;
std::vector<Elt2d> elt;
public:
Mesh2d(){};
Mesh2d(std::vector<R3>& node){}
void Load(const string& filename){}
void PushBack(const Elt2d& e){}
std::vector<Elt2d>::iterator begin(){}
std::vector<Elt2d>::iterator end(){}
std::vector<int> Num(const int& j) const {}
void Plot(string filename) const {}
const Elt2d& operator[](const int& j) const {}
std::vector<Elt2d> const GetElt() const {}
void GetBoundary(Mesh& mesh){}
friend std::vector<Elt2d> adj(Elt2d e, Mesh2d mesh){}
friend int find_index(Elt2d e,Mesh2d mesh){}
friend void DFS(int j , std::vector<bool> visited, Mesh2d boundary, std::vector<Mesh2d> ConnectedComponents, int n){
visited[j] = true;
std::cout<<"visited = " << visited << std::endl;
ConnectedComponents[n].PushBack(boundary[j]);
Elt2d e = boundary[j];
std::vector<Elt2d> neighbor = adj(e,boundary);
for(int i = 0; i<neighbor.size(); ++i){
// std::cout<<"i = " << i << std::endl;
int p = find_index(neighbor[i], boundary);
if(visited[p] == false){
DFS(p, visited, boundary, ConnectedComponents, n);
}
}
}
std::vector<Mesh2d> Boundary(Mesh mesh){
Mesh2d boundary;
boundary.GetBoundary(mesh);
std::vector<Mesh2d> ConnectedComponents;
std::vector<bool> visited(boundary.NbElt(),false);
std::vector<bool> True(boundary.NbElt(),true);
int k = 0;
for(int j = 0; j<boundary.NbElt(); ++j){
ConnectedComponents.resize(k+1);
std::cout<<"j =" << j << std::endl;
Elt2d e = boundary[j];
if(visited[j]==false){
DFS(j, visited, boundary, ConnectedComponents,k);
ConnectedComponents[k].PushBack(boundary[j]);
std::cout<< "NbCC = " << ConnectedComponents.size() << std::endl;
}
++k;
std::cout<<"k = " << k << std::endl;
}
return ConnectedComponents;
}
};
其中 R3
和 Elt2d
是自定义的 class,表示 3D 向量和三角形。
我的问题是两个函数 DFS
和 Boundary
,我正在使用深度优先搜索算法来探索我的网格(以三角形作为节点)。但是我遇到了一个奇怪的错误,我的向量 visited
将其某些值更改为 false
。如果我为一个小网格打印我的 visited
矢量,我得到这个:
visited = 1 1 1 1 1 1 1 1 1 1 1 1
visited = 1 1 1 1 0 1 1 1 1 1 1 1
visited = 1 1 1 1 1 1 1 1 1 1 1 1
visited = 1 1 1 1 0 0 1 1 1 1 0 1
visited = 1 1 1 1 1 0 1 1 1 1 0 1
visited = 1 1 1 1 1 1 1 1 1 1 0 1
visited = 1 1 1 1 1 1 1 1 1 1 1 1
visited = 1 1 1 1 1 0 1 1 1 1 1 1
visited = 1 1 1 1 1 1 1 1 1 1 1 1
visited = 1 1 1 1 0 1 1 1 1 1 0 1
visited = 1 1 1 1 1 1 1 1 1 1 0 1
visited = 1 1 1 1 1 1 1 1 1 1 1 1
visited = 1 1 1 1 0 1 1 1 1 1 1 1
visited = 1 1 1 1 1 1 1 1 1 1 1 1
visited = 1 1 1 1 0 0 1 1 1 1 1 1
visited = 1 1 1 1 1 0 1 1 1 1 1 1
visited = 1 1 1 1 1 1 1 1 1 1 1 1
visited = 1 1 1 1 0 1 1 1 1 1 1 1
visited = 1 1 1 1 1 1 1 1 1 1 1 1
visited = 1 1 1 1 0 0 1 1 1 0 1 1
visited = 1 1 1 1 1 0 1 1 1 0 1 1
visited = 1 1 1 1 1 1 1 1 1 0 1 1
visited = 1 1 1 1 1 1 1 1 1 1 1 1
visited = 1 1 1 1 1 0 1 1 1 1 1 1
我完全不知道为什么会这样。
请记住,我是 C++
的初学者,我的代码的某些部分(或大部分)看起来很傻。
任何帮助将不胜感激
您正在按值传递 visited
:
void DFS(int j, std::vector<bool> visited, Mesh2d boundary, std::vector<Mesh2d> ConnectedComponents, int n)
这意味着每次调用 DFS
函数时都会复制此向量,并且不会更改原始向量的值。您观察到当您从函数中 return 时值“恢复”。
改为通过引用传递向量:
void DFS(int j, std::vector<bool> &visited, Mesh2d &boundary, std::vector<Mesh2d> &ConnectedComponents, int n)
修改其余代码,您永远不会通过引用传递“重”对象。那至少是低效的。