コード例 #1
0
 public PrecomputedComplexLens(ComplexLens lens, string lrtfFilename, int sampleCount)
 {
     ComplexLens = lens;
     Lrtf = new LensRayTransferFunction(lens);
     // load precomputed LRTF from a file or compute it and save to file
     string filename = string.Format(lrtfFilename, sampleCount);
     LrtfTable = Lrtf.SampleLrtf3DCached(sampleCount, filename);
 }
コード例 #2
0
        public PrecomputedComplexLens(ComplexLens lens, string lrtfFilename, int sampleCount)
        {
            ComplexLens = lens;
            Lrtf        = new LensRayTransferFunction(lens);
            // load precomputed LRTF from a file or compute it and save to file
            string filename = string.Format(lrtfFilename, sampleCount);

            LrtfTable = Lrtf.SampleLrtf3DCached(sampleCount, filename);
        }
コード例 #3
0
ファイル: Program.cs プロジェクト: bzamecnik/bokehlab
        static void Main(string[] args)
        {
            //ComplexLens lens = ComplexLens.CreateDoubleGaussLens(Materials.Fixed.AIR, 4.0);
            //string lensName = "double_gauss";

            ComplexLens lens = ComplexLens.CreatePetzvalLens(Materials.Fixed.AIR, 4.0);
            string lensName = "petzval";

            //ComplexLens lens = ComplexLens.CreateBiconvexLens(150, 100, 0);
            //string lensName = "biconvex";

            LensRayTransferFunction lrtf = new LensRayTransferFunction(lens);

            int sampleCount = 128;

            Stopwatch stopwatch = Stopwatch.StartNew();

            var table = lrtf.SampleLrtf3D(sampleCount);

            stopwatch.Stop();

            //for (int i = 0; i < sampleCount; i++)
            //{
            //    for (int j = 0; j < sampleCount; j++)
            //    {
            //        for (int k = 0; k < sampleCount; k++)
            //        {
            //            var value = new LensRayTransferFunction.Parameters(table.Table[i, j, k]);
            //            Console.WriteLine((value != null) ? value.ToString() : "null");
            //        }
            //        Console.WriteLine();
            //    }
            //}

            Console.WriteLine("Size: {0}x{0}x{0}, elapsed time: {1} ms", sampleCount, stopwatch.ElapsedMilliseconds);

            string filename = string.Format(@"data\lrtf_{0}_{1}.bin", lensName, sampleCount);

            stopwatch.Reset();
            stopwatch.Start();
            table.Save(filename);
            stopwatch.Stop();

            Console.WriteLine("Saved sampled LRTF into file: {0}, elapsed time: {1} ms", filename, stopwatch.ElapsedMilliseconds);
        }
コード例 #4
0
        public void CompareInterpolatedLrtfValueWithOriginalOnes()
        {
            ComplexLens lens = ComplexLens.CreateDoubleGaussLens(Materials.Fixed.AIR, 4.0);
            LensRayTransferFunction lrtf = new LensRayTransferFunction(lens);

            int sampleCount = 128;
            string filename = string.Format(@"data\lrtf_double_gauss_{0}.bin", sampleCount);
            var table = lrtf.SampleLrtf3DCached(sampleCount, filename);

            Random random = new Random();
            for (int i = 0; i < 1000; i++)
            {
                var incomingParams = new LensRayTransferFunction.Parameters(
                    random.NextDouble(), random.NextDouble(),
                    random.NextDouble(), random.NextDouble()
                    );
                var outgoingParamsOriginal = lrtf.ComputeLrtf(incomingParams).ToVector4d();
                var outgoingParamsInterpolated = table.EvaluateLrtf3D(incomingParams).ToVector4d();
                //AssertEqualVector4d(outgoingParamsOriginal, outgoingParamsInterpolated);
            }
        }
