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; }
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); }
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; }
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)); }
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); }
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); }
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); } }
/* * * 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))); }
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); } }
/** * 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 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)); }
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); }
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; } }
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); }
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); }
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);
public Element(int id, Vector3Pair p, Transform3 transform) { this._id = id; this._position = p; this._transform = transform; }
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))); }