This repository has been archived on 2020-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
Files
Indoor/geo/Heading.h
2018-10-25 11:50:12 +02:00

138 lines
3.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* © 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 HEADING_H
#define HEADING_H
#include <cmath>
#include <random>
#include "Angle.h"
struct Heading {
#define _2PI (2*(float)M_PI)
private:
/** heading in radians. 0 = to-the-right */
float rad;
public:
/** ctor with radians */
Heading(const float rad) : rad(rad) {
Assert::isBetween(rad, 0.0f, (float)_2PI, "radians out of bounds");
}
/** ctor from(x1,y1) to(x2,y2) */
Heading(const float x1, const float y1, const float x2, const float y2) : rad(Angle::getRAD_2PI(x1,y1,x2,y2)) {
Assert::isBetween(rad, 0.0f, (float)_2PI, "radians out of bounds");
}
/** ctor from(x,y) -> to(x,y) */
Heading(const Point2 from, const Point2 to) : Heading(from.x, from.y, to.x, to.y) {
;
}
/** POSITIVE angular difference [0:PI] */
float getDiffHalfRAD(const Heading other) const {
return Angle::getDiffRAD_2PI_PI(rad, other.rad);
}
/** signled angular difference [-PI:+PI] */
// float getSignedDiff(const Heading other) const {
// return Angle::getSignedDiffRAD_2PI(other.rad, rad);
// }
static float getSignedDiff(const Heading from, const Heading to) {
return Angle::getSignedDiffRAD_2PI(from.rad, to.rad);
}
/** update the angle but ensure we stay within [0:2PI] */
Heading& operator += (const float _rad) {
// Assert::isBetween(_rad, float(-_2PI*0.999), float(+_2PI*0.999), "radians out of bounds");
// Assert::isBetween(_rad, float(-_2PI), float(+_2PI), "radians out of bounds");
rad += _rad;
while (rad >= _2PI) {rad -= _2PI;}
while (rad < 0) {rad += _2PI;}
return *this;
}
/** update the angle but ensure we stay within [0:2PI] */
Heading& operator -= (const float _rad) {
return *this += (-_rad);
}
/** update the angle but ensure we stay within [0:2PI] */
Heading operator + (const float _rad) const {
return (Heading(*this) += _rad);
}
/** update the angle but ensure we stay within [0:2PI] */
Heading operator - (const float _rad) const {
return (Heading(*this) -= _rad);
}
/** update the angle but ensure we stay within [0:2PI] */
Heading operator - (const Heading head) const {
return *this - head.rad;
}
/** update the angle but ensure we stay within [0:2PI] */
Heading operator + (const Heading head) const {
return *this + head.rad;
}
Heading& operator = (const float _rad) {
rad = _rad;
return *this;
}
/** compare two headings */
bool operator == (const Heading other) const {return rad == other.rad;}
bool operator != (const Heading other) const {return rad != other.rad;}
/** get an inverted version of this heading (upwards -> downwards, left -> right, ...) */
Heading getInverted() const {
Heading out(rad);
out += M_PI;
return out;
}
float getRAD() const {return rad;}
/** convert heading into a direction-vector */
Point2 asVector() const {
return Point2(std::cos(rad), std::sin(rad));
}
// /** get a random heading */
// static Heading rnd() {
// static std::minstd_rand gen(1234);
// static std::uniform_real_distribution<float> dist(0, _2PI);
// const float rnd = dist(gen);
// return Heading(rnd);
// }
#undef _2PI
};
namespace Headings {
static const Heading RIGHT = Heading((float)M_PI*0.0f/2.0f);
static const Heading UP = Heading((float)M_PI*1.0f/2.0f);
static const Heading LEFT = Heading((float)M_PI*2.0f/2.0f);
static const Heading DOWN = Heading((float)M_PI*3.0f/2.0f);
}
#endif // HEADING_H