如何找到在三角形上投影点的正确方法以在网格上画线?

时间:2019-05-02 15:23:09

标签: 3d geometry projection raycasting map-projections

我有网格和2个点- A B 。每个点都位于网格的某个三角形上。主要目标是-使用2个点在网格上绘制 correct 线。当点位于具有不同平面的三角形上时-画线时会遇到问题。

我做什么:

  

CurrentTriangle =点A所在的三角形。

     

CurrentTriangle!=带有B点的三角形:

     

将B投影( Bp )移到CurrentTriangle:将 B 移动   -CurrentTriangle.normal *到平面的距离。

     

找到三角形的出口点- ABp 与三角形侧面的交点(将3d坐标转换为2d并找到交点,然后使用重心坐标获得3d交点)。 / p>      

将结果位置移到位置 B ,以查找新的CurrentTriangle。

问题是将位置 B 正确投影到CurrentTriangle的平面上。实际结果:

Problem example

预期结果(红线): enter image description here

1 个答案:

答案 0 :(得分:2)

使用世界空间坐标(甚至更好的是3D笛卡尔坐标,其原点为相机中心,但无论3D坐标系是什么,都具有表示的所有数据)。假设您知道世界空间中A和B的笛卡尔坐标(基本上将它们的齐次坐标除以它们各自的第四分量,并摆脱第四分量,现在为1)。假设您也知道相机中心的笛卡尔坐标,则将该点称为O。

想法是将由点A,B,O确定的平面与每个三角形相交,从包含A的三角形开始到包含B的三角形结束。

  1. 首先,找到平面ABO的法线向量N,该向量是ABO的叉积。 向量OA和OB。

  2. 现在,从包含A的三角形开始。

    • 让三角形的顶点U,V和W再次用笛卡尔世界坐标表示。
    • 然后计算向量UV和UW的叉积向量M。
    • 之后,计算N和M的叉积,从而得出向量K。
    • 检查向量AB的K点积是否为正。如果不是,则将K乘以-1。
    • 从点A开始遵循矢量K,直到与三角形UVW的边缘相交。用P表示该点。
    • 作为这些步骤的结果,您选择了一个点P和一个三角形,该三角形与三角形UVW共享P所在的边。
  3. 重复以下过程:假设您在三角形UVW处,并且已确定点P的边缘之一(例如,请参见前面的步骤2)。

    • 取向量UV和UW的叉积向量M。
    • 取向量N和M的叉积向量K。
    • 从点P开始遵循向量K,直到您与三角形UVW的边相交(或者,如果您位于最后一个三角形中,则直到到达点B)。用P表示新的交点。
    • 点P位于三角形UVW的三个边缘之一上。取下一个三角形,该三角形与UVW共享P所在的边。将该新三角形称为UVW。
    • 继续进行第3步,直到到达B点所在的三角形UVW。

编辑1: (算法中几何构造的说明)您有垂直于平面N = OA x OB的向量OAB和向量{ {1}}垂直于平面M = UV x UW。然后,两个平面UVWL的交线OAB位于两个平面上。一方面,UVW位于平面L上并因此投影从点OAB到屏幕上作为一条线。另一方面,O位于三角形L的平面上。因此,线UVW垂直于向量LN。因此,向量MK = N x M的叉积向量N垂直于两个向量,因此平行于线M(即向量LK行对齐。因此,线L(位于三角形L的平面上)由点UVW和向量P定义。

编辑2: (可能是算法的简化)

同样,使用世界空间坐标(甚至更好的是,3D笛卡尔坐标以相机中心为原点,但无论3D坐标系是什么,所有数据都以其中表示)。假设您知道世界空间中A和B的笛卡尔坐标以及三角剖分顶点的所有世界坐标。假设您也知道相机中心的笛卡尔坐标,则将该点称为O。

想法是将由点A,B,O确定的平面与每个三角形相交,从包含A的三角形开始到包含B的三角形结束。

这是几何对齐。从包含A的三角形开始。让三角形的顶点U,V和W再次用笛卡尔世界坐标表示。想法是找到UVW的三个边缘中的哪一个在点P与平面OAB相交,从而AP与AB的点积AP.AB为正数。它基本上是3D线和3D平面的交点的公式。例如,此处的线由点V和W确定,平面为OAB。那么,对于平面OAB上的任何点X,平面的方程都是N.(X-A)= 0。这里 '。'是点积。线方程为X = V + t *(W-V)。因此,将线方程式插入平面方程式时,通过求解t可以找到交点: K 解决t很容易: N.(V + t*(W-V) - A) = 0
因此,OAB和UV之间的交点P为 t = ( N.(A-V) )/( N.(W-V) ) 为确保P在边缘上,即它在U和V之间,我们必须检查N.(W-V)/ = 0和0 <= t <=1。否则,我们移到另一个边缘。

  1. 首先,找到平面ABO的法线向量N,它是向量OA和OB的叉积P = V + ((N.(A-V))/( N.(W-V)))*(W-V)

  2. 从包含A的三角形开始。让该三角形具有分别以笛卡尔世界坐标表示的U,V和W顶点。

    • 计算点积N = OA x OB并检查其不等于零。如果是,请选择三角形的另一条边,然后从步骤2的开头重新开始;否则,请重新开始。
    • 计算N.(W-V)。如果t> 1或t <0,则选择UVW的另一个边缘,然后从步骤2的开头重新开始;
    • 计算t = ( N.(A-V) )/( N.(W-V) )
    • 执行以下检查:(i)计算叉积矢量OA x OP和OP x OB; (ii)计算其点积P = V + t*(W-V); (iii)检查(OA x OP).(OP x OB)。如果没有,请选择另一条边,然后从步骤2的开头重新开始;
    • 绘制将点A连接到点P的线段;
    • 采用与三角形UVW共享的三角形作为P所在的边。
    • 作为这些步骤的结果,您选择了一个点P和一个三角形,该三角形与三角形UVW共享P所在的边。
  3. 重复以下过程:假设您在三角形UVW处,并且已在其边之一上确定了点P,例如说VW(例如,参见前面的步骤2)。我们需要找到平面OAB相交的两条边UV或UW中的哪一条(应在其中一条相交)。首先说一下边缘UV:

    • 计算(OA x OP).(OP x OB) > 0并检查其不等于零。如果是,请选择另一个边沿UW,然后从步骤3的开头重新开始;否则,请重新开始。
    • 计算N.(V-U)。如果t> 1或t <0,则选择另一条边UW并从步骤3的开头重新开始;
    • 计算t = ( N.(A-U) )/( N.(V-U) )
    • 绘制将旧点连接到新点P的线段(在我们的示例中,第一个在边VW上,第二个在边UV上);
    • 采用与三角形UVW共享的三角形作为P所在的边。
    • 点P位于三角形UVW的三个边缘之一上。取下一个三角形,该三角形与UVW共享P所在的边。将该新三角形称为UVW。
    • 继续进行第3步,直到到达B点所在的三角形UVW。