예제 #1
0
 public Ray Transfer(Ray incomingRay)
 {
     incomingRay.NormalizeDirection();
     var inParams = ComplexLens.ConvertBackSurfaceRayToParameters(incomingRay);
     var outParams = LrtfTable.EvaluateLrtf3D(inParams);
     return ComplexLens.ConvertParametersToFrontSurfaceRay(outParams);
 }
예제 #2
0
파일: Ray.cs 프로젝트: bzamecnik/bokehlab
 public static Ray Reflect(Ray incoming, Vector3d normal)
 {
     Ray reflected = new Ray(
         incoming.Origin,
         Reflect(incoming.Direction, normal));
     return reflected;
 }
예제 #3
0
파일: Plane.cs 프로젝트: bzamecnik/bokehlab
 public Intersection Intersect(Ray ray)
 {
     double t = Vector3d.Dot((Origin - ray.Origin), Normal)
         / Vector3d.Dot(ray.Direction, Normal);
     Vector3d? intersectionPos = ray.Evaluate(t);
     return intersectionPos.HasValue ?
         new Intersection(intersectionPos.Value) : null;
 }
예제 #4
0
        public void TestTransferRayOutsideAperture()
        {
            // ray outside aperture but on the lens plane

            ThinLens thinLens = new ThinLens(5, 4);
            Vector3d lensPos = new Vector3d(20, 30, 0);
            Vector3d objectPos = new Vector3d(1, 2, 5);
            Ray expectedRay = new Ray(lensPos, new Vector3d(1, 2, 5));
            Ray outgoingRay = thinLens.Transfer(objectPos, lensPos);

            Assert.Null(outgoingRay);
        }
예제 #5
0
        public void TestTransferRayInfiniteImage()
        {
            // |object.Z| = |f|, so that the image is at infinity in image space

            ThinLens thinLens = new ThinLens(5, 4);
            Vector3d lensPos = new Vector3d(2, 3, 0);
            Vector3d objectPos = new Vector3d(1, 2, 5);
            Ray expectedRay = new Ray(lensPos, new Vector3d(1, 2, 5));
            Ray outgoingRay = thinLens.Transfer(objectPos, lensPos);

            Assert.NotNull(outgoingRay);
            Assert.Equal(expectedRay, outgoingRay, rayComparer);
        }
예제 #6
0
        public void TestTransferRayReverse()
        {
            // object from image space
            // |object.Z| > |f|
            // ray within aperture

            ThinLens thinLens = new ThinLens(5, 4);
            Vector3d lensPos = new Vector3d(2, 3, 0);
            Vector3d objectPos = new Vector3d(1, 2, -15);
            Ray expectedRay = new Ray(lensPos, new Vector3d(-2.5, -4.0, 7.5));
            Ray outgoingRay = thinLens.Transfer(objectPos, lensPos);

            Assert.NotNull(outgoingRay);
            Assert.Equal(expectedRay, outgoingRay, rayComparer);
        }
예제 #7
0
        public ComplexLensForm()
        {
            InitializeComponent();
            complexLens = CreateLens();
            if (showAlsoLrtf)
            {
                PrepareLrtf(complexLens, 128);
            }
            //directionPhi = Math.PI;
            directionPhi = 1.0;
            incomingRay = new Ray(new Vector3d(25, 0, 300), new Vector3d(Math.Sin(directionPhi), 0, Math.Cos(directionPhi)));

            rayDirectionPhiNumeric.Value = (decimal)directionPhi;
            FillVectorToControls(incomingRay.Origin, rayOriginXNumeric, rayOriginYNumeric, rayOriginZNumeric);
            initialized = true;
            Recompute();
        }
예제 #8
0
        public void TraceSingleRay()
        {
            ComplexLens lens = ComplexLens.CreateBiconvexLens(4, 2, 0);

            Sampler sampler = new Sampler();
            int sampleCount = 64;
            int sqrtSampleCount = (int)Math.Sqrt(sampleCount);
            Vector3d objectPos = new Vector3d(10, 0, 100);
            Vector3d direction = new Vector3d(0, 0, 0);
            Ray ray = new Ray(objectPos, direction);
            Intersection isec = lens.Intersect(ray);
            if (isec == null)
            {
                return;
            }
            Ray result = lens.Transfer(objectPos, isec.Position);
        }
