gpt4 book ai didi

java - 光线追踪三角形

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:48:04 25 4
gpt4 key购买 nike

我正在用 Java 编写光线追踪器,并且我能够追踪有效的球体,但我相信我追踪三角形的方式有问题。

这是我理解的基本算法:

  1. 首先确定射线是否与三角形所在的平面相交。
  2. 剪切所有点,使它们与三角形位于同一平面上(例如,xy 平面)。
  3. 根据您在沿新平面的任意方向发出光线时穿过的多边形边的数量,确定潜在的交点是落在三角形内部还是外部。

现在,这是我的实现(特别是第一点):

public Vector getIntersectionVector(Ray ray)
{
Vector planeIntersectionVector = getPlaneIntersectionVector(ray, getPlaneNormal());
if (planeIntersectionVector != null)
{
if (isIntersectionVectorInsideTriangle(planeIntersectionVector))
{
return planeIntersectionVector;
}
else
{
return null;
}
}
else
{
return null;
}
}

getPlaceIntersectionVector() 是:

private Vector getPlaneIntersectionVector(Ray ray, Vector planeNormal)
{
double vd = planeNormal.dotProduct(ray.getDirection());
//(p_n \dot r_d) == 0, parallel. (p_n \dot r_d) > 0 Plane normal pointing away from ray.
if (vd >= 0)
{
return null;
}
double distance = planeNormal.distance(0d, 0d, 0d);
double vo = -(planeNormal.dotProduct(ray.getOrigin()) + distance);
double intersectionDistance = vo / vd;

//intersectionDistance <= 0 means the "intersection" is behind the ray, so not a real intersection
return (intersectionDistance <= 0) ? null : ray.getLocation(intersectionDistance);
}

这基本上是试图模仿这个:
Plane Intersection

还有这个:
Ray intersection

其中t是点命中沿射线的距离,ro是射线的原点,rd是光线的方向,pn 指的是三角形/平面的平面法线,d 是三角形所在平面到原点的距离 (0,0,0)

我做错了吗?当我从图像 (0,0) 中的第一个像素发出光线时,我看到 intersectionDistance(或 t)几乎是 1100,这在我看来直觉上是错误的。我认为交点会更近。

相关数据如下:射线原点(0,0,1),射线方向大致为(0.000917, -0.4689, -0.8833)
三角形的顶点为 (-0.2, 0.1, 0.1), (-0.2, -0.5, 0.2), (-0.2, 0.1, -0.3),这使得平面正常 (-1, 0, 0)
根据我的代码,射线与平面相交 1090 距离,正如我之前提到的,这对我来说似乎是错误的。场景在每个方向上都只有-1.0到1.0,这意味着路口在距离上非常非常远。
我做的平面交叉点错了吗?

请让我知道在哪里澄清要点,以及您是否需要更多信息。

最佳答案

问题是这一行:

double distance = planeNormal.distance(0d, 0d, 0d);

平面由法线和平面到原点的距离定义。 vector 与原点的距离就是 vector 的长度,因此您计算的只是平面法线的长度(如果已归一化,则始终为 1.0)。

平面到原点的距离是一条额外的信息,需要传递给你的函数,你不能只从法线计算它,因为它独立于法线(你可以有很多平面在离原点不同距离处指向同一方向的法线)。

所以像这样定义你的函数:

private Vector getPlaneIntersectionVector(Ray ray, Vector planeNormal, double planeDistance)

并这样调用它:

Vector planeIntersectionVector = getPlaneIntersectionVector(ray, getPlaneNormal(), getPlaneDistance());

然后你可以这样计算vo:

double vo = -(planeNormal.dotProduct(ray.getOrigin()) + planeDistance);

关于java - 光线追踪三角形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40560000/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com