diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9fe0261..372b7c0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -43,6 +43,7 @@ else()
"test/Vector3_test.cc"
"test/Quaternion_test.cc"
"test/Matrix_test.cc"
+ "test/Polar_test.cc"
"test/Spherical_test.cc"
)
target_link_libraries(
diff --git a/Polar.cpp b/Polar.cpp
index aa28e9a..2ad451c 100644
--- a/Polar.cpp
+++ b/Polar.cpp
@@ -19,6 +19,13 @@ Polar::Polar(float newAngle, float newDistance) {
}
}
+Polar::Polar(Vector2 v) {
+ angle = Vector2::SignedAngle(
+ Vector2::forward,
+ v); // atan2(v.x, sqrt(v.z * v.z + v.y * v.y)) * Angle::Rad2Deg;
+ distance = v.magnitude();
+}
+
const Polar Polar::zero = Polar(0, 0);
float Polar::Distance(const Polar &v1, const Polar &v2) {
diff --git a/Polar.h b/Polar.h
index cbb161f..48d9f17 100644
--- a/Polar.h
+++ b/Polar.h
@@ -5,13 +5,15 @@
#ifndef POLAR_H
#define POLAR_H
+struct Vector2;
+
///
/// A polar vector
///
/// This will use the polar coordinate system consisting of a angle from a
/// reference direction and a distance.
struct Polar {
- public:
+public:
///
/// The angle in degrees, clockwise rotation
///
@@ -34,6 +36,8 @@ struct Polar {
/// The distance in meters
Polar(float angle, float distance);
+ Polar(Vector2 v);
+
///
/// A polar vector with zero degrees and distance
///
@@ -51,14 +55,14 @@ struct Polar {
///
/// The vector to subtract from this vector
/// The result of the subtraction
- Polar operator-(const Polar& v) const;
+ Polar operator-(const Polar &v) const;
///
/// Add another polar vector to this polar vector
///
/// The vector to add
/// The result of adding the vector
- Polar operator+(const Polar& v) const;
+ Polar operator+(const Polar &v) const;
///
/// Scale the vector uniformly up
@@ -76,7 +80,7 @@ struct Polar {
/// The scaled vector
/// This operation will scale the distance of the vector. The angle will be
/// unaffected.
- Polar operator/(const float& factor);
+ Polar operator/(const float &factor);
///
/// The distance between two vectors
@@ -84,7 +88,7 @@ struct Polar {
/// The first vector
/// The second vector
/// The distance between the two vectors
- static float Distance(const Polar& v1, const Polar& v2);
+ static float Distance(const Polar &v1, const Polar &v2);
///
/// Rotate the vector
@@ -95,4 +99,6 @@ struct Polar {
static Polar Rotate(Polar v, float angle);
};
+#include "Vector2.h"
+
#endif
\ No newline at end of file
diff --git a/Vector2.cpp b/Vector2.cpp
index c2a74c0..dbf6562 100644
--- a/Vector2.cpp
+++ b/Vector2.cpp
@@ -116,7 +116,7 @@ float Vector2::SignedAngle(Vector2 from, Vector2 to) {
float angleFrom = atan2(from.y, from.x);
float angleTo = atan2(to.y, to.x);
- return (angleTo - angleFrom) * Angle::Rad2Deg;
+ return -(angleTo - angleFrom) * Angle::Rad2Deg;
}
Vector2 Vector2::Rotate(Vector2 v, float angle) {
diff --git a/test/Polar_test.cc b/test/Polar_test.cc
new file mode 100644
index 0000000..ebadeee
--- /dev/null
+++ b/test/Polar_test.cc
@@ -0,0 +1,29 @@
+#if GTEST
+#include
+#include
+#include
+
+#include "Polar.h"
+
+#define FLOAT_INFINITY std::numeric_limits::infinity()
+
+TEST(Polar, FromVector2) {
+ Vector2 v = Vector2(0, 1);
+ Polar p = Polar::Polar(v);
+
+ EXPECT_FLOAT_EQ(p.distance, 1.0F) << "p.distance 0 1";
+ EXPECT_FLOAT_EQ(p.angle, 0.0F) << "s.angle 0 0 1";
+
+ v = Vector2(1, 0);
+ p = Polar::Polar(v);
+
+ EXPECT_FLOAT_EQ(p.distance, 1.0F) << "p.distance 1 0";
+ EXPECT_FLOAT_EQ(p.angle, 90.0F) << "s.angle 1 0";
+
+ v = Vector2(-1, 1);
+ p = Polar::Polar(v);
+
+ EXPECT_FLOAT_EQ(p.distance, sqrt(2.0F)) << "p.distance -1 1";
+ EXPECT_NEAR(p.angle, -45.0F, 1.0e-05) << "s.angle -1 1";
+}
+#endif
\ No newline at end of file
diff --git a/test/Vector2_test.cc b/test/Vector2_test.cc
index 9303bb0..88b8c97 100644
--- a/test/Vector2_test.cc
+++ b/test/Vector2_test.cc
@@ -399,11 +399,11 @@ TEST(Vector2, SignedAngle) {
bool r = false;
f = Vector2::SignedAngle(v1, v2);
- EXPECT_FLOAT_EQ(f, 12.09476F) << "SignedAngle(4 5, 1 2)";
+ EXPECT_FLOAT_EQ(f, -12.09476F) << "SignedAngle(4 5, 1 2)";
v2 = Vector2(-1, -2);
f = Vector2::SignedAngle(v1, v2);
- EXPECT_FLOAT_EQ(f, -167.9052F) << "SignedAngle(4 5, -1 -2)";
+ EXPECT_FLOAT_EQ(f, 167.9052F) << "SignedAngle(4 5, -1 -2)";
v2 = Vector2(0, 0);
f = Vector2::SignedAngle(v1, v2);
@@ -420,6 +420,16 @@ TEST(Vector2, SignedAngle) {
r = isnan(f);
EXPECT_TRUE(r) << "SignedAngle(4 5, -INFINITY -INFINITY)";
}
+
+ v1 = Vector2(0, 1);
+ v2 = Vector2(1, 0);
+ f = Vector2::SignedAngle(v1, v2);
+ EXPECT_FLOAT_EQ(f, 90.0F) << "SignedAngle(0 1, 1 0)";
+
+ v1 = Vector2(0, 1);
+ v2 = Vector2(0, -1);
+ f = Vector2::SignedAngle(v1, v2);
+ EXPECT_FLOAT_EQ(f, 180.0F) << "SignedAngle(0 1, 1 0)";
}
TEST(Vector2, Rotate) {