计算线是否与面相交

时间:2014-09-06 21:10:16

标签: java vector 3d line intersection

我正在写一个3D应用程序。我必须确定用户当前正在查看的面(并不总是轴对齐)。

我将每张脸的位置分为四点。 我把这条线作为矢量。

我抬头看到我可以计算脸部的法线以及脸部的等式。我也可以计算线的方程式。

如果我合并那些我能够计算交点(在平面上),然后查看该点是否在脸上。但是我如何在代码中解决这些方程?

我如何简单地计算线是否与面相交?

编辑: 如何使用java代码解决这些方程?

 Equations of Line
 x = point.x - dir.x * t
 y = point.y - dir.y * t
 z = point.z - dir.z * t

 Equation of Plane
 normal.x * (x - face[0].x) + normal.y * (y - face[0].y) + normal.z * (z - face[0].z) = 0

2 个答案:

答案 0 :(得分:4)

您可以先检查线是否与包含脸部的平面相交(这是一个非常简单的线性系统)。如果交叉点我存在,并且你的面部是ABCD,你可以在ABC中计算I的barycentric coordinates(alpha,beta)。如果α或β< 0意味着ABC不包含I),用BCD做同样的事情。

总结(伪代码):

// no intersection, or the line belongs to the plane. Treat both in the same way.
if (line is parallel to the plane) return false

I = intersection(line,plane(A,B,C))
(a,b) = barycentricCoordinates(i,triangle(A,B,C))

if (a >= 0 and b >= 0) return true
(c,d) = barycentricCoordinates(i,triangle(B,C,D))
return c >= 0 and d >= 0

我不知道它在性能方面是否是最佳的,但在数学上它是有效的。

编辑:您如何计算我?

要做到这一点,使用平面的笛卡尔表示(ABC)和线L =(U,P)更为舒适,其中U是引导向量(u,v,w)和P a点(x0,y0,z0)属于L.

  • 首先,找到(ABC)的法向量N =(a,b,c)。 (ABC)的等式则是(E0) : a.x + b.y + c.z + d = 0。通过在此等式中注入A的坐标来确定d。

  • L的等式为(E1) : (x,y,z) = (x0,y0,z0) + lambda.(u,v,w)

现在,如果U.N = 0,那么该线与平面平行,我们认为没有交叉点。否则,我们可以在(E0)中注入(E1)以确定lambda:

lambda = - (a.x0 + b.y0 + c.z0 + d) / (a.u + b.v + c.w)

在此之后,您可以使用(E1)中的lambda值计算点I的坐标。

答案 1 :(得分:0)

感谢所有答案。我现在解决了。如果有同样问题的人仍然需要方程式,我可以在这里发布:

/*
     * EQUATIONS OF LINE
     * x = point.x - dir.x * t
     * y = point.y - dir.y * t
     * z = point.z - dir.z * t
     * 
     * 
     * EQUATION OF PLANE
     * normal.x * (x - face[0].x) + normal.y * (y - face[0].y) + normal.z * (z - face[0].z) = 0
     * 
     * ax + by + cz = d
     * 
     * a = normal.x
     * b = normal.y
     * c = normal.z
     * d = (-face[0].x * normal.x - face[0].y * normal.y - face[0].z * normal.z) * -1
     * 
     * MERGE THEM
     * normal.x * x + normal.y * y + normal.z * z = (-face[0].x * normal.x - face[0].y * normal.y - face[0].z * normal.z) * -1
     * Einsetzen
     * normal.x * (point.x - dir.x * t) + normal.y * (point.y - dir.y * t) + normal.z * (point.z - dir.z * t) = (-face[0].x * normal.x - face[0].y * normal.y - face[0].z * normal.z) * -1
     * Ausmultiplizieren
     * (normal.x * point.x) - (normal.x * dir.x * t) + (normal.y * point.y) - (normal.y * dir.y * t) + (normal.z * point.z) - (normal.z * dir.z * t) = (-face[0].x * normal.x - face[0].y * normal.y - face[0].z * normal.z) * (-1)
     * 
     * Umformen
     * -(normal.x * point.x) + (normal.x * dir.x * t) - (normal.y * point.y) + (normal.y * dir.y * t) - (normal.z * point.z) + (normal.z * dir.z * t) = (-face[0].x * normal.x - face[0].y * normal.y - face[0].z * normal.z)
     * (normal.x * dir.x * t) + (normal.y * dir.y * t) + (normal.z * dir.z * t) = (-face[0].x * normal.x - face[0].y * normal.y - face[0].z * normal.z) + (normal.x * point.x) + (normal.y * point.y) + (normal.z * point.z)
     * t * ((normal.x * dir.x) + (normal.y * dir.y) + (normal.z * dir.z)) = (-face[0].x * normal.x - face[0].y * normal.y - face[0].z * normal.z) + (normal.x * point.x) + (normal.y * point.y) + (normal.z * point.z)
     * t = ((-face[0].x * normal.x - face[0].y * normal.y - face[0].z * normal.z) + (normal.x * point.x) + (normal.y * point.y) + (normal.z * point.z)) / ((normal.x * dir.x) + (normal.y * dir.y) + (normal.z * dir.z))
     * 
     */