List <TracedRay> process_rays(Surface surface, TraceIntensityMode m, RayTraceResults result, List <TracedRay> input) { RayTraceParameters params_ = result._parameters; List <TracedRay> rays = new(); foreach (TracedRay i in input) { TracedRay ray = i; Transform3 t = ray.get_creator().get_transform_to(surface); Vector3Pair local1 = t.transform_line(ray.get_ray()); Vector3Pair pt = surface is Stop ? intersect((Stop)surface, params_, local1) : intersect(surface, params_, local1); if (pt != null) { result.add_intercepted(surface, ray); TracedRay cray = trace_ray(surface, m, result, ray, local1, pt); if (cray != null) { rays.Add(cray); } } } return(rays); }
static bool draw_traced_ray_recurs(Renderer renderer, TracedRay ray, double lost_len, Element ref_, bool hit_image, int D, bool draw_lost) { Transform3 t1 = ray.get_creator().get_transform_to(ref_); Element i_element = null; Vector3 v0 = t1.transform(ray.get_ray().origin()); Vector3 v1; if (ray.is_lost()) { if (!draw_lost) { return(false); } v1 = t1.transform(ray.get_ray().origin().plus(ray.get_ray().direction().times(lost_len))); } else { i_element = ray.get_intercept_element(); Transform3 t2 = i_element.get_transform_to(ref_); v1 = t2.transform(ray.get_intercept_point()); } Vector3Pair p = new Vector3Pair(v0, v1); bool done = false; for (TracedRay child_ray = ray.get_first_child(); child_ray != null; child_ray = child_ray.get_next_child()) { if (draw_traced_ray_recurs(renderer, child_ray, lost_len, ref_, hit_image, 2, false)) { done = true; } } if (!done && hit_image && !(i_element is Image)) { return(false); } switch (D) { case 2: // skip non tangential rays in 2d mode if (Math.Abs(p.x1()) > 1e-6) { return(false); } draw_ray_line(renderer, new Vector2Pair(p.v0.project_zy(), p.v1.project_zy()), ray); break; case 3: draw_ray_line(renderer, p, ray); break; } return(true); }
bool _lost; // does the ray intersect with an element ? public TracedRay(Vector3 origin, Vector3 direction) : base(new Vector3Pair(origin, direction)) { _len = Double.MaxValue; _creator = null; _parent = null; _child = null; _lost = true; }
private TracedRay trace_ray_simple(Surface surface, RayTraceResults result, TracedRay incident, Vector3Pair local, Vector3Pair pt) { if (surface is OpticalSurface) { return(trace_ray_simple((OpticalSurface)surface, result, incident, local, pt)); } else if (surface is Stop) { return(trace_ray_simple((Stop)surface, result, incident, local, pt)); } else { return(null); } }
TracedRay trace_ray(Surface surface, TraceIntensityMode m, RayTraceResults result, TracedRay incident, Vector3Pair local, Vector3Pair pt) { incident.set_len((pt.origin().minus(local.origin())).len()); incident.set_intercept(surface, pt.origin()); if (m == TraceIntensityMode.Simpletrace) { incident.set_intercept_intensity(1.0); return(trace_ray_simple(surface, result, incident, local, pt)); } else { // apply absorbtion from current material double i_intensity = incident.get_intensity() * incident.get_material().get_internal_transmittance( incident.get_wavelen(), incident.get_len()); incident.set_intercept_intensity(i_intensity); // FIXME // if (i_intensity < _discard_intensity) // return; if (m == TraceIntensityMode.Intensitytrace) { return(trace_ray_intensity(surface, result, incident, local, pt)); } else if (m == TraceIntensityMode.Polarizedtrace) { return(trace_ray_polarized(surface, result, incident, local, pt)); } else { throw new InvalidOperationException(); } } }
TracedRay trace_ray_simple(Stop surface, RayTraceResults result, TracedRay incident, Vector3Pair local, Vector3Pair intersect) { Vector2 v = intersect.origin().project_xy(); bool ir = true; // FIXME _intercept_reemit || result.get_params ().is_sequential (); if (ir && surface.get_shape().inside(v)) { // re-emit incident ray TracedRay r = result.newRay(intersect.origin(), incident.get_ray().direction()); r.set_wavelen(incident.get_wavelen()); r.set_intensity(incident.get_intensity()); r.set_material(incident.get_material()); r.set_creator(surface); incident.add_generated(r); return(r); } return(null); }
List <TracedRay> process_rays(Stop surface, TraceIntensityMode m, RayTraceResults result, List <TracedRay> input) { List <TracedRay> rays = new(); foreach (TracedRay i in input) { TracedRay ray = i; Transform3 t = ray.get_creator().get_transform_to(surface); Vector3Pair local = t.transform_line(ray.get_ray()); Vector3 origin = surface.get_curve().intersect(local); if (origin != null) { if (origin.project_xy().len() < surface.get_external_radius()) { Vector3 normal = surface.get_curve().normal(origin); if (local.direction().z() < 0) { normal = normal.negate(); } result.add_intercepted(surface, ray); TracedRay cray = trace_ray(surface, m, result, ray, local, new Vector3Pair(origin, normal)); if (cray != null) { rays.Add(cray); } } } } return(rays); }
static void draw_ray_line(Renderer r, Vector3Pair l, TracedRay ray) { r.draw_segment(l, ray_to_rgb(ray)); }
private TracedRay trace_ray_simple(OpticalSurface surface, RayTraceResults result, TracedRay incident, Vector3Pair local, Vector3Pair intersect) { bool right_to_left = intersect.normal().z() > 0; Medium prev_mat = surface.get_material(right_to_left ? 1 : 0); Medium next_mat = surface.get_material(!right_to_left ? 1 : 0); // check ray didn't "escaped" from its material // std::cout << prev_mat->name << " " << next_mat->name << // " " << incident.get_material()->name << std::endl; if (prev_mat != incident.get_material()) { return(null); } double wl = incident.get_wavelen(); double index = prev_mat.get_refractive_index(wl) / next_mat.get_refractive_index(wl); // refracted ray direction Vector3 direction = refract(surface, local, intersect.normal(), index); if (direction == null) { // total internal reflection Vector3 o = intersect.origin(); Vector3 dir = reflect(surface, local, intersect.normal()); TracedRay r = result.newRay(o, dir); r.set_wavelen(wl); r.set_intensity(incident.get_intensity()); r.set_material(prev_mat); r.set_creator(surface); incident.add_generated(r); return(r); } // transmit if (!next_mat.is_opaque()) { Vector3 o = intersect.origin(); TracedRay r = result.newRay(o, direction); r.set_wavelen(wl); r.set_intensity(incident.get_intensity()); r.set_material(next_mat); r.set_creator(surface); incident.add_generated(r); return(r); } // reflect if (next_mat.is_reflecting()) { Vector3 o = intersect.origin(); Vector3 dir = reflect(surface, local, intersect.normal()); TracedRay r = result.newRay(o, dir); r.set_wavelen(wl); r.set_intensity(incident.get_intensity()); r.set_material(prev_mat); r.set_creator(surface); incident.add_generated(r); return(r); } return(null); }
private TracedRay trace_ray_intensity(Surface surface, RayTraceResults result, TracedRay incident, Vector3Pair local, Vector3Pair pt) { throw new InvalidOperationException(); }
List <TracedRay> generate_rays( RayTraceResults result, RayTraceParameters parameters, PointSource source, Element target, PointSource.SourceInfinityMode mode) { if (!(target is OpticalSurface)) { return(new()); } OpticalSurface target_surface = (OpticalSurface)target; double rlen = parameters.get_lost_ray_length(); Distribution d = parameters.get_distribution(target_surface); List <TracedRay> rays = new(); ConsumerVector3 de = (Vector3 v) => { Vector3 r = target_surface.get_transform_to(source).transform(v); // pattern point on target surface Vector3 direction; Vector3 position; switch (mode) { case PointSource.SourceInfinityMode.SourceAtFiniteDistance: position = Vector3.vector3_0; direction = r.normalize(); break; default: case PointSource.SourceInfinityMode.SourceAtInfinity: direction = Vector3.vector3_001; position = new Vector3Pair( target_surface.get_position(source).minus(Vector3.vector3_001.times(rlen)), Vector3.vector3_001) .pl_ln_intersect(new Vector3Pair(r, direction)); break; } foreach (SpectralLine l in source.spectrum()) { // generated rays use source coordinates TracedRay ray = result.newRay(position, direction); ray.set_creator(source); ray.set_intensity(l.get_intensity()); // FIXME depends on distance from // source and pattern density ray.set_wavelen(l.get_wavelen()); Medium material = source.get_material(); if (material == null) { material = Air.air; // FIXME centralize as env - original uses env proxy. } ray.set_material(material); rays.Add(ray); } }; target_surface.get_pattern(de, d, parameters.get_unobstructed()); return(rays); }
public void add_generated(TracedRay r) { r._parent = this; r._next = _child; _child = r; }