예제 #9
0
        public SphereIntersectionForm()
        {
            InitializeComponent();
            sphere = new Sphere()
            {
                Radius = 100,
                Center = new Vector3d(0, 0, 0)
            };
            double directionPhi = 0; // Math.PI;
            incomingRay = new Ray(new Vector3d(5, 0, 110), new Vector3d(Math.Sin(directionPhi), 0, Math.Cos(directionPhi)));

            rayDirectionPhiNumeric.Value = (decimal)directionPhi;
            sphereRadiusNumeric.Value = (decimal)sphere.Radius;
            FillVectorToControls(sphere.Center, sphereCenterXNumeric, sphereCenterYNumeric, sphereCenterZNumeric);
            FillVectorToControls(incomingRay.Origin, rayOriginXNumeric, rayOriginYNumeric, rayOriginZNumeric);
            initialized = true;
            Recompute();
        }
예제 #10
0
        public BiconvexLensForm()
        {
            InitializeComponent();
            biconvexLens = new BiconvexLens()
            {
                CurvatureRadius = 150,
                ApertureRadius = 100,
                RefractiveIndex = Materials.Fixed.GLASS_CROWN_BK7
            };
            complexLens = ComplexLens.CreateBiconvexLens(150, 100, 0);
            double directionPhi = Math.PI;
            incomingRay = new Ray(new Vector3d(70, 0, 150), new Vector3d(Math.Sin(directionPhi), 0, Math.Cos(directionPhi)));

            rayDirectionPhiNumeric.Value = (decimal)directionPhi;
            curvatureRadiusNumeric.Value = (decimal)biconvexLens.CurvatureRadius;
            apertureRadiusNumeric.Value = (decimal)biconvexLens.ApertureRadius;
            FillVectorToControls(incomingRay.Origin, rayOriginXNumeric, rayOriginYNumeric, rayOriginZNumeric);
            initialized = true;
            Recompute();
        }
예제 #11
0
        public Intersection Intersect(Ray ray)
        {
            //// there is an implicit assumption that the circle is on the XY
            //// plane and centered at (0,0,0)

            //Vector3d origin = ray.Origin;

            //// transform to XY plane
            //origin.Z -= Z;

            //double t = -origin.Y / ray.Direction.Y;
            //// TODO: use a better epsilon
            //if ((t < 0) || (ray.Direction.X < Double.Epsilon))
            //{
            //    // no intersection with the circle plane
            //    return null;
            //}
            //Vector3d intersectionPos = new Vector3d();
            //intersectionPos.Y = origin.Y - origin.X * ray.Direction.Y / ray.Direction.X;
            //if (Math.Abs(intersectionPos.Y) > Radius)
            //{
            //    // there is an intersection but outside the circle
            //    return null;
            //}

            //// transform from XY plane
            //intersectionPos.Z += Z;

            Intersection intersection = plane.Intersect(ray);
            if (intersection == null)
            {
                return null;
            }
            bool inside = intersection.Position.Xy.LengthSquared <= Radius * Radius;
            //if (Inverted)
            //{
            //    inside = !inside;
            //}
            return (inside) ? intersection : null;
        }
