public Ray Transfer(Ray incomingRay) { incomingRay.NormalizeDirection(); var inParams = ComplexLens.ConvertBackSurfaceRayToParameters(incomingRay); var outParams = LrtfTable.EvaluateLrtf3D(inParams); return ComplexLens.ConvertParametersToFrontSurfaceRay(outParams); }
public static Ray Reflect(Ray incoming, Vector3d normal) { Ray reflected = new Ray( incoming.Origin, Reflect(incoming.Direction, normal)); return reflected; }
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; }
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); }
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); }
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); }
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 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); }
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(); }
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 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; }
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())); } }
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; }
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); }
public static Ray NormalizeDirection(Ray ray) { return new Ray(ray.Origin, Vector3d.Normalize(ray.Direction)); }
public Ray(Ray ray) { Origin = ray.Origin; Direction = ray.Direction; }
public Ray Transfer(Vector3d objectPos, Vector3d lensPos) { Ray incomingRay = new Ray(lensPos, lensPos - objectPos); return Transfer(incomingRay); }
public Intersection Intersect(Ray ray) { return backSurface.Intersect(ray); }
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(); }
public Intersection Intersect(Ray ray) { FootprintDebugInfo debugInfo = null; return Intersect((Vector3)ray.Origin, (Vector3)(ray.Origin + ray.Direction), ref debugInfo); }
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); }
public Intersection Intersect(Ray ray) { return Layer.Intersect(ray); }
public Ray Transfer(Ray incomingRay) { return new Ray(incomingRay); }
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; }
public Ray Transfer(Ray incomingRay) { return Transfer(incomingRay.Origin, incomingRay.Origin + incomingRay.Direction); }
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(); }
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); }
public Intersection Intersect(Ray ray) { return ComplexLens.Intersect(ray); }
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); }
private Vector3d IntersectRayWithLensPlane(Ray incomingRay) { Vector3d origin = incomingRay.Origin; return new Vector3d(origin.X - origin.Z, origin.Y - origin.Z, 0); }