protected Medium _mat = Air.air; // FIXME - should be settable

        public RaySource(int id, Vector3Pair p, Transform3 transform, double min_intensity, double max_intensity,
                         List <SpectralLine> spectrum) : base(id, p, transform)
        {
            _max_intensity = max_intensity;
            _max_intensity = min_intensity;
            _spectrum      = spectrum;
        }
Exemple #2
0
        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);
        }
Exemple #3
0
 public Lens(int id, Vector3Pair position, Transform3 transform, List <OpticalSurface> surfaces,
             List <Element> elementList, Stop stop)
     : base(id, position, transform, elementList)
 {
     this._stop     = stop;
     this._surfaces = surfaces;
 }
Exemple #4
0
        private Vector3Pair intersect(Stop surface, RayTraceParameters params_, Vector3Pair ray)
        {
            Vector3 origin = surface.get_curve().intersect(ray);

            if (origin == null)
            {
                return(null);
            }

            Vector2 v = origin.project_xy();

            if (v.len() > surface.get_external_radius())
            {
                return(null);
            }

            bool ir = true; // FIXME _intercept_reemit || params.is_sequential ();

            if (!ir && surface.get_shape().inside(v))
            {
                return(null);
            }

            Vector3 normal = surface.get_curve().normal(origin);

            if (ray.direction().z() < 0)
            {
                normal = normal.negate();
            }

            return(new Vector3Pair(origin, normal));
        }
Exemple #5
0
 override public Vector3 intersect(Vector3Pair ray)
 {
     //static int count = 0;
     //count++;
     if (_feder_algo)
     {
         Vector3Pair v3p = compute_intersection(ray.origin(), ray.direction(), this);
         if (v3p == null)
         {
             return(null);
         }
         return(v3p.point());
         // normal.normalize();
         //	  if (ok && count % 25 == 0)
         //	    {
         //	      printf ("{ %.16f, %.16f", this->_r, this->_k);
         //	      printf (", %.16f, %.16f, %.16f, %.16f, %.16f, %.16f",
         //this->_A4,              this->_A6, this->_A8, this->_A10, this->_A12, this->_A14);
         //	      printf (", %.16f, %.16f, %.16f", ray.origin ().x (),
         //		      ray.origin ().y (), ray.origin ().z ());
         //	      printf (", %.16f, %.16f, %.16f", ray.direction ().x (),
         //		      ray.direction ().y (), ray.direction ().z ());
         //	      printf (", %.16f, %.16f, %.16f },\n", point.x (), point.y
         //(),             point.z ());
         //	    }
     }
     else
     {
         return(base_intersect(ray));
     }
 }
        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);
        }
        void draw_2d_fit(RendererViewport r, OpticalSystem system, bool keep_aspect)
        {
            Vector3Pair b = system.get_bounding_box();

            r.set_window(Vector2Pair.from(b, 2, 1), keep_aspect);
            r.set_camera_direction(Vector3.vector3_100);
            r.set_camera_position(Vector3.vector3_0);

            r.set_feature_size(b.v1.y() - b.v0.y() / 20.0);
        }
Exemple #8
0
        public override Vector3 intersect(Vector3Pair ray)
        {
            double ax = ray.origin().x();
            double ay = ray.origin().y();
            double az = ray.origin().z();
            double bx = ray.direction().x();
            double by = ray.direction().y();
            double bz = ray.direction().z();

            /*
             * find intersection point between conical section and ray,
             * telescope optics, page 266
             */
            double a = (_sh * MathUtils.square(bz) + MathUtils.square(by) + MathUtils.square(bx));
            double b = ((_sh * bz * az + by * ay + bx * ax) / _roc - bz) * 2.0;
            double c = (_sh * MathUtils.square(az) + MathUtils.square(ay) + MathUtils.square(ax))
                       / _roc
                       - 2.0 * az;

            double t;

            if (a == 0)
            {
                t = -c / b;
            }
            else
            {
                double d = MathUtils.square(b) - 4.0 * a * c / _roc;

                if (d < 0)
                {
                    return(null); // no intersection
                }
                double s = Math.Sqrt(d);

                if (a * bz < 0)
                {
                    s = -s;
                }

                if (_sh < 0)
                {
                    s = -s;
                }

                t = (2.0 * c) / (s - b);
            }

            if (t <= 0) // ignore intersection if before ray origin
            {
                return(null);
            }

            return(ray.origin().plus(ray.direction().times(t)));
        }
        protected Vector3 base_intersect(Vector3Pair ray)
        {
            Vector3 origin;
            // initial intersection with z=0 plane
            {
                double s = ray.direction().z();

                if (s == 0)
                {
                    return(null);
                }

                double a = -ray.origin().z() / s;

                if (a < 0)
                {
                    return(null);
                }

                origin = ray.origin().plus(ray.direction().times(a));
            }

            int n = 32; // avoid infinite loop

            while (n-- > 0)
            {
                double new_sag = sagitta(origin.project_xy());
                double old_sag = origin.z();

                // project previous intersection point on curve
                origin = new Vector3(origin.x(), origin.y(), new_sag);

                // stop if close enough
                if (Math.Abs(old_sag - new_sag) < 1e-10)
                {
                    break;
                }

                // get curve tangeante plane at intersection point
                Vector3 norm = normal(origin);

                // intersect again with new tangeante plane
                Vector3Pair p = new Vector3Pair(origin, norm);
                double      a = p.pl_ln_intersect_scale(ray);

                if (a < 0)
                {
                    return(null);
                }
                // See https://en.wikipedia.org/wiki/Line%E2%80%93plane_intersection
                origin = ray.origin().plus(ray.direction().times(a));
            }
            return(origin);
        }
