一个简单的 Java 光线追踪器不起作用,我不知道为什么

问题描述 投票:0回答:1

我正在尝试编写一个最简单的光线追踪器,它只会将一个圆输出到 PPM 文件,但我什么也没得到。问题不在于 PPM 代码,而在于光线代码。我数学不好,所以我真的不知道问题出在哪里,如果有人可以帮助我,我将不胜感激,因为我真的不知道我做错了什么。

这是代码:

public class Main {
    static  int WITDH = 200;
    static  int HEIGHT = 200;

    public static void main(String[] args) {
        Sphere Ball = new Sphere(0, 0, -1 ,1);
        Vector Camera = new Vector(0, 0, -1);


        int [][] Pic = new int[200][200];



        int number=0;

        for (int y = 0;y<HEIGHT;y++) {
            for (int x = 0; x < WITDH; x++) {
            number++;



                Ray test = new Ray(Camera);
                double first=0.5*(WITDH-x)/(double)WITDH;
                double second=0.5*(HEIGHT-y)/(double)HEIGHT;
                Vector direc=new Vector(first,second,-1.0);
                test.at(number,direc);

                if (Sphere.intersects(test, Ball) == true) {
                Pic[y][x]=0;

                } else if(Sphere.intersects(test,Ball) == false) {
                    Pic[y][x]=1;

                }

            }

        }

}
}
static Boolean intersects(Ray ray, Sphere Shape) {


        Vector Origin = ray.origin;
        Vector center = Shape.Pozicija;
        double discrimant;



        Vector L = Vector.SubtractVector(Origin, center);
        double a = Vector.ReturnDotProduct(ray.Direction, ray.Direction);
        double b = 2.0 * Vector.ReturnDotProduct(L, ray.Direction);
        double c = Vector.ReturnDotProduct(L, L) - (Shape.radius * Shape.radius);
        double t0=0.0;
        double t1=0.0;


        discrimant = (b * b) - (4.0 * a * c);
        double q;
        if(discrimant<0.0){
            return false;
        }else if(discrimant==0.0){
            t0=t1=-0.5*b/a;
        }else {
            if(b>0) {

                q = -0.5*(b+Math.sqrt(discrimant));



            }else{
                q = -0.5*(b-Math.sqrt(discrimant));
            }
            t0=q/a;
            t1=c/q;

        }
        if(t0>t1){
            double t3;
            t3=t1;
            t0=t1;
            t1=t3;
        }

        if (t0 < 0) {
            t0 = t1;
            if (t0 < 0) {
                return false;
            }


        }
        System.out.println(t0+t1);
        return true;
    }
Vector at(double t,Vector d2){
        Vector d1=new Vector(0,0,0);
        if(t==0){
            d1=Direction;
        }else if(t>0){
            d1=Vector.GetDirection(d2);
        }
        return Vector.AddVector(origin,Vector.MultiplyScalar(d1,t));
    }
java graphics 3d raytracing ppm
1个回答
0
投票

您的代码似乎是尝试实现一个简单的光线追踪器,但需要解决一些问题才能使其正常工作。我将帮助您识别并解决这些问题:

  1. Ray 类:在 Ray 类中,您有一个方法 at(double t, Vector d2) 尝试计算给定 t 值的新向量。但是,您似乎正在尝试改变 Ray 类的 Direction 字段,这是不正确的。相反,您应该使用更新的原点和方向创建一个新的 Ray 实例。这是更正的 at 方法:

    射线 at(double t, Vector d2) { 向量 newDirection = Vector.GetDirection(d2); Vector newOrigin = Vector.AddVector(origin, Vector.MultiplyScalar(newDirection, t)); 返回新射线(新原点,新方向); }

  2. Intersect 方法: intersects 方法在代码中似乎是静态方法,但它应该在 Sphere 类中定义,因为它对 Sphere 对象进行操作。将 intersects 方法移至 Sphere 类中。

    if(判别式 < 0.0) { return false; } else if (discriminant == 0.0) { t0 = t1 = -0.5 * b / a; } else { if (b > 0){ q = -0.5 * (b + Math.sqrt(判别式)); } 别的 { q = -0.5 * (b - Math.sqrt(判别式)); } t0 = q / a; t1=c/q; }

    如果(t0< 0 && t1 < 0) { return false; }

    返回真;

  3. 循环问题:在你的 main 方法中,变量 number 被用作递增因子,但这不是必需的。您应该在循环内增加数字,而不是事先增加。

  4. PPM 文件生成:您提到 PPM 代码正在运行,但它未包含在提供的代码中。确保写入 PPM 文件的代码正常运行,并确保使用正确的扩展名 (.ppm) 保存文件。

通过这些更正并确保其余代码(包括 Vector 和 Sphere 类)正确实现后,您的光线追踪器应该能够将圆渲染到 PPM 文件。此外,您可能需要考虑使用适当的开发环境或 IDE,因为它可以帮助您调试和编写更清晰的代码。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.