コード例 #5
0
        public void CompareEvaluationTime()
        {
            ComplexLens lens = ComplexLens.CreateDoubleGaussLens(Materials.Fixed.AIR, 4.0);
            LensRayTransferFunction lrtf = new LensRayTransferFunction(lens);

            int sampleCount = 128;
            Console.WriteLine("LRTF table size: {0}x{0}x{0}", sampleCount);
            string filename = string.Format(@"data\lrtf_double_gauss_{0}.bin", sampleCount);
            var table = lrtf.SampleLrtf3DCached(sampleCount, filename);

            int valueCount = 1000000;
            Console.WriteLine("Number of values to evaluate: {0}", valueCount);

            Random random = new Random();
            var inParams = new List<LensRayTransferFunction.Parameters>();
            for (int i = 0; i < valueCount; i++)
            {
                inParams.Add(new LensRayTransferFunction.Parameters(
                    random.NextDouble(), random.NextDouble(),
                    random.NextDouble(), random.NextDouble()
                    ));
            }
            Stopwatch stopwatch = Stopwatch.StartNew();
            foreach (var inParam in inParams)
            {
                lrtf.ComputeLrtf(inParam);
            }
            stopwatch.Stop();
            Console.WriteLine("Ray tracing: {0} ms", stopwatch.ElapsedMilliseconds);
            stopwatch.Reset();
            stopwatch.Start();
            foreach (var inParam in inParams)
            {
                table.EvaluateLrtf3D(inParam);
            }
            stopwatch.Stop();
            Console.WriteLine("LRTF table interpolation: {0} ms", stopwatch.ElapsedMilliseconds);
        }
コード例 #6
0
        public ComplexLensLrtfForm()
        {
            InitializeComponent();

            SetDoubleBuffered(posThetaPanel);
            SetDoubleBuffered(posPhiPanel);
            SetDoubleBuffered(dirThetaPanel);
            SetDoubleBuffered(dirPhiPanel);

            variableParameterComboBox.DataSource = Enum.GetValues(
                typeof(LensRayTransferFunction.VariableParameter));
            variableParameterComboBox.SelectedItem = LensRayTransferFunction.VariableParameter.DirectionTheta;

            complexLenses = CreateLenses();
            lrtf = new LensRayTransferFunction(complexLenses[0]);

            lensComboBox.Items.AddRange(new[] { "Double Gauss", "Petzval", "Biconvex" });
            lensComboBox.SelectedIndex = 0;

            sampleCountNumeric.Value = 256;

            initialized = true;
            Recompute();
        }
コード例 #7
0
        /// <summary>
        /// Sample the LRTF with fixed position and direction phi parameters,
        /// ie. vary the respective theta parameters.
        /// </summary>
        /// <param name="sampleCount">Number of sample in each of the two
        /// variable dimensions.</param>
        /// <returns>Table of rays in parametrized representation.</returns>
        public Parameters[] SampleLrtf1D(LensRayTransferFunction.Parameters parameters,
            VariableParameter variableParam, int sampleCount)
        {
            Parameters[] table = new Parameters[sampleCount];

            switch (variableParam)
            {
                case VariableParameter.PositionTheta:
                    parameters.PositionTheta = 0;
                    break;
                case VariableParameter.PositionPhi:
                    parameters.PositionPhi = 0;
                    break;
                case VariableParameter.DirectionTheta:
                    parameters.DirectionTheta = 0;
                    break;
                case VariableParameter.DirectionPhi:
                    parameters.DirectionPhi = 0;
                    break;
                default:
                    break;
            }

            double param = 0.0;
            double step = 1 / (double)(sampleCount - 1);
            for (int i = 0; i < sampleCount; i++)
            {
                switch (variableParam)
                {
                    case VariableParameter.PositionTheta:
                        parameters.PositionTheta = param;
                        break;
                    case VariableParameter.PositionPhi:
                        parameters.PositionPhi = param;
                        break;
                    case VariableParameter.DirectionTheta:
                        parameters.DirectionTheta = param;
                        break;
                    case VariableParameter.DirectionPhi:
                        parameters.DirectionPhi = param;
                        break;
                    default:
                        break;
                }
                var outputParams = ComputeLrtf(parameters);
                if (!outputParams.IsDefined)
                {
                    outputParams = null;
                }
                table[i] = outputParams;
                param += step;
            }
            return table;
        }
コード例 #8
0
 public void ComputeLrtfResultInCorrectInterval()
 {
     ComplexLens lens = ComplexLens.CreateDoubleGaussLens(Materials.Fixed.AIR, 4.0);
     LensRayTransferFunction lrtf = new LensRayTransferFunction(lens);
     var incomingParams = new LensRayTransferFunction.Parameters(0.835057026164167, 0.375245163857585, 0.854223355117358, 0.000161428470239708);
     LensRayTransferFunction.Parameters outgoingParams = lrtf.ComputeLrtf(incomingParams);
     Console.WriteLine(outgoingParams);
 }
