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); }
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); }
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); } }
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); }
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(); }
/// <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; }
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); }
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())); }
/// <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); }
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; } }
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); } } }
/// <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; }
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); }
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); }
private static void ConvertParametersToFrontSurfaceRayAndBack( LensRayTransferFunction.Parameters inputParams) { ConvertParametersToRayAndBack(inputParams, (parameters, lens) => lens.ConvertFrontSurfaceRayToParameters(lens.ConvertParametersToFrontSurfaceRay(parameters)) ); }
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"); }
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)); } }
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); }