- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在用 Java 编写光线追踪器,并且我能够追踪有效的球体,但我相信我追踪三角形的方式有问题。
这是我理解的基本算法:
xy
平面)。现在,这是我的实现(特别是第一点):
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);
}
其中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/
我正在尝试使用 Sfml 编写 2D 游戏。对于那个游戏,我需要一个 Lightengine 和一些代码,这些代码可以为我提供玩家可见的世界区域。由于这两个问题非常吻合(实际上是相同的),我想同时解决
我是一名优秀的程序员,十分优秀!