コード例 #9
0
 public void SampleLrtf()
 {
     ComplexLens lens = ComplexLens.CreateDoubleGaussLens(Materials.Fixed.AIR, 4.0);
     LensRayTransferFunction lrtf = new LensRayTransferFunction(lens);
     var defaultParameters = new LensRayTransferFunction.Parameters(0.5, 0.5, 1.0, 0.5);
     var table = lrtf.SampleLrtf1D(defaultParameters,
         LensRayTransferFunction.VariableParameter.DirectionTheta, 101);
     //int i = 0;
     //foreach (LensRayTransferFunction.Parameters rayParams in table)
     //{
     //    Console.WriteLine("[{0}]: {1}", i, rayParams);
     //    if (rayParams != null)
     //    {
     //        //Console.WriteLine("  {0}", lens.ConvertParametersToFrontSurfaceRay(rayParams));
     //    }
     //    i++;
     //}
     Console.WriteLine("{{ {0} }}", string.Join(",\n", table.Select((item) => (item != null) ? item.ToString() : "Null").ToArray()));
 }
コード例 #10
0
 /// <summary>
 /// Create a one-dimensional list of value of particular dimension
 /// from the list with all dimensions. Eg. select only list of
 /// direction phi's.
 /// </summary>
 /// <param name="rays"></param>
 /// <param name="?"></param>
 /// <returns></returns>
 private IEnumerable<double?> SelectRayParameterDimension(
     IList<LensRayTransferFunction.Parameters> rays,
     LensRayTransferFunction.VariableParameter dimension)
 {
     return rays.Select((ray) => (ray != null) ? (double?)ray[dimension] : null);
 }
コード例 #11
0
        private void PlotPanel(PaintEventArgs e, LensRayTransferFunction.VariableParameter shownParam)
        {
            base.OnPaint(e);

            Graphics g = e.Graphics;
            // scale drawing area to [0; sampleCount-1] x [0; 1]
            g.ScaleTransform(e.ClipRectangle.Width / (float)sampleCount, -e.ClipRectangle.Height);
            g.TranslateTransform(0, -1);

            g.Clear(Color.White);

            var values = SelectRayParameterDimension(outgoingRays, shownParam).ToList();
            double? lastValue = null;
            Pen linePen = new Pen(Color.Black, 40 / (float)e.ClipRectangle.Height);
            for (int i = 0; i < values.Count; i++)
            {
                var value = values[i];
                if (value.HasValue)
                {
                    g.FillRectangle(Brushes.LightBlue, i, 0, 1, (float)value.Value);
                }
                else
                {
                    g.FillRectangle(Brushes.LightSalmon, i, 0, 1, 1);
                }
                if ((lastValue != null) && (value != null))
                {
                    g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                    g.DrawLine(linePen, i - 0.5f, (float)lastValue.Value, i + 0.5f, (float)value.Value);
                    g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;
                }
                lastValue = value;
            }
        }
コード例 #12
0
 public void ComputeLrtfForRandomInput()
 {
     ComplexLens lens = ComplexLens.CreateDoubleGaussLens(Materials.Fixed.AIR, 4.0);
     LensRayTransferFunction lrtf = new LensRayTransferFunction(lens);
     Random random = new Random();
     for (int i = 0; i < 1000; i++)
     {
         var incomingParams = new LensRayTransferFunction.Parameters(
             random.NextDouble(), random.NextDouble(),
             random.NextDouble(), random.NextDouble()
             );
         LensRayTransferFunction.Parameters outgoingParams = lrtf.ComputeLrtf(incomingParams);
         if (outgoingParams != null)
         {
             if (outgoingParams.DirectionTheta < 0 || outgoingParams.DirectionTheta > 1 ||
                 outgoingParams.DirectionPhi < 0 || outgoingParams.DirectionPhi > 1 ||
                 outgoingParams.PositionTheta < 0 || outgoingParams.PositionTheta > 1 ||
                 outgoingParams.PositionPhi < 0 || outgoingParams.PositionPhi > 1)
             {
                 Console.WriteLine("Warning: parameter outside [0; 1] interval.");
                 Console.WriteLine("incoming: {0}", incomingParams);
                 Console.WriteLine("outgoing: {0}", outgoingParams);
                 Console.WriteLine();
             }
             //Assert.InRange(outgoingParams.DirectionTheta, 0.0, 1.0);
             //Assert.InRange(outgoingParams.DirectionPhi, 0.0, 1.0);
             //Assert.InRange(outgoingParams.PositionTheta, 0.0, 1.0);
             //Assert.InRange(outgoingParams.PositionPhi, 0.0, 1.0);
         }
     }
 }
