private Vector3Pair intersect(Surface surface, RayTraceParameters params_, Vector3Pair ray) { Vector3 origin = surface.get_curve().intersect(ray); if (origin == null) { return(null); } if (!params_.get_unobstructed() && !surface.get_shape().inside(origin.project_xy())) { return(null); } Vector3 normal = surface.get_curve().normal(origin); if (ray.direction().z() < 0) { normal = normal.negate(); } return(new Vector3Pair(origin, normal)); }
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); }