Exemple #10
0
        Vector3 reflect(OpticalSurface surface, Vector3Pair ray, Vector3 normal)
        {
            // Algorithm from Bram de Greve article "Reflections & Refractions in
            // Raytracing" http://www.bramz.org/

            // assert (Math.abs(normal.len() - 1.0) < 1e-10);
            // assert (Math.abs((ray.direction().len()) - 1.0) < 1e-10);

            double cosi = normal.dot(ray.direction());

            return(ray.direction().minus(normal.times(2.0 * cosi)));
        }
        void draw_2d(RendererSvg r, OpticalSystem system)
        {
            // optical axis
            Vector3Pair b = system.get_bounding_box();

            r.draw_segment(new Vector2Pair(new Vector2(b.v0.z(), 0.0), new Vector2(b.v1.z(), 0.0)), Rgb.rgb_gray);

            foreach (Element e in system.elements())
            {
                draw_element_2d(r, e, null);
            }
        }
Exemple #12
0
        /*
         *
         * ligne AB A + t * B
         * sphere passant par C(Cx, 0, 0), rayon R
         *
         * d = Ax - R - Cx
         * (Bz*t+Az)^2+(By*t+Ay)^2+(Bx*t+d)^2=R^2
         *
         * t=-(sqrt((Bz^2+By^2+Bx^2)*R^2+(-Bz^2-By^2)*d^2+(2*Az*Bx*Bz+2*Ay*Bx*By)
         * d-Ay^2*Bz^2+2*Ay*Az*By*Bz-Az^2*By^2+(-Az^2-Ay^2)*Bx^2)+Bx*d+Az*Bz+Ay*By)/(Bz^2+By^2+Bx^2),
         *
         * t= (sqrt((Bz^2+By^2+Bx^2)*R^2+(-Bz^2-By^2)*d^2+(2*Az*Bx*Bz+2*Ay*Bx*By)
         * d-Ay^2*Bz^2+2*Ay*Az*By*Bz-Az^2*By^2+(-Az^2-Ay^2)*Bx^2)-Bx*d-Az*Bz-Ay*By)/(Bz^2+By^2+Bx^2)
         *
         */

        override public Vector3 intersect(Vector3Pair ray)
        {
            double ax = (ray.origin().x());
            double ay = (ray.origin().y());
            double az = (ray.origin().z());
            double bx = (ray.direction().x());
            double by = (ray.direction().y());
            double bz = (ray.direction().z());

            // double bz2_by2_bx2 = math::square(bx) + math::square(by) +
            // math::square(bx);
            // == 1.0

            double d     = az - _roc;
            double ay_by = ay * by;
            double ax_bx = ax * bx;

            double s = +MathUtils.square(_roc) // * bz2_by2_bx2
                       + 2.0 * (ax_bx + ay_by) * bz * d + 2.0 * ax_bx * ay_by
                       - MathUtils.square(ay * bx) - MathUtils.square(ax * by)
                       - (MathUtils.square(bx) + MathUtils.square(by)) * MathUtils.square(d)
                       - (MathUtils.square(ax) + MathUtils.square(ay)) * MathUtils.square(bz);

            // no sphere/ray colision
            if (s < 0)
            {
                return(null);
            }

            s = Math.Sqrt(s);

            // there are 2 possible sphere/line collision point, keep the right
            // one depending on ray direction
            if (_roc * bz > 0)
            {
                s = -s;
            }

            double t = (s - (bz * d + ax_bx + ay_by)); // / bz2_by2_bx2;

            // do not collide if line intersection is before ray start position
            if (t <= 0)
            {
                return(null);
            }

            // intersection point
            return(ray.origin().plus(ray.direction().times(t)));
        }
Exemple #13
0
 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);
     }
 }
Exemple #14
0
        /**
         * Compute refracted ray direction given
         *
         * @param ray    Original ray - position and direction
         * @param normal Normal to the intercept
         * @param mu     Ration of refractive index
         */
        Vector3 compute_refraction(OpticalSurface surface, Vector3Pair ray, Vector3 normal, double mu)
        {
            Vector3 N = normal.times(-1.0); // Because we changed sign at intersection
            // See Feder paper p632
            double O2  = N.dot(N);
            double E1  = ray.direction().dot(N);
            double E1_ = Math.Sqrt(O2 * (1.0 - mu * mu) + mu * mu * E1 * E1);

            if (Double.IsNaN(E1_))
            {
                return(null);
            }

            double g1 = (E1_ - mu * E1) / O2;

            return(ray.direction().times(mu).plus(N.times(g1)));
        }
