/* * © Copyright 2014 – Urheberrechtshinweis * Alle Rechte vorbehalten / All Rights Reserved * * Programmcode ist urheberrechtlich geschuetzt. * Das Urheberrecht liegt, soweit nicht ausdruecklich anders gekennzeichnet, bei Frank Ebner. * Keine Verwendung ohne explizite Genehmigung. * (vgl. § 106 ff UrhG / § 97 UrhG) */ #ifndef ANGLE_H #define ANGLE_H #include #include "../Assertions.h" #include "Point2.h" #include "../math/speed.h" #define PI ((float) M_PI) struct Angle { public: /** get the radians from (x1,y1) to (x2,y2) between 0 (to-the-right) and <2_PI */ static float getRAD_2PI(const float x1, const float y1, const float x2, const float y2) { Assert::isFalse( (x1==x2)&&(y1==y2), "(x1,y1) must not equal (x2,y2)!!"); const float tmp = std::atan2(y2-y1, x2-x1); return (tmp < 0) ? (tmp + 2*PI) : (tmp); } /** get the radians from (0,0) to (p.x,p.y) between 0 (to-the-right) and <2_PI */ static float getRAD_2PI(const Point2& p) { return getRAD_2PI(0, 0, p.x, p.y); } /** get the degrees from (x1,y1) to (x2,y2) between 0 (to-the-right) and <360 */ static float getDEG_360(const float x1, const float y1, const float x2, const float y2) { return radToDeg(getRAD_2PI(x1,y1,x2,y2)); } /** ensure the given radians-value is within [0:2pi] */ static float makeSafe_2PI(float rad) { while(rad < 0) {rad += 2*PI;} while(rad >= 2*PI) {rad -= 2*PI;} return rad; } /** * gets the angular difference between * - the given radians [0:2PI] * - as a change-in-direction between [0:PI] */ static float getDiffRAD_2PI_PI(const float r1, const float r2) { Assert::isBetween(r1, 0.0f, (2*PI), "r1 out of bounds"); Assert::isBetween(r2, 0.0f, (2*PI), "r2 out of bounds"); float tmp = std::abs(r1-r2); return (tmp <= PI) ? (tmp) : (2*PI-tmp); } /** * gets the angular difference between * "angular change from r1 to r2" * - the given radians [0:2PI] * - as a change-in-direction between [-PI:+PI] */ static float getSignedDiffRAD_2PI(const float r1, const float r2) { Assert::isBetween(r1, 0.0f, (float)(2*PI), "r1 out of bounds"); // [0:360] deg Assert::isBetween(r2, 0.0f, (float)(2*PI), "r2 out of bounds"); // [0:360] deg float diff = r2-r1; if (diff > +PI) {diff = -(2*PI - diff);} else if (diff < -PI) {diff = +(2*PI + diff);} Assert::isBetween(diff, -PI, (float)(+PI), "result out of bounds"); // [-180:+180] deg return diff; } /** convert degrees to radians */ static constexpr inline float degToRad(const float deg) { return deg / 180.0f * PI; } /** convert radians to degrees */ static constexpr inline float radToDeg(const float rad) { return rad * 180.0f / PI; } /** get a pointer vector (length 1) pointing to the given angle (in radians) */ static Point2 getPointer(const float rad) { const float x = cos(rad); const float y = sin(rad); return Point2(x,y); } }; #undef PI #endif // ANGLE_H