Exemple #1
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 #3
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)));
        }
Exemple #4
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 #5
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 #6
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));
     }
 }
Exemple #7
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)));
        }
 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 #9
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 #10
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 #11
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_line(Vector3Pair v)
 {
     return(new Vector3Pair(transform(v.origin()), apply_rotation(v.direction())));
 }
 public override void draw_segment(Vector3Pair l, Rgb rgb)
 {
     draw_segment(new Vector2Pair(project(l.point()), project(l.direction())), rgb);
 }