Расчет raytracer лучей — векторы сходятся к одному выходу

Я пишу трассировщик лучей для удовольствия и внес в него приличную сумму. Я смотрел учебные пособия, лекции и исследовательский / другой код, чтобы вывести на перспективу вычисление векторного луча в проекции на изображение. К сожалению, после 4-5-й итерации, в зависимости от размера изображения, которое я создаю, он использует тот же векторный луч. Хотя это должно отличаться в зависимости от того, на какой пиксель смотрят изображение.

Прямо сейчас я делаю преобразование, которое в основном смещает луч влево или вправо x/y пикселя в зависимости от размера создаваемого изображения. В частности, я посмотрел на этих двух Raytracer — вычислительные лучи глаз && расчет генерации луча в трассировщике лучей ответы, попытался реализовать их, подправил мой код, и не получил никуда.

Как примечание, реализации портрета и пейзажа также не работают. Это жестко запрограммировано с шириной = 10 и высотой = 10, потому что это было измерение, с которым я играл. Они могут быть изменены и, безусловно, будут изменены в будущем.

Кодирование на C ++ с VS2013.

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();
}
}
}

текст, полученный с помощью кода выше:

creating rays...
-0.173037 0.117114 0.977928
-0.325543 -0.458438 0.826956
-0.517036 -0.198503 0.832629
-0.54971 -0.326274 0.769002
-0.575177 -0.269626 0.772316
-0.573114 -0.295291 0.764423
-0.575342 -0.283767 0.76711
-0.574404 -0.288958 0.765874
-0.574826 -0.286623 0.766435
-0.574637 -0.287674 0.766183
-0.574716 -0.287234 0.766288
-0.574689 -0.287388 0.766251
-0.574698 -0.287334 0.766264
-0.574695 -0.287353 0.76626
-0.574696 -0.287346 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261
-0.574696 -0.287348 0.766261

Векторный класс:

#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;
}

0

Решение

Проблемы в Vector учебный класс.

Вы реализуете +, -, *, / (double) так же, как вы реализуете +=, -= (const Vector&): вы меняете значение this,

При реализации бинарного оператора (первый операнд 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;
}
2

Другие решения


По вопросам рекламы [email protected]