コード例 #1
0
ファイル: AbstractCsg.cs プロジェクト: fremag/ray-tracer
        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);
        }
コード例 #2
0
ファイル: Cone.cs プロジェクト: KallDrexx/ray-tracer
        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);
        }
コード例 #3
0
ファイル: Cylinder.cs プロジェクト: KallDrexx/ray-tracer
        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);
        }
コード例 #4
0
        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);
        }