如何让freeBoundary尊重初始三角剖分顶点顺序。 (2017A +)

时间:2017-11-29 18:29:16

标签: matlab computational-geometry triangulation surface delaunay

这可能是一个x,y问题,所以这就是我所处的情况。我创建一个球体,使用定义的方法生成x,y,z点here 。但是对于我的项目,我需要能够生成半球并限制方位角和仰角,并且仍然具有由N定义的均匀点生成(在给定球面区域上生成的总点数)。我已经发现了如何做到这一点,但我也需要连接(大概是每个x y z的"邻居"或者az,el,r = 1的位置)。

Matlab提供了一个名为delaunayTriangulation的东西,它不会给我实际的表面连接,而是四面体连接。我找到了一种从delaunayTriangulation函数返回的三角测量对象中获取曲面的方法,该函数称为freeBoundary,它以[FBtri, FBpoints]的形式返回两个东西。 FBtri是一个n×3的整数矩阵,其中每一行包含一组三个整数,它们对应FBpoints内的行(从而创建一个三角形)。 FBpoints是一个n x 3矩阵,其中每一行对应于曲面上一个点的x,y和z坐标。

freeBoundary的问题在于,我不仅仅是半球表面上的任何点的三角形,只是在我的方位角高程范围内的那些点。例如,如果我将球体顶部的高程限制为不高于pi/4,那么球体顶部应该有一个大洞。以下是我所做的一些视觉示例。

有坏点的球体

enter image description here

带有移除点的球体

enter image description here

To"解决"这个问题我有一系列令人费解的步骤来产生"坏点"它们附加到用于生成初始delaunay三角剖分的点,然后在freeBoundary的输出中的连接列表中搜索以删除它们。这个 可以 通过简单地删除某个索引之后存在的所有连接来完成(因为我附加了"坏点"在我实际需要的之后)然而,令我惊恐的是freeBoundary实际上并没有保持点的顺序与来自三角测量对象的输入相同(并且喜欢加扰它,但仅限于我已经添加的坏点)所以我无法轻松删除无效连接,并且连接中的索引实际上与我原始的真实点集不相符1:1。以下是订购问题的示例

实际订单

enter image description here

破坏的订单

enter image description here

如果我不能强迫freeBoundary变得更好,那么我将不得不自己重新排序这些点,我不认为这是一个时间复杂的快速操作(尽管我可能是错的)。我相信为了手动执行此操作,我必须找到新的更新位置,并为连接列表中的每个连接手动更新它们,(O(triangleCount)*changedIdxCount)这对我来说并不好看,我和#39; m产生数千个点。

这是我到目前为止所做的一个例子:

goodPoints = generateSphere(...);
badPoints = generateBadSpherePoints(...);
points = vertcat(goodPoints, badPoints);
triObj = delaunayTriangulation(points(:,1), points(:,2), points(:,3));
[FBtri, FBpoints] = freeBoundary(triObj);
...
%remove the bad points and get only good connections!

1 个答案:

答案 0 :(得分:2)

如果您希望FBtri中的构面引用用于进行初始三角测量的点而不是FBpoints中的顶点,则您只需将FBpoints省略为FBtri = freeBoundary(triObj); 第二个输出:

FBtri

根据freeBoundary文档:

  

freeBoundary中的顶点ID引用特定矩阵,具体取决于您选择的语法:

     
      
  • 如果您使用一个输出参数调用FBtri,则TR.Points的元素是freeBoundary的行号。

  •   
  • 如果您使用两个输出参数调用FBtri,则FBpoints的元素的行号为if( isset( $_REQUEST['calculate'] )){ $type = $_REQUEST['type']; $lam = $_REQUEST['lam']; $add1 = (int)$_REQUEST['quantity']; if($type == "One Side Colour") { $res = ($add1 * .70) + ($add1 * ($lam == "One Side" ? .15 : 0)); } elseif($type == "Two Sides Colour") { $res = ($add1 * 1.4); }}

  •