public override bool Hit(Ray ray, double t_min, double t_max, ref ShadeRec sr)
        {
            Vector3D origin    = new Vector3D(ray.original);
            Vector3D direction = new Vector3D(ray.direction);

            origin[0]    = cos_theta * ray.original[0] - sin_theta * ray.original[2];
            origin[2]    = sin_theta * ray.original[0] + cos_theta * ray.original[2];
            direction[0] = cos_theta * ray.direction[0] - sin_theta * ray.direction[2];
            direction[2] = sin_theta * ray.direction[0] + cos_theta * ray.direction[2];
            Ray      rotatedR = new Ray(origin, direction, ray.time);
            ShadeRec rec      = new ShadeRec(sr);

            if (Object.Hit(rotatedR, t_min, t_max, ref sr))
            {
                Vector3D p      = new Vector3D(sr.p);
                Vector3D normal = new Vector3D(sr.normal);
                p[0]      = cos_theta * sr.p[0] + sin_theta * sr.p[2];
                p[2]      = -sin_theta * sr.p[0] + cos_theta * sr.p[2];
                normal[0] = cos_theta * sr.normal[0] + sin_theta * sr.normal[2];
                normal[2] = -sin_theta * sr.normal[0] + cos_theta * sr.normal[2];
                sr.p      = p;
                sr.normal = normal;
                return(true);
            }
            sr = rec;
            return(false);
        }
 public override bool Hit(Ray ray, double t_min, double t_max, ref ShadeRec sr)
 {
     //检测包围和碰撞,返回碰撞的子树的信息
     if (box.Hit(ray, t_min, t_max))
     {
         ShadeRec left_rec = new ShadeRec(), right_rec = new ShadeRec();
         bool     hit_left  = left.Hit(ray, t_min, t_max, ref left_rec);
         bool     hit_right = right.Hit(ray, t_min, t_max, ref right_rec);
         if (hit_left && hit_right)
         {
             sr = left_rec.t < right_rec.t ? left_rec : right_rec;
             return(true);
         }
         if (hit_left)
         {
             sr = left_rec;
             return(true);
         }
         if (hit_right)
         {
             sr = right_rec;
             return(true);
         }
         return(false);
     }
     return(false);
 }
 public override bool Hit(Ray ray, double t_min, double t_max, ref ShadeRec sr)
 {
     if (!hitable.Hit(ray, t_min, t_max, ref sr))
     {
         return(false);
     }
     sr.normal = -sr.normal;
     return(true);
 }
        public override bool Hit(Ray ray, double t_min, double t_max, ref ShadeRec sr)
        {
            Ray moved = new Ray(ray.original - offset, ray.direction, ray.time);

            if (!Object.Hit(moved, t_min, t_max, ref sr))
            {
                return(false);
            }
            sr.p += offset;
            return(true);
        }
        public override bool Hit(Ray ray, double t_min, double t_max, ref ShadeRec sr)
        {
            ShadeRec sr1 = new ShadeRec(), sr2 = new ShadeRec();

            if (boundary.Hit(ray, -double.MaxValue, double.MaxValue, ref sr1))
            {
                if (boundary.Hit(ray, sr1.t + 0.0001, double.MaxValue, ref sr2))
                {
                    sr1.t = Mathf.Range(sr1.t, t_min, t_max);
                    if (sr1.t < t_min)
                    {
                        sr1.t = t_min;
                    }
                    if (sr2.t > t_max)
                    {
                        sr2.t = t_max;
                    }
                    if (sr1.t >= sr2.t)
                    {
                        return(false);
                    }
                    if (sr1.t < 0)
                    {
                        sr1.t = 0;
                    }
                    double distance_inside_boundary = (sr2.t - sr1.t) * ray.direction.Magnitude();

                    double hit_distance = -(1 / density) * Math.Log(Mathematics.Random.Get());
                    if (hit_distance < distance_inside_boundary)
                    {
                        sr.t        = sr1.t + hit_distance / ray.direction.Magnitude();
                        sr.p        = ray.GetPoint(sr.t);
                        sr.normal   = new Vector3D(1, 0, 0);
                        sr.material = phase_function;
                        return(true);
                    }
                }
            }
            return(false);
        }