예제 #12
0
        public void IntersectSphere()
        {
            Sphere sphere = new Sphere()
            {
                Radius = 2
            };
            double biggerSphereFactor = 3;

            Sampler sampler = new Sampler();
            int sampleCount = 64;
            int sqrtSampleCount = (int)Math.Sqrt(sampleCount);
            foreach (Vector2d sample in sampler.GenerateJitteredSamples(sqrtSampleCount))
            {
                // shoot rays at the sphere center from a bigger concontric sphere
                Vector3d unitSphereSample = Sampler.UniformSampleSphereWithEqualArea(sample, -1, 1);
                Vector3d sourcePos = biggerSphereFactor * sphere.Radius * unitSphereSample;
                Ray ray = new Ray(sourcePos, sphere.Center - sourcePos);
                Intersection intersection = sphere.Intersect(ray);
                Assert.NotNull(intersection);
                Vector3d intPos = intersection.Position;
                Console.WriteLine("Black, {0},", ray.ToLine());
                Console.WriteLine(String.Format("Red, {0},", intPos.ToPoint()));
            }
        }
예제 #13
0
파일: Ray.cs 프로젝트: bzamecnik/bokehlab
 public static Ray Refract(Ray incoming, Vector3d normal, double n1, double n2)
 {
     Vector3d direction = Refract(incoming.Direction, normal, n1, n2, false);
     Ray refracted = new Ray(incoming.Origin, direction);
     return refracted;
 }
예제 #14
0
        public void TestTransferRayStraightLensCenter()
        {
            // object from object space
            // |object.Z| > |f|
            // ray goes through the lens center

            ThinLens thinLens = new ThinLens(5, 4);
            Vector3d lensPos = new Vector3d(0, 0, 0);
            Vector3d objectPos = new Vector3d(1, 2, 15);
            Ray expectedRay = new Ray(lensPos, new Vector3d(-0.5, -1.0, -7.5));
            Ray outgoingRay = thinLens.Transfer(objectPos, lensPos);

            Assert.NotNull(outgoingRay);
            Assert.Equal(expectedRay, outgoingRay, rayComparer);
        }
예제 #15
0
파일: Ray.cs 프로젝트: bzamecnik/bokehlab
 public static Ray NormalizeDirection(Ray ray)
 {
     return new Ray(ray.Origin, Vector3d.Normalize(ray.Direction));
 }
예제 #16
0
파일: Ray.cs 프로젝트: bzamecnik/bokehlab
 public Ray(Ray ray)
 {
     Origin = ray.Origin;
     Direction = ray.Direction;
 }
예제 #17
0
 public Ray Transfer(Vector3d objectPos, Vector3d lensPos)
 {
     Ray incomingRay = new Ray(lensPos, lensPos - objectPos);
     return Transfer(incomingRay);
 }
예제 #18
0
 public Intersection Intersect(Ray ray)
 {
     return backSurface.Intersect(ray);
 }
예제 #19
0
        private void Recompute()
        {
            if (!initialized)
            {
                return;
            }

            directionPhi = (double)rayDirectionPhiNumeric.Value;
            if (inputLensPosDirectly)
            {
                incomingRay.Origin = GetVectorFromControls(rayOriginXNumeric, rayOriginYNumeric, rayOriginZNumeric);
                incomingRay.Direction = new Vector3d(Math.Sin(directionPhi), 0, Math.Cos(directionPhi));
            }
            else
            {
                //// compute lens position from lens position parameter
                //// (with Y = 0)
                //double lensPosV = 0.5;
                //lensPosU = (double)lensPosTNumeric.Value;
                //if (lensPosU > 1.0)
                //{
                //    lensPosU = 2.0 - lensPosU;
                //    lensPosV = 0.0;
                //}
                //incomingRay = complexLens.ConvertParametersToBackSurfaceRay(
                //    new LensRayTransferFunction.Parameters(
                //        lensPosU, lensPosV, directionPhi, 0));
                ////Console.WriteLine("IN: {0}", incomingRay);
                var incomingParams = GetIncomingParams();
                incomingRay = complexLens.ConvertParametersToBackSurfaceRay(incomingParams);
            }

            intersections = new List<Vector3d>();
            outgoingRay = complexLens.TransferDebug(incomingRay, out intersections, true);
            if (!inputLensPosDirectly)
            {
                backLensPos = incomingRay.Origin;
                //Console.WriteLine("OUT: {0}", outgoingRay);
            }
            else
            {
                if (outgoingRay != null)
                {
                    Intersection backInt = complexLens.Intersect(incomingRay);
                    backLensPos = backInt.Position;
                }
                else
                {
                    backLensPos = Vector3d.Zero;
                }
            }
            drawingYProjectionPanel.Invalidate();
            drawingXProjectionPanel.Invalidate();
            drawingZProjectionPanel.Invalidate();
        }
