Added first Float and Angle functions

This commit is contained in:
Pascal Serrarens 2022-03-17 14:40:07 +01:00
parent 90da11db68
commit c2b5791f53
7 changed files with 293 additions and 1 deletions

View File

@ -15,12 +15,14 @@ set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
include_directories(include)
add_library(VectorAlgebra STATIC "src/Vector2.cpp" "src/Vector3.cpp" "src/Quaternion.cpp" )
add_library(VectorAlgebra STATIC "src/FloatSingle.cpp" "src/Angle.cpp" "src/Vector2.cpp" "src/Vector3.cpp" "src/Quaternion.cpp" )
enable_testing()
add_executable(
VectorAlgebraTest
"test/Angle_test.cc"
"test/FloatSingle_test.cc"
"test/Vector2_test.cc"
"test/Vector3_test.cc"
"test/Quaternion_test.cc"

16
include/Angle.h Normal file
View File

@ -0,0 +1,16 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0.If a copy of the MPL was not distributed with this
// file, You can obtain one at https ://mozilla.org/MPL/2.0/.
#ifndef ANGLE_H
#define ANGLE_H
class Angle {
public:
static float Normalize(float angle);
static float Clamp(float angle, float min, float max);
static float Difference(float a, float b);
static float MoveTowards(float fromAngle, float toAngle, float maxAngle);
};
#endif

15
include/FloatSingle.h Normal file
View File

@ -0,0 +1,15 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0.If a copy of the MPL was not distributed with this
// file, You can obtain one at https ://mozilla.org/MPL/2.0/.
#ifndef FLOAT_H
#define FLOAT_H
class Float {
public:
static const float epsilon;
static const float sqrEpsilon;
static float Clamp(float f, float min, float max);
};
#endif

34
src/Angle.cpp Normal file
View File

@ -0,0 +1,34 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0.If a copy of the MPL was not distributed with this
// file, You can obtain one at https ://mozilla.org/MPL/2.0/.
#include <math.h>
#include "Angle.h"
#include "FloatSingle.h"
float Angle::Normalize(float angle) {
if (!isfinite(angle))
return angle;
while (angle <= -180) angle += 360;
while (angle > 180) angle -= 360;
return angle;
}
float Angle::Clamp(float angle, float min, float max) {
float normalizedAngle = Normalize(angle);
float r = Float::Clamp(normalizedAngle, min, max);
return r;
}
float Angle::Difference(float a, float b) {
float r = Normalize(b - a);
return r;
}
float Angle::MoveTowards(float fromAngle, float toAngle, float maxAngle) {
float d = toAngle - fromAngle;
float sign = signbit(d) ? -1 : 1;
d = sign * Float::Clamp(fabs(d), 0, maxAngle);
return d;
}

17
src/FloatSingle.cpp Normal file
View File

@ -0,0 +1,17 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0.If a copy of the MPL was not distributed with this
// file, You can obtain one at https ://mozilla.org/MPL/2.0/.
#include <math.h>
#include "FloatSingle.h"
const float Float::epsilon = 1e-05f;
const float Float::sqrEpsilon = 1e-10f;
float Float::Clamp(float f, float min, float max) {
if (f < min)
return min;
if (f > max)
return max;
return f;
}

167
test/Angle_test.cc Normal file
View File

@ -0,0 +1,167 @@
#if GTEST
#include <gtest/gtest.h>
#include <math.h>
#include <limits>
#include "Angle.h"
#define FLOAT_INFINITY std::numeric_limits<float>::infinity()
TEST(Angle, Normalize) {
float r = 0;
r = Angle::Normalize(90);
EXPECT_FLOAT_EQ(r, 90) << "Normalize 90";
r = Angle::Normalize(-90);
EXPECT_FLOAT_EQ(r, -90) << "Normalize -90";
r = Angle::Normalize(270);
EXPECT_FLOAT_EQ(r, -90) << "Normalize 270";
r = Angle::Normalize(270+360);
EXPECT_FLOAT_EQ(r, -90) << "Normalize 270+360";
r = Angle::Normalize(-270);
EXPECT_FLOAT_EQ(r, 90) << "Normalize -270";
r = Angle::Normalize(-270 - 360);
EXPECT_FLOAT_EQ(r, 90) << "Normalize -270-360";
r = Angle::Normalize(0);
EXPECT_FLOAT_EQ(r, 0) << "Normalize 0";
if (std::numeric_limits<float>::is_iec559) {
r = Angle::Normalize(FLOAT_INFINITY);
EXPECT_FLOAT_EQ(r, FLOAT_INFINITY) << "Normalize INFINITY";
r = Angle::Normalize(-FLOAT_INFINITY);
EXPECT_FLOAT_EQ(r, -FLOAT_INFINITY) << "Normalize INFINITY";
}
}
TEST(Angle, Clamp) {
float r = 0;
r = Angle::Clamp(1, 0, 2);
EXPECT_FLOAT_EQ(r, 1) << "Clamp 1 0 2";
r = Angle::Clamp(-1, 0, 2);
EXPECT_FLOAT_EQ(r, 0) << "Clamp -1 0 2";
r = Angle::Clamp(3, 0, 2);
EXPECT_FLOAT_EQ(r, 2) << "Clamp 3 0 2";
r = Angle::Clamp(1, 0, 0);
EXPECT_FLOAT_EQ(r, 0) << "Clamp 1 0 0";
r = Angle::Clamp(0, 0, 0);
EXPECT_FLOAT_EQ(r, 0) << "Clamp 0 0 0";
r = Angle::Clamp(0, 1, -1);
EXPECT_FLOAT_EQ(r, 1) << "Clamp 0 1 -1";
if (std::numeric_limits<float>::is_iec559) {
r = Angle::Clamp(1, 0, FLOAT_INFINITY);
EXPECT_FLOAT_EQ(r, 1) << "Clamp 1 0 INFINITY";
r = Angle::Clamp(1, -FLOAT_INFINITY, 1);
EXPECT_FLOAT_EQ(r, 1) << "Clamp 1 -INFINITY 1";
}
}
TEST(Angle, Difference) {
float r = 0;
r = Angle::Difference(0, 90);
EXPECT_FLOAT_EQ(r, 90) << "Difference 0 90";
r = Angle::Difference(0, -90);
EXPECT_FLOAT_EQ(r, -90) << "Difference 0 -90";
r = Angle::Difference(0, 270);
EXPECT_FLOAT_EQ(r, -90) << "Difference 0 270";
r = Angle::Difference(0, -270);
EXPECT_FLOAT_EQ(r, 90) << "Difference 0 -270";
r = Angle::Difference(90, 0);
EXPECT_FLOAT_EQ(r, -90) << "Difference 90 0";
r = Angle::Difference(-90, 0);
EXPECT_FLOAT_EQ(r, 90) << "Difference -90 0";
r = Angle::Difference(0, 0);
EXPECT_FLOAT_EQ(r, 0) << "Difference 0 0";
r = Angle::Difference(90, 90);
EXPECT_FLOAT_EQ(r, 0) << "Difference 90 90";
if (std::numeric_limits<float>::is_iec559) {
r = Angle::Difference(0, INFINITY);
EXPECT_FLOAT_EQ(r, INFINITY) << "Difference 0 INFINITY";
r = Angle::Difference(0, -INFINITY);
EXPECT_FLOAT_EQ(r, -INFINITY) << "Difference 0 -INFINITY";
r = Angle::Difference(-INFINITY, INFINITY);
EXPECT_FLOAT_EQ(r, INFINITY) << "Difference -INFINITY INFINITY";
}
}
TEST(Angle, MoveTowards) {
float r = 0;
r = Angle::MoveTowards(0, 90, 30);
EXPECT_FLOAT_EQ(r, 30) << "MoveTowards 0 90 30";
r = Angle::MoveTowards(0, 90, 90);
EXPECT_FLOAT_EQ(r, 90) << "MoveTowards 0 90 90";
r = Angle::MoveTowards(0, 90, 180);
EXPECT_FLOAT_EQ(r, 90) << "MoveTowards 0 90 180";
r = Angle::MoveTowards(0, 90, 270);
EXPECT_FLOAT_EQ(r, 90) << "MoveTowards 0 90 270";
r = Angle::MoveTowards(0, 90, -30);
EXPECT_FLOAT_EQ(r, -30) << "MoveTowards 0 90 -30";
r = Angle::MoveTowards(0, -90, -30);
EXPECT_FLOAT_EQ(r, 30) << "MoveTowards 0 -90 -30";
r = Angle::MoveTowards(0, -90, -90);
EXPECT_FLOAT_EQ(r, 90) << "MoveTowards 0 -90 -90";
r = Angle::MoveTowards(0, -90, -180);
EXPECT_FLOAT_EQ(r, 180) << "MoveTowards 0 -90 -180";
r = Angle::MoveTowards(0, -90, -270);
EXPECT_FLOAT_EQ(r, 270) << "MoveTowards 0 -90 -270";
r = Angle::MoveTowards(0, 90, 0);
EXPECT_FLOAT_EQ(r, 0) << "MoveTowards 0 90 0";
r = Angle::MoveTowards(0, 0, 0);
EXPECT_FLOAT_EQ(r, 0) << "MoveTowards 0 0 0";
r = Angle::MoveTowards(0, 0, 30);
EXPECT_FLOAT_EQ(r, 0) << "MoveTowards 0 0 30";
if (std::numeric_limits<float>::is_iec559) {
r = Angle::MoveTowards(0, 90, FLOAT_INFINITY);
EXPECT_FLOAT_EQ(r, 90) << "MoveTowards 0 90 FLOAT_INFINITY";
r = Angle::MoveTowards(0, FLOAT_INFINITY, 30);
EXPECT_FLOAT_EQ(r, 30) << "MoveTowards 0 FLOAT_INFINITY 30";
r = Angle::MoveTowards(0, -90, -FLOAT_INFINITY);
EXPECT_FLOAT_EQ(r, FLOAT_INFINITY) << "MoveTowards 0 -90 -FLOAT_INFINITY";
r = Angle::MoveTowards(0, -FLOAT_INFINITY, -30);
EXPECT_FLOAT_EQ(r, 30) << "MoveTowards 0 -FLOAT_INFINITY -30";
}
}
#endif

41
test/FloatSingle_test.cc Normal file
View File

@ -0,0 +1,41 @@
#if GTEST
#include <gtest/gtest.h>
#include <math.h>
#include <limits>
#include "FloatSingle.h"
#define FLOAT_INFINITY std::numeric_limits<float>::infinity()
TEST(FloatC, Clamp) {
float r = 0;
r = Float::Clamp(1, 0, 2);
EXPECT_FLOAT_EQ(r, 1) << "Clamp 1 0 2";
r = Float::Clamp(-1, 0, 2);
EXPECT_FLOAT_EQ(r, 0) << "Clamp -1 0 2";
r = Float::Clamp(3, 0, 2);
EXPECT_FLOAT_EQ(r, 2) << "Clamp 3 0 2";
r = Float::Clamp(1, 0, 0);
EXPECT_FLOAT_EQ(r, 0) << "Clamp 1 0 0";
r = Float::Clamp(0, 0, 0);
EXPECT_FLOAT_EQ(r, 0) << "Clamp 0 0 0";
r = Float::Clamp(0, 1, -1);
EXPECT_FLOAT_EQ(r, 1) << "Clamp 0 1 -1";
if (std::numeric_limits<float>::is_iec559) {
r = Float::Clamp(1, 0, FLOAT_INFINITY);
EXPECT_FLOAT_EQ(r, 1) << "Clamp 1 0 INFINITY";
r = Float::Clamp(1, -FLOAT_INFINITY, 1);
EXPECT_FLOAT_EQ(r, 1) << "Clamp 1 -INFINITY 1";
}
}
#endif