bool calcRayEarthIntersection(const Vec3 &linePoint, const Vec3 &lineDirn, Vec3 &nearXsecPoint) { // the solution for intersection points between a ray // and the Earth's surface is a quadratic equation // first calculate the quadratic equation params: // a(x^2) + b(x) + c // a, b and c are found by substituting the parametric // equation of a line into the equation for a ellipsoid // and solving in terms of the line's parameter // * http://en.wikipedia.org/wiki/Ellipsoid // * http://gis.stackexchange.com/questions/20780/... // ...point-of-intersection-for-a-ray-and-earths-surface std::vector<double> listRoots; double a = (pow(lineDirn.x,2) / ELL_SEMI_MAJOR_EXP2) + (pow(lineDirn.y,2) / ELL_SEMI_MAJOR_EXP2) + (pow(lineDirn.z,2) / ELL_SEMI_MINOR_EXP2); double b = (2*linePoint.x*lineDirn.x/ELL_SEMI_MAJOR_EXP2) + (2*linePoint.y*lineDirn.y/ELL_SEMI_MAJOR_EXP2) + (2*linePoint.z*lineDirn.z/ELL_SEMI_MINOR_EXP2); double c = (pow(linePoint.x,2) / ELL_SEMI_MAJOR_EXP2) + (pow(linePoint.y,2) / ELL_SEMI_MAJOR_EXP2) + (pow(linePoint.z,2) / ELL_SEMI_MINOR_EXP2) - 1; calcQuadraticEquationReal(a,b,c,listRoots); if(!listRoots.empty()) { // ensure poi lies along ray dirn if((listRoots[0] > 0) && (listRoots[1] > 0)) { Vec3 point1; point1.x = linePoint.x + listRoots.at(0)*lineDirn.x; point1.y = linePoint.y + listRoots.at(0)*lineDirn.y; point1.z = linePoint.z + listRoots.at(0)*lineDirn.z; Vec3 point2; point2.x = linePoint.x + listRoots.at(1)*lineDirn.x; point2.y = linePoint.y + listRoots.at(1)*lineDirn.y; point2.z = linePoint.z + listRoots.at(1)*lineDirn.z; // save the point nearest to the ray's origin if(linePoint.DistanceTo(point1) > linePoint.DistanceTo(point2)) { nearXsecPoint = point2; } else { nearXsecPoint = point1; } return true; } } return false; }