15 #ifndef MOTIVE_MATH_ANGLE_H_
16 #define MOTIVE_MATH_ANGLE_H_
21 #include "mathfu/constants.h"
22 #include "mathfu/matrix.h"
23 #include "mathfu/vector.h"
24 #include "mathfu/glsl_mappings.h"
26 #ifdef FPL_ANGLE_UNIT_TESTS
27 #include "gtest/gtest.h"
28 #endif // FPL_ANGLE_UNIT_TESTS
43 enum AngleToVectorSystem {
53 static const float kPi =
static_cast<float>(M_PI);
54 static const float kTwoPi =
static_cast<float>(2.0 * M_PI);
55 static const float kThreePi =
static_cast<float>(3.0 * M_PI);
56 static const float kHalfPi =
static_cast<float>(M_PI_2);
57 static const float kQuarterPi =
static_cast<float>(0.5 * M_PI_2);
58 static const float kDegreesToRadians =
static_cast<float>(M_PI / 180.0);
59 static const float kRadiansToDegrees =
static_cast<float>(180.0 / M_PI);
60 static const float kMaxUniqueAngle = kPi;
61 static const float kDegreesPerCircle = 360.0f;
73 static const float kMinUniqueAngle = -3.1415925f;
99 Angle() : angle_(0.0f) {}
118 angle_ = ModWithinThreePi(angle_ + rhs.angle_);
124 angle_ = ModWithinThreePi(angle_ - rhs.angle_);
147 float ToDegrees()
const {
return kRadiansToDegrees * angle_; }
159 default: assert(
false);
161 return mathfu::kZeros3f;
173 return mathfu::vec3(x, y, 0.0f);
184 ToVector(&r.x, &r.y);
197 return mathfu::vec3(x, 0.0f, z);
209 return mathfu::vec3(0.0f, y, z);
221 return mathfu::vec3(x, y, 0.0f);
232 ToVector(&r.y, &r.x);
245 return mathfu::vec3(x, 0.0f, z);
257 return mathfu::vec3(0.0f, y, z);
270 default: assert(
false);
272 return mathfu::mat3();
279 return mathfu::mat3(x, y, 0.0f, -y, x, 0.0f, 0.0f, 0.0f, 1.0f);
286 return mathfu::mat3(x, 0.0f, z, 0.0f, 1.0f, 0.0f, -z, 0.0f, x);
293 return mathfu::mat3(1.0f, 0.0f, 0.0f, 0.0f, y, z, 0.0f, -z, y);
323 angle -= (floor(angle / kTwoPi) + 1.0f) * kTwoPi;
337 return Angle(ModWithinThreePi(angle));
353 const AngleToVectorSystem system) {
361 default: assert(
false);
369 return Angle(ModIfNegativePi(atan2f(v[1], v[0])));
375 return Angle(ModIfNegativePi(atan2f(v[2], v[0])));
381 return Angle(ModIfNegativePi(atan2f(v[2], v[1])));
387 return Angle(ModIfNegativePi(atan2f(v[0], v[1])));
393 return Angle(ModIfNegativePi(atan2f(v[0], v[2])));
399 return Angle(ModIfNegativePi(atan2f(v[1], v[2])));
405 return kMinUniqueAngle <= angle && angle <= kMaxUniqueAngle;
409 friend bool operator==(
const Angle& a,
const Angle& b);
410 friend bool operator<(
const Angle& a,
const Angle& b);
411 friend bool operator<=(
const Angle& a,
const Angle& b);
413 #ifdef FPL_ANGLE_UNIT_TESTS
414 FRIEND_TEST(AngleTests, ModWithinThreePi);
415 FRIEND_TEST(AngleTests, ModIfNegativePi);
416 #endif // FPL_ANGLE_UNIT_TESTS
424 void ToVector(
float*
const zero_axis,
float*
const ninety_axis)
const {
426 *zero_axis = cos(angle_);
427 *ninety_axis = sin(angle_);
432 static float ModWithinThreePi(
const float angle) {
433 assert(-kThreePi < angle && angle < kThreePi);
436 const float above = angle < kMinUniqueAngle ? angle + kTwoPi : angle;
437 const float below = above > kMaxUniqueAngle ? above - kTwoPi : above;
442 static float ModIfNegativePi(
const float angle) {
444 return angle < kMinUniqueAngle ? kMaxUniqueAngle : angle;
450 inline Angle operator+(Angle lhs,
const Angle& rhs) {
455 inline Angle operator-(Angle lhs,
const Angle& rhs) {
460 inline Angle operator*(Angle lhs,
float rhs) {
465 inline Angle operator/(Angle lhs,
float rhs) {
470 inline bool operator==(
const Angle& a,
const Angle& b) {
471 return a.angle_ == b.angle_;
474 inline bool operator!=(
const Angle& a,
const Angle& b) {
475 return !operator==(a, b);
478 inline bool operator<(
const Angle& a,
const Angle& b) {
479 return a.angle_ < b.angle_;
482 inline bool operator>=(
const Angle& a,
const Angle& b) {
483 return !operator<(a, b);
486 inline bool operator<=(
const Angle& a,
const Angle& b) {
487 return a.angle_ <= b.angle_;
490 inline bool operator>(
const Angle& a,
const Angle& b) {
491 return !operator<=(a, b);
495 assert(0 <= max_diff.angle_ && max_diff.angle_ <= kPi);
499 const Angle diff = (*this) - center;
502 const Angle diff_clamped(
503 mathfu::Clamp(diff.angle_, -max_diff.angle_, max_diff.angle_));
507 return center + diff_clamped;
515 const mathfu::vec3& VectorSystemUp(
const AngleToVectorSystem system);
526 mathfu::vec3 LatitudeAndLongitudeToUnitSphere(
const Angle& latitude,
527 const Angle& longitude,
528 AngleToVectorSystem system);
532 #endif // MOTIVE_MATH_ANGLE_H_
mathfu::vec2 ToXYVector2f() const
Definition: angle.h:182
Angle(float angle)
Definition: angle.h:106
Angle & operator*=(const float rhs)
Multiply rhs and ensure result is in the normalized range (-pi,pi].
Definition: angle.h:129
static Angle FromYXVector(const mathfu::vec3 &v)
Definition: angle.h:386
static Angle FromXYVector(const mathfu::vec3 &v)
Definition: angle.h:368
Angle operator-() const
Negate the angle and ensure result is in the normalized range (-pi,pi].
Definition: angle.h:141
float ToDegrees() const
Return the angle value in degrees. Value is in the range (-180,180].
Definition: angle.h:147
mathfu::vec3 ToVectorSystem(const AngleToVectorSystem system) const
Definition: angle.h:151
mathfu::vec3 ToXYVector() const
Definition: angle.h:170
Angle & operator/=(const float rhs)
Divide rhs and ensure result is in the normalized range (-pi,pi].
Definition: angle.h:135
mathfu::vec3 ToZXVector() const
Definition: angle.h:242
static Angle FromZXVector(const mathfu::vec3 &v)
Definition: angle.h:392
Angle Clamp(const Angle ¢er, const Angle &max_diff) const
Definition: angle.h:494
static Angle FromDegrees(const float degrees)
Create from degrees, which is converted to the range (-pi, pi].
Definition: angle.h:346
Angle & operator+=(const Angle &rhs)
Add rhs and ensure result is in the range (-pi,pi].
Definition: angle.h:117
mathfu::mat3 ToZYRotationMatrix() const
Returns a matrix that rotates about the X axis -angle radians.
Definition: angle.h:307
bool IsValid() const
Definition: angle.h:313
static Angle FromRadians(const float radians)
Create from radians, which is converted to the range (-pi, pi].
Definition: angle.h:341
mathfu::vec2 ToYXVector2f() const
Definition: angle.h:230
static Angle FromXZVector(const mathfu::vec3 &v)
Definition: angle.h:374
Represent an angle in radians, uniquely in the range (-pi, pi].
Definition: angle.h:97
mathfu::mat3 ToRotationMatrix(const AngleToVectorSystem system) const
Definition: angle.h:262
Angle Abs() const
Returns the absolute value of an angle.
Definition: angle.h:109
mathfu::vec3 ToXZVector() const
Definition: angle.h:194
static Angle FromZYVector(const mathfu::vec3 &v)
Definition: angle.h:398
Angle & operator-=(const Angle &rhs)
Subtract rhs and ensure result is in the range (-pi,pi].
Definition: angle.h:123
static Angle FromYZVector(const mathfu::vec3 &v)
Definition: angle.h:380
mathfu::vec3 ToYZVector() const
Definition: angle.h:206
static Angle FromVectorSystem(const mathfu::vec3 &v, const AngleToVectorSystem system)
Definition: angle.h:352
float ToRadians() const
Return the angle value in radians. Value is in the range (-pi,pi].
Definition: angle.h:144
static float WrapAngle(float angle)
Definition: angle.h:322
mathfu::vec3 ToYXVector() const
Definition: angle.h:218
mathfu::mat3 ToYZRotationMatrix() const
Returns a matrix that rotates about the X axis angle radians.
Definition: angle.h:290
static Angle FromWithinThreePi(const float angle)
Definition: angle.h:336
mathfu::mat3 ToZXRotationMatrix() const
Returns a matrix that rotates about the Y axis -angle radians.
Definition: angle.h:302
mathfu::mat3 ToXYRotationMatrix() const
Returns a matrix that rotates about the Z axis angle radians.
Definition: angle.h:276
mathfu::mat3 ToYXRotationMatrix() const
Returns a matrix that rotates about the Z axis -angle radians.
Definition: angle.h:297
mathfu::vec3 ToZYVector() const
Definition: angle.h:254
mathfu::mat3 ToXZRotationMatrix() const
Returns a matrix that rotates about the Y axis angle radians.
Definition: angle.h:283
static bool IsAngleInRange(const float angle)
Definition: angle.h:404