Exemple #15
0
        public static Vector3Pair get_bounding_box(List <Element> elementList)
        {
            Vector3 a = new Vector3(Double.MaxValue);
            Vector3 b = new Vector3(Double.MinValue);

            foreach (Element e in elementList)
            {
                Vector3Pair bi = e.get_bounding_box();
                if (bi == null) // FIXME - this is a temp solution to failure
                {
                    continue;
                }

                if (bi.v0 == bi.v1)
                {
                    continue;
                }

                bi = e.get_transform().transform_pair(bi);

                for (int j = 0; j < 3; j++)
                {
                    if (bi.v0.v(j) > bi.v1.v(j))
                    {
                        bi = Vector3Pair.swapElement(bi, j);
                    }

                    if (bi.v0.v(j) < a.v(j))
                    {
                        a = a.v(j, bi.v0.v(j));
                    }

                    if (bi.v1.v(j) > b.v(j))
                    {
                        b = b.v(j, bi.v1.v(j));
                    }
                }
            }

            return(new Vector3Pair(a, b));
        }
Exemple #16
0
        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();
                }
            }
        }
Exemple #17
0
        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);
        }
 public Transform3(Vector3Pair position)
 {
     this.translation = position.point();
     if (position.direction().x() == 0 && position.direction().y() == 0)
     {
         if (position.direction().z() < 0.0)
         {
             this.rotation_matrix     = Matrix3.diag(1.0, 1.0, -1.0);
             this.use_rotation_matrix = true;
         }
         else
         {
             this.rotation_matrix     = Matrix3.diag(1.0, 1.0, 1.0);
             this.use_rotation_matrix = false;
         }
     }
     else
     {
         // Get a rotation matrix representing the rotation of unit vector in z
         // to the direction vector.
         this.rotation_matrix     = Matrix3.get_rotation_between(Vector3.vector3_001, position.direction());
         this.use_rotation_matrix = true;
     }
 }
Exemple #19
0
        Vector3 refract(OpticalSurface surface, Vector3Pair ray,
                        Vector3 normal,
                        double refract_index)
        {
            // Algorithm from Bram de Greve article "Reflections & Refractions in
            // Raytracing" http://www.bramz.org/

            // assert (Math.abs(normal.len() - 1.0) < 1e-10);
            // assert (Math.abs((ray.direction().len()) - 1.0) < 1e-10);

            double cosi  = normal.dot(ray.direction());
            double sint2 = MathUtils.square(refract_index) * (1.0 - MathUtils.square(cosi));

            if (sint2 > 1.0)
            {
                return(null); // total internal reflection
            }
            Vector3 dir = ray.direction().times(refract_index).minus(
                normal.times(refract_index * cosi + Math.Sqrt(1.0 - sint2)));

            // This uses Feder refractive formula
            Vector3 dir2 = compute_refraction(surface, ray, normal, refract_index);

//        if ((fabs (dir.x () - dir2.x ()) > 1e-14
//                || fabs (dir.y () - dir2.y ()) > 1e-14
//                || fabs (dir.z () - dir2.z ()) > 1e-14))
//        {
//            printf ("Refract Orig  %.16f, %.16f, %.16f\n", dir.x (), dir.y (),
//                    dir.z ());
//            printf ("Refract Feder %.16f, %.16f, %.16f\n", dir2.x (), dir2.y (),
//                    dir2.z ());
//        }

            dir = dir2;
            return(dir);
        }
Exemple #20
0
        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);
        }
Exemple #21
0
        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));
        }
 public Vector3Pair transform_pair(Vector3Pair p)
 {
     return(new Vector3Pair(transform(p.v0), transform(p.v1)));
 }
 public Vector3Pair transform_line(Vector3Pair v)
 {
     return(new Vector3Pair(transform(v.origin()), apply_rotation(v.direction())));
 }
 public abstract void draw_segment(Vector3Pair s, Rgb rgb);
Exemple #25
0
 public Element(int id, Vector3Pair p, Transform3 transform)
 {
     this._id        = id;
     this._position  = p;
     this._transform = transform;
 }
Exemple #26
0
 public virtual Builder position(Vector3Pair position)
 {
     this._position  = position;
     this._transform = new Transform3(position);
     return(this);
 }
 public virtual Vector3 intersect(Vector3Pair ray)
 {
     return(base_intersect(ray));
 }
 public override void draw_segment(Vector3Pair l, Rgb rgb)
 {
     draw_segment(new Vector2Pair(project(l.point()), project(l.direction())), rgb);
 }
 public PointSource(int id, Vector3Pair p, Transform3 transform, double min_intensity, double max_intensity,
                    List <SpectralLine> spectrum, SourceInfinityMode mode) : base(id, p, transform, min_intensity, max_intensity,
                                                                                  spectrum)
 {
     _mode = mode;
 }
 /**
  * Create a 2d vector pair and initialize vectors from
  * specified components of vectors from an other pair.
  */
 public static Vector2Pair from(Vector3Pair v, int c0, int c1)
 {
     return(new Vector2Pair(Vector2.from(v.v0, c0, c1), Vector2.from(v.v1, c0, c1)));
 }