图片缩略图

快速Alpha船体(Alpha形状在3d;parfor启用)

version 1.8.0.0 (3.23 KB) by 迪伦穆尔
计算一组点的外壳(外部和内部)。
3.0
2评级

5下载

更新2017年8月29日

视图版本历史

查看许可协议

另请参阅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中央文件交换。检索

意见及评分(8

扫罗拉米雷斯

haiqing张

你能举个例子吗?谢谢你!

迪伦穆尔

@Ben, zip文件已经更新了。

迪伦穆尔

嗨,本,很抱歉。在提交过程中一定发生了什么事。我已经重新提交了文件,但可能需要一天时间审批。如果你给我发邮件,我可以直接把zip文件发给你,或者你可以从文件交换网站上复制粘贴每个功能的代码。

本康

坏的zip文件…

迪伦穆尔

嗨Borc,

点云包含许多共面点和三角形;这将导致决定三角形是否在alpha表面表现糟糕。如果你在每个点上添加一个微小的抖动:

云=云+ (rand(size(Cloud))-0.5)*0.001;

然后一切都按照它应该的方式运行。如果你对解决这个棘手的案子有什么建议,我很乐意听听。

最好的问候,
迪伦。

Borc

你好,

对于下面的数据,代码似乎不能很好地工作。请检查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半径,半径))
结束

帕特里克•Eschle

在盒子外面工作得很好,非常感谢。

我做了一个小演示,你们可以看一下。

函数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半径,半径))
结束

MATLAB版本兼容性
创建R2008b
与任何版本兼容
平台的兼容性
窗户 macOS Linux

社区寻宝

在MATLAB中心找到宝藏,并发现社区如何可以帮助你!

开始狩猎!