コード例 #13
0
ファイル: ComplexLens.cs プロジェクト: bzamecnik/bokehlab
        /// <summary>
        /// Convert a ray with origin at the back or front lens surface from
        /// its parametric representation.
        /// </summary>
        /// <param name="position">Position on lens surface in parameteric
        /// representation (normalized hemispherical coordinates).</param>
        /// <param name="direction">Direction of the ray with respect to the
        /// local frame in parameteric representation (normalized hemispherical
        /// coordinates).
        /// </param>
        /// <param name="canonicalNormal">Normal of the lens surface
        /// hemisphere (typically (0,0,1) for the back surface or (0,0,-1) for
        /// the front surface).</param>
        /// <param name="surfaceSinTheta">Sine of the surface spherical cap
        /// theta angle.</param>
        /// <param name="sphericalSurface">Lens surface represented as a
        /// sphere.</param>
        /// <param name="surface">Lens surface with its normal field.</param>
        /// <returns>Ray corresponding to its parametric representation.
        /// </returns>
        public Ray ConvertParametersToSurfaceRay(
            LensRayTransferFunction.Parameters parameters,
            Vector3d canonicalNormal, double surfaceSinTheta,
            Sphere sphericalSurface, ElementSurface surface)
        {
            //Console.WriteLine("parameters->ray");

            //Console.WriteLine("position parameters: {0}", parameters.Position);
            // uniform spacing sampling for LRTF sampling
            Vector3d unitSpherePos = Sampler.SampleSphereWithUniformSpacing(
                parameters.Position, surfaceSinTheta, 1);
            //Console.WriteLine("unit sphere position: {0}", unitSpherePos);
            unitSpherePos.Z *= canonicalNormal.Z;

            Vector3d lensPos = sphericalSurface.Center + sphericalSurface.Radius * unitSpherePos;
            //Console.WriteLine("ray origin: {0}", lensPos);

            // - get normal N at P
            Vector3d normalLocal = surface.SurfaceNormalField.GetNormal(lensPos);
            // - compute direction D from spherical coordinates (wrt normal Z = (0,0,+/-1))
            double theta = 0.5 * Math.PI * parameters.DirectionTheta;
            double phi = 2 * Math.PI * parameters.DirectionPhi;
            double cosTheta = Math.Cos(theta);
            Vector3d directionZ = new Vector3d(
                Math.Cos(phi) * cosTheta,
                Math.Sin(phi) * cosTheta,
                Math.Sin(theta) * canonicalNormal.Z);
            // - rotate D from Z to N frame
            //   - using a (normalized) quaternion Q
            //   - N and Z should be assumed to be already normalized
            //   - more efficient method: Efficiently building a matrix to
            //     rotate one vector to another [moller1999]

            normalLocal.Normalize(); // TODO: check if it is unnecessary
            //Console.WriteLine("abs. direction: {0}", directionZ);
            //Console.WriteLine("local normal: {0}", normalLocal);
            Vector3d rotationAxis = Vector3d.Cross(canonicalNormal, normalLocal);
            //Console.WriteLine("rotation axis: {0}", rotationAxis);

            Vector3d rotatedDir = directionZ;
            if (rotationAxis.Length > 0)
            {
                double angle = Math.Acos(Vector3d.Dot(canonicalNormal, normalLocal));
                //Console.WriteLine("angle: {0}", angle);
                // first the local direction must be rotated around using the position phi!
                //Console.WriteLine("position phi: {0}", parameters.PositionPhi);
                Matrix4d rotMatrix = Matrix4d.CreateRotationZ(2 * Math.PI * parameters.PositionPhi);
                // only then can be transformed to the frame of the local normal
                rotMatrix = rotMatrix * Matrix4d.CreateFromAxisAngle(rotationAxis, angle);
                rotatedDir = Vector3d.Transform(directionZ, rotMatrix);
            }
            if (surface.Convex)
            {
                rotatedDir = -rotatedDir;
            }
            //Console.WriteLine("local direction: {0}", rotatedDir);

            Ray result = new Ray(lensPos, rotatedDir);
            return result;
        }
