diff --git a/CMakeLists.txt b/CMakeLists.txt index c7a360c..d4aa351 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,6 @@ option(VERSION_STRING "Project version string" "0.0.0") project(antkeeper VERSION ${VERSION_STRING} LANGUAGES CXX) - # Find dependency packages find_package(dr_wav REQUIRED CONFIG) find_package(stb REQUIRED CONFIG) diff --git a/src/astro/coordinates.cpp b/src/astro/coordinates.cpp deleted file mode 100644 index 10e85f5..0000000 --- a/src/astro/coordinates.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (C) 2021 Christopher J. Howard - * - * This file is part of Antkeeper source code. - * - * Antkeeper source code is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Antkeeper source code is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Antkeeper source code. If not, see . - */ - -#include "coordinates.hpp" -#include - -namespace astro -{ - -double3 rectangular_to_spherical(const double3& rectangular) -{ - const double xx_yy = rectangular.x * rectangular.x + rectangular.y * rectangular.y; - - return double3 - { - std::sqrt(xx_yy + rectangular.z * rectangular.z), - std::atan2(rectangular.z, std::sqrt(xx_yy)), - std::atan2(rectangular.y, rectangular.x) - }; -} - -double3 spherical_to_rectangular(const double3& spherical) -{ - return double3 - { - spherical[0] * std::cos(spherical[1]) * std::cos(spherical[2]), - spherical[0] * std::cos(spherical[1]) * std::sin(spherical[2]), - spherical[0] * std::sin(spherical[1]), - }; -} - -double3x3 ecliptic_to_equatorial(double ecl) -{ - const double c_ecl = std::cos(ecl); - const double s_ecl = std::sin(ecl); - - return double3x3 - { - 1.0, 0.0, 0.0, - 0.0, c_ecl, s_ecl, - 0.0, -s_ecl, c_ecl - }; -} - -double3x3 ecliptic_to_horizontal(double ecl, double lat, double lst) -{ - const double c_ecl = std::cos(ecl); - const double s_ecl = std::sin(ecl); - const double c_lat = std::cos(lat); - const double s_lat = std::sin(lat); - const double c_lst = std::cos(lst); - const double s_lst = std::sin(lst); - - return double3x3 - { - s_lat * c_lst, s_lst, c_lat * c_lst, - s_lat * s_lst * c_ecl - c_lat * s_ecl, -c_lst * c_ecl, c_lat * s_lst * c_ecl + s_lat * s_ecl, - s_lat * s_lst * -s_ecl - c_lat * c_ecl, c_lst * s_ecl, c_lat * s_lst * -s_ecl + s_lat * c_ecl - }; -} - -double3x3 equatorial_to_ecliptic(double ecl) -{ - const double c_ecl = std::cos(ecl); - const double s_ecl = std::sin(ecl); - - return double3x3 - { - 1.0, 0.0, 0.0, - 0.0, c_ecl, -s_ecl, - 0.0, s_ecl, c_ecl - }; -} - -double3x3 equatorial_to_horizontal(double lat, double lst) -{ - const double c_lat = std::cos(lat); - const double s_lat = std::sin(lat); - const double c_lst = std::cos(lst); - const double s_lst = std::sin(lst); - - return double3x3 - { - s_lat * c_lst, s_lst, c_lat * c_lst, - s_lat * s_lst, -c_lst, c_lat * s_lst, - -c_lat, 0.0, s_lat - }; -} - -double3x3 horizontal_to_equatorial(double lat, double lst) -{ - const double c_lat = std::cos(lat); - const double s_lat = std::sin(lat); - const double c_lst = std::cos(lst); - const double s_lst = std::sin(lst); - - return double3x3 - { - c_lst * s_lat, s_lst * s_lat, -c_lat, - s_lst, c_lst, 0.0, - c_lst * c_lat, s_lst * c_lat, s_lat - }; -} - -double3x3 horizontal_to_ecliptic(double ecl, double lat, double lst) -{ - const double c_ecl = std::cos(ecl); - const double s_ecl = std::sin(ecl); - const double c_lat = std::cos(lat); - const double s_lat = std::sin(lat); - const double c_lst = std::cos(lst); - const double s_lst = std::sin(lst); - - return double3x3 - { - s_lat * c_lst, s_lat * s_lst * c_ecl - c_lat * s_ecl, s_lat * s_lst * -s_ecl - c_lat * c_ecl, - s_lst, -c_lst * c_ecl, c_lst * s_ecl, - c_lat * c_lst, c_lat * s_lst * c_ecl + s_lat * s_ecl, c_lat * s_lst * -s_ecl + s_lat * c_ecl - }; -} - -} // namespace astro diff --git a/src/astro/coordinates.hpp b/src/astro/coordinates.hpp deleted file mode 100644 index 5e76468..0000000 --- a/src/astro/coordinates.hpp +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2021 Christopher J. Howard - * - * This file is part of Antkeeper source code. - * - * Antkeeper source code is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Antkeeper source code is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Antkeeper source code. If not, see . - */ - -#ifndef ANTKEEPER_ASTRO_COORDINATES_HPP -#define ANTKEEPER_ASTRO_COORDINATES_HPP - -#include "utility/fundamental-types.hpp" - -namespace astro -{ - -/** - * Converts rectangular coordinates to spherical coordinates. - * - * @param rectangular Rectangular coordinates. - * @return Equivalent spherical coordinates, in the ISO order of radial distance, polar angle (radians), and azimuthal angle (radians). - */ -double3 rectangular_to_spherical(const double3& rectangular); - -/** - * Convert spherical coordinates to rectangular coordinates. - * - * @param spherical Spherical coordinates, in the ISO order of radial distance, polar angle (radians), and azimuthal angle (radians). - * @return Equivalent rectangular coordinates. - */ -double3 spherical_to_rectangular(const double3& spherical); - -/** - * Produces a matrix which transforms rectangular coordinates from ecliptic space to equatorial space. - * - * @param ecl Obliquity of the ecliptic, in radians. - * @return Transformation matrix. - */ -double3x3 ecliptic_to_equatorial(double ecl); - -/** - * Produces a matrix which transforms coordinates from ecliptic space to horizontal space. - * - * @param ecl Obliquity of the ecliptic, in radians. - * @param lat Observer's latitude, in radians. - * @param lst Local sidereal time, in radians. - * @return Transformation matrix. - */ -double3x3 ecliptic_to_horizontal(double ecl, double lat, double lst); - -/** - * Produces a matrix which transforms rectangular coordinates from equatorial space to ecliptic space. - * - * @param ecl Obliquity of the ecliptic, in radians. - * @return Transformation matrix. - */ -double3x3 equatorial_to_ecliptic(double ecl); - -/** - * Produces a matrix which transforms rectangular coordinates from equatorial space to horizontal space. - * - * @param lat Observer's latitude, in radians. - * @param lst Local sidereal time, in radians. - * @return Transformation matrix. - */ -double3x3 equatorial_to_horizontal(double lat, double lst); - -/** - * Produces a matrix which transforms rectangular coordinates from horizontal space to equatorial space. - * - * @param lat Observer's latitude, in radians. - * @param lst Local sidereal time, in radians. - * @return Transformation matrix. - */ -double3x3 horizontal_to_equatorial(double lat, double lst); - -/** - * Produces a matrix which transforms rectangular coordinates from horizontal space to ecliptic space. - * - * @param ecl Obliquity of the ecliptic, in radians. - * @param lat Observer's latitude, in radians. - * @param lst Local sidereal time, in radians. - * @return Transformation matrix. - */ -double3x3 horizontal_to_ecliptic(double ecl, double lat, double lst); - -/// Matrix which transforms coordinates from horizontal space to a right-handed coordinate system. -constexpr double3x3 horizontal_to_right_handed = -{ - 0.0, 0.0, 1.0, - 1.0, 0.0, 0.0, - 0.0, -1.0, 0.0 -}; - -} // namespace astro - -#endif // ANTKEEPER_ASTRO_COORDINATES_HPP diff --git a/src/coordinates/coordinates.hpp b/src/coordinates/coordinates.hpp new file mode 100644 index 0000000..4751438 --- /dev/null +++ b/src/coordinates/coordinates.hpp @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2021 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#ifndef ANTKEEPER_COORDINATES_HPP +#define ANTKEEPER_COORDINATES_HPP + +#include "utility/fundamental-types.hpp" + +/// Functions for converting between coordinate systems. +namespace coordinates {} + +#include "ecliptic.hpp" +#include "equatorial.hpp" +#include "horizontal.hpp" +#include "rectangular.hpp" +#include "spherical.hpp" + +#endif // ANTKEEPER_COORDINATES_HPP diff --git a/src/coordinates/ecliptic.hpp b/src/coordinates/ecliptic.hpp new file mode 100644 index 0000000..2277f61 --- /dev/null +++ b/src/coordinates/ecliptic.hpp @@ -0,0 +1,220 @@ +/* + * Copyright (C) 2021 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#ifndef ANTKEEPER_COORDINATES_ECLIPTIC_HPP +#define ANTKEEPER_COORDINATES_ECLIPTIC_HPP + +#include "coordinates/rectangular.hpp" +#include "coordinates/spherical.hpp" +#include "utility/fundamental-types.hpp" +#include + +namespace coordinates { + +namespace rectangular { + + /// Rectangular coordinate system with the plane of the Earth's orbit as the fundamental plane. This is a right-handed coordinate system with the x-axis pointing to the vernal equinox, the y-axis pointing east, and the z-axis is the north orbital pole. + namespace ecliptic { + + /** + * Produces a matrix which rotates rectangular coordinates from ecliptic space into equatorial space. + * + * @param ecl Obliquity of the ecliptic, in radians. + * @return Rotation matrix. + * + * @see coordinates::equatorial + */ + template + math::matrix3 to_equatorial(T ecl); + + /** + * Rotates rectangular coordinates from ecliptic space into equatorial space. + * + * @param v Rectangular coordinates in ecliptic space. + * @param ecl Obliquity of the ecliptic, in radians. + * @return Rectangular coordinates in equatorial space. + * + * @note If more than one point is being rotated, it is recommended to use the rotation matrix directly. + * + * @see coordinates::ecliptic::rectangular::to_equatorial(T) + * @see coordinates::equatorial + */ + template + math::vector3 to_equatorial(const math::vector3& v, T ecl); + + /** + * Produces a matrix which rotates rectangular coordinates from ecliptic space into local horizontal space. + * + * @param ecl Obliquity of the ecliptic, in radians. + * @param lat Observer's latitude, in radians. + * @param lst Local sidereal time, in radians. + * @return Rotation matrix. + * + * @see coordinates::horizontal + */ + template + math::matrix3 to_horizontal(T ecl, T lat, T lst); + + /** + * Rotates rectangular coordinates from ecliptic space into local horizontal space. + * + * @param v Rectangular coordinates in ecliptic space. + * @param ecl Obliquity of the ecliptic, in radians. + * @param lat Observer's latitude, in radians. + * @param lst Local sidereal time, in radians. + * @return Rectangular coordinates in local horizontal space. + * + * @note If more than one point is being rotated, it is recommended to use the rotation matrix directly. + * + * @see coordinates::ecliptic::rectangular::to_horizontal(T, T, T) + * @see coordinates::horizontal + */ + template + math::vector3 to_horizontal(const math::vector3& v, T ecl, T lat, T lst); + + } // namespace ecliptic + +} // namespace rectangular + +namespace spherical { + + /// Spherical equatorial coordinate system. + namespace ecliptic { + + /** + * Rotates spherical coordinates from ecliptic space into equatorial space. + * + * @param v Spherical coordinates in ecliptic space, in the ISO order of radial distance, ecliptic latitude (radians), and ecliptic longitude (radians). + * @param ecl Obliquity of the ecliptic, in radians. + * @return Spherical coordinates in equatorial space, in the ISO order of radial distance, declination (radians), and right ascension (radians). + * + * @see coordinates::equatorial + */ + template + math::vector3 to_equatorial(const math::vector3& v, T ecl); + + /** + * Rotates spherical coordinates from ecliptic space into local horizontal space. + * + * @param v Spherical coordinates in ecliptic space, in the ISO order of radial distance, ecliptic latitude (radians), and ecliptic longitude (radians). + * @param ecl Obliquity of the ecliptic, in radians. + * @param lat Observer's latitude, in radians. + * @param lst Local sidereal time, in radians. + * @return Spherical coordinates in local horizontal space, in the ISO order of radial distance, altitude (radians), and azimuth (radians). + * + * @see coordinates::horizontal + */ + template + math::vector3 to_horizontal(const math::vector3& v, T ecl, T lat, T lst); + + } // namespace ecliptic + +} // namespace spherical + +namespace rectangular { + + namespace ecliptic { + + template + math::matrix3 to_equatorial(T ecl) + { + const T c_ecl = std::cos(ecl); + const T s_ecl = std::sin(ecl); + + return math::matrix3 + { + T(1.0), T(0.0), T(0.0), + T(0.0), c_ecl, s_ecl, + T(0.0), -s_ecl, c_ecl + }; + } + + template + math::vector3 to_equatorial(const math::vector3& v, T ecl) + { + return to_equatorial(ecl) * v; + } + + template + math::matrix3 to_horizontal(T ecl, T lat, T lst) + { + const T c_ecl = std::cos(ecl); + const T s_ecl = std::sin(ecl); + const T c_lat = std::cos(lat); + const T s_lat = std::sin(lat); + const T c_lst = std::cos(lst); + const T s_lst = std::sin(lst); + + return math::matrix3 + { + s_lat * c_lst, s_lst, c_lat * c_lst, + s_lat * s_lst * c_ecl - c_lat * s_ecl, -c_lst * c_ecl, c_lat * s_lst * c_ecl + s_lat * s_ecl, + s_lat * s_lst * -s_ecl - c_lat * c_ecl, c_lst * s_ecl, c_lat * s_lst * -s_ecl + s_lat * c_ecl + }; + } + + template + math::vector3 to_horizontal(const math::vector3& v, T ecl, T lat, T lst) + { + return to_horizontal(ecl, lat, lst) * v; + } + + } // namespace ecliptic + +} // namespace rectangular + +namespace spherical { + + namespace ecliptic { + + template + math::vector3 to_equatorial(const math::vector3& v, T ecl) + { + return coordinates::rectangular::to_spherical + ( + coordinates::rectangular::ecliptic::to_equatorial + ( + coordinates::spherical::to_rectangular(v), + ecl + ) + ); + } + + template + math::vector3 to_horizontal(const math::vector3& v, T ecl, T lat, T lst) + { + return coordinates::rectangular::to_spherical + ( + coordinates::rectangular::ecliptic::to_horizontal + ( + coordinates::spherical::to_rectangular(v), + ecl, + lat, + lst + ) + ); + } + + } // namespace ecliptic + +} // namespace spherical + +} // namespace coordinates + +#endif // ANTKEEPER_COORDINATES_ECLIPTIC_HPP diff --git a/src/coordinates/equatorial.hpp b/src/coordinates/equatorial.hpp new file mode 100644 index 0000000..30f86e3 --- /dev/null +++ b/src/coordinates/equatorial.hpp @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2021 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#ifndef ANTKEEPER_COORDINATES_EQUATORIAL_HPP +#define ANTKEEPER_COORDINATES_EQUATORIAL_HPP + +#include "coordinates/rectangular.hpp" +#include "coordinates/spherical.hpp" +#include "utility/fundamental-types.hpp" +#include + +namespace coordinates { + +namespace rectangular { + + /// Rectangular coordinate system with the Earth's equator as the fundamental plane. This is a right-handed coordinate system with the x-axis pointing to the vernal equinox, the y-axis pointing east, and the z-axis is the north celestial pole. + namespace equatorial { + + /** + * Produces a matrix which rotates rectangular coordinates from equatorial space into ecliptic space. + * + * @param ecl Obliquity of the ecliptic, in radians. + * @return Rotation matrix. + * + * @see coordinates::ecliptic + */ + template + math::matrix3 to_ecliptic(T ecl); + + /** + * Rotates rectangular coordinates from equatorial space into ecliptic space. + * + * @param v Rectangular coordinates in equatorial space. + * @param ecl Obliquity of the ecliptic, in radians. + * @return Rectangular coordinates in ecliptic space. + * + * @see coordinates::ecliptic + */ + template + math::vector3 to_ecliptic(const math::vector3& v, T ecl); + + /** + * Produces a matrix which rotates rectangular coordinates from equatorial space into local horizontal space. + * + * @param lat Observer's latitude, in radians. + * @param lst Local sidereal time, in radians. + * @return Rotation matrix. + * + * @see coordinates::horizontal + */ + template + math::matrix3 to_horizontal(T lat, T lst); + + /** + * Rotates rectangular coordinates from equatorial space into local horizontal space. + * + * @param v Rectangular coordinates in equatorial space. + * @param lat Observer's latitude, in radians. + * @param lst Local sidereal time, in radians. + * @return Rectangular coordinates in local horizontal space. + * + * @see coordinates::horizontal + */ + template + math::vector3 to_horizontal(const math::vector3& v, T lat, T lst); + + } // namespace equatorial + +} // namespace rectangular + +namespace spherical { + + /// Spherical equatorial coordinate system. + namespace equatorial { + + /** + * Rotates spherical coordinates from equatorial space into ecliptic space. + * + * @param v Spherical coordinates in equatorial space, in the ISO order of radial distance, declination (radians), and right ascension (radians). + * @param ecl Obliquity of the ecliptic, in radians. + * @return Spherical coordinates in ecliptic space, in the ISO order of radial distance, ecliptic latitude (radians), and ecliptic longitude (radians). + * + * @see coordinates::ecliptic + */ + template + math::vector3 to_ecliptic(const math::vector3& v, T ecl); + + /** + * Rotates spherical coordinates from equatorial space into local horizontal space. + * + * @param v Spherical coordinates in equatorial space, in the ISO order of radial distance, declination (radians), and right ascension (radians). + * @param lat Observer's latitude, in radians. + * @param lst Local sidereal time, in radians. + * @return Spherical coordinates in local horizontal space, in the ISO order of radial distance, altitude (radians), and azimuth (radians). + * + * @see coordinates::horizontal + */ + template + math::vector3 to_horizontal(const math::vector3& v, T lat, T lst); + + } // namespace equatorial + +} // namespace spherical + +namespace rectangular { + + namespace equatorial { + + template + math::matrix3 to_ecliptic(T ecl) + { + const T c_ecl = std::cos(ecl); + const T s_ecl = std::sin(ecl); + + return math::matrix3 + { + T(1.0), T(0.0), T(0.0), + T(0.0), c_ecl, -s_ecl, + T(0.0), s_ecl, c_ecl + }; + } + + template + math::vector3 to_ecliptic(const math::vector3& v, T ecl) + { + return to_ecliptic(ecl) * v; + } + + template + math::matrix3 to_horizontal(T lat, T lst) + { + const T c_lat = std::cos(lat); + const T s_lat = std::sin(lat); + const T c_lst = std::cos(lst); + const T s_lst = std::sin(lst); + + return math::matrix3 + { + s_lat * c_lst, s_lst, c_lat * c_lst, + s_lat * s_lst, -c_lst, c_lat * s_lst, + -c_lat, T(0.0), s_lat + }; + } + + template + math::vector3 to_horizontal(const math::vector3& v, T lat, T lst) + { + return to_horizontal(lat, lst) * v; + } + + } // namespace equatorial + +} // namespace rectangular + +namespace spherical { + + namespace equatorial { + + template + math::vector3 to_ecliptic(const math::vector3& v, T ecl) + { + return coordinates::rectangular::to_spherical + ( + coordinates::rectangular::equatorial::to_ecliptic + ( + coordinates::spherical::to_rectangular(v), + ecl + ) + ); + } + + template + math::vector3 to_horizontal(const math::vector3& v, T lat, T lst) + { + return coordinates::rectangular::to_spherical + ( + coordinates::rectangular::equatorial::to_horizontal + ( + coordinates::spherical::to_rectangular(v), + lat, + lst + ) + ); + } + + } // namepace equatorial + +} // namespace spherical + +} // namespace coordinates + +#endif // ANTKEEPER_COORDINATES_EQUATORIAL_HPP diff --git a/src/coordinates/horizontal.hpp b/src/coordinates/horizontal.hpp new file mode 100644 index 0000000..23f08ec --- /dev/null +++ b/src/coordinates/horizontal.hpp @@ -0,0 +1,220 @@ +/* + * Copyright (C) 2021 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#ifndef ANTKEEPER_COORDINATES_HORIZONTAL_HPP +#define ANTKEEPER_COORDINATES_HORIZONTAL_HPP + +#include "coordinates/rectangular.hpp" +#include "coordinates/spherical.hpp" +#include "utility/fundamental-types.hpp" +#include + +namespace coordinates { + +namespace rectangular { + + /// Rectangular local horizontal coordinate system in which the x-axis points north, the y-axis points east, and the z-axis points to the vertical. + namespace horizontal { + + /** + * Produces a matrix which rotates rectangular coordinates from local horizontal space into equatorial space. + * + * @param lat Observer's latitude, in radians. + * @param lst Local sidereal time, in radians. + * @return Rotation matrix. + * + * @see coordinates::equatorial + */ + template + math::matrix3 to_equatorial(T lat, T lst); + + /** + * Rotates rectangular coordinates from local horizontal space into equatorial space. + * + * @param v Rectangular coordinates in local horizontal space. + * @param lat Observer's latitude, in radians. + * @param lst Local sidereal time, in radians. + * @return Rectangular coordinates in equatorial space. + * + * @see coordinates::equatorial + */ + template + math::vector3 to_equatorial(const math::vector3& v, T lat, T lst); + + /** + * Produces a matrix which rotates rectangular coordinates from local horizontal space into ecliptic space. + * + * @param ecl Obliquity of the ecliptic, in radians. + * @param lat Observer's latitude, in radians. + * @param lst Local sidereal time, in radians. + * @return Rotation matrix. + * + * @see coordinates::ecliptic + */ + template + math::matrix3 to_ecliptic(T ecl, T lat, T lst); + + /** + * Rotates rectangular coordinates from local horizontal space into ecliptic space. + * + * @param v Rectangular coordinates in local horizontal space. + * @param ecl Obliquity of the ecliptic, in radians. + * @param lat Observer's latitude, in radians. + * @param lst Local sidereal time, in radians. + * @return Rectangular coordinates in ecliptic space. + * + * @see coordinates::ecliptic + */ + template + math::vector3 to_ecliptic(const math::vector3& v, T ecl, T lat, T lst); + + } // namespace horizontal + +} // namespace rectangular + +namespace spherical { + + /// Spherical local horizontal coordinate system. + namespace horizontal { + + /** + * Rotates spherical coordinates from local horizontal space into equatorial space. + * + * @param v Spherical coordinates in local horizontal space, in the ISO order of radial distance, altitude (radians), and azimuth (radians). + * @param lat Observer's latitude, in radians. + * @param lst Local sidereal time, in radians. + * @return Spherical coordinates in equatorial space, in the ISO order of radial distance, declination (radians), and right ascension (radians). + * + * @see coordinates::equatorial + */ + template + math::vector3 to_equatorial(const math::vector3& v, T lat, T lst); + + /** + * Rotates spherical coordinates from local horizontal space into ecliptic space. + * + * @param v Spherical coordinates in local horizontal space, in the ISO order of radial distance, altitude (radians), and azimuth (radians). + * @param ecl Obliquity of the ecliptic, in radians. + * @param lat Observer's latitude, in radians. + * @param lst Local sidereal time, in radians. + * @return Spherical coordinates in ecliptic space, in the ISO order of radial distance, ecliptic latitude (radians), and ecliptic longitude (radians). + * + * @see coordinates::ecliptic + */ + template + math::vector3 to_ecliptic(const math::vector3& v, T ecl, T lat, T lst); + + } // namespace horizontal + +} // namespace spherical + +namespace rectangular { + + namespace horizontal { + + template + math::matrix3 to_equatorial(T lat, T lst) + { + const T c_lat = std::cos(lat); + const T s_lat = std::sin(lat); + const T c_lst = std::cos(lst); + const T s_lst = std::sin(lst); + + return math::matrix3 + { + c_lst * s_lat, s_lst * s_lat, -c_lat, + s_lst, c_lst, T(0.0), + c_lst * c_lat, s_lst * c_lat, s_lat + }; + } + + template + math::vector3 to_equatorial(const math::vector3& v, T lat, T lst) + { + return to_equatorial(lat, lst) * v; + } + + template + math::matrix3 to_ecliptic(T ecl, T lat, T lst) + { + const T c_ecl = std::cos(ecl); + const T s_ecl = std::sin(ecl); + const T c_lat = std::cos(lat); + const T s_lat = std::sin(lat); + const T c_lst = std::cos(lst); + const T s_lst = std::sin(lst); + + return math::matrix3 + { + s_lat * c_lst, s_lat * s_lst * c_ecl - c_lat * s_ecl, s_lat * s_lst * -s_ecl - c_lat * c_ecl, + s_lst, -c_lst * c_ecl, c_lst * s_ecl, + c_lat * c_lst, c_lat * s_lst * c_ecl + s_lat * s_ecl, c_lat * s_lst * -s_ecl + s_lat * c_ecl + }; + } + + template + math::vector3 to_ecliptic(const math::vector3& v, T ecl, T lat, T lst) + { + return to_ecliptic(ecl, lat, lst) * v; + } + + } // namespace horizontal + +} // namespace rectangular + +namespace spherical { + + namespace horizontal { + + template + math::vector3 to_equatorial(const math::vector3& v, T lat, T lst) + { + return coordinates::rectangular::to_spherical + ( + coordinates::rectangular::horizontal::to_equatorial + ( + coordinates::spherical::to_rectangular(v), + lat, + lst + ) + ); + } + + template + math::vector3 to_ecliptic(const math::vector3& v, T ecl, T lat, T lst) + { + return coordinates::rectangular::to_spherical + ( + coordinates::rectangular::horizontal::to_ecliptic + ( + coordinates::spherical::to_rectangular(v), + ecl, + lat, + lst + ) + ); + } + + } // namespace horizontal + +} // namespace spherical + +} // namespace coordinates + +#endif // ANTKEEPER_COORDINATES_HORIZONTAL_HPP diff --git a/src/coordinates/rectangular.hpp b/src/coordinates/rectangular.hpp new file mode 100644 index 0000000..382e537 --- /dev/null +++ b/src/coordinates/rectangular.hpp @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2021 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#ifndef ANTKEEPER_COORDINATES_RECTANGULAR_HPP +#define ANTKEEPER_COORDINATES_RECTANGULAR_HPP + +#include "utility/fundamental-types.hpp" +#include + +namespace coordinates { + +/// Rectangular (Cartesian) coordinate systems. +namespace rectangular { + +/** + * Produces a matrix which rotates rectangular coordinates about the x-axis by a given angle. + * + * @param angle Angle of rotation, in radians. + * @return Rotation matrix. + */ +template +math::matrix3 rotate_x(T angle); + +/** + * Rotates rectangular coordinates about the x-axis. + * + * @param v Rectangular coordinates to rotate. + * @param angle Angle of rotation, in radians. + * @return Rotated rectangular coordinates. + */ +template +math::vector3 rotate_x(const math::vector3& v, T angle); + +/** + * Produces a matrix which rotates rectangular coordinates about the y-axis by a given angle. + * + * @param angle Angle of rotation, in radians. + * @return Rotation matrix. + */ +template +math::matrix3 rotate_y(T angle); + +/** + * Rotates rectangular coordinates about the y-axis. + * + * @param v Rectangular coordinates to rotate. + * @param angle Angle of rotation, in radians. + * @return Rotated rectangular coordinates. + */ +template +math::vector3 rotate_y(const math::vector3& v, T angle); + +/** + * Produces a matrix which rotates rectangular coordinates about the z-axis by a given angle. + * + * @param angle Angle of rotation, in radians. + * @return Rotation matrix. + */ +template +math::matrix3 rotate_z(T angle); + +/** + * Rotates rectangular coordinates about the z-axis. + * + * @param v Rectangular coordinates to rotate. + * @param angle Angle of rotation, in radians. + * @return Rotated rectangular coordinates. + */ +template +math::vector3 rotate_z(const math::vector3& v, T angle); + +/** + * Converts rectangular coordinates to spherical coordinates. + * + * @param v Rectangular coordinates. + * @return Spherical coordinates, in the ISO order of radial distance, polar angle (radians), and azimuthal angle (radians). + * + * @see coordinates::spherical + */ +template +math::vector3 to_spherical(const math::vector3& v); + +template +math::vector3 to_spherical(const math::vector3& v) +{ + const T xx_yy = v.x * v.x + v.y * v.y; + + return math::vector3 + { + std::sqrt(xx_yy + v.z * v.z), + std::atan2(v.z, std::sqrt(xx_yy)), + std::atan2(v.y, v.x) + }; +} + +template +math::matrix3 rotate_x(T angle) +{ + const T c = std::cos(angle); + const T s = std::sin(angle); + + return math::matrix3 + { + T(1), T(0), T(0), + T(0), c, -s, + T(0), s, c + }; +} + +template +math::vector3 rotate_x(const math::vector3& v, T angle) +{ + return rotate_x(angle) * v; +} + +template +math::matrix3 rotate_y(T angle) +{ + const T c = std::cos(angle); + const T s = std::sin(angle); + + return math::matrix3 + { + c, T(0), s, + T(0), T(1), T(0), + -s, T(0), c + }; +} + +template +math::vector3 rotate_y(const math::vector3& v, T angle) +{ + return rotate_y(angle) * v; +} + +template +math::matrix3 rotate_z(T angle) +{ + const T c = std::cos(angle); + const T s = std::sin(angle); + + return math::matrix3 + { + c, -s, T(0), + s, c, T(0), + T(0), T(0), T(1) + }; +} + +template +math::vector3 rotate_z(const math::vector3& v, T angle) +{ + return rotate_z(angle) * v; +} + +} // namespace rectangular +} // namespace coordinates + +#endif // ANTKEEPER_COORDINATES_RECTANGULAR_HPP diff --git a/src/coordinates/spherical.hpp b/src/coordinates/spherical.hpp new file mode 100644 index 0000000..649439c --- /dev/null +++ b/src/coordinates/spherical.hpp @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2021 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#ifndef ANTKEEPER_COORDINATES_SPHERICAL_HPP +#define ANTKEEPER_COORDINATES_SPHERICAL_HPP + +#include "utility/fundamental-types.hpp" +#include + +namespace coordinates { + +/// Spherical coordinate systems. +namespace spherical { + +/** + * Converts spherical coordinates to rectangular coordinates. + * + * @param v Spherical coordinates, in the ISO order of radial distance, polar angle (radians), and azimuthal angle (radians). + * @return Rectangular coordinates. + * + * @see coordinates::rectangular + */ +template +math::vector3 to_rectangular(const math::vector3& v); + +template +math::vector3 to_rectangular(const math::vector3& v) +{ + const T x = v[0] * std::cos(v[1]); + + return math::vector3 + { + x * std::cos(v[2]), + x * std::sin(v[2]), + v[0] * std::sin(v[1]), + }; +} + +} // namespace spherical +} // namespace coordinates + +#endif // ANTKEEPER_COORDINATES_SPHERICAL_HPP diff --git a/src/ecs/systems/astronomy-system.cpp b/src/ecs/systems/astronomy-system.cpp index d74cb68..a6470e5 100644 --- a/src/ecs/systems/astronomy-system.cpp +++ b/src/ecs/systems/astronomy-system.cpp @@ -18,7 +18,7 @@ */ #include "ecs/systems/astronomy-system.hpp" -#include "astro/coordinates.hpp" +#include "coordinates/coordinates.hpp" #include "astro/apparent-size.hpp" #include "ecs/components/celestial-body-component.hpp" #include "ecs/components/transform-component.hpp" @@ -60,15 +60,21 @@ void astronomy_system::update(double t, double dt) horizontal.z -= observer_location[0]; // Convert rectangular horizontal coordinates to spherical - double3 spherical = astro::rectangular_to_spherical(horizontal); - spherical.z -= math::pi; + double3 spherical = coordinates::rectangular::to_spherical(horizontal); // Find angular radius - double angular_radius = astro::find_angular_radius(body.radius, spherical.x); + double angular_radius = astro::find_angular_radius(body.radius, spherical[0]); - // Transform into local right-handed coordinates - double3 translation = astro::horizontal_to_right_handed * horizontal; - double3x3 rotation = astro::horizontal_to_right_handed * ecliptic_to_horizontal; + // Transform into local coordinates + const double3x3 horizontal_to_local = + { + 0.0, 0.0, -1.0, + 1.0, 0.0, 0.0, + 0.0, 1.0, 0.0 + }; + + double3 translation = horizontal_to_local * horizontal; + double3x3 rotation = horizontal_to_local * ecliptic_to_horizontal; // Set local transform of transform component transform.local.translation = math::type_cast(translation); @@ -180,7 +186,7 @@ void astronomy_system::update_sidereal_time() void astronomy_system::update_ecliptic_to_horizontal() { - ecliptic_to_horizontal = astro::ecliptic_to_horizontal(obliquity, observer_location[1], lst); + ecliptic_to_horizontal = coordinates::rectangular::ecliptic::to_horizontal(obliquity, observer_location[1], lst); } } // namespace ecs diff --git a/src/ecs/systems/solar-system.cpp b/src/ecs/systems/solar-system.cpp index fd4e3c4..322ade7 100644 --- a/src/ecs/systems/solar-system.cpp +++ b/src/ecs/systems/solar-system.cpp @@ -18,7 +18,7 @@ */ #include "ecs/systems/solar-system.hpp" -#include "astro/coordinates.hpp" +#include "coordinates/coordinates.hpp" #include "astro/orbit.hpp" #include "astro/constants.hpp" #include "ecs/components/celestial-body-component.hpp" diff --git a/src/game/bootloader.cpp b/src/game/bootloader.cpp index 77d3a9f..d9e7eac 100644 --- a/src/game/bootloader.cpp +++ b/src/game/bootloader.cpp @@ -1180,9 +1180,9 @@ void setup_controls(game_context* ctx) ( [ctx, time_scale]() { - ctx->weather_system->set_time_scale(time_scale * 500.0f); - ctx->solar_system->set_time_scale(time_scale * 500.0f); - ctx->astronomy_system->set_time_scale(time_scale * 500.0f); + ctx->weather_system->set_time_scale(time_scale * 100.0f); + ctx->solar_system->set_time_scale(time_scale * 100.0f); + ctx->astronomy_system->set_time_scale(time_scale * 100.0f); } ); ctx->control_system->get_fast_forward_control()->set_deactivated_callback @@ -1198,9 +1198,9 @@ void setup_controls(game_context* ctx) ( [ctx, time_scale]() { - ctx->weather_system->set_time_scale(time_scale * -500.0f); - ctx->solar_system->set_time_scale(time_scale * -500.0f); - ctx->astronomy_system->set_time_scale(time_scale * -500.0f); + ctx->weather_system->set_time_scale(time_scale * -100.0f); + ctx->solar_system->set_time_scale(time_scale * -100.0f); + ctx->astronomy_system->set_time_scale(time_scale * -100.0f); } ); ctx->control_system->get_rewind_control()->set_deactivated_callback diff --git a/src/game/states/play-state.cpp b/src/game/states/play-state.cpp index c2c9a19..321cb7b 100644 --- a/src/game/states/play-state.cpp +++ b/src/game/states/play-state.cpp @@ -234,7 +234,7 @@ void play_state_enter(game_context* ctx) auto nest_entity = nest_archetype->create(ecs_registry); // Create terrain - int terrain_radius = 6; + int terrain_radius = 0;//6; for (int x = -terrain_radius; x <= terrain_radius; ++x) { for (int z = -terrain_radius; z <= terrain_radius; ++z) @@ -249,7 +249,7 @@ void play_state_enter(game_context* ctx) } // Create trees - for (int i = 0; i < 30; ++i) + for (int i = 0; i < 0; ++i) { auto redwood = redwood_archetype->create(ecs_registry); diff --git a/src/renderer/passes/sky-pass.cpp b/src/renderer/passes/sky-pass.cpp index e127084..c15c033 100644 --- a/src/renderer/passes/sky-pass.cpp +++ b/src/renderer/passes/sky-pass.cpp @@ -38,8 +38,9 @@ #include "scene/camera.hpp" #include "utility/fundamental-types.hpp" #include "color/color.hpp" +#include "astro/illuminance.hpp" #include "math/interpolation.hpp" -#include "astro/astro.hpp" +#include "coordinates/coordinates.hpp" #include #include #include @@ -107,9 +108,8 @@ sky_pass::sky_pass(gl::rasterizer* rasterizer, const gl::framebuffer* framebuffe ra = math::wrap_radians(math::radians(ra)); dec = math::wrap_radians(math::radians(dec)); - // Transform spherical coordinates to rectangular (Cartesian) coordinates - double3 spherical = {1.0, dec, ra}; - double3 rectangular = astro::spherical_to_rectangular(spherical); + // Transform spherical equatorial coordinates to rectangular equatorial coordinates + double3 position = coordinates::spherical::to_rectangular(double3{1.0, dec, ra}); // Convert color index to color temperature double cct = color::index::bv_to_cct(bv_color); @@ -130,9 +130,9 @@ sky_pass::sky_pass(gl::rasterizer* rasterizer, const gl::framebuffer* framebuffe double3 scaled_color = color_acescg * vmag_lux; // Build vertex - *(star_vertex++) = static_cast(rectangular.x); - *(star_vertex++) = static_cast(rectangular.y); - *(star_vertex++) = static_cast(rectangular.z); + *(star_vertex++) = static_cast(position.x); + *(star_vertex++) = static_cast(position.y); + *(star_vertex++) = static_cast(position.z); *(star_vertex++) = static_cast(scaled_color.x); *(star_vertex++) = static_cast(scaled_color.y); *(star_vertex++) = static_cast(scaled_color.z); @@ -287,19 +287,35 @@ void sky_pass::render(render_context* context) const // Draw stars { - float star_distance = (clip_near + clip_far) * 0.5f; + float star_distance = (clip_near + clip_far) * 0.5f; - math::quaternion rotation_y = math::angle_axis(time_of_day / 24.0f * -math::two_pi, {0, 1, 0}); - math::quaternion rotation_x = math::angle_axis(-math::half_pi + math::radians(30.0f), {1, 0, 0}); + double lat = math::radians(30.0); + double lst = time_of_day / 24.0f * math::two_pi; + //std::cout << "lst: " << lst << std::endl; - math::transform star_transform; - star_transform.translation = {0.0, 0.0, 0.0}; + double3x3 equatorial_to_horizontal = coordinates::rectangular::equatorial::to_horizontal(lat, lst); + + const double3x3 horizontal_to_local = + { + 0.0, 0.0, -1.0, + 1.0, 0.0, 0.0, + 0.0, 1.0, 0.0 + }; + + double3x3 rotation = horizontal_to_local * equatorial_to_horizontal; + //math::quaternion rotation_y = math::angle_axis(time_of_day / 24.0f * -math::two_pi, {0, 1, 0}); + //math::quaternion rotation_x = math::angle_axis(-math::half_pi + math::radians(30.0f), {1, 0, 0}); + + model = math::type_cast(math::scale(math::resize<4, 4>(rotation), double3{star_distance, star_distance, star_distance}));; + + //math::transform star_transform; + //star_transform.translation = {0.0, 0.0, 0.0}; //star_transform.rotation = math::normalize(rotation_x * rotation_y); - star_transform.rotation = math::normalize(rotation_x * rotation_y * math::angle_axis(math::radians(-90.0f), {1, 0, 0})); + //star_transform.rotation = math::normalize(math::type_cast(math::quaternion_cast(rotation))); //star_transform.rotation = math::identity_quaternion; - star_transform.scale = {star_distance, star_distance, star_distance}; + //star_transform.scale = {star_distance, star_distance, star_distance}; + //model = math::matrix_cast(star_transform); - model = math::matrix_cast(star_transform); model_view = view * model; rasterizer->use_program(*star_shader_program);