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)); }
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); } }
private void Recompute() { if (!initialized) { return; } double positionTheta = (double)positionThetaNumeric.Value; double positionPhi = (double)positionPhiNumeric.Value; double directionTheta = (double)directionThetaNumeric.Value; double directionPhi = (double)directionPhiNumeric.Value; var inputRay = new LensRayTransferFunction.Parameters( positionTheta, positionPhi, directionTheta, directionPhi); var variableParam = (LensRayTransferFunction.VariableParameter) variableParameterComboBox.SelectedValue; outgoingRays = lrtf.SampleLrtf1D(inputRay, variableParam, sampleCount); InvalidatePanels(); }
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); } } }
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 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())); }
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); }
/// <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); }
/// <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); }