Real raySphereIntersectionTime(Ray3 const & ray, Vector3 const & center, Real radius) { Vector3 pmc = ray.getOrigin() - center; double s[3]; s[2] = ray.getDirection().squaredLength(); s[1] = 2 * pmc.dot(ray.getDirection()); s[0] = pmc.squaredLength() - radius * radius; double roots[2]; int num_roots = Math::solveQuadratic(s[0], s[1], s[2], roots); double min_root = -1; for (int i = 0; i < num_roots; ++i) if (roots[i] >= 0 && (min_root < 0 || roots[i] < min_root)) min_root = roots[i]; #if 0 if (min_root >= 0) qDebug() << "min_root =" << min_root; #endif return (Real)min_root; }
Real closestPtRayTriangle(Ray3 const & ray, Vector3 const & v0, Vector3 const & edge01, Vector3 const & edge02, Real & s, Vector3 & c1, Vector3 & c2) { Real sqdist = closestPtLineTriangle(Line3::fromPointAndDirection(ray.getOrigin(), ray.getDirection()), v0, edge01, edge02, s, c1, c2); if (s >= 0) return sqdist; // Not the most efficient way but the most convenient LocalTriangle3 tri(v0, v0 + edge01, v0 + edge02); s = 0; c1 = ray.getOrigin(); c2 = tri.closestPoint(c1); return (c1 - c2).squaredLength(); }
Real rayTorusIntersectionTime(Ray3 const & ray, Real torus_radius, Real torus_width) { double r2pw2 = torus_radius * torus_radius + torus_width * torus_width; double r2mw2 = r2pw2 - 2 * torus_width * torus_width; Vector3 p2 = ray.getOrigin() * ray.getOrigin(); Vector3 pu = ray.getOrigin() * ray.getDirection(); Vector3 u2 = ray.getDirection() * ray.getDirection(); double s[5]; s[4] = u2[0] * (u2[0] + 2 * u2[1]) + u2[1] * (u2[1] + 2 * u2[2]) + u2[2] * (u2[2] + 2 * u2[0]); s[3] = 4 * (pu[0] + pu[1] + pu[2]) * (u2[0] + u2[1] + u2[2]); s[2] = 2 * (r2mw2 * u2[2] - r2pw2 * (u2[0] + u2[1])) + 8 * (pu[0] * pu[1] + pu[1] * pu[2] + pu[2] * pu[0]) + 6 * (pu[0] * pu[0] + pu[1] * pu[1] + pu[2] * pu[2]) + 2 * (p2[0] * (u2[1] + u2[2]) + p2[1] * (u2[2] + u2[0]) + p2[2] * (u2[0] + u2[1])); s[1] = 4 * (r2mw2 * pu[2] - r2pw2 * (pu[0] + pu[1]) + (p2[0] + p2[1] + p2[2]) * (pu[0] + pu[1] + pu[2])); s[0] = 2 * (r2mw2 * p2[2] - r2pw2 * (p2[0] + p2[1]) + p2[0] * p2[1] + p2[1] * p2[2] + p2[2] * p2[0]) + p2[0] * p2[0] + p2[1] * p2[1] + p2[2] * p2[2] + r2mw2 * r2mw2; double roots[4]; int num_roots = Math::solveQuartic(s[0], s[1], s[2], s[3], s[4], roots); double min_root = -1; for (int i = 0; i < num_roots; ++i) if (roots[i] >= 0 && (min_root < 0 || roots[i] < min_root)) min_root = roots[i]; #if 0 if (min_root >= 0) qDebug() << "min_root =" << min_root; #endif return (Real)min_root; }