diff --git a/modules/skybrowser/include/utility.h b/modules/skybrowser/include/utility.h new file mode 100644 index 0000000000..2a9b0068d4 --- /dev/null +++ b/modules/skybrowser/include/utility.h @@ -0,0 +1,33 @@ +#include +#include +#include +#include // For atan2 +#include // For printing glm data +#define _USE_MATH_DEFINES +#include + + +namespace openspace::skybrowser { + const double SCREENSPACE_Z = -2.1; + const double RAD_TO_DEG = 180.0 / M_PI; + const double DEG_TO_RAD = M_PI / 180.0; + + // Conversion matrix from this paper: https://arxiv.org/abs/1010.3773v1 + const glm::dmat3 conversionMatrix = glm::dmat3({ + -0.054875539390, 0.494109453633, -0.867666135681, // col 0 + -0.873437104725, -0.444829594298, -0.198076389622, // col 1 + -0.483834991775, 0.746982248696, 0.455983794523 // col 2 + }); + + // J2000 to galactic conversion and vice versa + glm::dvec2 cartesianToSpherical(glm::dvec3 cartesianCoords); + glm::dvec3 sphericalToCartesian(glm::dvec2 sphericalCoords); + glm::dvec2 galacticCartesianToJ2000(glm::dvec3 rGal); + glm::dvec3 J2000ToGalacticCartesian(double ra, double dec, double distance); + glm::dvec2 J2000ToScreenSpace(double ra, double dec); + + glm::dvec2 galacticToScreenSpace(glm::dvec3 galacticCoord); +} + + + diff --git a/modules/skybrowser/src/utility.cpp b/modules/skybrowser/src/utility.cpp new file mode 100644 index 0000000000..913e8089c8 --- /dev/null +++ b/modules/skybrowser/src/utility.cpp @@ -0,0 +1,77 @@ + +#include +#include +#include +#include +#include // For atan2 +#include // For printing glm data +#define _USE_MATH_DEFINES +#include + + + +namespace openspace::skybrowser { + + glm::dvec3 sphericalToCartesian(glm::dvec2 sphericalCoords) { + + glm::dvec3 cartesian = glm::dvec3( + cos(sphericalCoords.x * DEG_TO_RAD) * cos(sphericalCoords.y * DEG_TO_RAD), + sin(sphericalCoords.x * DEG_TO_RAD) * cos(sphericalCoords.y * DEG_TO_RAD), + sin(sphericalCoords.y * DEG_TO_RAD) + ); + + return cartesian; + } + + glm::dvec2 cartesianToSpherical(glm::dvec3 cartesianCoords) { + + double ra = atan2(cartesianCoords[1], cartesianCoords[0]); + double dec = atan2(cartesianCoords[2], glm::sqrt((cartesianCoords[0] * cartesianCoords[0]) + (cartesianCoords[1] * cartesianCoords[1]))); + + ra = ra > 0 ? ra : ra + (2 * M_PI); + + return glm::dvec2(RAD_TO_DEG * ra, RAD_TO_DEG * dec); + } + + glm::dvec2 galacticCartesianToJ2000(glm::dvec3 rGal) { + glm::dvec3 J2000 = glm::transpose(conversionMatrix) * rGal; + return cartesianToSpherical(J2000); + } + + glm::dvec3 J2000ToGalacticCartesian(double ra, double dec, double distance) { + glm::dvec3 rGalactic = conversionMatrix * sphericalToCartesian(glm::dvec2(ra, dec)); // on the unit sphere + return distance * rGalactic; + } + + glm::dvec2 galacticToScreenSpace(glm::dvec3 imageCoordsGalacticCartesian) { + + // Transform vector to camera's local coordinate system + glm::dvec3 camPos = global::navigationHandler->camera()->positionVec3(); + glm::dvec3 camToCoordsDir = glm::normalize(imageCoordsGalacticCartesian - camPos); + glm::dmat4 camMat = global::navigationHandler->camera()->viewRotationMatrix(); + glm::dvec3 viewDirectionLocal = camMat * glm::dvec4(camToCoordsDir, 1.0); + viewDirectionLocal = glm::normalize(viewDirectionLocal); + + // Calculate screen space coords x and y + long double tan_x = viewDirectionLocal.x / viewDirectionLocal.z; + long double tan_y = viewDirectionLocal.y / viewDirectionLocal.z; + + glm::dvec2 angleCoordsLocal = glm::dvec2(std::atanl(tan_x), std::atanl(tan_y)); + glm::dvec2 imageCoordsScreenSpace = glm::dvec2(SCREENSPACE_Z * static_cast(std::tanl(angleCoordsLocal.x)), SCREENSPACE_Z * static_cast(std::tanl(angleCoordsLocal.y))); + + return imageCoordsScreenSpace; + } + + glm::dvec2 J2000ToScreenSpace(double ra, double dec) { + // Transform equatorial J2000 to galactic coord with infinite radius + constexpr double infinity = std::numeric_limits::max(); + glm::dvec3 imageCoordsGalacticCartesian = J2000ToGalacticCartesian(ra, dec, infinity); + // Transform galactic coord to screen space + glm::dvec2 imageCoordsScreenSpace = galacticToScreenSpace(imageCoordsGalacticCartesian); + return imageCoordsScreenSpace; + } + + } + + +