예제 #20
0
 public Intersection Intersect(Ray ray)
 {
     FootprintDebugInfo debugInfo = null;
     return Intersect((Vector3)ray.Origin, (Vector3)(ray.Origin + ray.Direction), ref debugInfo);
 }
예제 #21
0
        public Intersection Intersect(Ray ray)
        {
            // Method: Zara et al.: Modern Computer Graphics

            // T is a point in the middle of the segment between the two
            // intersections (if they exist).
            // T is also projection of Center to the ray, thus (T-Center) is
            // perpendicular to (T-Origin).

            // we must work with normalized ray direction
            Vector3d direction = ray.Direction;
            direction.Normalize();

            Vector3d b = Center - ray.Origin;
            // |b|^2
            double bLengthSqr = Vector3d.Dot(b, b);

            // t_0 is the length od projection of b to ray.Direction
            // t_0 = |(T-Origin)| = |b.direction|
            // t_0 is a ray parameter, T = Origin + t_0 * Direction
            double bDotDirection = Vector3d.Dot(b, direction);
            double t0 = Math.Abs(bDotDirection);
            // d = |(T-Center)|, d^2 = |b|^2 - t_0^2 (Pythagorean theorem)
            double dSqr = bLengthSqr - t0 * t0;
            // t_d ... distance from T to the intersection(s)
            // t_d^2 = Radius^2 - d^2 (Pythagorean theorem again)
            // t_d also acts as a ray parameter
            double tdSqr = Radius * Radius - dSqr;

            Vector3d intersection;
            if (tdSqr > epsilon)
            {
                // two intersections, at Origin + (t_0 +/- t_d) * Direction
                // we're intereseted only in the first intersection
                // NOTE: bDotDirection is the signed t0
                double td = Math.Sqrt(tdSqr);
                double t = bDotDirection - td;
                if (t < epsilon)
                {
                    // the first intersection is behind the ray or
                    // the ray origin is the first intersection
                    t = bDotDirection + td;
                }
                if (t < epsilon)
                {
                    // even the second intersection is behind the ray
                    return null;
                }
                intersection = ray.Origin + t * direction;
            }
            else if (tdSqr < -epsilon)
            {
                // no intersection
                return null;
            }
            else // if ((t_d)^2 == 0)
            {
                // one (double) intersection, at Origin + t_0 * Direction
                double t = bDotDirection;
                if (t < epsilon)
                {
                    // intersection is behind the ray
                    return null;
                }
                intersection = ray.Origin + t * direction;
            }
            return new Intersection(intersection, null);
        }
예제 #22
0
파일: Scene.cs 프로젝트: bzamecnik/bokehlab
 public Intersection Intersect(Ray ray)
 {
     return Layer.Intersect(ray);
 }
예제 #23
0
 public Ray Transfer(Ray incomingRay)
 {
     return new Ray(incomingRay);
 }
