Пример #1
0
        public LinearOpticalBench()
        {
            RefractiveIndexGlass = 1.52; // crown glass
            RefractiveIndexAir = 1.00029;

            RefractedDirection = direction;

            Normal = new Vector(0.0, 100.0);
        }
Пример #2
0
        public void Update()
        {
            IntersectionResults.Clear();

            IntersectionResult previousResult = new IntersectionResult()
            {
                OutgoingRay = new Ray(IncidentRay)
            };

            double lastRefractiveIndex = RefractiveIndices.AIR;
            Vector translationFromLensCenter = new Vector(0.0, 0.0);

            int maxIntersections = Elements.Count;
            for (int i = 0; i < maxIntersections; i++)
            {
                IntersectionResult result = new IntersectionResult();
                OpticalElement element = Elements[i];

                result.IncidentRay = new Ray(previousResult.OutgoingRay);

                Vector toLocal = element.TranslationToLocal();

                // compute intersection

                Point intersection = null;
                Ray rayIncidentToElement = result.IncidentRay.Translate(translationFromLensCenter + toLocal);
                result.Intersected = element.IntersectRay(rayIncidentToElement, out intersection);
                result.Normal = Vector.FromPoint(intersection);
                intersection = intersection - (translationFromLensCenter + toLocal);
                if (!result.Intersected)
                {
                    break;
                }
                result.Intersection = intersection;

                // compute refracted ray

                Vector outgoingDirection;
                if (Math.Abs(lastRefractiveIndex - element.NextRefractiveIndex) > double.Epsilon)
                {
                    outgoingDirection = result.IncidentRay.Direction.Length * Vector.refract(result.IncidentRay.Direction, result.Normal, lastRefractiveIndex, element.NextRefractiveIndex);
                }
                else
                {
                    // there's no border between different media and thus no refraction
                    outgoingDirection = result.IncidentRay.Direction;
                }
                result.OutgoingRay = new Ray(result.Intersection, outgoingDirection);
                result.Refracted = true; // TODO: differ refraction and TIR
                IntersectionResults.Add(result);
                previousResult = result;
                lastRefractiveIndex = element.NextRefractiveIndex;
                translationFromLensCenter.X += element.DistanceToNext;
            }
        }
Пример #3
0
 public static double Dot(Vector v1, Vector v2)
 {
     return v1.X * v2.X + v1.Y * v2.Y;
 }
Пример #4
0
 public Vector(Vector vector)
     : this(vector.X, vector.Y)
 {
 }
Пример #5
0
        /// <summary>
        /// Refract a ray on a border of different optical environments.
        /// </summary>
        /// <remarks>
        /// In case of total internal reflection a zero vector is returned.
        /// 
        /// The code is based on the PBRT implementation.
        /// </remarks>
        /// <param name="incident">incident vector in the world coordinates</param>
        /// <param name="normal">normal vector pointing outside the surface</param>
        /// <param name="etaI">index of refraction of the outer medium</param>
        /// <param name="etaT">index of refraction of the inner medium</param>
        /// <returns></returns>
        public static Vector refract(Vector incident, Vector normal, double etaI, double etaT)
        {
            Vector incidentNormalized = -incident.Normalize();

            // transform incident vector to the local coordinates with normal = (0, 1)
            double transformToLocalPhi = 0.5 * Math.PI - normal.Phi;
            incidentNormalized.Phi += transformToLocalPhi;

            // alpha = incident angle (incident vector to normal)
            // beta = refracted angle (refracted vector to normal)
            double cosi = incidentNormalized.Y;
            bool entering = cosi > 0.0;

            //// swap the indices of the ray is going from inside the surface
            //double ei = entering ? etaI : etaT;
            //double et = entering ? etaT : etaI;
            double ei = etaI;
            double et = etaT;

            double sini2 = Math.Max(0.0, 1.0 - incidentNormalized.Y * incidentNormalized.Y);
            double eta = ei / et;
            double sint2 = eta * eta * sini2;

            Vector refracted;
            if (sint2 < 1.0)
            {
                // compute the refraction vector
                double cost = Math.Sqrt(Math.Max(0.0, 1.0 - sint2));
                if (entering)
                {
                    cost = -cost;
                }
                double sintOverSini = eta;
                refracted = new Vector(sintOverSini * -incidentNormalized.X, cost);
                // transform back from the local coordinates
                refracted.Phi -= transformToLocalPhi;
            }
            else
            {
                // total internal reflection
                refracted = new Vector(incident);
                refracted.Phi += transformToLocalPhi;
                refracted.phi *= -1.0;
                refracted.Phi -= transformToLocalPhi;

                // or posibly return a dummy vector
                //return new Vector(0.0, 0.0);
            }
            return refracted;
        }
Пример #6
0
 public override Vector TranslationToLocal()
 {
     Vector signedRadius = new Vector((Convex ? 1.0 : -1.0) * Radius, 0.0);
     return signedRadius;
 }
Пример #7
0
 public static Point FromVector(Vector vector)
 {
     return new Point(vector.X, vector.Y);
 }
Пример #8
0
 public Ray Translate(Vector translation)
 {
     return new Ray(Origin + translation, Direction);
 }
Пример #9
0
 public Ray(Point origin, Vector direction)
 {
     Origin = new Point(origin);
     Direction = new Vector(direction);
 }