public LinearOpticalBench() { RefractiveIndexGlass = 1.52; // crown glass RefractiveIndexAir = 1.00029; RefractedDirection = direction; Normal = new Vector(0.0, 100.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; } }
public static double Dot(Vector v1, Vector v2) { return v1.X * v2.X + v1.Y * v2.Y; }
public Vector(Vector vector) : this(vector.X, vector.Y) { }
/// <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; }
public override Vector TranslationToLocal() { Vector signedRadius = new Vector((Convex ? 1.0 : -1.0) * Radius, 0.0); return signedRadius; }
public static Point FromVector(Vector vector) { return new Point(vector.X, vector.Y); }
public Ray Translate(Vector translation) { return new Ray(Origin + translation, Direction); }
public Ray(Point origin, Vector direction) { Origin = new Point(origin); Direction = new Vector(direction); }