光线跟踪-几何球体相交-相交函数为所有光线返回true,尽管没有相交 我用C++和OpenGL编写了一个光线跟踪程序,用我的球交集函数运行了一些障碍:我检查了多个源,数学看起来正确,但是由于每个射线的某种原因,交集方法返回了真。以下是球体相交函数的代码以及一些其他代码,以供说明: bool intersect(Vertex & origin, Vertex & rayDirection, float intersection) { bool insideSphere = false; Vertex oc = position - origin; float tca = 0.0; float thcSquared = 0.0; if (oc.length() < radius) insideSphere = true; tca = oc.dot(rayDirection); if (tca < 0 && !insideSphere) return false; thcSquared = pow(radius, 2) - pow(oc.length(), 2) + pow(tca, 2); if (thcSquared < 0) return false; insideSphere ? intersection = tca + sqrt(thcSquared) : intersection = tca - sqrt(thcSquared); return true; } bool相交(顶点与原点、顶点与光线方向、浮点相交) { bool insideSphere=false; 顶点oc=位置-原点; 浮动tca=0.0; 浮动thcSquared=0.0; 如果(oc.length()
下面是光线跟踪函数调用交集函数的一些上下文。仅供参考,我的相机位于(0,0,0),这是光线跟踪函数中我的“原点”变量中的值:光线跟踪-几何球体相交-相交函数为所有光线返回true,尽管没有相交 我用C++和OpenGL编写了一个光线跟踪程序,用我的球交集函数运行了一些障碍:我检查了多个源,数学看起来正确,但是由于每个射线的某种原因,交集方法返回了真。以下是球体相交函数的代码以及一些其他代码,以供说明: bool intersect(Vertex & origin, Vertex & rayDirection, float intersection) { bool insideSphere = false; Vertex oc = position - origin; float tca = 0.0; float thcSquared = 0.0; if (oc.length() < radius) insideSphere = true; tca = oc.dot(rayDirection); if (tca < 0 && !insideSphere) return false; thcSquared = pow(radius, 2) - pow(oc.length(), 2) + pow(tca, 2); if (thcSquared < 0) return false; insideSphere ? intersection = tca + sqrt(thcSquared) : intersection = tca - sqrt(thcSquared); return true; } bool相交(顶点与原点、顶点与光线方向、浮点相交) { bool insideSphere=false; 顶点oc=位置-原点; 浮动tca=0.0; 浮动thcSquared=0.0; 如果(oc.length(),c++,opengl,geometry,intersection,raytracing,C++,Opengl,Geometry,Intersection,Raytracing,下面是光线跟踪函数调用交集函数的一些上下文。仅供参考,我的相机位于(0,0,0),这是光线跟踪函数中我的“原点”变量中的值: #define WINDOW_WIDTH 640 #define WINDOW_HEIGHT 480 #define WINDOW_METERS_WIDTH 30 #define WINDOW_METERS_HEIGHT 20 #define FOCAL_LENGTH 25 rayDirection.z = FOCAL_LENGTH * -1; for (int r
#define WINDOW_WIDTH 640
#define WINDOW_HEIGHT 480
#define WINDOW_METERS_WIDTH 30
#define WINDOW_METERS_HEIGHT 20
#define FOCAL_LENGTH 25
rayDirection.z = FOCAL_LENGTH * -1;
for (int r = 0; r < WINDOW_HEIGHT; r++)
{
rayDirection.y = (WINDOW_METERS_HEIGHT / 2 * -1) + (r * ((float)WINDOW_METERS_HEIGHT / (float)WINDOW_HEIGHT));
for (int c = 0; c < WINDOW_WIDTH; c++)
{
intersection = false;
t = 0.0;
rayDirection.x = (WINDOW_METERS_WIDTH / 2 * -1) + (c * ((float)WINDOW_METERS_WIDTH / (float)WINDOW_WIDTH));
rayDirection = rayDirection - origin;
for (int i = 0; i < NUM_SPHERES; i++)
{
if (spheres[i].intersect(CAM_POS, rayDirection, t))
{
intersection = true;
}
}
#定义窗口宽度640
#定义窗高480
#定义窗宽30米
#定义窗高20米
#定义焦距25
射线方向z=焦距*-1;
对于(int r=0;r
感谢您查看,并让我知道是否有其他代码可以帮助您!您的数学似乎有点混乱。函数的第一部分,即直到第一个
返回false
,是可以的,如果光线从球体外部开始,并且不朝向球体,则将返回false。但是,我认为您将相机放在所有外部你的球体以一种所有球体都可见的方式,这就是为什么这部分永远不会返回false
thcSquared
确实是错误的,我不知道它应该代表什么
让我们用数学方法进行交叉。我们有:
:光线的起点,我们称之为origin
A
:无限光线的方向,我们称之为光线方向
d
:球体的中心,称为位置
P
:不言自明,称为radius
r
M
:
因为它在线路上M=A+t*d
,因为它在球体上| M-P |=r
| A+t*d-p |²=r²
,它给出(A-p)²+2*t*(A-p).点(d)+t²d²=r²
。这是一个简单的二次方程。一旦解出,就有0、1或2个解,选择最接近射线原点的解(但它是正的)
编辑:您被迫使用另一种方法,我将在这里详细介绍:
l
)。这是通过在直线上“投影”中心来完成的。因此:
tca=((p-A)点d)/| d |
,或者使用您的变量名,tca=(OC点rd)/| rd |
。投影为H=A+tca*d
,和l=| H-p
l>R
然后返回false,则不存在交点
M
称为一个交点。三角形MHP
有一个直角,所以MH²+HP²=MP²
,换句话说thc²+l²=r²
,所以我们现在有了thc
,从H
到球体的距离
t=tca+-thc
,只需取两者中最低的非负数
旁注:3d向量的名称
Vertex
选择得非常糟糕,像Vector3
或vec3
会更好。好吧,intersect()
中有两个返回true
s,调试器说哪一个会一直被命中?应该只有一个“返回true”语句;另一个只指定“insideSphere”一个真值。抱歉,阅读理解失败。在intersect结尾处为intersect赋值有什么意义?但是在函数结尾处修改局部变量在函数返回后没有效果,那么为什么要这样做呢?我们在本项目中使用的算法基于本演示文稿幻灯片13之后的算法:这似乎是有道理的,我将尝试它只是为了看看它是否能解决我的问题,但最终不幸的是,我不得不使用几何算法。我也非常同意对名称顶点的评论;使用它的唯一原因是因为它是从早期项目中回收的。好的,我将看到你的算法-可能需要一些时间,一个这篇文章的质量并不高,但是(在拼写错误、错误定义、过度和无用的共谋之间)这篇文章的质量并不高