101 lines
2.9 KiB
C++
Executable File
101 lines
2.9 KiB
C++
Executable File
/*
|
||
* © 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 <cmath>
|
||
#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
|