c#点云到网格
c# Point Cloud to Mesh
是否可以从 X、Y、Z 点(非结构化点云)到三角形网格重建 2.5D 表面?是否有可用的库可以为我执行此操作,我可以将其与 C# 一起使用?我找不到任何具有此内置功能的开箱即用的开源软件。
第一个选项:
这是场景。我有一个 CNC,可以用来捕获位置数据。我将从特定轴扫描并以特定间隔进行测量。因此,例如,我在 X 轴上移动并每 0.5 毫米进行一次测量。我将每隔 0.5 毫米有一个 X、Y 和 Z 点。完成 X 轴扫描后,我会将 Y 移动 0.05 毫米,然后再次扫描 X 轴。似乎将其变成网格应该非常简单。一个点将始终与 8 个三角形相交,除了边缘为 4 并且连接点将是已知的。所有 X/Y 将每 0.5 毫米对齐一次。
首选:
可能需要一个密度估计算法,据我所知,如果没有像 MatLab 这样我不想使用的东西是不可能的。
如果我不必以一致的 X 轴间隔进行测量会更好。激光位移传感器和相关设备将使我能够以 50hz 的频率捕获点数据。我宁愿在扫描 X 的那个时间段内进行尽可能多的测量,但很可能 X 在前一个 Y 位置不会对齐。
在上述选项中,我仍然可以通过创建归一化算法来对齐 X 和 Y 坐标。
我几乎可以用 C# 编写任何代码,但我对 3D 术语知之甚少。因此,如果我使用了错误的措辞来描述我想要完成的事情,我提前道歉。
我知道这样的东西对业余 CNC 用户非常有用。创建网格后,我可以将结果保存到 STL,我已经弄清楚了那部分。
假设您使用 X,Y,Z 捕获了以下点:
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
你有一个顶点数组,上面的每个数字都是该数组的索引,生成一个索引数组(每个值都是顶点数组的索引,标识从 CNC 捕获的顶点探测 - 在你的网格中)
// first row of quads - values are indices into the vertex array
0,1,4
1,5,4
1,2,5
2,6,5
2,3,6
3,7,6
// second row...
4,5,8
5,9,8
5,6,9
6,10,9
6,7,10
7,11,10
// etc. ..
在这里识别模式,我们可以说:(对格式表示歉意,请注意这是伪代码。我在 phone 上写了这个,可能有很多错误。)
int cols = 4; // number of points in X
int rows = 4; // number of points in Y
std::vector<int> ti // triangle indices;
// speed things up a bit...
ti.reserve((cols + 1) * (rows + 1));
for(int j = 0; j < rows-1; ++j)
{
for(int i = 0; i < cols-1; ++i)
{
/*
i0--i1
| / |
|/ |
i2--i3
*/
int o = j * cols + i;
int i0 = o; // nw corner of local quad
int i1 = i0 + 1; // ne corner of local quad
int i2 = i0 + cols; // sw corner of local quad
int i3 = i2 + 1; // se corner of local quad
// upper-left triangle in this quad
ti.push_back(i0);
ti.push_back(i1);
ti.push_back(i2);
// lower-right triangle in this quad
ti.push_back(i1);
ti.push_back(i3);
ti.push_back(i2);
}
}
现在,ti
中的每个三元组表示单个三角形的索引。例如,ti
的第一部分将是
[0,1,4, 1,5,4, 1,2,5, 2,6,5...]
等
或者,google "height map mesh generate from grid"。
这假设您的探测数据按照 post 开头的 "matrix" 指示的模式排列 - 即,沿着 x 探测后,您快速返回另一侧,移动到下一个 X,然后再次探测,这样您就可以获得光栅图案。
几年前我为我的 DIY CNC 路由器做了类似的事情。这很简单。可能已经有软件可以做到这一点——如果没有我会感到惊讶——但算法非常基础。我是一名图形编码器,所以我自己构建了一个。 (我不能分享。)
此方法不要求样本以精确的规则间隔排列,但如果它们 接近,您将获得更好的结果(更接近采样对象)常规的。
是否可以从 X、Y、Z 点(非结构化点云)到三角形网格重建 2.5D 表面?是否有可用的库可以为我执行此操作,我可以将其与 C# 一起使用?我找不到任何具有此内置功能的开箱即用的开源软件。
第一个选项: 这是场景。我有一个 CNC,可以用来捕获位置数据。我将从特定轴扫描并以特定间隔进行测量。因此,例如,我在 X 轴上移动并每 0.5 毫米进行一次测量。我将每隔 0.5 毫米有一个 X、Y 和 Z 点。完成 X 轴扫描后,我会将 Y 移动 0.05 毫米,然后再次扫描 X 轴。似乎将其变成网格应该非常简单。一个点将始终与 8 个三角形相交,除了边缘为 4 并且连接点将是已知的。所有 X/Y 将每 0.5 毫米对齐一次。
首选: 可能需要一个密度估计算法,据我所知,如果没有像 MatLab 这样我不想使用的东西是不可能的。
如果我不必以一致的 X 轴间隔进行测量会更好。激光位移传感器和相关设备将使我能够以 50hz 的频率捕获点数据。我宁愿在扫描 X 的那个时间段内进行尽可能多的测量,但很可能 X 在前一个 Y 位置不会对齐。
在上述选项中,我仍然可以通过创建归一化算法来对齐 X 和 Y 坐标。
我几乎可以用 C# 编写任何代码,但我对 3D 术语知之甚少。因此,如果我使用了错误的措辞来描述我想要完成的事情,我提前道歉。
我知道这样的东西对业余 CNC 用户非常有用。创建网格后,我可以将结果保存到 STL,我已经弄清楚了那部分。
假设您使用 X,Y,Z 捕获了以下点:
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
你有一个顶点数组,上面的每个数字都是该数组的索引,生成一个索引数组(每个值都是顶点数组的索引,标识从 CNC 捕获的顶点探测 - 在你的网格中)
// first row of quads - values are indices into the vertex array
0,1,4
1,5,4
1,2,5
2,6,5
2,3,6
3,7,6
// second row...
4,5,8
5,9,8
5,6,9
6,10,9
6,7,10
7,11,10
// etc. ..
在这里识别模式,我们可以说:(对格式表示歉意,请注意这是伪代码。我在 phone 上写了这个,可能有很多错误。)
int cols = 4; // number of points in X
int rows = 4; // number of points in Y
std::vector<int> ti // triangle indices;
// speed things up a bit...
ti.reserve((cols + 1) * (rows + 1));
for(int j = 0; j < rows-1; ++j)
{
for(int i = 0; i < cols-1; ++i)
{
/*
i0--i1
| / |
|/ |
i2--i3
*/
int o = j * cols + i;
int i0 = o; // nw corner of local quad
int i1 = i0 + 1; // ne corner of local quad
int i2 = i0 + cols; // sw corner of local quad
int i3 = i2 + 1; // se corner of local quad
// upper-left triangle in this quad
ti.push_back(i0);
ti.push_back(i1);
ti.push_back(i2);
// lower-right triangle in this quad
ti.push_back(i1);
ti.push_back(i3);
ti.push_back(i2);
}
}
现在,ti
中的每个三元组表示单个三角形的索引。例如,ti
的第一部分将是
[0,1,4, 1,5,4, 1,2,5, 2,6,5...]
等
或者,google "height map mesh generate from grid"。
这假设您的探测数据按照 post 开头的 "matrix" 指示的模式排列 - 即,沿着 x 探测后,您快速返回另一侧,移动到下一个 X,然后再次探测,这样您就可以获得光栅图案。
几年前我为我的 DIY CNC 路由器做了类似的事情。这很简单。可能已经有软件可以做到这一点——如果没有我会感到惊讶——但算法非常基础。我是一名图形编码器,所以我自己构建了一个。 (我不能分享。)
此方法不要求样本以精确的规则间隔排列,但如果它们 接近,您将获得更好的结果(更接近采样对象)常规的。