三角形算法的三维交叉点 - 显示最顶层的平面

时间:2011-07-30 01:33:34

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

我正在尝试计算任意数量的飞机的最顶部交叉点,没有快乐!我正在使用actionscript,但只需要找到一个我可以实现的算法。

问题:

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

这是一张图片,用于阐明我对2个三角形的含义:

enter image description here

然而,当我们允许超过2个三角形时,我会遇到尴尬的交叉线。

4 个答案:

答案 0 :(得分:1)

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

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

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

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

答案 1 :(得分:1)

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

{ 有关凸壳的理论和代码很多。

我不知道ActionScript,但是对“凸面相交的平面船体”进行了快速的互联网搜索,而这些条款让我得到了这个(声称)解决问题的代码:

convex hull

希望这有帮助, 格伦

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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

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

  • (a,b,c)
  • 角上的高度为B的飞机
  • PB,重心坐标为(x,y,z) [x+y+z=1, x,y,z>=0]

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

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

通过这种方法,可以很容易地计算出重心坐标中2个平面(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. 从一个角落开始,然后乘坐最高的平面(例如,平面最大(a_i))。将前线设置到该角落。
  2. 找到与起始平面相交的平面与最靠近前方的交叉线。向前移动到这些交叉线。
  3. 取一条(任意)平面位于前线,与未处理平面交叉,交叉线最靠近前方。向前移动到这些交叉线。
  4. 重复3.直到前线覆盖三角形B

    我更喜欢第二种算法。