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); }
public abstract bool Hit(Ray r, double tMin, double tMax, out Object3D rec);
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); }