в приведенном ниже коде я хочу нарисовать все эти 3 сферы (сфера, сфера1, сфера2 в векторе "s") с помощью алгоритма трассировки лучей. Если я рисую 1 сферу, это дает хороший результат, но от 2 до n изображение искажается.
Я не могу поймать свою ошибку в этом коде. Не могли бы вы мне помочь? Как я могу увидеть три сферы?
#include <fstream>
#include <cmath>
#include <vector>
using namespace std;
struct Vec{
double x,y,z;
Vec(double x, double y, double z): x(x), y(y), z(z){}
Vec operator + (const Vec& v) const {
return Vec(x + v.x, y + v.y, z + v.z);
}
Vec operator - (const Vec& v) const {
return Vec(x-v.x, y-v.y, z-v.z);
}
Vec operator * (double d) const {
return Vec(x*d, y*d, z*d);
}
Vec operator / (double d) const {
return Vec(x/d, y/d, z/d);
}
Vec normalize() const {
double norm = sqrt(x*x + y*y + z*z);
return Vec(x/norm,y/norm,z/norm);
}
};
inline double dot(const Vec& u, const Vec& v) {
return (u.x*v.x + u.y*v.y + u.z*v.z);
}
struct Ray{
Vec origin, direction;
Ray(const Vec& origin, const Vec& direction): origin(origin), direction(direction){}
};
struct Sphere{
Vec center;
double radius;
Sphere(const Vec& center, double radius): center(center), radius(radius){}
Vec getNormal(const Vec& point) const { return (point - center) / radius; } // Küre üzerindeki normal
bool intersect(const Ray& ray, double &t) const { // t = parameter
const Vec ori = ray.origin; //e
const Vec dir = ray.direction; //d
const Vec origintocenter = ori - center; // e-c
const double b = 2 * dot(origintocenter, dir);
const double c = dot(origintocenter, origintocenter) - radius*radius;
const double a = dot(dir, dir);
double delta = b*b - 4 * a * c;
if (delta < 0) return false;
delta = sqrt(delta);
const double t0 = (-b - delta)/(2*a);
const double t1 = (-b + delta)/(2*a);
t = (t0 < t1) ? t0 : t1;
return true;
}
};
void range255(Vec& col) {
col.x = (col.x > 255) ? 255 : (col.x < 0) ? 0 : col.x;
col.y = (col.y > 255) ? 255 : (col.y < 0) ? 0 : col.y;
col.z = (col.z > 255) ? 255 : (col.z < 0) ? 0 : col.z;
}
int main(){
//image size
const int width = 1000;
const int height = 1000;
//colors
const Vec white(255, 255, 255);
const Vec black(0, 0, 0);
const Vec red(255, 0, 0);
const Vec green(0,255,0);
const Vec blue(0,0,255);
const Sphere sphere(Vec(width*0.8, height*0.2, 30), 50);
const Sphere sphere1(Vec(width*0.5, height*0.5, 30), 50);
const Sphere sphere2(Vec(width*0.8, height*0.8, 30), 50);
const Sphere light(Vec(0, 0, 0), 1);
vector<Sphere> s;
s.push_back(sphere);
s.push_back(sphere1);
s.push_back(sphere2);
ofstream out("out.ppm");
out << "P3\n" << width << ' ' << height << ' ' << "255\n";
Vec pixelColor(black);
double t;
for(int y=0; y<height; ++y){
for(int x=0; x<width; ++x){
pixelColor = black;
const Ray ray(Vec(x,y,0), Vec(0,0,1)); // z'den xy düzlemine gönderiyor
for(int a=0; a<s.size(); ++a){
if (s[a].intersect(ray, t)) {
const Vec p = ray.origin + ray.direction*t;
const Vec n = s[a].getNormal(p); //normal
const Vec l = light.center - p; // light condition
const double dt = dot(l.normalize(), n.normalize());
pixelColor = (red + white*dt) * 0.5;
range255(pixelColor);
}
out << (int)pixelColor.x << ' ' << (int)pixelColor.y << ' ' << (int)pixelColor.z << '\n';
}
}
}
}