示例#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)));
        }
示例#2
0
        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);
        }
示例#3
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)));
        }
示例#4
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));
     }
 }
示例#5
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();
                }
            }
        }
示例#6
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);
        }
示例#7
0
 public Vector3Pair transform_line(Vector3Pair v)
 {
     return(new Vector3Pair(transform(v.origin()), apply_rotation(v.direction())));
 }
示例#8
0
        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);
        }