예제 #24
0
        public Ray Transfer(Vector3d objectPos, Vector3d lensPos)
        {
            //Console.WriteLine("Biconvex lens");

            // lensPos should be already an intersection of of the incoming
            // ray with the back surface

            if ((lensPos.Z <= 0) || (objectPos.Z < lensPos.Z))
            {
                // lens sample is in the scene space or the ray origin
                // is not behind the back surface
                return null;
            }

            // refract the incoming ray
            Vector3d incomingDir = Vector3d.Normalize(lensPos - objectPos);
            //Console.WriteLine("Incoming: {0}, ", new Ray(lensPos, lensPos - objectPos).ToString());
            Vector3d direction = Ray.Refract(incomingDir, backSurface.GetNormal(lensPos),
                Materials.Fixed.AIR, RefractiveIndex, false);
            if (direction == Vector3d.Zero)
            {
                return null;
            }
            // intersect the ray with the front surface
            Intersection intersection = frontSurface.Intersect(new Ray(lensPos, direction));
            //Console.WriteLine("Outgoing: {0}, ", new Ray(lensPos, direction).ToString());
            if (intersection == null)
            {
                return null;
            }
            // refract the ray again
            direction = Vector3d.Normalize(intersection.Position - lensPos);
            direction = Ray.Refract(direction, -frontSurface.GetNormal(intersection.Position),
                RefractiveIndex, Materials.Fixed.AIR, false);
            if (direction == Vector3d.Zero)
            {
                return null;
            }
            Ray transferredRay = new Ray(intersection.Position, direction);
            //Console.WriteLine("Outgoing: {0}, ", transferredRay.ToString());
            return transferredRay;
        }
예제 #25
0
 public Ray Transfer(Ray incomingRay)
 {
     return Transfer(incomingRay.Origin, incomingRay.Origin + incomingRay.Direction);
 }
예제 #26
0
        private void Recompute()
        {
            if (!initialized)
            {
                return;
            }

            incomingRay.Origin = GetVectorFromControls(rayOriginXNumeric, rayOriginYNumeric, rayOriginZNumeric);
            double directionPhi = (double)rayDirectionPhiNumeric.Value;
            incomingRay.Direction = new Vector3d(Math.Sin(directionPhi), 0, Math.Cos(directionPhi));

            Intersection backInt = biconvexLens.Intersect(incomingRay);
            if (backInt != null)
            {
                outgoingRay = biconvexLens.Transfer(incomingRay.Origin, backInt.Position);
                backLensPos = backInt.Position;
            }
            else
            {
                outgoingRay = null;
                backLensPos = Vector3d.Zero;
            }
            backInt = complexLens.Intersect(incomingRay);
            if (backInt != null)
            {
                complexOutgoingRay = complexLens.Transfer(incomingRay.Origin, backInt.Position);
            }
            else
            {
                complexOutgoingRay = null;
            }
            drawingPanel.Invalidate();
        }
예제 #27
0
 public Ray Transfer(Ray incomingRay)
 {
     Vector3d origin = incomingRay.Origin;
     Vector3d lensPos;
     if (origin.Z != 0)
     {
         // make sure lensPos is on the lens
         // - if it is not on the lens plane (z=0) intersect the ray with this plane
         lensPos = IntersectRayWithLensPlane(incomingRay);
     }
     else
     {
         lensPos = origin;
         origin = -incomingRay.Direction;
     }
     return Transfer(origin, lensPos);
 }
예제 #28
0
 public Intersection Intersect(Ray ray)
 {
     return ComplexLens.Intersect(ray);
 }
예제 #29
0
        public Intersection Intersect(Ray ray)
        {
            // intersect
            Intersection intersection = Plane.Intersect(ray);
            if (intersection == null)
            {
                return null;
            }
            Vector3d intersectionPos = intersection.Position;

            // compute 2D position in image coordinates
            Vector2d intPosImage = WorldToImage(intersectionPos);
            if ((intPosImage.X < 0) || (intPosImage.X >= RasterSize.Width) ||
                (intPosImage.Y < 0) || (intPosImage.Y >= RasterSize.Height))
            {
                return null;
            }

            // retrieve color
            // TODO: possibly to some bilinear interpolation
            int x = (int)intPosImage.X;
            int y = (int)intPosImage.Y;

            float[] color = new float[Image.ColorChannelsCount];
            for (int i = 0; i < Image.ColorChannelsCount; i++)
            {
                color[i] = Image.Image[x, y, i];
            }
            return new Intersection(intersectionPos, color);
        }
예제 #30
0
 private Vector3d IntersectRayWithLensPlane(Ray incomingRay)
 {
     Vector3d origin = incomingRay.Origin;
     return new Vector3d(origin.X - origin.Z, origin.Y - origin.Z, 0);
 }