C++ 计算光线跟踪器光线-向量收敛到相同的输出

C++ 计算光线跟踪器光线-向量收敛到相同的输出,c++,raytracing,C++,Raytracing,我一直在写一个光线跟踪器来取乐,并且已经得到了相当数量的投入。我观看了一些教程、讲座和研究/其他代码,以透视计算投影到图像中的矢量光线。不幸的是,根据我正在创建的图像的大小,经过4-5次迭代后,它使用了相同的矢量光线。虽然这应该是不同的取决于哪个像素是在图像中看到 现在我正在做一个变换,根据创建的图像的尺寸,基本上将像素的光线向左或向右移动x/y。具体地说,我研究了这两个答案,尝试了实现它们,调整了我的代码,但没有得到任何结果 作为旁注,纵向和横向实现也不起作用。它是用宽度=10和高度=10硬编

我一直在写一个光线跟踪器来取乐,并且已经得到了相当数量的投入。我观看了一些教程、讲座和研究/其他代码,以透视计算投影到图像中的矢量光线。不幸的是,根据我正在创建的图像的大小,经过4-5次迭代后,它使用了相同的矢量光线。虽然这应该是不同的取决于哪个像素是在图像中看到

现在我正在做一个变换,根据创建的图像的尺寸,基本上将像素的光线向左或向右移动
x/y
。具体地说,我研究了这两个答案,尝试了实现它们,调整了我的代码,但没有得到任何结果

作为旁注,纵向和横向实现也不起作用。它是用宽度=10和高度=10硬编码的,因为这是我一直在玩的维度。他们可以改变,将来肯定会改变

在C++中用VS2013编码< < /P>
int WIDTH = 10;
int HEIGHT = 10;

int main(int argc, char **argv) {
    std::cout << "creating rays..." << std::endl;

    Vector Y(0, 1, 0);
    Vector camPos(3, 1.5, -4);
    Vector looking_at(0, 0, 0); // may change - but want to look at center for this scene
    Vector difference(camPos - looking_at);

    Vector camDir = difference.negative().normalize();
    Vector camRight = (Y.cross(camDir)).normalize();
    Vector camDown = camRight.cross(camDir);

    double aspectRatio = (double) WIDTH / (double) HEIGHT;
    double xAMT, yAMT;  //slightly left of right from direction of camera

    for (int x = 0; x < HEIGHT; x++) {
        for (int y = 0; y < WIDTH; y++) {
            if (WIDTH > HEIGHT) {
                // landscape
                xAMT = ((x + 0.5) / WIDTH) * aspectRatio - (((WIDTH - HEIGHT) / (double) HEIGHT) /2);
                yAMT = ((HEIGHT - y) + 0.5) / HEIGHT;
            }
            else if (HEIGHT > WIDTH) {
                // portrait
                xAMT = (y + 0.5) / WIDTH;
                yAMT = (((HEIGHT - y) + 0.5) / HEIGHT) / aspectRatio - (((HEIGHT - WIDTH) / (double) WIDTH) / 2);
            }
            else {
                // square
                xAMT = (x + 0.5) / WIDTH;
                yAMT = ((HEIGHT - y) + 0.5) / HEIGHT;
            }

            // YES - this indeed does work
            Vector camRayOrigin     = camPos;
            Vector camRightDir      = camRight * (yAMT - 0.5);
            Vector camDownDir       = camDown  * (xAMT - 0.5);
            Vector camRayDirection  = (camDir + (camRightDir + camDownDir)).normalize();

            Ray camRay(camRayOrigin, camRayDirection);
            camRayDirection.print_vector();
        }
    }           
}
向量类:

#include <cmath>

class Vector {
    double x, y, z;
    int size = 3;

public:
    ~Vector() {};
    Vector() : x(0), y(0), z(0) {}
    Vector(double _x, double _y, double _z) : x(_x), y(_y), z(_z) {}

    Vector& operator=(Vector rhs);

