static void longLatLabel(const string& labelText, double longitude, double latitude, const Vec3d& viewRayOrigin, const Vec3d& viewNormal, const Vec3d& bodyCenter, const Quatd& bodyOrientation, const Vec3f& semiAxes, float labelOffset, Renderer* renderer) { double theta = degToRad(longitude); double phi = degToRad(latitude); Vec3d pos(cos(phi) * cos(theta) * semiAxes.x, sin(phi) * semiAxes.y, -cos(phi) * sin(theta) * semiAxes.z); float nearDist = renderer->getNearPlaneDistance(); pos = pos * (1.0 + labelOffset); double boundingRadius = max(semiAxes.x, max(semiAxes.y, semiAxes.z)); // Draw the label only if it isn't obscured by the body ellipsoid double t = 0.0; if (testIntersection(Ray3d(Point3d(0.0, 0.0, 0.0) + viewRayOrigin, pos - viewRayOrigin), Ellipsoidd(Vec3d(semiAxes.x, semiAxes.y, semiAxes.z)), t) && t >= 1.0) { // Compute the position of the label Vec3d labelPos = bodyCenter + (1.0 + labelOffset) * pos * bodyOrientation.toMatrix3(); // Calculate the intersection of the eye-to-label ray with the plane perpendicular to // the view normal that touches the front of the objects bounding sphere double planetZ = viewNormal * bodyCenter - boundingRadius; if (planetZ < -nearDist * 1.001) planetZ = -nearDist * 1.001; double z = viewNormal * labelPos; labelPos *= planetZ / z; renderer->addObjectAnnotation(NULL, labelText, Renderer::PlanetographicGridLabelColor, Point3f((float) labelPos.x, (float) labelPos.y, (float) labelPos.z)); } }
Point3d SynchronousOrbit::positionAtTime(double jd) const { Quatd q = body.getEquatorialToBodyFixed(jd); return position * q.toMatrix3(); }