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