コード例 #14
0
ファイル: ComplexLensForm.cs プロジェクト: bzamecnik/bokehlab
 private void PrepareLrtf(ComplexLens lens, int sampleCount)
 {
     lrtf = new LensRayTransferFunction(lens);
     // load precomputed LRTF from a file or compute it and save to file
     string filename = string.Format(@"data\lrtf_double_gauss_{0}.bin", sampleCount);
     lrtfTable = lrtf.SampleLrtf3DCached(sampleCount, filename);
 }
コード例 #15
0
 private static void ConvertParametersToRayAndBack(
     LensRayTransferFunction.Parameters inputParams,
     Func<LensRayTransferFunction.Parameters, ComplexLens, LensRayTransferFunction.Parameters> func)
 {
     ComplexLens lens = ComplexLens.CreateDoubleGaussLens(Materials.Fixed.AIR, 4.0);
     var outputParams = func(inputParams, lens);
     Assert.Equal(inputParams.PositionTheta, outputParams.PositionTheta, 5);
     Assert.Equal(inputParams.PositionPhi, outputParams.PositionPhi, 5);
     Assert.Equal(inputParams.DirectionTheta, outputParams.DirectionTheta, 5);
     Assert.Equal(inputParams.DirectionPhi, outputParams.DirectionPhi, 5);
 }
コード例 #16
0
 private static void ConvertParametersToFrontSurfaceRayAndBack(
     LensRayTransferFunction.Parameters inputParams)
 {
     ConvertParametersToRayAndBack(inputParams, (parameters, lens) =>
         lens.ConvertFrontSurfaceRayToParameters(lens.ConvertParametersToFrontSurfaceRay(parameters))
     );
 }
コード例 #17
0
        public void SampleLrtfSaveLoadAndCompare()
        {
            ComplexLens lens = ComplexLens.CreateDoubleGaussLens(Materials.Fixed.AIR, 4.0);
            LensRayTransferFunction lrtf = new LensRayTransferFunction(lens);

            int sampleCount = 16;

            var table = lrtf.SampleLrtf3D(sampleCount);

            Console.WriteLine("Size: {0}x{0}x{0}", sampleCount);

            string filename = string.Format("lrtf_double_gauss_{0}.bin", sampleCount);

            table.Save(filename);

            Console.WriteLine("Saved sampled LRTF into file: {0}", filename);

            Console.WriteLine("Trying to load sampled LRTF from file and compare...");

            var recoveredTable = LensRayTransferFunction.Table3d.Load(filename);

            Assert.Equal(sampleCount, recoveredTable.Size);

            for (int i = 0; i < sampleCount; i++)
            {
                for (int j = 0; j < sampleCount; j++)
                {
                    for (int k = 0; k < sampleCount; k++)
                    {
                        Vector4d orig = table.Table[i, j, k];
                        Vector4d recovered = recoveredTable.Table[i, j, k];
                        AssertEqualVector4d(orig, recovered);
                    }
                }
            }

            Console.WriteLine("Compared OK");
        }
コード例 #18
0
 public void ComputeLrtf()
 {
     ComplexLens lens = ComplexLens.CreateDoubleGaussLens(Materials.Fixed.AIR, 4.0);
     LensRayTransferFunction lrtf = new LensRayTransferFunction(lens);
     var incomingParams = new LensRayTransferFunction.Parameters(0.5, 0.5, 0.7000000000000004, 0.0);
     LensRayTransferFunction.Parameters outgoingParams = lrtf.ComputeLrtf(incomingParams);
     Console.WriteLine("IN: {0}", incomingParams);
     Console.WriteLine("OUT: {0}", outgoingParams);
     if (outgoingParams != null)
     {
         Console.WriteLine("  {0}", lens.ConvertParametersToFrontSurfaceRay(outgoingParams));
     }
 }
コード例 #19
0
ファイル: ComplexLens.cs プロジェクト: bzamecnik/bokehlab
        public Ray ConvertParametersToFrontSurfaceRay(
            LensRayTransferFunction.Parameters parameters)
        {
            Vector3d canonicalNormal = -Vector3d.UnitZ;
            double surfaceSinTheta = frontSurfaceSinTheta;
            Sphere sphericalSurface = frontSphericalSurface;
            ElementSurface surface = ElementSurfaces.Last();

            return ConvertParametersToSurfaceRay(parameters,
                canonicalNormal, surfaceSinTheta, sphericalSurface, surface);
        }