std::vector<double> PolyBase::realRoots(const double epsilon) /** Get just the real roots @param epsilon :: tolerance factor (-ve to use default) @return vector of the real roots (if any) */ { const double eps((epsilon > 0.0) ? epsilon : Eaccuracy); std::vector<std::complex<double>> Croots = calcRoots(epsilon); std::vector<double> Out; std::vector<std::complex<double>>::const_iterator vc; for (vc = Croots.begin(); vc != Croots.end(); ++vc) { if (fabs(vc->imag()) < eps) Out.push_back(vc->real()); } return Out; }
bool Sphere::closestIntersectionModel(const Ray &ray, double maxLambda, RayIntersection& intersection) const { /* A ray and a sphere intersect if and only if (o + lambda * d - c)^2 = r^2 where o is the origin of the ray d is the direction vector of the ray c is the center of the sphere r is the radius of the sphere Since o and d are known, c = O and r = 1, we have a quadratic equation in lambda. We solve it using calcRoots() which is a slightly modified version of the classical quadratic formula (as described in [1]). [1] http://wiki.delphigl.com/index.php/Tutorial_Raytracing_-_Grundlagen_I#Quadratische_Gleichungen */ // a, b and c are the constants in // a * lambda^2 + b * lambda + c = 0. double a = dot(ray.direction(), ray.direction()); double b = 2 * dot(ray.direction(), ray.origin()); double c = dot(ray.origin(), ray.origin()) - 1; // t1 and t2 are the solutions of our quadratic equation. // W.l.o.g. t1 <= t2 (calcRoots takes care of that) // calcRoots return the number of roots it found (zero, one or two). double t1, t2; int roots = calcRoots(a, b, c, t1, t2); bool doIntersect = false; if (roots > 0) { // There is a solution, we just need the (smallest) positve one. double lambda = t1 >= 0 ? t1 : t2; if (lambda >= 0.0 && lambda < maxLambda) { doIntersect = true; intersection = RayIntersection(ray, shared_from_this(), lambda, ray.pointOnRay(lambda), Vec3d(0,0,0)); } } return doIntersect; }