    // Vector mathematical operations                                                                                                                                                                                               
    Vector operator+(const Vector& rhs);
    Vector& operator+=(const Vector& rhs);
    Vector operator-(const Vector& rhs);
    Vector& operator-=(const Vector& rhs);

    // Vector scalar operations
    Vector operator+(const double& rhs);
    Vector operator-(const double& rhs);
    Vector operator*(const double& rhs);
    Vector operator/(const double& rhs);

    Vector cross(const Vector& rhs); // Cross-Product
    double dot(const Vector& rhs); // Dot-Product
    Vector normalize(); // Normalize
    Vector negative(); // Negative 
    double mag(); // Magnitude

    void swap(Vector& rhs);
    void print_vector();
};

Vector& Vector::operator=(Vector rhs) {
    swap(rhs);
    return *this;
}

Vector Vector::operator+(const Vector& rhs) {
    Vector result(*this);
    result += rhs;
    return result;
}

Vector& Vector::operator+=(const Vector& rhs) {
    this->x += rhs.x;
    this->y += rhs.y;
    this->z += rhs.z;

    return *this;
}

Vector Vector::operator-(const Vector& rhs) {
    Vector result(*this);
    result -= rhs;
    return result;
}

Vector& Vector::operator-=(const Vector& rhs) {
    this->x -= rhs.x;
    this->y -= rhs.y;
    this->z -= rhs.z;

    return *this;
}

Vector Vector::operator+(const double& rhs) {
    this->x += rhs;
    this->y += rhs;
    this->z += rhs;

    return *this;
}

Vector Vector::operator-(const double& rhs) {
    this->x -= rhs;
    this->y -= rhs;
    this->z -= rhs;

    return *this;
}

Vector Vector::operator*(const double& rhs) {
    this->x *= rhs;
    this->y *= rhs;
    this->z *= rhs;

    return *this;
}

Vector Vector::operator/(const double& rhs) {
    this->x /= rhs;
    this->y /= rhs;
    this->z /= rhs;

    return *this;
}

Vector Vector::cross(const Vector& rhs) {
    double a = (y * rhs.z) - (z * rhs.y);
    double b = (z * rhs.x) - (x * rhs.z);
    double c = (x * rhs.y) - (y * rhs.x);
    Vector product(a, b, c);
    return product;
}

double Vector::dot(const Vector& rhs) {
    double scalar = (x * rhs.x) + (y * rhs.y) + (x * rhs.z);
    return scalar;
}

double Vector::mag() {
    return sqrt(pow(x, 2) + pow(y, 2) + pow(z, 2));
}

Vector Vector::normalize() {
    double mag = sqrt(pow(x, 2) + pow(y, 2) + pow(z, 2));

    if (mag != 0) {
        this->x /= mag;
        this->y /= mag;
        this->z /= mag;
    }
    return *this;
}

Vector Vector::negative() {
    this->x *= -1;
    this->y *= -1;
    this->z *= -1;
    return *this;
}

void Vector::swap(Vector& rhs) {
    using std::swap;

    swap(this->x, rhs.x);
    swap(this->y, rhs.y);
    swap(this->z, rhs.z);
}

