我正在写一个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
答案 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))
*
*/