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); }
/* * * 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))); }
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)); } }
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 Vector3Pair transform_line(Vector3Pair v) { return(new Vector3Pair(transform(v.origin()), apply_rotation(v.direction()))); }
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); }