c# - 如何找到射线和三角形的交点?
问题描述
我通过重心坐标找到交点坐标的三线性坐标。重心坐标是正确的(看似)。
private const double Epsilon = 0.000001d;
public static Vector3? GetPointIntersectionRayAndTriangle(Vector3 rayOrigin, Vector3 rayDirection, Vector3 vert0, Vector3 vert1, Vector3 vert2)
{
Vector3 edge1 = new Vector3();
Vector3 edge2 = new Vector3();
Vector3 tvec = new Vector3();
Vector3 pvec = new Vector3();
Vector3 qvec = new Vector3();
double det, invDet;
edge1 = vert1 - vert0;
edge2 = vert2 - vert0;
pvec = Cross(rayDirection, edge2);
det = Dot(edge1, pvec);
if (det > -Epsilon && det < Epsilon)
{
return null;
}
invDet = 1d / det;
tvec = rayOrigin - vert0;
double t, u, v;
u = Dot(tvec, pvec) * invDet;
if (u < 0 || u > 1)
{
return null;
}
qvec = Cross(tvec, edge1);
v = Dot(rayDirection, qvec) * invDet;
if (v < 0 || u + v > 1)
{
return null;
}
t = Dot(edge2, qvec) * invDet;
return GetTrilinearCoordinates(t, u, v, vert0, vert1, vert2);
}
private static double Dot(Vector3 v1, Vector3 v2)
{
return v1.X * v2.X + v1.Y * v2.Y + v1.Z * v2.Z;
}
private static Vector3 Cross(Vector3 v1, Vector3 v2)
{
Vector3 dest;
dest.X = v1.Y * v2.Z - v1.Z * v2.Y;
dest.Y = v1.Z * v2.X - v1.X * v2.Z;
dest.Z = v1.X * v2.Y - v1.Y * v2.X;
return dest;
}
private static Vector3 GetTrilinearCoordinates(double t, double u, double v, Vector3 vert0, Vector3 vert1, Vector3 vert2)
{
float a = (vert0 - vert1).Length();
float b = (vert1 - vert2).Length();
float c = (vert2 - vert0).Length();
return new Vector3((float)t / a, (float)u / b, (float)v / c);
}
- rayOrigin - 光线的起点。
- vert0, vert1, vert2 - 三角形的坐标。
我使用这个单元测试来检查:
[TestMethod]
public void GetPointIntersectionRayAndTriangleCheckOnResult()
{
Vector3? vector1 = ComputationsInThreeDimensionalSpace.GetPointIntersectionRayAndTriangle(
new Vector3(1, 1, 2),
new Vector3(0, 0, -4),
new Vector3(0, 0, 0),
new Vector3(4, -1, 0),
new Vector3(0, 5, 0));
if (!vector1.HasValue)
{
Assert.Fail();
}
Assert.AreEqual(new Vector3(1, 1, 0), vector1.Value);
}
还有其他方法可以找到射线与三角形的交点吗?最好没有重心坐标。
解决方案
t
不是重心坐标,而是原点到交点的距离,所以不应该传给GetTrilinearCoordinates
. 相反,您应该通过1 - u - v
,因为 Moller-Trumbore 返回归一化的重心坐标。
推荐阅读
- docker - 在 docker 容器中找不到包 ipfs、peer 和 shim 包
- babeljs - CLI 中的 @babel/runtime / @babel/plugin-transform-runtime 是否需要是依赖项(即不是 devDependencies)?
- mysql - Wordpress / MySQL - 如何修复“'user_registered'的默认值无效”
- heroku - Heroku 和 Dynadot DNS
- java - 如何使用 JDBC 访问 Tomcat 中的 SQLite 数据库?抛出 UnsatisfiedLinkError
- python - Python3中的排序字典
- javascript - 异步函数返回 Promises 而不是解析值
- python - 替换python列表中的引号
- javascript - TypeORM 连接失败,没有任何错误信息
- laravel - Laravel - 连接被拒绝(选择,插入)