public override IntersectionList LocalIntersect(Ray ray) { var sphereToRay = ray.Origin - Vector4.CreatePosition(0, 0, 0); var a = Vector4.Dot(ray.Direction, ray.Direction); var b = 2 * Vector4.Dot(ray.Direction, sphereToRay); var c = Vector4.Dot(sphereToRay, sphereToRay) - 1; var discriminant = (b * b) - (4 * a * c); // If the discriminant is negative, the ray misses // and there are no intersections. if (discriminant < 0) { return(IntersectionList.Empty()); } // Otherwise, we have two intersections which we can // solve for t using the quadratic formula. var t1 = (-b - Math.Sqrt(discriminant)) / (2 * a); var t2 = (-b + Math.Sqrt(discriminant)) / (2 * a); var xs = new[] { new Intersection(t1, this), new Intersection(t2, this), }; return(IntersectionList.Create(xs)); }
public IntersectionList FilterIntersections(IntersectionList xs) { var inl = false; var inr = false; var result = new List <Intersection>(); foreach (var i in xs) { var lhit = this.Left.Includes(i.Object); if (IntersectionAllowed(this.Operation, lhit, inl, inr)) { result.Add(i); } if (lhit) { inl = !inl; } else { inr = !inr; } } return(IntersectionList.Create(result.ToArray())); }
public override IntersectionList LocalIntersect(Ray ray) { var dirCrossE2 = ray.Direction.Cross3(this.E2); var det = this.E1.Dot(dirCrossE2); if (Math.Abs(det) < Epsilon) { return(IntersectionList.Empty()); } var f = 1.0 / det; var p1ToOrigin = ray.Origin - this.P1; var u = f * p1ToOrigin.Dot(dirCrossE2); if (u < 0 || u > 1) { return(IntersectionList.Empty()); } var originCrossE1 = p1ToOrigin.Cross3(this.E1); var v = f * ray.Direction.Dot(originCrossE1); if (v < 0 || (u + v) > 1) { return(IntersectionList.Empty()); } var t = f * this.E2.Dot(originCrossE1); return(IntersectionList.Create( new Intersection(t, this))); }
/// <summary> /// Intersect with a predicate to select a subset /// of shapes from the world. /// </summary> public IntersectionList Intersect(Ray ray, Func <Shape, bool> predicate) { Interlocked.Increment(ref Stats.Tests); var xs = this.Objects .Where(predicate) .SelectMany(x => x.Intersect(ray)) .ToArray(); return(IntersectionList.Create(xs)); }
public override IntersectionList LocalIntersect(Ray ray) { var a = Math.Pow(ray.Direction.X, 2) + Math.Pow(ray.Direction.Z, 2); // ray is parallel to the y-axis if (Math.Abs(a) < Epsilon) { var caps = new List <Intersection>(); this.IntersectCaps(ray, caps); return(IntersectionList.Create(caps.ToArray())); } var b = 2 * ray.Origin.X * ray.Direction.X + 2 * ray.Origin.Z * ray.Direction.Z; var c = Math.Pow(ray.Origin.X, 2) + Math.Pow(ray.Origin.Z, 2) - 1; var disc = b * b - 4 * a * c; if (disc < 0) { return(IntersectionList.Empty()); } 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 xs = new List <Intersection>(); var y0 = ray.Origin.Y + t0 * ray.Direction.Y; if (this.Minimum < y0 && y0 < this.Maximum) { xs.Add(new Intersection(t0, this)); } var y1 = ray.Origin.Y + t1 * ray.Direction.Y; if (this.Minimum < y1 && y1 < this.Maximum) { xs.Add(new Intersection(t1, this)); } this.IntersectCaps(ray, xs); return(IntersectionList.Create(xs.ToArray())); }
public override IntersectionList LocalIntersect(Ray ray) { if (Math.Abs(ray.Direction.Y) < Epsilon) { return(IntersectionList.Empty()); } var t = -ray.Origin.Y / ray.Direction.Y; var i = new Intersection(t, this); return(IntersectionList.Create(i)); }
public override IntersectionList LocalIntersect(Ray ray) { var bounds = this.GetBounds(); if (!bounds.Intersect(ray)) { return(IntersectionList.Empty()); } var xs = new List <Intersection>(); xs.AddRange(this.Left.Intersect(ray)); xs.AddRange(this.Right.Intersect(ray)); return(this.FilterIntersections( IntersectionList.Create(xs.ToArray()))); }
public override IntersectionList LocalIntersect(Ray ray) { CheckAxis(ray.Origin.X, ray.Direction.X, out var xtmin, out var xtmax); CheckAxis(ray.Origin.Y, ray.Direction.Y, out var ytmin, out var ytmax); CheckAxis(ray.Origin.Z, ray.Direction.Z, out var ztmin, out var ztmax); var tmin = Max(xtmin, ytmin, ztmin); var tmax = Min(xtmax, ytmax, ztmax); if (tmin > tmax) { return(IntersectionList.Empty()); } return(IntersectionList.Create( new Intersection(tmin, this), new Intersection(tmax, this))); }
private void CalculateRefraction(IntersectionList xs, out double n1, out double n2) { n1 = 0; n2 = 0; var containers = new List <Shape>(); foreach (var i in xs) { if (i.Equals(this)) { if (containers.Count == 0) { n1 = 1.0; } else { n1 = containers.Last().Material.RefractiveIndex; } } if (containers.Contains(i.Object)) { containers.Remove(i.Object); } else { containers.Add(i.Object); } if (i.Equals(this)) { if (containers.Count == 0) { n2 = 1.0; } else { n2 = containers.Last().Material.RefractiveIndex; } break; } } }
public Interaction Precompute(Ray r, IntersectionList xs) { var t = this.T; var obj = this.Object; var point = r.GetPosition(t); var eyev = -r.Direction; var normalv = obj.GetNormal(point); var inside = false; if (normalv.Dot(eyev) < 0) { inside = true; normalv = -normalv; } var overPoint = point + normalv * Epsilon; var underPoint = point - normalv * Epsilon; var reflectv = r.Direction.Reflect(normalv); this.CalculateRefraction(xs, out var n1, out var n2); return(new Interaction { T = t, Object = obj, Point = point, OverPoint = overPoint, UnderPoint = underPoint, Eyev = eyev, Normalv = normalv, Reflectv = reflectv, Inside = inside, N1 = n1, N2 = n2, }); }
public Interaction Precompute(Ray r) => Precompute(r, IntersectionList.Create(this));
public override IntersectionList LocalIntersect(Ray ray) { List <Intersection> xs; var o = ray.Origin; var d = ray.Direction; var a = (d.X * d.X) - (d.Y * d.Y) + (d.Z * d.Z); var b = (2 * o.X * d.X) - (2 * o.Y * d.Y) + (2 * o.Z * d.Z); var c = (o.X * o.X) - (o.Y * o.Y) + (o.Z * o.Z); if (a == 0) { if (b == 0) { return(IntersectionList.Empty()); } var t = -c / (2 * b); xs = new List <Intersection>() { new Intersection(t, this), }; this.IntersectCaps(ray, xs); return(IntersectionList.Create(xs.ToArray())); } var disc = b * b - 4 * a * c; if (disc < 0) { return(IntersectionList.Empty()); } 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; } xs = new List <Intersection>(); var y0 = o.Y + t0 * d.Y; if (this.Minimum < y0 && y0 < this.Maximum) { xs.Add(new Intersection(t0, this)); } var y1 = o.Y + t1 * d.Y; if (this.Minimum < y1 && y1 < this.Maximum) { xs.Add(new Intersection(t1, this)); } this.IntersectCaps(ray, xs); return(IntersectionList.Create(xs.ToArray())); }