예제 #1
0
        public override bool Hit(Ray r, double tMin, double tMax, out Object3D rec)
        {
            var oc           = r.Origin - Center;
            var a            = r.Direction.LengthSquared;
            var halfB        = Vector3.DotProduct(oc, r.Direction);
            var c            = oc.LengthSquared - Radius * Radius;
            var discriminant = halfB * halfB - a * c;

            if (discriminant > 0)
            {
                var root = Math.Sqrt(discriminant);
                var temp = (-halfB - root) / a;
                if (temp < tMax && temp > tMin)
                {
                    rec   = new Sphere(Center, Radius, Material);
                    rec.T = temp;
                    rec.P = r.At(rec.T);
                    var outwardNormal = (rec.P - Center) / Radius;
                    rec.SetFaceNormal(r, outwardNormal);
                    return(true);
                }

                temp = (-halfB + root) / a;
                if (temp < tMax && temp > tMin)
                {
                    rec   = new Sphere(Center, Radius, Material);
                    rec.T = temp;
                    rec.P = r.At(rec.T);
                    var outwardNormal = (rec.P - Center) / Radius;
                    rec.SetFaceNormal(r, outwardNormal);
                    return(true);
                }
            }

            rec = null;
            return(false);
        }
예제 #2
0
 public abstract bool Hit(Ray r, double tMin, double tMax, out Object3D rec);
예제 #3
0
        public static bool Hit(this IEnumerable <Object3D> source, Ray ray, double min, double max, out Object3D hit)
        {
            hit = null;

            var hitDetected  = false;
            var closestSoFar = max;

            foreach (var item in source)
            {
                if (!item.Hit(ray, min, closestSoFar, out var localHit))
                {
                    continue;
                }

                hit          = localHit;
                hitDetected  = true;
                closestSoFar = localHit.T;
            }

            return(hitDetected);
        }