bool yz_rect::hit(const ray& r, double t_min, double t_max, hit_record& rec) const { double t = (k - r.origin().x()) / r.direction().x(); if (t<t_min || t>t_max) return false; double y = r.origin().y() + t*r.direction().y(); double z = r.origin().z() + t*r.direction().z(); if (y<y0 || y>y1 || z<z0 || z>z1) return false; rec.u = (y - y0) / (y1 - y0); rec.v = (z - z0) / (z1 - z0); rec.t = t; rec.mat_ptr = mat_ptr; rec.point = r.point_at_parameter(t); rec.normal = vec3(1.0, 0.0, 0.0); return true; }
bool sphere::hit(const ray& r, float t_min, float t_max, hit_record& rec) const { vec3 oc = r.origin() - center; float v2 = dot(r.direction(), r.direction()); float voc = dot(oc, r.direction()); // 判別式. float discriminant = voc * voc - v2 * (dot(oc, oc) - radius*radius); if (discriminant > 0) { // 手前. float temp = (-voc - sqrt(discriminant)) / v2; if (temp < t_max && temp > t_min) { rec.t = temp; rec.p = r.org + rec.t * r.dir; rec.normal = (rec.p - center); rec.normal.noramlize(); getUV(rec.u, rec.v, rec.normal); rec.mat_ptr = mat_ptr; return true; } // 奥. temp = (-voc + sqrt(discriminant)) / v2; if (temp < t_max && temp > t_min) { rec.t = temp; rec.p = r.org + rec.t * r.dir; rec.normal = (rec.p - center) / radius; rec.normal.noramlize(); getUV(rec.u, rec.v, rec.normal); rec.mat_ptr = mat_ptr; return true; } } return false; }