public Intersections Filter(Intersections xs) { // begin outside of both children bool inLeft = false; bool inRight = false; // prepare a list to receive the filtered intersections var result = new Intersections(); foreach (var intersection in xs) { // if i.object is part of the "left" child, then lhit is true bool leftHit = Left.Contains(intersection.Object); if (IntersectionAllowed(leftHit, inLeft, inRight)) { result.Add(intersection); } // depending on which object was hit, toggle either inl or inr if (leftHit) { inLeft = !inLeft; } else { inRight = !inRight; } } result.Sort(); return(result); }
public override Intersections IntersectLocal(Ray ray) { var xs = new Intersections(); var a = ray.Direction.X * ray.Direction.X - ray.Direction.Y * ray.Direction.Y + ray.Direction.Z * ray.Direction.Z; var b = 2 * ray.Origin.X * ray.Direction.X - 2 * ray.Origin.Y * ray.Direction.Y + 2 * ray.Origin.Z * ray.Direction.Z; var c = ray.Origin.X * ray.Origin.X - ray.Origin.Y * ray.Origin.Y + ray.Origin.Z * ray.Origin.Z; if (Math.Abs(a) <= double.Epsilon && Math.Abs(b) > double.Epsilon) { var t = -c / (2 * b); xs.Add(new Intersection(t, this)); } if (Math.Abs(a) > double.Epsilon) { var disc = b * b - 4 * a * c; if (disc >= 0) { var t0 = (-b - Math.Sqrt(disc)) / (2 * a); var t1 = (-b + Math.Sqrt(disc)) / (2 * a); if (t0 > t1) { var tmp = t0; t0 = t1; t1 = tmp; } var y0 = ray.Origin.Y + t0 * ray.Direction.Y; if (Minimum < y0 && y0 < Maximum) { xs.Add(new Intersection(t0, this)); } var y1 = ray.Origin.Y + t1 * ray.Direction.Y; if (Minimum < y1 && y1 < Maximum) { xs.Add(new Intersection(t1, this)); } } } IntersectCaps(ray, xs); xs.Sort(); return(xs); }
public override Intersections IntersectLocal(Ray ray) { var xs = new Intersections(); var a = ray.Direction.X * ray.Direction.X + ray.Direction.Z * ray.Direction.Z; // ray is not parallel to the y axis if (a > double.Epsilon) { var b = 2 * ray.Origin.X * ray.Direction.X + 2 * ray.Origin.Z * ray.Direction.Z; var c = ray.Origin.X * ray.Origin.X + ray.Origin.Z * ray.Origin.Z - 1; var disc = b * b - 4 * a * c; // ray does not intersect the cylinder if (disc < 0) { return(xs); } var t0 = (-b - Math.Sqrt(disc)) / (2 * a); var t1 = (-b + Math.Sqrt(disc)) / (2 * a); if (t0 > t1) { var t = t0; t0 = t1; t1 = t; } var y0 = ray.Origin.Y + t0 * ray.Direction.Y; if (Minimum < y0 && y0 < Maximum) { xs.Add(new Intersection(t0, this)); } var y1 = ray.Origin.Y + t1 * ray.Direction.Y; if (Minimum < y1 && y1 < Maximum) { xs.Add(new Intersection(t1, this)); } } IntersectCaps(ray, xs); xs.Sort(); return(xs); }
public void IntersectingRayWithNonEmptyGroupTest() { var g = new Group(); var s1 = Helper.Sphere(); var s2 = Helper.Sphere().Translate(tz: -3); var s3 = Helper.Sphere().Translate(tx: 5); g.Add(s1, s2, s3); var r = Helper.Ray(0, 0, -5, 0, 0, 1); var xs = new Intersections(); g.IntersectLocal(ref r.Origin, ref r.Direction, xs); xs.Sort(); Check.That(xs).CountIs(4); Check.That(xs[0].Object).IsSameReferenceAs(s2); Check.That(xs[1].Object).IsSameReferenceAs(s2); Check.That(xs[2].Object).IsSameReferenceAs(s1); Check.That(xs[3].Object).IsSameReferenceAs(s1); }