public void PrepareLrtfLens(ComplexLens lens, string name) { int sampleCount = (int)lrtfSampleCountNumeric.Value; precomputedComplexLens = new PrecomputedComplexLens(lens, @"data\lrtf_" + name + @"_{0}.bin", sampleCount); rayTracer.Camera.Lens = precomputedComplexLens; }
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); }
public Ray Transfer(Ray incomingRay) { incomingRay.NormalizeDirection(); var inParams = ComplexLens.ConvertBackSurfaceRayToParameters(incomingRay); var outParams = LrtfTable.EvaluateLrtf3D(inParams); return(ComplexLens.ConvertParametersToFrontSurfaceRay(outParams)); }
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(); }
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(); }
public static ComplexLens CreateBiconvexLens( double curvatureRadius, double apertureRadius, double thickness) { var surfaces = new List <ComplexLens.ElementSurface>(); Sphere backSphere = new Sphere() { Radius = curvatureRadius, }; backSphere.Center = backSphere.GetCapCenter(apertureRadius, -Vector3d.UnitZ); backSphere.Center += new Vector3d(0, 0, thickness); surfaces.Add(new ComplexLens.ElementSurface() { ApertureRadius = apertureRadius, NextRefractiveIndex = Materials.Fixed.GLASS_CROWN_K7, Surface = backSphere, SurfaceNormalField = backSphere, Convex = true }); Sphere frontSphere = new Sphere() { Radius = curvatureRadius, }; frontSphere.Center = frontSphere.GetCapCenter(apertureRadius, Vector3d.UnitZ); surfaces.Add(new ComplexLens.ElementSurface() { ApertureRadius = apertureRadius, Surface = frontSphere, SurfaceNormalField = frontSphere, Convex = false }); ComplexLens lens = new ComplexLens(surfaces); return(lens); }
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 void DrawComplexLens(Graphics g, Func<Vector3d, Point> projFunc, ComplexLens lens) { float maxApertureRadius = (float)lens.ElementSurfaces.Select( surface => surface.ApertureRadius).Max(); // draw spheres foreach (var surface in lens.ElementSurfaces) { if (surface.Surface is Sphere) { Sphere sphere = (Sphere)surface.Surface; //DrawCircle(g, Pens.Blue, projFunc(sphere.Center), (float)sphere.Radius); //FillSquare(g, Brushes.Aquamarine, projFunc(sphere.Center), 3); DrawSphericalCap(g, sphere, surface.ApertureRadius, surface.Convex); } else if (surface.Surface is Circle) { Circle circle = (Circle)surface.Surface; DrawCircularStop(g, Pens.Violet, projFunc( new Vector3d(0, 0, circle.Z)), (float)circle.Radius, maxApertureRadius); } } }
public LensRayTransferFunction(ComplexLens lens) { this.Lens = lens; }
public Intersection Intersect(Ray ray) { return(ComplexLens.Intersect(ray)); }
public Vector3d GetFrontSurfaceSample(Vector2d sample) { return(ComplexLens.GetFrontSurfaceSample(sample)); }
public static ComplexLens CreateBiconvexLens( double curvatureRadius, double apertureRadius, double thickness) { var surfaces = new List<ComplexLens.ElementSurface>(); Sphere backSphere = new Sphere() { Radius = curvatureRadius, }; backSphere.Center = backSphere.GetCapCenter(apertureRadius, -Vector3d.UnitZ); backSphere.Center += new Vector3d(0, 0, thickness); surfaces.Add(new ComplexLens.ElementSurface() { ApertureRadius = apertureRadius, NextRefractiveIndex = Materials.Fixed.GLASS_CROWN_K7, Surface = backSphere, SurfaceNormalField = backSphere, Convex = true }); Sphere frontSphere = new Sphere() { Radius = curvatureRadius, }; frontSphere.Center = frontSphere.GetCapCenter(apertureRadius, Vector3d.UnitZ); surfaces.Add(new ComplexLens.ElementSurface() { ApertureRadius = apertureRadius, Surface = frontSphere, SurfaceNormalField = frontSphere, Convex = false }); ComplexLens lens = new ComplexLens(surfaces); return lens; }
/// <summary> /// Creates a new instance of a complex lens using a definition of /// elements. /// </summary> /// <remarks> /// The first and last surfaces have to be spherical. TODO: this is /// needed only for simpler sampling. In general planar surfaces or /// stops could be sampled too. /// </remarks> /// <param name="surfaceDefs">List of definitions of spherical or /// planar element surfaces or stops. Ordered from front to back. /// Must not be empty or null. /// </param> /// <param name="mediumRefractiveIndex">Index of refraction of medium /// outside the lens. It is assumed there is one medium on the scene /// side, senzor side and inside the lens.</param> /// <returns>The created complex lens instance.</returns> public static ComplexLens Create( IList<SphericalElementSurfaceDefinition> surfaceDefs, double mediumRefractiveIndex, double scale) { var surfaces = new List<ElementSurface>(); var surfaceDefsReverse = surfaceDefs.Reverse().ToList(); // scale the lens if needed if (Math.Abs(scale - 1.0) > epsilon) { surfaceDefsReverse = surfaceDefsReverse.Select(surface => surface.Scale(scale)).ToList(); } // thickness of the whole lens (from front to back apex) // (without the distance to the senzor - backmost surface def.) double lensThickness = surfaceDefsReverse.Skip(1).Sum(def => def.Thickness); double elementBasePlaneShiftZ = lensThickness; double lastCapHeight = 0; double capHeight = 0; // definition list is ordered from front to back, working list // must be ordered from back to front, so a conversion has to be // performed int defIndex = 0; foreach (var definition in surfaceDefsReverse) { if (defIndex > 0) { elementBasePlaneShiftZ -= definition.Thickness; } ElementSurface surface = new ElementSurface(); surface.ApertureRadius = 0.5 * definition.ApertureDiameter; if (defIndex + 1 < surfaceDefsReverse.Count) { surface.NextRefractiveIndex = surfaceDefsReverse[defIndex + 1].NextRefractiveIndex; } else { surface.NextRefractiveIndex = mediumRefractiveIndex; } if (definition.CurvatureRadius.HasValue) { // spherical surface double radius = definition.CurvatureRadius.Value; // convexity reverses when converting from front-to-back // back-to-front ordering surface.Convex = radius < 0; Sphere sphere = new Sphere() { Radius = Math.Abs(radius) }; sphere.Center = Math.Sign(radius) * sphere.GetCapCenter(surface.ApertureRadius, Vector3d.UnitZ); capHeight = Math.Sign(radius) * sphere.GetCapHeight(sphere.Radius, surface.ApertureRadius); elementBasePlaneShiftZ -= lastCapHeight - capHeight; sphere.Center += new Vector3d(0, 0, elementBasePlaneShiftZ); surface.Surface = sphere; surface.SurfaceNormalField = sphere; } else { // planar surface // both media are the same -> circular stop // else -> planar element surface surface.NextRefractiveIndex = definition.NextRefractiveIndex; surface.Convex = true; capHeight = 0; elementBasePlaneShiftZ -= lastCapHeight - capHeight; Circle circle = new Circle() { Radius = 0.5 * definition.ApertureDiameter, Z = elementBasePlaneShiftZ, }; surface.Surface = circle; surface.SurfaceNormalField = circle; } lastCapHeight = capHeight; surfaces.Add(surface); defIndex++; } //DEBUG //foreach (var surface in surfaces) //{ // Console.WriteLine("{0}, {1}, {2}", surface.ApertureRadius, // surface.Convex, surface.NextRefractiveIndex); //} ComplexLens lens = new ComplexLens(surfaces) { MediumRefractiveIndex = mediumRefractiveIndex }; return lens; }
/// <summary> /// Creates a new instance of a complex lens using a definition of /// elements. /// </summary> /// <remarks> /// The first and last surfaces have to be spherical. TODO: this is /// needed only for simpler sampling. In general planar surfaces or /// stops could be sampled too. /// </remarks> /// <param name="surfaceDefs">List of definitions of spherical or /// planar element surfaces or stops. Ordered from front to back. /// Must not be empty or null. /// </param> /// <param name="mediumRefractiveIndex">Index of refraction of medium /// outside the lens. It is assumed there is one medium on the scene /// side, senzor side and inside the lens.</param> /// <returns>The created complex lens instance.</returns> public static ComplexLens Create( IList <SphericalElementSurfaceDefinition> surfaceDefs, double mediumRefractiveIndex, double scale) { var surfaces = new List <ElementSurface>(); var surfaceDefsReverse = surfaceDefs.Reverse().ToList(); // scale the lens if needed if (Math.Abs(scale - 1.0) > epsilon) { surfaceDefsReverse = surfaceDefsReverse.Select(surface => surface.Scale(scale)).ToList(); } // thickness of the whole lens (from front to back apex) // (without the distance to the senzor - backmost surface def.) double lensThickness = surfaceDefsReverse.Skip(1).Sum(def => def.Thickness); double elementBasePlaneShiftZ = lensThickness; double lastCapHeight = 0; double capHeight = 0; // definition list is ordered from front to back, working list // must be ordered from back to front, so a conversion has to be // performed int defIndex = 0; foreach (var definition in surfaceDefsReverse) { if (defIndex > 0) { elementBasePlaneShiftZ -= definition.Thickness; } ElementSurface surface = new ElementSurface(); surface.ApertureRadius = 0.5 * definition.ApertureDiameter; if (defIndex + 1 < surfaceDefsReverse.Count) { surface.NextRefractiveIndex = surfaceDefsReverse[defIndex + 1].NextRefractiveIndex; } else { surface.NextRefractiveIndex = mediumRefractiveIndex; } if (definition.CurvatureRadius.HasValue) { // spherical surface double radius = definition.CurvatureRadius.Value; // convexity reverses when converting from front-to-back // back-to-front ordering surface.Convex = radius < 0; Sphere sphere = new Sphere() { Radius = Math.Abs(radius) }; sphere.Center = Math.Sign(radius) * sphere.GetCapCenter(surface.ApertureRadius, Vector3d.UnitZ); capHeight = Math.Sign(radius) * sphere.GetCapHeight(sphere.Radius, surface.ApertureRadius); elementBasePlaneShiftZ -= lastCapHeight - capHeight; sphere.Center += new Vector3d(0, 0, elementBasePlaneShiftZ); surface.Surface = sphere; surface.SurfaceNormalField = sphere; } else { // planar surface // both media are the same -> circular stop // else -> planar element surface surface.NextRefractiveIndex = definition.NextRefractiveIndex; surface.Convex = true; capHeight = 0; elementBasePlaneShiftZ -= lastCapHeight - capHeight; Circle circle = new Circle() { Radius = 0.5 * definition.ApertureDiameter, Z = elementBasePlaneShiftZ, }; surface.Surface = circle; surface.SurfaceNormalField = circle; } lastCapHeight = capHeight; surfaces.Add(surface); defIndex++; } //DEBUG //foreach (var surface in surfaces) //{ // Console.WriteLine("{0}, {1}, {2}", surface.ApertureRadius, // surface.Convex, surface.NextRefractiveIndex); //} ComplexLens lens = new ComplexLens(surfaces) { MediumRefractiveIndex = mediumRefractiveIndex }; return(lens); }