| struct Cylinder : public Object {double rad, h; Vec p;
 Cylinder(double r_,double h_,Vec p_,Vec c_,Refl_t re_) : Object(c_,re_), rad(r_),h(h_),p(p_){}
 virtual double intersect(const Ray &r, Vec* nrm) const {
 Vec o = r.o - p;
 double a = sq(r.d.x) + sq(r.d.z);
 if (a == 0)  return 1e20;
 double b = 2 * (o.x * r.d.x + o.z * r.d.z);
 double c = sq(o.x) + sq(o.z) - sq(rad);
 double D = sq(b) - 4 * a * c;
 if (D <= 0) {
 return 1e20;
 } else {
 double det = sqrt(D);
 double t;
 if ((t = (-b - det) / (2 * a)) > 1e-4 && (fabs(o.y + r.d.y*t) <= h)) {
 
 } else if ((t = (-b + det) / (2 * a)) > 1e-4 && (fabs(o.y + r.d.y*t) <= h)) {
 
 } else {
 return 1e20;
 }
 
 Vec x=r.o+r.d*t;
 Vec n = (x-this->p); n.y = 0;
 *nrm = n.norm();
 return t;
 }
 }
 };
 
 |