void Vector::print_vector() {
    std::cout 
        << x 
        << " " 
        << y 
        << " "
        << z 
        << std::endl;
}
#包括
类向量{
双x,y,z;
int size=3;
公众:
~Vector(){};
向量():x(0),y(0),z(0){}
向量(double x,double y,double z):x(x),y(y),z(z){
向量和运算符=(向量rhs);
//向量数学运算
向量运算符+(常量向量和rhs);
向量和运算符+=(常量向量和rhs);
向量运算符-(常量向量和rhs);
向量和运算符-=(常量向量和rhs);
//向量标量运算
向量运算符+(常数双精度和rhs);
向量运算符-(常数双精度和rhs);
向量运算符*(常数双精度和rhs);
向量运算符/(常数双精度和rhs);
向量交叉(const Vector&rhs);//交叉积
双点(常数向量和rhs);//点积
向量规格化();//规格化
向量负();//负
双磁极();//量级
无效掉期(矢量和rhs);
void print_vector();
};
向量和向量::运算符=(向量rhs){
掉期(rhs);
归还*这个;
}
向量向量::运算符+(常量向量和rhs){
矢量结果(*此);
结果+=rhs;
返回结果;
}
向量和向量::运算符+=(常量向量和rhs){
此->x+=rhs.x;
此->y+=rhs.y;
此->z+=rhs.z;
归还*这个;
}
向量向量::运算符-(常量向量和rhs){
矢量结果(*此);
结果-=rhs;
返回结果;
}
向量和向量::运算符-=(常量向量和rhs){
此->x-=rhs.x;
此->y-=rhs.y;
此->z-=rhs.z;
归还*这个;
}
向量向量::运算符+(常量双精度和rhs){
此->x+=rhs;
此->y+=rhs;
此->z+=rhs;
归还*这个;
}
向量:运算符-(常量双精度和rhs){
此->x-=rhs;
此->y-=rhs;
此->z-=rhs;
归还*这个;
}
向量向量::运算符*(常量双精度和rhs){
此->x*=rhs;
这->y*=rhs;
此->z*=rhs;
归还*这个;
}
向量:运算符/(常数双精度和rhs){
这->x/=rhs;
这->y/=rhs;
这->z/=rhs;
归还*这个;
}
矢量::交叉(常量矢量和rhs){
双a=(y*rhs.z)-(z*rhs.y);
双b=(z*rhs.x)-(x*rhs.z);
双c=(x*rhs.y)-(y*rhs.x);
向量积(a,b,c);
退货产品;
}
双矢量::点(常数矢量和rhs){
双标量=(x*rhs.x)+(y*rhs.y)+(x*rhs.z);
返回标量;
}
双向量::mag(){
返回sqrt(pow(x,2)+pow(y,2)+pow(z,2));
}
Vector::normalize(){
双磁感应=sqrt(功率(x,2)+功率(y,2)+功率(z,2));
如果(磁!=0){
这->x/=mag;
这->y/=mag;
这->z/=mag;
}
归还*这个;
}
向量::负(){
这->x*=-1;
这->y*=-1;
这->z*=-1;
归还*这个;
}
void Vector::swap(Vector和rhs){
使用std::swap;
交换(此->x,rhs.x);
交换(此->y,rhs.y);
交换(此->z,rhs.z);
}
void Vector::print_Vector(){
标准::cout

问题在
Vector
类中

实现
+
-
*
/
(双)
的方法与实现
+=
-=
(常量向量&)
的方法相同:更改
的值

在实现二进制运算符时(第一个操作数是
this
,第二个操作数是
rhs
),您通常不想更改操作数的值。在这种情况下,我强烈建议您使用
const
,以便在出现类似错误时警告运算符

Vector operator+(const double& rhs) const;
而不是:

Vector operator+(const double& rhs);
然后,实施是:

Vector Vector::operator+(const double& rhs) const {
    Vector result(*this);
    result.x += rhs;
    result.y += rhs;
    result.z += rhs;

    return result;
}

尽可能简化代码片段以使代码更易于阅读是非常有用的。有很多代码基本上与您要处理的问题无关…@MichalHosala相反,当它被删除时,代码会丢失对相机重要方面的定义以及来自它的光线eds使用线性代数-错了?我认为实际查看数字和实现更有用,以掌握正在发生的事情。我在过去两天一直在尝试调试这段代码,这是它得到的最基本的代码,没有中断。我还知道
xAMT
yAMT
f或者横向和纵向都被破坏了,你想知道对于整个代码段还有什么其他的解决方案。好吧,你说横向/纵向也被破坏了,但是硬编码的
WIDTH==HEIGHT==10
提供的代码将总是默认为方形模式…所以最好至少在我提到的某个地方在您的帖子中,您不仅对
WIDTH时的解决方案感兴趣==
Vector Vector::operator+(const double& rhs) const {
    Vector result(*this);
    result.x += rhs;
    result.y += rhs;
    result.z += rhs;

    return result;
}