Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何从入射向量和曲面法线中找到折射向量?_Java_Vector_Raytracing - Fatal编程技术网

Java 如何从入射向量和曲面法线中找到折射向量?

Java 如何从入射向量和曲面法线中找到折射向量?,java,vector,raytracing,Java,Vector,Raytracing,我正在用java编写一个光线跟踪器,我正在尝试实现折射,但是我被我在这个主题上找到的信息弄糊涂了。如果我有一个入射光线的3D矢量,作为3D矢量给出的表面法线和两种介质的折射率,为了得到透射光线的矢量,我需要应用什么操作?让V__成为标准化的入射矢量。设n1和n2为两个表面的折射率。您要计算V_折射。设n为归一化法向量 V_refraction = r*V_incedence + (rc - sqrt(1-Math.pow(r,2)(1-Math.pow(c,2))))n where r = n1

我正在用java编写一个光线跟踪器,我正在尝试实现折射,但是我被我在这个主题上找到的信息弄糊涂了。如果我有一个入射光线的3D矢量,作为3D矢量给出的表面法线和两种介质的折射率,为了得到透射光线的矢量,我需要应用什么操作?

V__成为标准化的入射矢量。设
n1
n2
为两个表面的折射率。您要计算V_折射。设n为归一化法向量

V_refraction = r*V_incedence + (rc - sqrt(1-Math.pow(r,2)(1-Math.pow(c,2))))n
where r = n1/n2 and c = -n dot V_incedence.

我在我的rayjava跟踪器中实现了这个

专用静态双钳位(最终双val、最终双最小值、最终双最大值){
返回Math.max(min,Math.min(max,val));
}
私有向量3D getRefractionVector(最终向量3D I、最终向量3D N、最终双ior){
双余弦=钳位(-1,1,I.dot(N));
双etai=1,etat=ior;
矢量3d n=n;
if(cosi<0){
cosi=-cosi;
}否则{
双温=etai;
etai=etat;
etat=温度;
n=n.乘(-1);
}
双eta=etai/etat;
双k=1-(eta*eta)*(1-(cosi*cosi));

if(kBram de Greve写了一篇关于光线跟踪中的反射和折射的好文章。你可以找到它

他的实现(C++)如下所示:

Vector refract(const Vector& normal, const Vector& incident, 
               double n1, double n2) 
{
    const double n = n1 / n2;
    const double cosI = -dot(normal, incident);
    const double sinT2 = n * n * (1.0 - cosI * cosI);
    if(sinT2 > 1.0) return Vector::invalid; // TIR
    const double cosT = sqrt(1.0 - sinT2);
    return n * incident + (n * cosI - cosT) * normal;
}

谢谢你的回答。在第一行中,这是否意味着要加上V_置信度向量。乘以(r)和n的向量。乘以(rc-sqrt(1-r^2(1-c^2))?这是一个近似值吗?似乎偏离了一些小数位这是一个非常有用的方法,尽管我必须写出cosI=abs(dot(normal,incident))才能正确工作。
Vector refract(const Vector& normal, const Vector& incident, 
               double n1, double n2) 
{
    const double n = n1 / n2;
    const double cosI = -dot(normal, incident);
    const double sinT2 = n * n * (1.0 - cosI * cosI);
    if(sinT2 > 1.0) return Vector::invalid; // TIR
    const double cosT = sqrt(1.0 - sinT2);
    return n * incident + (n * cosI - cosT) * normal;
}