/* +------------------------------------------------------+ ____/ \____ /| - Open source game framework licensed to freely use, | \ / / | copy, modify and sell without restriction | +--\ ^__^ /--+ | | | ~/ \~ | | - created for | | ~~~~~~~~~~~~ | +------------------------------------------------------+ | SPACE ~~~~~ | / | ~~~~~~~ BOX |/ +--------------+ [math.hpp] For math helper functions that require only GLM primitives, especially trigonometric functions. Angle values are in radians. 0 is directly up on the screen in GL coordinates, and the angle increases clockwise. This test of points on a square and one point below the square should print the output below. glm::vec2 a {5.0f, 5.0f}, b {1.0f, 1.0f}, c {1.0f, 5.0f}, d {5.0f, 1.0f}, e {5.0f, -1.0f}; std::cout << glm::degrees(sb::angle_between(a, b)) << " " << glm::degrees(sb::angle_between(b, a)) << " " << glm::degrees(sb::angle_between(a, c)) << " " << glm::degrees(sb::angle_between(c, a)) << " " << glm::degrees(sb::angle_between(b, e)) << " " << glm::degrees(sb::angle_between(e, b)) << std::endl << sb::velocity_to_delta(sb::angle_between(a, b), 4.0f * glm::sqrt(2.0f)) << " " << sb::velocity_to_delta(sb::angle_between(b, a), 4.0f * glm::sqrt(2.0f)) << " " << sb::velocity_to_delta(sb::angle_between(d, a), 4.0f) << " " << sb::velocity_to_delta(sb::angle_between(b, e), 1.0f) << std::endl; Should print, -135 45 -90 90 116.565 -63.435 {-4, -4} {4, 4} {0, 4} {0.894427, -0.447214} This test of angle differences should print the output below. float a = 0.0f, b = glm::pi(), c = glm::half_pi(), d = 0.5f, e = glm::pi() * 4; std::cout << sb::angle_difference(a, b) << " " << sb::angle_difference(a, c) << " " << sb::angle_difference(b, c) << " " << sb::angle_difference(a, d) << " " << sb::angle_difference(c, d) << " " << sb::angle_difference(a, e) << " " << sb::angle_difference(c, e) << " " << sb::angle_difference(d, e) << " " << sb::angle_difference(c, c) << std::endl << sb::angle_ratio(a, b) << " " << sb::angle_ratio(a, c) << " " << sb::angle_ratio(b, c) << " " << sb::angle_ratio(a, d) << " " << sb::angle_ratio(c, d) << " " << sb::angle_ratio(a, e) << " " << sb::angle_ratio(c, e) << " " << sb::angle_ratio(d, e) << " " << sb::angle_ratio(c, c) << std::endl; Should print, -3.14159 1.5708 -1.5708 0.5 -1.0708 3.49691e-07 -1.5708 -0.5 0 -1 0.5 -0.5 0.159155 -0.340845 1.1131e-07 -0.5 -0.159155 0 */ #pragma once #include /* GLM */ #define GLM_ENABLE_EXPERIMENTAL #include #include namespace sb { static inline const glm::vec3 ZAXIS {0.0f, 0.0f, 1.0f}; /*! * Convert a vector described by the given angle and magnitude to an X and Y offset vector. * * @param angle a float representing the angle of velocity in radians, with 0 being up on the screen and increasing * values going clockwise * @param magnitude a float representing the speed, or the magnitude of the input vector in the X/Y plane * @return a glm::vec2 of the change in X and Y for the given velocity vector */ glm::vec2 velocity_to_delta(float angle, float magnitude); /*! * @overload glm::vec2 velocity_to_delta(float angle, float magnitude) */ glm::vec2 velocity_to_delta(glm::vec2 velocity); /*! * Get the angle between two vectors, or the angle the first would rotate to to point toward the second. * * @param start X/Y coordinates * @param end X/Y coordinates * @return an angle in radians */ float angle_between(glm::vec2 start, glm::vec2 end); /*! * Get the signed shortest angle difference between two angles, or how much the first angle would have to rotate * to be equivalent to the second angle. Negative is counter-clockwise, positive clockwise. * * @param start X/Y coordinates of the angle which the difference will be relative to * @param end X/Y coordinates of the angle which the difference will be rotated to * @return angle difference relative to the start parameter in radians */ float angle_difference(float start, float end); /*! * Get the angle difference between two angles as a signed ratio of how much of a 180 degree turn it is. Negative * is counter-clockwise, positive clockwise. * * @param start X/Y coordinates of the angle which the difference will be relative to * @param end X/Y coordinates of the angle which the difference will be rotated to * @return angle difference relative to the start parameter as a signed ratio of how much of a 180 degree * turn it is. */ float angle_ratio(float start, float end); /*! * Calculate a 2D bezier curve from four 2D control points. * * Adapted from public domain released code, 2007 Victor Blomqvist, originally at https://www.pygame.org/wiki/BezierCurve. * * @param vertices four 2D control points * @param resolution number of points that will be in the computed curve */ std::vector bezier(const std::vector& vertices, int resolution = 30); }