另请参阅http://www.dylan-muir.com/articles/alpha_hulls/
用法:[triHull, vbOutside, vbInside] = AlphaHull(mfPoints, fAlphaRadius, triDelaunay)
这个函数计算一组点的alpha形状/ alpha壳;船体的外部和内部都有空隙。该函数使用Matlab parfor构造,因此该代码将在运行Matlab并行计算工具箱的多个实例的机器上快速运行。
该算法基于qhull和点集的delaunay四面体化。它将返回一个船体三角测量,并忽略仅由一条线连接的点。
'mfPoints'是一个Nx3矩阵,其中每一行定义3空间中的一个点。AlphaHull将在'mfPoints'中找到集合点的船体。
“fAlphaRadius”是一个标量距离,它定义了外壳的参数。这个距离被解释为球体的半径,球体的边界会接触到“mfPoints”中的1到3个点。Delaunay四面体的三角形,球体可以适合而不与任何其他点相交,将形成alpha船体的一部分。
可选参数'triDelaunay'可以用来提供点集的Delaunary四面体,如果它是预先知道的。
'triHull'将是一个三角测量,包含三角形,要么落在阿尔法船体表面,或在点集内的阿尔法空洞(洞)的内表面。布尔向量'vbOutside'和'vbInside'定义了'triHull'中的哪些行定义了' outside '和' inside '船体。由AlphaHull返回的表面将是空间参数alpha的凸。
'triHull'将是一个Tx3矩阵,其中每一行['p1' 'p2' 'p3']定义了一个alpha表面上的三角形。索引'pn'指的是'mfPoints'中的行,因此定义了包含三个原始点的三角形。
*注意事项和改进空间*
标记“内”和“外”三角形的方法并不理想。它的工作原理是确定一个三角形的法线,在远离点云的其余部分的方向上,是否指向点集质心的方向。一种更好的技术可能是沿着表面进行迭代,在移动过程中始终如一地标记三角形。如果你在这方面有所改进,我很乐意听听。
迪伦穆尔(2021)。快速Alpha船体(Alpha形状在3d;parfor启用)(//www.tatmou.com/matlabcentral/fileexchange/32725-fast-alpha-hulls-alpha-shapes-in-3d-parfor-enabled), MATLAB中央文件交换。检索.
你能举个例子吗?谢谢你!
@Ben, zip文件已经更新了。
嗨,本,很抱歉。在提交过程中一定发生了什么事。我已经重新提交了文件,但可能需要一天时间审批。如果你给我发邮件,我可以直接把zip文件发给你,或者你可以从文件交换网站上复制粘贴每个功能的代码。
坏的zip文件…
嗨Borc,
点云包含许多共面点和三角形;这将导致决定三角形是否在alpha表面表现糟糕。如果你在每个点上添加一个微小的抖动:
云=云+ (rand(size(Cloud))-0.5)*0.001;
然后一切都按照它应该的方式运行。如果你对解决这个棘手的案子有什么建议,我很乐意听听。
最好的问候,
迪伦。
你好,
对于下面的数据,代码似乎不能很好地工作。请检查AlphaHull功能。
亲切的问候
%3D示例-环
[x, y, z] =球;
Ii = abs(z) < 0.4;
X = [X (ii), y (ii)、z (ii)];
云= [X;0.8 * X];
%循环遍历r的不同值
radiusVals = [0.01 0.1 0.5 1 2];
for radiusx = 1:length(radiusVals)
图(radiusIx);
clf;
半径= radiusVals (radiusIx);
流(% .2g \ n半径,半径);
抽搐
[triHull, vbOutside, vbInside] = AlphaHull(云,半径);
fprintf(' *在%中得到船体。1 f秒\ n”,toc);
plot3(云(:1)、云(:,2)、云(:,3),' b。');
抓住;
fprintf(' *为外表面找到%d个点\n',sum(vbOutside));
if (sum(vbOutside) > 0)
trisurf (triHull (vbOutside:)、云(:1)、云(:,2)、云(:,3),…
“FaceColor”、“青”、“FaceAlpha”,0.5)
结束
fprintf(' *为内表面找到%d个点\n',sum(vbInside));
如果(sum (vbInside) > 0)
trisurf (triHull (vbInside:)、云(:1)、云(:,2)、云(:,3),…
“FaceColor”、“绿色”、“FaceAlpha”,0.5)
结束
网格;
轴平等
标题(sprintf (= % .1g半径,半径))
结束
在盒子外面工作得很好,非常感谢。
我做了一个小演示,你们可以看一下。
函数alphaHull_demo
演示alpha船体函数
%
定义一个嘈杂环面
N = 500;
t = linspace (0, 1, N) * 2 *π;
云= (sin (t),因为(t)的(大小(t))) + (randn (-0.5 N, 3)) / 10;
%循环遍历r的不同值
radiusVals = [0.01 0.1 0.5 1 2];
for radiusx = 1:length(radiusVals)
图(radiusIx);
clf;
半径= radiusVals (radiusIx);
流(% .2g \ n半径,半径);
抽搐
[triHull, vbOutside, vbInside] = AlphaHull(云,半径);
fprintf(' *在%中得到船体。1 f秒\ n”,toc);
plot3(云(:1)、云(:,2)、云(:,3),' b。');
抓住;
fprintf(' *为外表面找到%d个点\n',sum(vbOutside));
if (sum(vbOutside) > 0)
trisurf (triHull (vbOutside:)、云(:1)、云(:,2)、云(:,3),…
“FaceColor”、“青”、“FaceAlpha”,0.5)
结束
fprintf(' *为内表面找到%d个点\n',sum(vbInside));
如果(sum (vbInside) > 0)
trisurf (triHull (vbInside:)、云(:1)、云(:,2)、云(:,3),…
“FaceColor”、“绿色”、“FaceAlpha”,0.5)
结束
网格;
轴平等
标题(sprintf (= % .1g半径,半径))
结束