【问题标题】:3d intersections of triangles algorithm - Displaying the topmost plane三角形的 3d 交点算法 - 显示最上面的平面
【发布时间】:2011-07-30 01:33:34
【问题描述】:

我正在尝试计算任意数量的平面的最顶部的交点,但没有任何乐趣!我正在使用 actionscript,但只需要找到我可以实现的算法。

问题:

  • 考虑 3 个垂直轴。
  • 用户为每个三角形/平面输入 3 个点,使三角形的点位于其中一个轴上。
  • 用户可以输入任意数量的三角形
  • 我需要找到这些三角形的最顶层并将其显示在屏幕上以及相交的坐标。

这里有一张图片来阐明我对 2 个三角形的意思:

但是,当我们允许超过 2 个三角形时,我会得到尴尬的相交线。

【问题讨论】:

  • 如何将所有点存储在八叉树中并对其进行排序?

标签: actionscript-3 algorithm collision-detection computational-geometry


【解决方案1】:

我对你的问题很感兴趣,所以我描述了算法并用 C++ 实现了它(我不知道 AS 和 C++ 一样好)。该算法的主要思想是在添加新三角形的同时迭代重新计算顶面。

三角形截断后,可以将其形状更改为具有自定义顶点编号的多边形。因此,每个三角形最初都转换为普通多边形。每个多边形实例包括其平面方程和一组多边形面。作为数据结构的每个面包括多边形的一个顶点和穿过该顶点的垂直边界平面方程和多边形顶点序列中的下一个顶点。 (因此,一组人脸的顺序很重要。)

让我们将顶面视为一个多边形集。在添加新多边形时,我们应该迭代地重新计算所有表面多边形的面。人脸重算算法包括以下步骤:

  1. 在多边形的边缘找到两个位于多边形截线的点。在移除其覆盖部分后,这些点应成为所考虑多边形的新顶点。这些点中的每一个都可以计算为 3 个平面的交集:考虑的多边形平面、新的多边形平面、考虑的多边形面之一。不应该考虑不在多边形边缘的点。
  2. 如果截取点少于两个,则其中一个多边形与另一个多边形完全重叠。因此我们应该确定上一个。让我们考虑当前多边形的任何点,而不是放置在多边形截取线上。我们可以获取它的 x 和 y 坐标,计算新多边形平面内的点并比较它们的 z 坐标。
  3. 如果有两个点,则应修改多边形面集。在点计算之后,我们还知道交叉面的索引。考虑索引范围内的点,可以确定要删除的面集部分。
  4. 从多边形中删除重叠的面,并将根据截点计算的面插入到多边形中。

不要在此页面上泛滥我已将代码放入pastebin

【讨论】:

    【解决方案2】:

    您正在三个垂直“轴”之间构建感兴趣的表面。该表面以底部为界。将其绑定在上面,使问题包含在一个三棱柱中。

    体积上方你的表面是一个convex hull由相交的平面(即:帽、三个边和三角形的交点)形成。有很多关于凸包的理论和代码。

    我不知道 ActionScript,但在互联网上快速搜索“凸壳相交平面”和此类术语让我找到了这段代码(旨在)解决您的问题:

    http://nauful.com/pages/convexhull.html

    希望这会有所帮助, 格伦

    【讨论】:

      【解决方案3】:

      可能效率不高,但这里有一个想法。
      您计算每两个单独的三角形之间的相交线。
      然后将三角形边添加到该集合中,并计算其中每两条线之间的交点。
      找出这些点中的哪些从顶部是不可见的,并将它们从集合中删除。这可以使用光线投射和寻找交点来完成,但可能有更有效的方法。
      您最终会得到一组点,它们是最顶层网格的顶点。

      【讨论】:

        【解决方案4】:

        您可以将其视为三角形B=[(0,0),(0,1),(1,0)] 上的高度字段。

        由于平面被定义为B 角上的高度,所以B 内点上的平面高度可以用重心坐标计算。给定:

        • 平面高度为(a,b,c),位于B 的拐角处
        • B 中用重心坐标(x,y,z) [x+y+z=1, x,y,z>=0]P

        P 上的平面高度为x*a + y*b + z*c

        B 中点 P=(x,y) 的自然重心坐标为 (x,y,1-x-y)

        有了这个,很容易计算两个平面的交线,(a1,b1,c1)(a2,b2,c2),在重心坐标。 只需在 2 个平面具有相同高度的地方进行均衡

        x*a1 + y*b1 + (1-x-y)*c1 = x*a2 + y*b2 + (1-x-y)*c2
        =>
        x*(a1-c1-(a2-c2)) + y*(b1-c1-(b2-c2)) + c1-c2 = 0
        

        对于0 <= x,y <= 1x+y <= 1,2 平面这是B 中2 平面相交线的方程。

        我认为有两种方法可用于创建结果高度场(最顶层):

        迭代添加新三角形

        为了支持它,它需要具有以下结构 将三角形B 划分为多边形。多边形是三角形的区域,其中一个平面最高。由于我们处理的是平面,多边形将是凸的,一个平面最多可以产生一个多边形。 添加新三角形并计算与现有高度场多边形的交点将产生 新多边形(B 的交叉线和边界)。 这个新的多边形被添加到高度字段中。如果现有多边形相交,则部分被删除。如果现有的多边形重叠,则多边形会被删除。

        路口前线传播

        1. 从一个拐角开始,取其上最高的平面(例如,具有 max(a_i) 的平面)。将前线设置到那个角落。
        2. 查找与起始平面相交的平面与最靠近前面的相交线。向前移动到这些交叉线。
        3. 取一个(任何)位于前线上的平面,并与最靠近前线的未处理平面相交。向前移动到这些交叉线。

        重复 3. 直到前线覆盖三角形B

        我更喜欢第二种算法。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-01-25
          • 2015-07-29
          • 2010-10-07
          • 1970-01-01
          • 2011-04-13
          • 1970-01-01
          相关资源
          最近更新 更多