diff --git a/.gitignore b/.gitignore index d710913..0d46faf 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ testingBuild CMakeCache.txt dependencies CMakeFiles +build \ No newline at end of file diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 47a0d5d..f4f3e12 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -13,7 +13,8 @@ "compilerPath": "C:/msys64/mingw64/bin/g++.exe", "cStandard": "c17", "cppStandard": "gnu++17", - "intelliSenseMode": "windows-gcc-x64" + "intelliSenseMode": "windows-gcc-x64", + "configurationProvider": "ms-vscode.cmake-tools" } ], "version": 4 diff --git a/.vscode/settings.json b/.vscode/settings.json index 5bb4b0e..cfe40bd 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,4 @@ -{ +{ "files.associations": { "any": "cpp", "array": "cpp", @@ -87,4 +87,4 @@ "xtree": "cpp", "xutility": "cpp" } -} \ No newline at end of file +} diff --git a/CMakeLists.txt b/CMakeLists.txt index 5d9c0b2..3c0c947 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,6 +27,12 @@ add_executable( test/quaternion_unittest.cpp source/quaternion.hpp source/quaternion.cpp + test/line_unittest.cpp + source/line.hpp + source/line.cpp + test/plane_unittest.cpp + source/plane.hpp + source/plane.cpp ) target_link_libraries( diff --git a/DevGuide/utils/runBuild.bat b/DevGuide/utils/runBuild.bat deleted file mode 100644 index 67ee9d5..0000000 --- a/DevGuide/utils/runBuild.bat +++ /dev/null @@ -1,3 +0,0 @@ -set -x - -cmake --build testingBuild \ No newline at end of file diff --git a/DevGuide/utils/runtests.bat b/DevGuide/utils/runtests.bat index a02398a..53607de 100644 --- a/DevGuide/utils/runtests.bat +++ b/DevGuide/utils/runtests.bat @@ -1 +1,4 @@ +set -x + +cmake --build testingBuild .\testingBuild\Debug\testBuild.exe \ No newline at end of file diff --git a/exception/exception.hpp b/exception/exception.hpp new file mode 100644 index 0000000..5cbb0c9 --- /dev/null +++ b/exception/exception.hpp @@ -0,0 +1 @@ +#include "value.hpp" diff --git a/exception/value.hpp b/exception/value.hpp new file mode 100644 index 0000000..62a4eec --- /dev/null +++ b/exception/value.hpp @@ -0,0 +1,14 @@ +#ifndef VALUE_HPP +#define VALUE_HPP + +#include + +class value_error : public std::exception { + public: + value_error(const char* msg) : message(msg) {}; + const char* what() const noexcept {return message.c_str();} + private: + std::string message; +}; + +#endif diff --git a/source/cpp_utils.hpp b/source/cpp_utils.hpp index ab6ee46..f93694f 100644 --- a/source/cpp_utils.hpp +++ b/source/cpp_utils.hpp @@ -1,3 +1,5 @@ #include "vector.hpp" #include "quaternion.hpp" #include "matrix.hpp" +#include "line.hpp" +#include "plane.hpp" diff --git a/source/line.cpp b/source/line.cpp new file mode 100644 index 0000000..7cb3bc7 --- /dev/null +++ b/source/line.cpp @@ -0,0 +1,57 @@ +#include "line.hpp" + +namespace cpp_utils { + + Line::Line(Vector _point, Vector _direction) : point(_point) { + Vector normDir = _direction.normalise(); + if ((normDir.x < 0) || (normDir.x == 0 && normDir.y < 0) || (normDir.x == 0 && normDir.y == 0 && normDir.z < 0)) { + direction = -normDir; + } else { + direction = normDir; + } + }; + + bool Line::operator==(const Line &that) const { + return direction == that.direction && this->isOnLine(that.point); + }; + + /** + * Determines whether a point lies on the line. + */ + bool Line::isOnLine(const Vector &that) const { + bool isOn = true; + try { + this->whereOnLine(that); + } catch (value_error) { + isOn = false; + } + return isOn; + }; + + /** + * Determines where on the line a point lies. + */ + double Line::whereOnLine(const Vector &that) const { + Vector vecDiff = that - point; + double scalarX, scalarY, scalarZ; + + if (direction.x == 0) {scalarX = vecDiff.x;} else {scalarX = vecDiff.x / direction.x;} + if (direction.y == 0) {scalarY = vecDiff.y;} else {scalarY = vecDiff.y / direction.y;} + if (direction.z == 0) {scalarZ = vecDiff.z;} else {scalarZ = vecDiff.z / direction.z;} + + if ((scalarX == scalarY && scalarX == scalarZ) || + (scalarY == 0 && scalarX == scalarZ && direction.y == 0) || + (scalarZ == 0 && scalarX == scalarY && direction.z == 0) || + (scalarY == 0 && scalarZ == 0 && direction.y == 0 && direction.z == 0)) { + return scalarX; + } else if ((scalarX == 0 && scalarY == scalarZ && direction.x == 0) || + (scalarX == 0 && scalarZ == 0 && direction.x == 0 && direction.z == 0)) { + return scalarY; + } else if ((scalarX == 0 && scalarY == 0 && direction.x == 0 && direction.y == 0)) { + return scalarZ; + } else { + throw value_error("Point not on line."); + } + }; + +} diff --git a/source/line.hpp b/source/line.hpp new file mode 100644 index 0000000..47a4d21 --- /dev/null +++ b/source/line.hpp @@ -0,0 +1,28 @@ +#ifndef LINE_HPP +#define LINE_HPP + +#include "vector.hpp" + +const double norm = (1 / sqrt(3)); + +namespace cpp_utils { + + class Line { + public: + Vector point, direction; + inline Line() : point(0, 0, 0), direction(norm, norm, norm) {}; + Line(Vector _point, Vector _direction); + + bool operator==(const Line &that) const; + inline bool operator!=(const Line &that) const { + return true != (*this == that); + }; + + bool isOnLine(const Vector &that) const; + + double whereOnLine(const Vector &that) const; + }; + +} + +#endif diff --git a/source/matrix.cpp b/source/matrix.cpp index ce7fd0d..4452a7c 100644 --- a/source/matrix.cpp +++ b/source/matrix.cpp @@ -1,5 +1,3 @@ -#include -#include #include "matrix.hpp" namespace cpp_utils { @@ -16,77 +14,73 @@ namespace cpp_utils { double Matrix::det() const { return xx*(yy*zz-yz*zy)-xy*(yx*zz-yz*zx)+xz*(yx*zy-yy*zx); - } + }; - bool Matrix::operator==(const Matrix & that) const { - double test_precision = std::fmax(precision, that.precision); - if ((xx < (that.xx - test_precision)) || (xx > (that.xx + test_precision))) { - return false; - } - if ((xy < (that.xy - test_precision)) || (xy > (that.xy + test_precision))) { - return false; - } - if ((xz < (that.xz - test_precision)) || (xz > (that.xz + test_precision))) { - return false; - } - if ((yx < (that.yx - test_precision)) || (yx > (that.yx + test_precision))) { - return false; - } - if ((yy < (that.yy - test_precision)) || (yy > (that.yy + test_precision))) { - return false; - } - if ((yz < (that.yz - test_precision)) || (yz > (that.yz + test_precision))) { - return false; - } - if ((zx < (that.zx - test_precision)) || (zx > (that.zx + test_precision))) { - return false; - } - if ((zy < (that.zy - test_precision)) || (zy > (that.zy + test_precision))) { - return false; - } - if ((zz < (that.zz - test_precision)) || (zz > (that.zz + test_precision))) { - return false; - } - return true; - } + bool Matrix::operator==(const Matrix &that) const { + double testPrecision = std::fmax(precision, that.precision); + return !(std::abs(xx - that.xx) > testPrecision || + std::abs(xy - that.xy) > testPrecision || + std::abs(xz - that.xz) > testPrecision || + std::abs(yx - that.yx) > testPrecision || + std::abs(yy - that.yy) > testPrecision || + std::abs(yz - that.yz) > testPrecision || + std::abs(zx - that.zx) > testPrecision || + std::abs(zy - that.zy) > testPrecision || + std::abs(zz - that.zz) > testPrecision); + }; - Matrix Matrix::operator+(const Matrix & that) const { - return Matrix(this->xx + that.xx, this->xy + that.xy, this->xz + that.xz, this->yx + that.yx, this->yy + that.yy, this->yz + that.yz, this->zx + that.zx, this->zy + that.zy, this->zz + that.zz); - } + Matrix Matrix::operator+(const Matrix &that) const { + return Matrix(this->xx + that.xx, this->xy + that.xy, this->xz + that.xz, + this->yx + that.yx, this->yy + that.yy, this->yz + that.yz, + this->zx + that.zx, this->zy + that.zy, this->zz + that.zz); + }; - Matrix Matrix::operator-(const Matrix & that) const { - return Matrix(this->xx - that.xx, this->xy - that.xy, this->xz - that.xz, this->yx - that.yx, this->yy - that.yy, this->yz - that.yz, this->zx - that.zx, this->zy - that.zy, this->zz - that.zz); - } + Matrix Matrix::operator-(const Matrix &that) const { + return Matrix(this->xx - that.xx, this->xy - that.xy, this->xz - that.xz, + this->yx - that.yx, this->yy - that.yy, this->yz - that.yz, + this->zx - that.zx, this->zy - that.zy, this->zz - that.zz); + }; - Matrix Matrix::operator*(const double & that) const { + Matrix Matrix::operator*(const double &that) const { return Matrix(xx * that, xy * that, xz * that, yx * that, yy * that, yz * that, zx * that, zy * that, zz * that); - } + }; - Matrix operator*(double that, const Matrix & those) { + Matrix operator*(const double that, const Matrix &those) { return those * that; - } + }; - Matrix Matrix::operator*(const Matrix & that) const { - return Matrix((xx * that.xx) + (xy * that.yx) + (xz * that.zx), (xx * that.xy) + (xy * that.yy) + (xz * that.zy), (xx * that.xz) + (xy * that.yz) + (xz * that.zz), - (yx * that.xx) + (yy * that.yx) + (yz * that.zx), (yx * that.xy) + (yy * that.yy) + (yz * that.zy), (yx * that.xz) + (yy * that.yz) + (yz * that.zz), - (zx * that.xx) + (zy * that.yx) + (zz * that.zx), (zx * that.xy) + (zy * that.yy) + (zz * that.zy), (zx * that.xz) + (zy * that.yz) + (zz * that.zz)); - } + Matrix Matrix::operator*(const Matrix &that) const { + return Matrix((xx * that.xx) + (xy * that.yx) + (xz * that.zx), + (xx * that.xy) + (xy * that.yy) + (xz * that.zy), + (xx * that.xz) + (xy * that.yz) + (xz * that.zz), + (yx * that.xx) + (yy * that.yx) + (yz * that.zx), + (yx * that.xy) + (yy * that.yy) + (yz * that.zy), + (yx * that.xz) + (yy * that.yz) + (yz * that.zz), + (zx * that.xx) + (zy * that.yx) + (zz * that.zx), + (zx * that.xy) + (zy * that.yy) + (zz * that.zy), + (zx * that.xz) + (zy * that.yz) + (zz * that.zz)); + }; - Vector Matrix::operator*(const Vector & that) const { - return Vector((xx * that.x) + (xy * that.y) + (xz * that.z), (yx * that.x) + (yy * that.y) + (yz * that.z), (zx * that.x) + (zy * that.y) + (zz * that.z)); - } + Vector Matrix::operator*(const Vector &that) const { + return Vector((xx * that.x) + (xy * that.y) + (xz * that.z), + (yx * that.x) + (yy * that.y) + (yz * that.z), + (zx * that.x) + (zy * that.y) + (zz * that.z)); + }; - Vector operator*(Vector that, const Matrix & those) { - return Vector((that.x * those.xx) + (that.y * those.yx) + (that.z * those.zx), (that.x * those.xy) + (that.y * those.yy) + (that.z * those.zy), (that.x * those.xz) + (that.y * those.yz) + (that.z * those.zz)); - } + Vector operator*(const Vector that, const Matrix &those) { + return Vector((that.x * those.xx) + (that.y * those.yx) + (that.z * those.zx), + (that.x * those.xy) + (that.y * those.yy) + (that.z * those.zy), + (that.x * those.xz) + (that.y * those.yz) + (that.z * those.zz)); + }; Matrix Matrix::inverse() const { - if(this->det() == 0) { - throw std::overflow_error("No inverse due to zero value of determinant."); - } - return (1/det()) * Matrix( ((yy * zz) - (zy * yz)), -((xy * zz) - (zy * xz)), ((xy * yz) - (yy * xz)), - -((yx * zz) - (zx * yz)), ((xx * zz) - (zx * xz)), -((xx * yz) - (yx * xz)), - ((yx * zy) - (zx * yy)), -((xx * zy) - (zx * xy)), ((xx * yy) - (yx * xy))); - } - + if (this->det() == 0) { + throw value_error("No inverse due to zero value of determinant."); + } else { + return (1/det()) * Matrix( ((yy * zz) - (zy * yz)), -((xy * zz) - (zy * xz)), ((xy * yz) - (yy * xz)), + -((yx * zz) - (zx * yz)), ((xx * zz) - (zx * xz)), -((xx * yz) - (yx * xz)), + ((yx * zy) - (zx * yy)), -((xx * zy) - (zx * xy)), ((xx * yy) - (yx * xy))); + }; + }; + } diff --git a/source/matrix.hpp b/source/matrix.hpp index eafb6b5..d3a27d7 100644 --- a/source/matrix.hpp +++ b/source/matrix.hpp @@ -1,37 +1,36 @@ #ifndef MATRIX_HPP #define MATRIX_HPP -#include #include "vector.hpp" namespace cpp_utils { -class Matrix{ - public: - double xx, xy, xz, yx, yy, yz, zx, zy, zz; - inline Matrix() : xx(1), xy(0), xz(0), yx(0), yy(1), yz(0), zx(0), zy(0), zz(1) {}; - Matrix(double xx, double xy, double xz, double yx, double yy, double yz, double zx, double zy, double zz); - Matrix(double xx, double yy, double zz); - double det() const; + class Matrix { + public: + double xx, xy, xz, yx, yy, yz, zx, zy, zz; + inline Matrix() : xx(1), xy(0), xz(0), yx(0), yy(1), yz(0), zx(0), zy(0), zz(1) {}; + Matrix(double xx, double xy, double xz, double yx, double yy, double yz, double zx, double zy, double zz); + Matrix(double xx, double yy, double zz); + double det() const; - bool operator==(const Matrix & that) const; - inline bool operator!=(const Matrix & that) const { - return true != (*this == that); - }; - Matrix operator+(const Matrix & that) const; - Matrix operator-(const Matrix & that) const; - Matrix operator*(const double & that) const; - inline Matrix operator/(const double & that) const {return *this * (1/that);}; - inline Matrix operator-() {return *this * -1;}; - Matrix operator*(const Matrix & that) const; - Vector operator*(const Vector & that) const; - Matrix inverse() const; - private: - double precision = 0.0001; -}; + bool operator==(const Matrix &that) const; + inline bool operator!=(const Matrix &that) const { + return true != (*this == that); + }; + Matrix operator+(const Matrix &that) const; + Matrix operator-(const Matrix &that) const; + Matrix operator*(const double &that) const; + inline Matrix operator/(const double & that) const {return *this * (1/that);}; + inline Matrix operator-() {return *this * -1;}; + Matrix operator*(const Matrix &that) const; + Vector operator*(const Vector &that) const; + Matrix inverse() const; + private: + double precision = 0.0001; + }; -Vector operator*(Vector that, const Matrix & those); -Matrix operator*(double that, const Matrix & those); + Vector operator*(const Vector that, const Matrix &those); + Matrix operator*(const double that, const Matrix &those); } diff --git a/source/plane.cpp b/source/plane.cpp new file mode 100644 index 0000000..11c5308 --- /dev/null +++ b/source/plane.cpp @@ -0,0 +1,56 @@ +#include "plane.hpp" + +namespace cpp_utils { + + Plane::Plane(Vector _point, Vector _normal) : point(_point) { + Vector normNor = _normal.normalise(); + if ((normNor.x < 0) || (normNor.x == 0 && normNor.y < 0) || (normNor.x == 0 && normNor.y == 0 && normNor.z < 0)) { + normal = -normNor; + } else { + normal = normNor; + } + }; + + bool Plane::operator==(const Plane &that) const { + return normal == that.normal && this->isOnPlane(that.point); + }; + + /** + * Determines whether a point lines on a plane. + */ + bool Plane::isOnPlane(const Vector &that) const { + Vector vecDiff = that - point; + return vecDiff * normal == 0; + }; + + /** + * Finds the point of intersection for a given line with the plane. + */ + Vector Plane::intersection(const Line &that) const { + double cosAngle = that.direction * normal; + Vector vecDiff = that.point - point; + double dotProd = vecDiff * normal; + if (cosAngle == 0) { + throw value_error("Line lies in plane or is parallel to plane."); + } else if (dotProd == 0) { + return that.point; + } else { + double scalar = -dotProd / cosAngle; + return that.point + (scalar * that.direction); + } + }; + + /** + * Determines whether a line lies stricly between twos planes. + */ + bool isBetween(const Line line, const Plane &plane1, const Plane &plane2) { + if (plane1.normal != plane2.normal || line.direction * plane1.normal != 0) { + return false; + } else { + double abovePlane1 = (line.point - plane1.point) * plane1.normal; + double abovePlane2 = (line.point - plane2.point) * plane2.normal; + return abovePlane1 * abovePlane2 < 0; + } + }; + +} diff --git a/source/plane.hpp b/source/plane.hpp new file mode 100644 index 0000000..3b33f51 --- /dev/null +++ b/source/plane.hpp @@ -0,0 +1,28 @@ +#ifndef PLANE_HPP +#define PLANE_HPP + +#include "line.hpp" + +namespace cpp_utils { + + class Plane { + public: + Vector point, normal; + inline Plane() : point(0, 0, 0), normal(norm, norm, norm) {}; + Plane(Vector _point, Vector _normal); + + bool operator==(const Plane &that) const; + inline bool operator!=(const Plane &that) const { + return true != (*this == that); + }; + + bool isOnPlane(const Vector &that) const; + + Vector intersection(const Line &that) const; + }; + + bool isBetween(const Line line, const Plane &plane1, const Plane &plane2); + +} + +#endif diff --git a/source/quaternion.cpp b/source/quaternion.cpp index 01945ea..4aceed2 100644 --- a/source/quaternion.cpp +++ b/source/quaternion.cpp @@ -1,6 +1,4 @@ #include "quaternion.hpp" -#include -#include namespace cpp_utils { @@ -9,7 +7,7 @@ namespace cpp_utils { x(axis.x / axis.mod() * sin(angle / 2)), y(axis.y / axis.mod() * sin(angle / 2)), z(axis.z / axis.mod() * sin(angle / 2)) - {}; + {}; double Quaternion::mod() const { return sqrt((w * w) + (x * x) + (y * y) + (z * z)); @@ -17,9 +15,9 @@ namespace cpp_utils { Quaternion Quaternion::conj() const { return {w, -x, -y, -z}; - } + }; - Quaternion Quaternion::operator*(const double & that) const { + Quaternion Quaternion::operator*(const double &that) const { return Quaternion(w * that, x * that, y * that, z * that); }; @@ -43,7 +41,7 @@ namespace cpp_utils { ); }; - Quaternion Quaternion::operator*(const Vector & vec) const { + Quaternion Quaternion::operator*(const Vector &vec) const { return *this * Quaternion(0.0, vec.x, vec.y, vec.z); }; @@ -51,4 +49,4 @@ namespace cpp_utils { return Quaternion(0.0, vec.x, vec.y, vec.z) * quat; }; -} \ No newline at end of file +} diff --git a/source/quaternion.hpp b/source/quaternion.hpp index 4bed08f..bb9da50 100644 --- a/source/quaternion.hpp +++ b/source/quaternion.hpp @@ -7,43 +7,42 @@ namespace cpp_utils { -class Quaternion { - public: - double w, x, y, z; - inline Quaternion() : w(0), x(0), y(0), z(0) {}; - inline Quaternion(double w, double x, double y, double z): - w(w), x(x), y(y), z(z) {}; - Quaternion(double angle, Vector axis); - double mod() const; - Quaternion conj() const; - - bool operator==(const Quaternion & that) const; - inline bool operator!=(const Quaternion & that) const { - return true != (*this == that); - }; - Quaternion operator*(const double & that) const; - inline Quaternion operator/(const double & that) const { - return *this * (1/that); - }; - inline Quaternion operator-() {return *this * -1;}; - Quaternion operator*(const Quaternion & that) const; - Quaternion operator*(const Vector & vec) const; - private: - double relPrecision = 0.0001; - -}; - -Quaternion operator*(const Vector vec, const Quaternion quat); - -inline Vector rotate(Vector vec, Quaternion quat) { - Quaternion result = quat.conj() * vec * quat / quat.mod(); - return {result.x, result.y, result.z}; -}; - -inline std::ostream &operator<<(std::ostream &os, Quaternion const &quat) { - return os << "Quat(" << quat.w << ", " << quat.x << ", " << quat.y << ", "<< quat.z << ")\n"; -}; + class Quaternion { + public: + double w, x, y, z; + inline Quaternion() : w(0), x(0), y(0), z(0) {}; + inline Quaternion(double w, double x, double y, double z): + w(w), x(x), y(y), z(z) {}; + Quaternion(double angle, Vector axis); + double mod() const; + Quaternion conj() const; + + bool operator==(const Quaternion &that) const; + inline bool operator!=(const Quaternion &that) const { + return true != (*this == that); + }; + Quaternion operator*(const double &that) const; + inline Quaternion operator/(const double &that) const { + return *this * (1/that); + }; + inline Quaternion operator-() {return *this * -1;}; + Quaternion operator*(const Quaternion &that) const; + Quaternion operator*(const Vector &vec) const; + private: + double relPrecision = 0.0001; + }; + + Quaternion operator*(const Vector vec, const Quaternion quat); + + inline Vector rotate(Vector vec, Quaternion quat) { + Quaternion result = quat.conj() * vec * quat / quat.mod(); + return {result.x, result.y, result.z}; + }; + + inline std::ostream &operator<<(std::ostream &os, Quaternion const &quat) { + return os << "Quat(" << quat.w << ", " << quat.x << ", " << quat.y << ", "<< quat.z << ")\n"; + }; } -#endif \ No newline at end of file +#endif diff --git a/source/vector.cpp b/source/vector.cpp index 0939796..ad2bcb5 100644 --- a/source/vector.cpp +++ b/source/vector.cpp @@ -1,53 +1,50 @@ - -#include -#include - #include "vector.hpp" namespace cpp_utils { -Vector::Vector(double x, double y, double z) : x(x), y(y), z(z) {}; + Vector::Vector(double x, double y, double z) : x(x), y(y), z(z) {}; -double Vector::mod() const { - return sqrt(pow(x, 2) + pow(y, 2) + pow(z, 2)); -} + double Vector::mod() const { + return sqrt(pow(x, 2) + pow(y, 2) + pow(z, 2)); + }; -bool Vector::operator==(const Vector & that) const { - double test_precision = std::fmax(precision, that.precision); - if ((x < (that.x - test_precision)) || (x > (that.x + test_precision))) { - return false; - } - if ((y < (that.y - test_precision)) || (y > (that.y + test_precision))) { - return false; - } - if ((z < (that.z - test_precision)) || (z > (that.z + test_precision))) { - return false; - } - return true; -} + Vector Vector::normalise() const { + return (1 / this->mod()) * *this; + }; -Vector Vector::operator+(const Vector & that) const { - return Vector(this->x + that.x, this->y + that.y, this->z + that.z); -} + bool Vector::operator==(const Vector &that) const { + double testPrecision = std::fmax(precision, that.precision); + return !(std::abs(x - that.x) > testPrecision || + std::abs(y - that.y) > testPrecision || + std::abs(z - that.z) > testPrecision); + }; -Vector Vector::operator-(const Vector & that) const { - return Vector(this->x - that.x, this->y - that.y, this->z - that.z); -} + Vector Vector::operator+(const Vector &that) const { + return Vector(this->x + that.x, this->y + that.y, this->z + that.z); + }; -Vector Vector::operator*(const double & that) const { - return Vector(x * that, y * that, z * that); -} + Vector Vector::operator-(const Vector &that) const { + return Vector(this->x - that.x, this->y - that.y, this->z - that.z); + }; -double Vector::operator*(const Vector & that) const { - return (x * that.x) + (y * that.y) + (z * that.z); -} + Vector Vector::operator*(const double &that) const { + return Vector(x * that, y * that, z * that); + }; -Vector Vector::operator^(const Vector & that) const { - return Vector( - (y * that.z) - (z * that.y), - (z * that.x) - (x * that.z), - (x * that.y) - (y * that.x) - ); -} + Vector operator*(const double that, const Vector &those) { + return those * that; + }; -} \ No newline at end of file + double Vector::operator*(const Vector &that) const { + return (x * that.x) + (y * that.y) + (z * that.z); + }; + + Vector Vector::operator^(const Vector &that) const { + return Vector( + (y * that.z) - (z * that.y), + (z * that.x) - (x * that.z), + (x * that.y) - (y * that.x) + ); + }; + +} diff --git a/source/vector.hpp b/source/vector.hpp index e67e5a6..8130aed 100644 --- a/source/vector.hpp +++ b/source/vector.hpp @@ -2,34 +2,38 @@ #define VECTOR_HPP #include +#include "..\exception\exception.hpp" namespace cpp_utils { -class Vector{ - public: - double x, y, z; - inline Vector() : x(0), y(0), z(0) {}; - Vector(double x, double y, double z); - double mod() const; - - bool operator==(const Vector & that) const; - inline bool operator!=(const Vector & that) const { - return true != (*this == that); - }; - Vector operator+(const Vector & that) const; - Vector operator-(const Vector & that) const; - Vector operator*(const double & that) const; - inline Vector operator/(const double & that) const {return *this * (1/that);}; - inline Vector operator-() {return *this * -1;}; - double operator*(const Vector & that) const; - Vector operator^(const Vector & that) const; - protected: - double precision = 0.0001; -}; - -inline std::ostream &operator<<(std::ostream &os, Vector const &vec) { - return os << "Vec(" << vec.x << ", " << vec.y << ", "<< vec.z << ")\n"; -}; + class Vector { + public: + double x, y, z; + inline Vector() : x(0), y(0), z(0) {}; + Vector(double x, double y, double z); + double mod() const; + Vector normalise() const; + + bool operator==(const Vector &that) const; + inline bool operator!=(const Vector &that) const { + return true != (*this == that); + }; + Vector operator+(const Vector &that) const; + Vector operator-(const Vector &that) const; + Vector operator*(const double &that) const; + inline Vector operator/(const double &that) const {return *this * (1/that);}; + inline Vector operator-() {return *this * -1;}; + double operator*(const Vector &that) const; + Vector operator^(const Vector &that) const; + protected: + double precision = 0.0001; + }; + + Vector operator*(const double that, const Vector &those); + + inline std::ostream &operator<<(std::ostream &os, Vector const &vec) { + return os << "Vec(" << vec.x << ", " << vec.y << ", "<< vec.z << ")\n"; + }; } diff --git a/test/line_unittest.cpp b/test/line_unittest.cpp new file mode 100644 index 0000000..9615a3a --- /dev/null +++ b/test/line_unittest.cpp @@ -0,0 +1,359 @@ +#include "gtest/gtest.h" +#include "../source/line.hpp" + +namespace cpp_utils { + + TEST(LineTest, DefaultInitTest) { + Vector point(0, 0, 0); + Vector direction(norm, norm, norm); + Line line; + EXPECT_TRUE(line.point == point); + EXPECT_TRUE(line.direction == direction); + } + + TEST(LineTest, InitTest) { + Vector point(1, 2, 3); + Vector direction(4, 5, 6); + Line line(point, direction); + EXPECT_TRUE(line.point == point); + EXPECT_TRUE(line.direction == direction.normalise()); + } + + TEST(LineTest, BasicEqualityTest) { + EXPECT_TRUE(Line() == Line()); + EXPECT_FALSE(Line() == Line({1, 0, 0}, {0, 3, 6})); + } + + TEST(LineTest, EqualityTest_DirectionChanges) { + // Same Line but direction reversal + Line line01({0, 0, 0}, {1, 0, 0}); + Line line02({0, 0, 0}, {-1, 0, 0}); + EXPECT_TRUE(line01 == line02); + + Line line02a({0, 0, 0}, {0, 2, 2}); + Line line02b({0, 0, 0}, {0, -2, -2}); + EXPECT_TRUE(line02a == line02b); + + Line line02c({0, 0, 0}, {0, -2, 2}); + Line line02d({0, 0, 0}, {0, 2, -2}); + EXPECT_TRUE(line02c == line02d); + + // same point different direction + Line line07({1, 0, 0}, {1, 0, 0}); + Line line08({1, 0, 0}, {0, 1, 0}); + EXPECT_FALSE(line07 == line08); + } + + TEST(LineTest, EqualityTest_PointChanges) { + // Different points - same direction - different line + Line line03({1, 0, 0}, {1, 0, 0}); + Line line04({0, 1, 0}, {1, 0, 0}); + EXPECT_FALSE(line03 == line04); + + // Different points but the same line + Line line05({1, 0, 0}, {1, 0, 0}); + Line line06({0, 0, 0}, {1, 0, 0}); + EXPECT_TRUE(line05 == line06); + } + + TEST(LineTest, EqualityTest_Composite) { + // different point - reversed direction - same line + Line line09({0, 0, 0}, {0, 1, 1}); + Line line10({0, 2, 2}, {0, -1, -1}); + EXPECT_TRUE(line09 == line10); + } + + TEST(LineTest, BasicNotEqualityTest) { + EXPECT_FALSE(Line() != Line()); + EXPECT_TRUE(Line() != Line({1, 0, 0}, {0, 3, 6})); + } + + TEST(LineTest, NotEqualityTest_DirectionChanges) { + // Same Line but direction reversal + Line line01({0, 0, 0}, {1, 0, 0}); + Line line02({0, 0, 0}, {-1, 0, 0}); + EXPECT_FALSE(line01 != line02); + + Line line02a({0, 0, 0}, {0, 2, 2}); + Line line02b({0, 0, 0}, {0, -2, -2}); + EXPECT_FALSE(line02a != line02b); + + Line line02c({0, 0, 0}, {0, -2, 2}); + Line line02d({0, 0, 0}, {0, 2, -2}); + EXPECT_FALSE(line02c != line02d); + + // same point different direction + Line line07({1, 0, 0}, {1, 0, 0}); + Line line08({1, 0, 0}, {0, 1, 0}); + EXPECT_TRUE(line07 != line08); + } + + TEST(LineTest, NotEqualityTest_PointChanges) { + // Different points - same direction - different line + Line line03({1, 0, 0}, {1, 0, 0}); + Line line04({0, 1, 0}, {1, 0, 0}); + EXPECT_TRUE(line03 != line04); + + // Different points but the same line + Line line05({1, 0, 0}, {1, 0, 0}); + Line line06({0, 0, 0}, {1, 0, 0}); + EXPECT_FALSE(line05 != line06); + } + + TEST(LineTest, NotEqualityTest_Composite) { + // different point - reversed direction - same line + Line line09({0, 0, 0}, {0, 1, 1}); + Line line10({0, 2, 2}, {0, -1, -1}); + EXPECT_FALSE(line09 != line10); + } + + TEST(LineTest, IsOnTest_UnitChecks) { + // Direction {1, 0, 0} + Line line0({1, 0, 0}, {1, 0, 0}), + line1({0, 1, 0}, {1, 0, 0}), + line2({0, 0, 1}, {1, 0, 0}); + + EXPECT_TRUE(line0.isOnLine({1, 0, 0})); + EXPECT_TRUE(line0.isOnLine({2, 0, 0})); + EXPECT_TRUE(line0.isOnLine({0, 0, 0})); + EXPECT_FALSE(line0.isOnLine({0, 1, 0})); + EXPECT_FALSE(line0.isOnLine({0, 0, 1})); + + EXPECT_TRUE(line1.isOnLine({0, 1, 0})); + EXPECT_TRUE(line1.isOnLine({1, 1, 0})); + EXPECT_TRUE(line1.isOnLine({-1, 1, 0})); + EXPECT_FALSE(line1.isOnLine({0, 0, 1})); + EXPECT_FALSE(line1.isOnLine({1, 0, 0})); + EXPECT_FALSE(line1.isOnLine({0, 0, 0})); + + EXPECT_TRUE(line2.isOnLine({0, 0, 1})); + EXPECT_TRUE(line2.isOnLine({1, 0, 1})); + EXPECT_TRUE(line2.isOnLine({-1, 0, 1})); + EXPECT_FALSE(line2.isOnLine({1, 0, 0})); + EXPECT_FALSE(line2.isOnLine({0, 1, 0})); + EXPECT_FALSE(line2.isOnLine({0, 0, 0})); + + // Direction {0, 1, 0} + Line line3({1, 0, 0}, {0, 1, 0}), + line4({0, 1, 0}, {0, 1, 0}), + line5({0, 0, 1}, {0, 1, 0}); + + EXPECT_TRUE(line3.isOnLine({1, 0, 0})); + EXPECT_TRUE(line3.isOnLine({1, 1, 0})); + EXPECT_TRUE(line3.isOnLine({1, -1, 0})); + EXPECT_FALSE(line3.isOnLine({0, 1, 0})); + EXPECT_FALSE(line3.isOnLine({0, 0, 1})); + EXPECT_FALSE(line3.isOnLine({0, 0, 0})); + + EXPECT_TRUE(line4.isOnLine({0, 1, 0})); + EXPECT_TRUE(line4.isOnLine({0, 2, 0})); + EXPECT_TRUE(line4.isOnLine({0, 0, 0})); + EXPECT_FALSE(line4.isOnLine({0, 0, 1})); + EXPECT_FALSE(line4.isOnLine({1, 0, 0})); + + EXPECT_TRUE(line5.isOnLine({0, 0, 1})); + EXPECT_TRUE(line5.isOnLine({0, 1, 1})); + EXPECT_TRUE(line5.isOnLine({0, -1, 1})); + EXPECT_FALSE(line5.isOnLine({1, 0, 0})); + EXPECT_FALSE(line5.isOnLine({0, 1, 0})); + EXPECT_FALSE(line5.isOnLine({0, 0, 0})); + + // Direction {0, 0, 1} + Line line6({1, 0, 0}, {0, 0, 1}), + line7({0, 1, 0}, {0, 0, 1}), + line8({0, 0, 1}, {0, 0, 1}); + + EXPECT_TRUE(line6.isOnLine({1, 0, 0})); + EXPECT_TRUE(line6.isOnLine({1, 0, 1})); + EXPECT_TRUE(line6.isOnLine({1, 0, -1})); + EXPECT_FALSE(line6.isOnLine({0, 1, 0})); + EXPECT_FALSE(line6.isOnLine({0, 0, 1})); + EXPECT_FALSE(line6.isOnLine({0, 0, 0})); + + EXPECT_TRUE(line7.isOnLine({0, 1, 0})); + EXPECT_TRUE(line7.isOnLine({0, 1, 1})); + EXPECT_TRUE(line7.isOnLine({0, 1, -1})); + EXPECT_FALSE(line7.isOnLine({0, 0, 1})); + EXPECT_FALSE(line7.isOnLine({1, 0, 0})); + EXPECT_FALSE(line7.isOnLine({0, 0, 0})); + + EXPECT_TRUE(line8.isOnLine({0, 0, 1})); + EXPECT_TRUE(line8.isOnLine({0, 0, 2})); + EXPECT_TRUE(line8.isOnLine({0, 0, 0})); + EXPECT_FALSE(line8.isOnLine({1, 0, 0})); + EXPECT_FALSE(line8.isOnLine({0, 1, 0})); + } + + TEST(LineTest, IsOnTest_PointChanges) { + // Direction {1, -1, 0} + Line line0({1, 0, 0}, {1, -1, 0}), + line1({0, 1, 0}, {1, -1, 0}), + line2({0, 0, 1}, {1, -1, 0}); + + EXPECT_TRUE(line0.isOnLine({1, 0, 0})); + EXPECT_TRUE(line0.isOnLine({2, -1, 0})); + EXPECT_TRUE(line0.isOnLine({0, 1, 0})); + EXPECT_FALSE(line0.isOnLine({1, -1, 0})); + EXPECT_FALSE(line0.isOnLine({0, 0, 0})); + + EXPECT_TRUE(line1.isOnLine({0, 1, 0})); + EXPECT_TRUE(line1.isOnLine({1, 0, 0})); + EXPECT_TRUE(line1.isOnLine({-1, 2, 0})); + EXPECT_FALSE(line1.isOnLine({1, -1, 0})); + EXPECT_FALSE(line1.isOnLine({0, 0, 0})); + + EXPECT_TRUE(line2.isOnLine({0, 0, 1})); + EXPECT_TRUE(line2.isOnLine({1, -1, 1})); + EXPECT_TRUE(line2.isOnLine({-1, 1, 1})); + EXPECT_FALSE(line2.isOnLine({1, -1, 0})); + EXPECT_FALSE(line2.isOnLine({0, 0, 0})); + + // Direction {0, 1, -1} + Line line3({1, 0, 0}, {0, 1, -1}), + line4({0, 1, 0}, {0, 1, -1}), + line5({0, 0, 1}, {0, 1, -1}); + + EXPECT_TRUE(line3.isOnLine({1, 0, 0})); + EXPECT_TRUE(line3.isOnLine({1, 1, -1})); + EXPECT_TRUE(line3.isOnLine({1, -1, 1})); + EXPECT_FALSE(line3.isOnLine({0, 1, -1})); + EXPECT_FALSE(line3.isOnLine({0, 0, 0})); + + EXPECT_TRUE(line4.isOnLine({0, 1, 0})); + EXPECT_TRUE(line4.isOnLine({0, 2, -1})); + EXPECT_TRUE(line4.isOnLine({0, 0, 1})); + EXPECT_FALSE(line4.isOnLine({0, 1, -1})); + EXPECT_FALSE(line4.isOnLine({0, 0, 0})); + + EXPECT_TRUE(line5.isOnLine({0, 0, 1})); + EXPECT_TRUE(line5.isOnLine({0, 1, 0})); + EXPECT_TRUE(line5.isOnLine({0, -1, 2})); + EXPECT_FALSE(line5.isOnLine({0, 1, -1})); + EXPECT_FALSE(line5.isOnLine({0, 0, 0})); + + // Direction {-1, 0, 1} + Line line6({1, 0, 0}, {-1, 0, 1}), + line7({0, 1, 0}, {-1, 0, 1}), + line8({0, 0, 1}, {-1, 0, 1}); + + EXPECT_TRUE(line6.isOnLine({1, 0, 0})); + EXPECT_TRUE(line6.isOnLine({0, 0, 1})); + EXPECT_TRUE(line6.isOnLine({2, 0, -1})); + EXPECT_FALSE(line6.isOnLine({-1, 0, 1})); + EXPECT_FALSE(line6.isOnLine({0, 0, 0})); + + EXPECT_TRUE(line7.isOnLine({0, 1, 0})); + EXPECT_TRUE(line7.isOnLine({-1, 1, 1})); + EXPECT_TRUE(line7.isOnLine({1, 1, -1})); + EXPECT_FALSE(line7.isOnLine({-1, 0, 1})); + EXPECT_FALSE(line7.isOnLine({0, 0, 0})); + + EXPECT_TRUE(line8.isOnLine({0, 0, 1})); + EXPECT_TRUE(line8.isOnLine({-1, 0, 2})); + EXPECT_TRUE(line8.isOnLine({1, 0, 0})); + EXPECT_FALSE(line8.isOnLine({-1, 0, 1})); + EXPECT_FALSE(line8.isOnLine({0, 0, 0})); + } + + TEST(LineTest, IsOnTest_DirectionChanges) { + // Point {1, -1, 0} + Line line0({1, -1, 0}, {1, 0, 0}), + line1({1, -1, 0}, {0, 1, 0}), + line2({1, -1, 0}, {0, 0, 1}); + + EXPECT_TRUE(line0.isOnLine({1, -1, 0})); + EXPECT_TRUE(line0.isOnLine({2, -1, 0})); + EXPECT_TRUE(line0.isOnLine({0, -1, 0})); + EXPECT_FALSE(line0.isOnLine({1, 0, 0})); + EXPECT_FALSE(line0.isOnLine({0, 0, 0})); + + EXPECT_TRUE(line1.isOnLine({1, -1, 0})); + EXPECT_TRUE(line1.isOnLine({1, 0, 0})); + EXPECT_TRUE(line1.isOnLine({1, -2, 0})); + EXPECT_FALSE(line1.isOnLine({0, 1, 0})); + EXPECT_FALSE(line1.isOnLine({0, 0, 0})); + + EXPECT_TRUE(line2.isOnLine({1, -1, 0})); + EXPECT_TRUE(line2.isOnLine({1, -1, 1})); + EXPECT_TRUE(line2.isOnLine({1, -1, -1})); + EXPECT_FALSE(line2.isOnLine({0, 0, 1})); + EXPECT_FALSE(line2.isOnLine({0, 0, 0})); + + // Point {0, 1, -1} + Line line3({0, 1, -1}, {1, 0, 0}), + line4({0, 1, -1}, {0, 1, 0}), + line5({0, 1, -1}, {0, 0, 1}); + + EXPECT_TRUE(line3.isOnLine({0, 1, -1})); + EXPECT_TRUE(line3.isOnLine({1, 1, -1})); + EXPECT_TRUE(line3.isOnLine({-1, 1, -1})); + EXPECT_FALSE(line3.isOnLine({1, 0, 0})); + EXPECT_FALSE(line3.isOnLine({0, 0, 0})); + + EXPECT_TRUE(line4.isOnLine({0, 1, -1})); + EXPECT_TRUE(line4.isOnLine({0, 2, -1})); + EXPECT_TRUE(line4.isOnLine({0, 0, -1})); + EXPECT_FALSE(line4.isOnLine({0, 1, 0})); + EXPECT_FALSE(line4.isOnLine({0, 0, 0})); + + EXPECT_TRUE(line5.isOnLine({0, 1, -1})); + EXPECT_TRUE(line5.isOnLine({0, 1, 0})); + EXPECT_TRUE(line5.isOnLine({0, 1, -2})); + EXPECT_FALSE(line5.isOnLine({0, 0, 1})); + EXPECT_FALSE(line5.isOnLine({0, 0, 0})); + + // Point {-1, 0, 1} + Line line6({-1, 0, 1}, {1, 0, 0}), + line7({-1, 0, 1}, {0, 1, 0}), + line8({-1, 0, 1}, {0, 0, 1}); + + EXPECT_TRUE(line6.isOnLine({-1, 0, 1})); + EXPECT_TRUE(line6.isOnLine({0, 0, 1})); + EXPECT_TRUE(line6.isOnLine({-2, 0, 1})); + EXPECT_FALSE(line6.isOnLine({1, 0, 0})); + EXPECT_FALSE(line6.isOnLine({0, 0, 0})); + + EXPECT_TRUE(line7.isOnLine({-1, 0, 1})); + EXPECT_TRUE(line7.isOnLine({-1, 1, 1})); + EXPECT_TRUE(line7.isOnLine({-1, -1, 1})); + EXPECT_FALSE(line7.isOnLine({0, 1, 0})); + EXPECT_FALSE(line7.isOnLine({0, 0, 0})); + + EXPECT_TRUE(line8.isOnLine({-1, 0, 1})); + EXPECT_TRUE(line8.isOnLine({-1, 0, 2})); + EXPECT_TRUE(line8.isOnLine({-1, 0, 0})); + EXPECT_FALSE(line8.isOnLine({0, 0, 1})); + EXPECT_FALSE(line8.isOnLine({0, 0, 0})); + } + + TEST(LineTest, WhereOnTest) { + + Vector point0(0, 1, 1); + Vector point1(-1, 1, -1); + Vector point2(-1, 2, 0); + Line line0(point0, point1); + + Vector point3(1, 0, 1); + Vector point4(-1, -1, 1); + Vector point5(2, 1, 0); + Line line1(point3, point4); + + Vector point6(1, 1, 0); + Vector point7(1, -1, -1); + Vector point8(0, 2, 1); + Line line2(point6, point7); + + EXPECT_EQ(line0.whereOnLine(point0), 0); + EXPECT_THROW(line0.whereOnLine(point1), value_error); + EXPECT_EQ(line0.whereOnLine(point2), - 1 / norm); + + EXPECT_EQ(line1.whereOnLine(point3), 0); + EXPECT_THROW(line1.whereOnLine(point4), value_error); + EXPECT_EQ(line1.whereOnLine(point5), 1 / norm); + + EXPECT_EQ(line2.whereOnLine(point6), 0); + EXPECT_THROW(line2.whereOnLine(point7), value_error); + EXPECT_EQ(line2.whereOnLine(point8), - 1 / norm); + } + +} diff --git a/test/matrix_unittest.cpp b/test/matrix_unittest.cpp index 22c6416..03d728e 100644 --- a/test/matrix_unittest.cpp +++ b/test/matrix_unittest.cpp @@ -1,155 +1,146 @@ #include "gtest/gtest.h" -#include #include "../source/matrix.hpp" -TEST(MatrixTest, DefaultInitTest) { - cpp_utils::Matrix iMat; - EXPECT_EQ(iMat.xx, 1); - EXPECT_EQ(iMat.xy, 0); - EXPECT_EQ(iMat.xz, 0); - EXPECT_EQ(iMat.yx, 0); - EXPECT_EQ(iMat.yy, 1); - EXPECT_EQ(iMat.yz, 0); - EXPECT_EQ(iMat.zx, 0); - EXPECT_EQ(iMat.zy, 0); - EXPECT_EQ(iMat.zz, 1); -} - -TEST(MatrixTest, InitTest) { - cpp_utils::Matrix Mat1(0, 1, 2, 3, 4, 5, 6, 7, 8); - EXPECT_EQ(Mat1.xx, 0); - EXPECT_EQ(Mat1.xy, 1); - EXPECT_EQ(Mat1.xz, 2); - EXPECT_EQ(Mat1.yx, 3); - EXPECT_EQ(Mat1.yy, 4); - EXPECT_EQ(Mat1.yz, 5); - EXPECT_EQ(Mat1.zx, 6); - EXPECT_EQ(Mat1.zy, 7); - EXPECT_EQ(Mat1.zz, 8); -} - -TEST(MatrixTest, DiagonalInitTest) { - cpp_utils::Matrix Mat1(1, 2, 3); - EXPECT_EQ(Mat1.xx, 1); - EXPECT_EQ(Mat1.xy, 0); - EXPECT_EQ(Mat1.xz, 0); - EXPECT_EQ(Mat1.yx, 0); - EXPECT_EQ(Mat1.yy, 2); - EXPECT_EQ(Mat1.yz, 0); - EXPECT_EQ(Mat1.zx, 0); - EXPECT_EQ(Mat1.zy, 0); - EXPECT_EQ(Mat1.zz, 3); -} - -TEST(MatrixTest, DetTest) { - cpp_utils::Matrix iMat; - cpp_utils::Matrix Mat1(2, 0, 0, 0, 2, 0, 0, 0, 2); - cpp_utils::Matrix Mat2(0, 1, 2, 3, 4, 5, 6, 7, 8); - - EXPECT_NEAR(iMat.det(), 1, 0.0001); - EXPECT_NEAR(Mat1.det(), 8, 0.0001); - EXPECT_NEAR(Mat2.det(), 0, 0.0001); -} - -TEST(MatrixTest, EqualityTest) { - cpp_utils::Matrix Mat1(1, 0, 1, 0, 1, 0, 1, 0, 1); - cpp_utils::Matrix Mat2(0, 1, 0, 1, 0, 1, 0, 1, 0); - - EXPECT_TRUE(Mat1 == Mat1); - EXPECT_FALSE(Mat1 == Mat2); -} - -TEST(MatrixTest, NotEqualityTest) { - cpp_utils::Matrix Mat1(1, 0, 1, 0, 1, 0, 1, 0, 1); - cpp_utils::Matrix Mat2(0, 1, 0, 1, 0, 1, 0, 1, 0); - - EXPECT_FALSE(Mat1 != Mat1); - EXPECT_TRUE(Mat1 != Mat2); -} - -TEST(MatrixTest, AdditionTest) { - cpp_utils::Matrix Mat1(1, 0, 1, 0, 1, 0, 1, 0, 1); - cpp_utils::Matrix Mat2(0, 1, 0, 1, 0, 1, 0, 1, 0); - - cpp_utils::Matrix Exp1(1, 1, 1, 1, 1, 1, 1, 1, 1); - EXPECT_EQ(Mat1 + Mat2, Exp1); -} - -TEST(MatrixTest, SubtractionTest) { - cpp_utils::Matrix Mat1(1, 0, 1, 0, 1, 0, 1, 0, 1); - cpp_utils::Matrix Mat2(0, 1, 0, 1, 0, 1, 0, 1, 0); - - cpp_utils::Matrix Exp1(1, -1, 1, -1, 1, -1, 1, -1, 1); - EXPECT_EQ(Mat1 - Mat2, Exp1); - EXPECT_EQ(Mat2 - Mat1, -Exp1); -} - -TEST(MatrixTest, NegativeTest) { - cpp_utils::Matrix Mat1(0, -1, 2, -3, 4, -5, 6, -7, 8); - cpp_utils::Matrix Mat2(0, 1, -2, 3, -4, 5, -6, 7, -8); - - EXPECT_EQ(-Mat1, Mat2); -} - -TEST(MatrixTest, MultiplicationTest) { - cpp_utils::Matrix Mat1(0, 1, 2, 3, 4, -1, -2, -3, -4); - - cpp_utils::Matrix Exp1(0, -2, -4, -6, -8, 2, 4, 6, 8); - EXPECT_EQ(Mat1 * int(-2), Exp1) << "Failed to multiply by negative int"; - EXPECT_EQ(Mat1 * float(-2), Exp1) << "Failed to multiply by negative float"; - EXPECT_EQ(int(-2) * Mat1, Exp1) << "Failed to multiply by negative int"; - EXPECT_EQ(float(-2) * Mat1, Exp1) << "Failed to multiply by negative float"; - - cpp_utils::Matrix Exp2(0.0, 0.5, 1.0, 1.5, 2.0, -0.5, -1.0, -1.5, -2.0); - cpp_utils::Matrix res = Mat1 * float(0.5); - EXPECT_EQ(Mat1 * float(0.5), Exp2) << "Failed to multiply by decimal value"; - EXPECT_EQ(float(0.5) * Mat1, Exp2) << "Failed to multiply by decimal value"; -} - -TEST(MatrixTest, DivisionTest) { - cpp_utils::Matrix Mat1(0, 2, 4, 6, 8, -2, -4, -6, -8); - - cpp_utils::Matrix Exp1(0, 1, 2, 3, 4, -1, -2, -3, -4); - EXPECT_EQ(Mat1 / float(2), Exp1); - EXPECT_EQ(Mat1 / int(2), Exp1); -} - -TEST(MatrixTest, ZeroDivisionTest) { - cpp_utils::Matrix Mat1; - std::invalid_argument Excep("Division by zero is not possible"); -} - -TEST(MatrixTest, MatrixMultiplicationTest) { - cpp_utils::Matrix Mat1(1, 1, 0, 0, 1, 0, 0, 0, 0); - cpp_utils::Matrix Mat2(0, 1, 2, 3, 4, 5, 6, 7, 8); - cpp_utils::Matrix Mat3(3, 5, 7, 3, 4, 5, 0, 0, 0); - - EXPECT_TRUE(Mat1 * Mat2 == Mat3); - EXPECT_FALSE(Mat2 * Mat1 == Mat3); -} - -TEST(MatrixTest, VectorMultiplicationTest) { - cpp_utils::Matrix Mat1(1, 1, 0, 0, 1, 0, 0, 0, 0); - cpp_utils::Vector Vec1(0, 1, 2); - cpp_utils::Vector Vec2(1, 0, 2); - cpp_utils::Vector Vec3(1, 1, 0); - - EXPECT_TRUE(Mat1 * Vec1 == Vec3); - EXPECT_FALSE(Mat1 * Vec3 == Vec1); - EXPECT_TRUE(Vec2 * Mat1 == Vec3); - EXPECT_FALSE(Vec3 * Mat1 == Vec2); -} +namespace cpp_utils { + + TEST(MatrixTest, DefaultInitTest) { + Matrix iMat; + EXPECT_EQ(iMat.xx, 1); + EXPECT_EQ(iMat.xy, 0); + EXPECT_EQ(iMat.xz, 0); + EXPECT_EQ(iMat.yx, 0); + EXPECT_EQ(iMat.yy, 1); + EXPECT_EQ(iMat.yz, 0); + EXPECT_EQ(iMat.zx, 0); + EXPECT_EQ(iMat.zy, 0); + EXPECT_EQ(iMat.zz, 1); + } + + TEST(MatrixTest, InitTest) { + Matrix Mat1(0, 1, 2, 3, 4, 5, 6, 7, 8); + EXPECT_EQ(Mat1.xx, 0); + EXPECT_EQ(Mat1.xy, 1); + EXPECT_EQ(Mat1.xz, 2); + EXPECT_EQ(Mat1.yx, 3); + EXPECT_EQ(Mat1.yy, 4); + EXPECT_EQ(Mat1.yz, 5); + EXPECT_EQ(Mat1.zx, 6); + EXPECT_EQ(Mat1.zy, 7); + EXPECT_EQ(Mat1.zz, 8); + } + + TEST(MatrixTest, DiagonalInitTest) { + Matrix Mat1(1, 2, 3); + EXPECT_EQ(Mat1.xx, 1); + EXPECT_EQ(Mat1.xy, 0); + EXPECT_EQ(Mat1.xz, 0); + EXPECT_EQ(Mat1.yx, 0); + EXPECT_EQ(Mat1.yy, 2); + EXPECT_EQ(Mat1.yz, 0); + EXPECT_EQ(Mat1.zx, 0); + EXPECT_EQ(Mat1.zy, 0); + EXPECT_EQ(Mat1.zz, 3); + } + + TEST(MatrixTest, DetTest) { + Matrix iMat, Mat1(2, 0, 0, 0, 2, 0, 0, 0, 2), Mat2(0, 1, 2, 3, 4, 5, 6, 7, 8); + + EXPECT_NEAR(iMat.det(), 1, 0.0001); + EXPECT_NEAR(Mat1.det(), 8, 0.0001); + EXPECT_NEAR(Mat2.det(), 0, 0.0001); + } + + TEST(MatrixTest, EqualityTest) { + Matrix Mat1(1, 0, 1, 0, 1, 0, 1, 0, 1), Mat2(0, 1, 0, 1, 0, 1, 0, 1, 0); + + EXPECT_TRUE(Mat1 == Mat1); + EXPECT_FALSE(Mat1 == Mat2); + } + + TEST(MatrixTest, NotEqualityTest) { + Matrix Mat1(1, 0, 1, 0, 1, 0, 1, 0, 1), Mat2(0, 1, 0, 1, 0, 1, 0, 1, 0); + + EXPECT_FALSE(Mat1 != Mat1); + EXPECT_TRUE(Mat1 != Mat2); + } + + TEST(MatrixTest, AdditionTest) { + Matrix Mat1(1, 0, 1, 0, 1, 0, 1, 0, 1), Mat2(0, 1, 0, 1, 0, 1, 0, 1, 0); + + Matrix Exp1(1, 1, 1, 1, 1, 1, 1, 1, 1); + EXPECT_EQ(Mat1 + Mat2, Exp1); + } + + TEST(MatrixTest, SubtractionTest) { + Matrix Mat1(1, 0, 1, 0, 1, 0, 1, 0, 1), Mat2(0, 1, 0, 1, 0, 1, 0, 1, 0); + + Matrix Exp1(1, -1, 1, -1, 1, -1, 1, -1, 1); + EXPECT_EQ(Mat1 - Mat2, Exp1); + EXPECT_EQ(Mat2 - Mat1, -Exp1); + } + + TEST(MatrixTest, NegativeTest) { + Matrix Mat1(0, -1, 2, -3, 4, -5, 6, -7, 8), Mat2(0, 1, -2, 3, -4, 5, -6, 7, -8); + + EXPECT_EQ(-Mat1, Mat2); + } + + TEST(MatrixTest, MultiplicationTest) { + Matrix Mat1(0, 1, 2, 3, 4, -1, -2, -3, -4); + + Matrix Exp1(0, -2, -4, -6, -8, 2, 4, 6, 8); + EXPECT_EQ(Mat1 * int(-2), Exp1) << "Failed to multiply by negative int"; + EXPECT_EQ(Mat1 * float(-2), Exp1) << "Failed to multiply by negative float"; + EXPECT_EQ(int(-2) * Mat1, Exp1) << "Failed to multiply by negative int"; + EXPECT_EQ(float(-2) * Mat1, Exp1) << "Failed to multiply by negative float"; + + Matrix Exp2(0.0, 0.5, 1.0, 1.5, 2.0, -0.5, -1.0, -1.5, -2.0); + EXPECT_EQ(Mat1 * float(0.5), Exp2) << "Failed to multiply by decimal value"; + EXPECT_EQ(float(0.5) * Mat1, Exp2) << "Failed to multiply by decimal value"; + } + + TEST(MatrixTest, DivisionTest) { + Matrix Mat1(0, 2, 4, 6, 8, -2, -4, -6, -8); + + Matrix Exp1(0, 1, 2, 3, 4, -1, -2, -3, -4); + EXPECT_EQ(Mat1 / float(2), Exp1); + EXPECT_EQ(Mat1 / int(2), Exp1); + } + + TEST(MatrixTest, ZeroDivisionTest) { + Matrix Mat1; + std::invalid_argument Excep("Division by zero is not possible"); + } + + TEST(MatrixTest, MatrixMultiplicationTest) { + Matrix Mat1(1, 1, 0, 0, 1, 0, 0, 0, 0), Mat2(0, 1, 2, 3, 4, 5, 6, 7, 8), Mat3(3, 5, 7, 3, 4, 5, 0, 0, 0); + + EXPECT_TRUE(Mat1 * Mat2 == Mat3); + EXPECT_FALSE(Mat2 * Mat1 == Mat3); + } + + TEST(MatrixTest, VectorMultiplicationTest) { + Matrix Mat1(1, 1, 0, 0, 1, 0, 0, 0, 0); + Vector Vec1(0, 1, 2), Vec2(1, 0, 2), Vec3(1, 1, 0); + + EXPECT_TRUE(Mat1 * Vec1 == Vec3); + EXPECT_FALSE(Mat1 * Vec3 == Vec1); + EXPECT_TRUE(Vec2 * Mat1 == Vec3); + EXPECT_FALSE(Vec3 * Mat1 == Vec2); + } + + TEST(MatrixTest, InverseTest) { + Matrix Mat1(0, 1, 2, 3, 4, 5, 6, 7, 8), + Mat2(0, 0, 0, 0, 0, 0, 0, 0, 0), + Mat3(0, 0, -1, 0, 1, 0, 1, 0, 0), + Mat4(0, 0, 1, 0, 1, 0, -1, 0, 0), + Mat5(0, 0, 1, 0, 1, 0, 1, 0, 0); + + EXPECT_THROW(Mat1.inverse(), value_error); + EXPECT_THROW(Mat2.inverse(), value_error); + EXPECT_TRUE(Mat3.inverse() == Mat4); + EXPECT_TRUE(Mat4.inverse() == Mat3); + EXPECT_TRUE(Mat5.inverse() == Mat5); + } -TEST(MatrixTest, InverseTest) { - cpp_utils::Matrix Mat1(0, 1, 2, 3, 4, 5, 6, 7, 8); - cpp_utils::Matrix Mat2(0, 0, 0, 0, 0, 0, 0, 0, 0); - cpp_utils::Matrix Mat3(0, 0, -1, 0, 1, 0, 1, 0, 0); - cpp_utils::Matrix Mat4(0, 0, 1, 0, 1, 0, -1, 0, 0); - cpp_utils::Matrix Mat5(0, 0, 1, 0, 1, 0, 1, 0, 0); - - EXPECT_THROW(Mat1.inverse(), std::exception); - EXPECT_THROW(Mat2.inverse(), std::exception); - EXPECT_TRUE(Mat3.inverse() == Mat4); - EXPECT_TRUE(Mat4.inverse() == Mat3); - EXPECT_TRUE(Mat5.inverse() == Mat5); } diff --git a/test/plane_unittest.cpp b/test/plane_unittest.cpp new file mode 100644 index 0000000..4f1daa9 --- /dev/null +++ b/test/plane_unittest.cpp @@ -0,0 +1,131 @@ +#include "gtest/gtest.h" +#include "../source/plane.hpp" + +namespace cpp_utils { + + TEST(PlaneTest, DefaultInitTest) { + Vector point(0, 0, 0), normal(norm, norm, norm); + Plane plane; + EXPECT_TRUE(plane.point == point); + EXPECT_TRUE(plane.normal == normal); + } + + TEST(PlaneTest, InitTest) { + Vector point(1, 2, 3), normal(4, 5, 6); + Plane plane(point, normal); + EXPECT_TRUE(plane.point == point); + EXPECT_TRUE(plane.normal == normal.normalise()); + } + + TEST(PlaneTest, EqualityTest) { + + Vector vec00, + vec01(1, 0, 0), vec02(0, 1, 0), vec03(0, 0, 1), + vec04(-1, 0, 0), vec05(0, -1, 0), vec06(0, 0, -1), + vec07(1, 1, 1), + vec08(1, 0, -1), vec09(-1, 1, 0), vec10(0, -1, 1), + vec11(-1, 0, 1), vec12(1, -1, 0), vec13(0, 1, -1), + vec14(-1, -1, -1); + + Plane plane00, + plane01(vec06, vec01), plane02(vec04, vec02), plane03(vec05, vec03), + plane04(vec02, vec04), plane05(vec03, vec05), plane06(vec01, vec06), + plane07(vec00, vec07), + plane08(vec02, vec08), plane09(vec03, vec09), plane10(vec01, vec10), + plane11(vec05, vec11), plane12(vec06, vec12), plane13(vec04, vec13), + plane14(vec00, vec14); + + EXPECT_TRUE(plane00 == plane00); + EXPECT_FALSE(plane00 == plane01); + EXPECT_TRUE(plane01 == plane04); + EXPECT_FALSE(plane00 == plane02); + EXPECT_TRUE(plane02 == plane05); + EXPECT_FALSE(plane00 == plane03); + EXPECT_TRUE(plane03 == plane06); + EXPECT_TRUE(plane00 == plane07); + EXPECT_TRUE(plane07 == plane14); + EXPECT_FALSE(plane00 == plane08); + EXPECT_TRUE(plane08 == plane11); + EXPECT_FALSE(plane00 == plane09); + EXPECT_TRUE(plane09 == plane12); + EXPECT_FALSE(plane00 == plane10); + EXPECT_TRUE(plane10 == plane13); + } + + TEST(PlaneTest, NotEqualityTest) { + + Vector vec00, + vec01(1, 0, 0), vec02(0, 1, 0), vec03(0, 0, 1), + vec04(-1, 0, 0), vec05(0, -1, 0), vec06(0, 0, -1), + vec07(1, 1, 1), + vec08(1, 0, -1), vec09(-1, 1, 0), vec10(0, -1, 1), + vec11(-1, 0, 1), vec12(1, -1, 0), vec13(0, 1, -1), + vec14(-1, -1, -1); + + Plane plane00, + plane01(vec06, vec01), plane02(vec04, vec02), plane03(vec05, vec03), + plane04(vec02, vec04), plane05(vec03, vec05), plane06(vec01, vec06), + plane07(vec00, vec07), + plane08(vec02, vec08), plane09(vec03, vec09), plane10(vec01, vec10), + plane11(vec05, vec11), plane12(vec06, vec12), plane13(vec04, vec13), + plane14(vec00, vec14); + + EXPECT_FALSE(plane00 != plane00); + EXPECT_TRUE(plane00 != plane01); + EXPECT_FALSE(plane01 != plane04); + EXPECT_TRUE(plane00 != plane02); + EXPECT_FALSE(plane02 != plane05); + EXPECT_TRUE(plane00 != plane03); + EXPECT_FALSE(plane03 != plane06); + EXPECT_FALSE(plane00 != plane07); + EXPECT_FALSE(plane07 != plane14); + EXPECT_TRUE(plane00 != plane08); + EXPECT_FALSE(plane08 != plane11); + EXPECT_TRUE(plane00 != plane09); + EXPECT_FALSE(plane09 != plane12); + EXPECT_TRUE(plane00 != plane10); + EXPECT_FALSE(plane10 != plane13); + } + + TEST(PlaneTest, IsOnTest) { + Vector point0(0, 1, 1), point1(1, 1, 1), point2(1, 0, 1); + Plane plane(point0, point1); + + EXPECT_TRUE(plane.isOnPlane(point0)); + EXPECT_FALSE(plane.isOnPlane(point1)); + EXPECT_TRUE(plane.isOnPlane(point2)); + } + + TEST(PlaneTest, IntersectionTest) { + Vector point0, point1(1, -1, 1), point2(1, 0, -1); + Line line1(point0, point1), line2(point1, point1), + line3(point0, point2), line4(point1, point2); + Plane plane; + + EXPECT_EQ(plane.intersection(line1), point0); + EXPECT_EQ(plane.intersection(line2), point0); + EXPECT_THROW(plane.intersection(line3), value_error); + EXPECT_THROW(plane.intersection(line4), value_error); + } + + TEST(PlaneTest, IsBetweenTest) { + Vector point0, + point1(1, 1, 1), + point2(1, 0, -1), + point3(0.5, 0.5, 0.5), + point4(-0.5, -0.5, -0.5), + point5(1.5, 1.5, 1.5); + + Line line0, line1(point2, point2), line2(point3, point2), line3(point4, point2), line4(point5, point2); + + Plane plane0, plane1(point1, point1), plane2(point0, point2); + + EXPECT_FALSE(cpp_utils::isBetween(line1, plane0, plane0)); + EXPECT_TRUE(cpp_utils::isBetween(line2, plane0, plane1)); + EXPECT_FALSE(cpp_utils::isBetween(line3, plane0, plane1)); + EXPECT_FALSE(cpp_utils::isBetween(line4, plane0, plane1)); + EXPECT_FALSE(cpp_utils::isBetween(line0, plane0, plane1)); + EXPECT_FALSE(cpp_utils::isBetween(line0, plane0, plane2)); + } + +} diff --git a/test/quaternion_unittest.cpp b/test/quaternion_unittest.cpp index 36286be..2b8bc32 100644 --- a/test/quaternion_unittest.cpp +++ b/test/quaternion_unittest.cpp @@ -2,165 +2,165 @@ #include "../source/quaternion.hpp" #include "testing.hpp" -namespace cpp_utils { - double pi = 3.1415926535; -TEST(QuaternionTest, DefaultInitTest) { - Quaternion quat; - EXPECT_EQ(quat.w, 0); - EXPECT_EQ(quat.x, 0); - EXPECT_EQ(quat.y, 0); - EXPECT_EQ(quat.z, 0); -} +namespace cpp_utils { -TEST(QuaternionTest, InitTest) { - Quaternion quat(1, 2, 3, 4); - EXPECT_EQ(quat.w, 1); - EXPECT_EQ(quat.x, 2); - EXPECT_EQ(quat.y, 3); - EXPECT_EQ(quat.z, 4); -} + TEST(QuaternionTest, DefaultInitTest) { + Quaternion quat; + EXPECT_EQ(quat.w, 0); + EXPECT_EQ(quat.x, 0); + EXPECT_EQ(quat.y, 0); + EXPECT_EQ(quat.z, 0); + } -TEST(QuaternionTest, InitTestAngleVec) { - Quaternion quat(pi/2, {1, 0, 0}); + TEST(QuaternionTest, InitTest) { + Quaternion quat(1, 2, 3, 4); + EXPECT_EQ(quat.w, 1); + EXPECT_EQ(quat.x, 2); + EXPECT_EQ(quat.y, 3); + EXPECT_EQ(quat.z, 4); + } - EXPECT_EQ(quat, Quaternion(cos(pi/4), sin(pi/4), 0, 0)); -} + TEST(QuaternionTest, InitTestAngleVec) { + Quaternion quat(pi/2, {1, 0, 0}); -TEST(QuaternionTest, ModTest) { - Quaternion quat1(1, 1, 1, 1); - EXPECT_NEAR(quat1.mod(), sqrt(4), 0.0001); -} + EXPECT_EQ(quat, Quaternion(cos(pi/4), sin(pi/4), 0, 0)); + } -TEST(QuaternionTest, EqualityTest) { - Quaternion quat1(1, 0, 1, 1); - Quaternion quat2(0, 1, 0, 1); + TEST(QuaternionTest, ModTest) { + Quaternion quat1(1, 1, 1, 1); + EXPECT_NEAR(quat1.mod(), sqrt(4), 0.0001); + } - EXPECT_TRUE(quat1 == quat1); - EXPECT_FALSE(quat1 == quat2); -} + TEST(QuaternionTest, EqualityTest) { + Quaternion quat1(1, 0, 1, 1); + Quaternion quat2(0, 1, 0, 1); -TEST(QuaternionTest, NotEqualityTest) { - Quaternion quat1(1, 0, 1, 1); - Quaternion quat2(0, 1, 0, 1); + EXPECT_TRUE(quat1 == quat1); + EXPECT_FALSE(quat1 == quat2); + } - EXPECT_FALSE(quat1 != quat1); - EXPECT_TRUE(quat1 != quat2); -} + TEST(QuaternionTest, NotEqualityTest) { + Quaternion quat1(1, 0, 1, 1); + Quaternion quat2(0, 1, 0, 1); -TEST(QuaternionTest, NegativeTest) { - Quaternion quat1(1, -2, 3, 4); - Quaternion quat2(-1, 2, -3, -4); + EXPECT_FALSE(quat1 != quat1); + EXPECT_TRUE(quat1 != quat2); + } - EXPECT_EQ(-quat1, quat2); -} + TEST(QuaternionTest, NegativeTest) { + Quaternion quat1(1, -2, 3, 4); + Quaternion quat2(-1, 2, -3, -4); -TEST(QuaternionTest, MultiplicationTest) { - Quaternion quat1(1, 2, -1, 3); + EXPECT_EQ(-quat1, quat2); + } - Quaternion Exp1(-2, -4, 2, -6); - EXPECT_EQ(quat1 * int(-2), Exp1) << "Failed to multiply by negative int"; - EXPECT_EQ(quat1 * float(-2), Exp1) << "Failed to multiply by negative float"; + TEST(QuaternionTest, MultiplicationTest) { + Quaternion quat1(1, 2, -1, 3); - Quaternion Exp2(0.5, 1.0, -0.5, 1.5); - Quaternion res = quat1 * float(0.5); - EXPECT_EQ( quat1 * float(0.5), Exp2) << "Failed to multiply by decimal value"; -} + Quaternion Exp1(-2, -4, 2, -6); + EXPECT_EQ(quat1 * int(-2), Exp1) << "Failed to multiply by negative int"; + EXPECT_EQ(quat1 * float(-2), Exp1) << "Failed to multiply by negative float"; -TEST(QuaternionTest, DivisionTest) { - Quaternion quat1(2, 4, -2, 3); + Quaternion Exp2(0.5, 1.0, -0.5, 1.5); + Quaternion res = quat1 * float(0.5); + EXPECT_EQ( quat1 * float(0.5), Exp2) << "Failed to multiply by decimal value"; + } - Quaternion Exp1(1, 2, -1, 1.5); - EXPECT_EQ(quat1 / float(2), Exp1); - EXPECT_EQ(quat1 / int(2), Exp1); -} + TEST(QuaternionTest, DivisionTest) { + Quaternion quat1(2, 4, -2, 3); -TEST(QuaternionTest, AssignmentTest) { - Quaternion quat1 = {1, {2, 3, 4}}; - Quaternion quat2; - quat2 = quat1; + Quaternion Exp1(1, 2, -1, 1.5); + EXPECT_EQ(quat1 / float(2), Exp1); + EXPECT_EQ(quat1 / int(2), Exp1); + } - EXPECT_TRUE(quat1 == quat2); -} + TEST(QuaternionTest, AssignmentTest) { + Quaternion quat1 = {1, {2, 3, 4}}; + Quaternion quat2; + quat2 = quat1; -TEST(QuaternionTest, productTest) { - Quaternion quat1 = {1, 0, 0, 0}; - Quaternion quat2 = {0, 2, 3, -6}; + EXPECT_TRUE(quat1 == quat2); + } - EXPECT_EQ(quat1 * quat2, quat2); - EXPECT_EQ(quat2 * quat1, quat2); + TEST(QuaternionTest, productTest) { + Quaternion quat1 = {1, 0, 0, 0}; + Quaternion quat2 = {0, 2, 3, -6}; - Quaternion quat3 = {1, 2, 4, 7}; - Quaternion quat4 = {6, 2, 3, -6}; - Quaternion exp4 = {32, -31, 53, 34}; + EXPECT_EQ(quat1 * quat2, quat2); + EXPECT_EQ(quat2 * quat1, quat2); - EXPECT_EQ(quat3 * quat4, exp4); + Quaternion quat3 = {1, 2, 4, 7}; + Quaternion quat4 = {6, 2, 3, -6}; + Quaternion exp4 = {32, -31, 53, 34}; - Quaternion quat5 = {1, 0, 1, 0}; - Quaternion quat6 = {0, 2, 3, -6}; - Quaternion exp6 = {3, -4, 3, -8}; + EXPECT_EQ(quat3 * quat4, exp4); - EXPECT_EQ(quat5 * quat6, exp6); -} + Quaternion quat5 = {1, 0, 1, 0}; + Quaternion quat6 = {0, 2, 3, -6}; + Quaternion exp6 = {3, -4, 3, -8}; -TEST(QuaternionTest, VectorMultiplication1) { - Quaternion quat = {1, 0, 0, 0}; - Vector vec = {2, 3, 4}; - Quaternion exp = {0, 2, 3, 4}; + EXPECT_EQ(quat5 * quat6, exp6); + } - EXPECT_EQ(exp, quat.conj() * vec * quat); -} + TEST(QuaternionTest, VectorMultiplication1) { + Quaternion quat = {1, 0, 0, 0}; + Vector vec = {2, 3, 4}; + Quaternion exp = {0, 2, 3, 4}; -TEST(QuaternionTest, VectorMultiplication2) { - Quaternion quat = {cos(pi / 4), 0, 0, sin(pi / 4)}; - Vector vec = {1, 0, 0}; - Quaternion exp = {0, 0, -1, 0}; + EXPECT_EQ(exp, quat.conj() * vec * quat); + } - EXPECT_EQ(exp, quat.conj() * vec * quat); -} + TEST(QuaternionTest, VectorMultiplication2) { + Quaternion quat = {cos(pi / 4), 0, 0, sin(pi / 4)}; + Vector vec = {1, 0, 0}; + Quaternion exp = {0, 0, -1, 0}; -TEST(QuaternionTest, VectorMultiplication3) { - Quaternion quat = {cos(pi / 4), sin(pi / 4), 0, 0}; - Vector vec = {0, 1, -3}; - Quaternion exp = {0, 0, -3, -1}; + EXPECT_EQ(exp, quat.conj() * vec * quat); + } - EXPECT_EQ(exp, quat.conj() * vec * quat); -} + TEST(QuaternionTest, VectorMultiplication3) { + Quaternion quat = {cos(pi / 4), sin(pi / 4), 0, 0}; + Vector vec = {0, 1, -3}; + Quaternion exp = {0, 0, -3, -1}; -TEST(QuaternionTest, VectorMultiplication4) { - Quaternion quat = {cos(pi / 4), 0, sin(pi / 4), 0}; - Vector vec = {1, 0, 2}; - Quaternion exp = {0, -2, 0, 1}; + EXPECT_EQ(exp, quat.conj() * vec * quat); + } - EXPECT_EQ(exp, quat.conj() * vec * quat); -}; + TEST(QuaternionTest, VectorMultiplication4) { + Quaternion quat = {cos(pi / 4), 0, sin(pi / 4), 0}; + Vector vec = {1, 0, 2}; + Quaternion exp = {0, -2, 0, 1}; + EXPECT_EQ(exp, quat.conj() * vec * quat); + }; -TEST(QuaternionTest, VectorRotation1) { - Vector vec = {1, 0, 0}; - Quaternion quat = {cos(pi/4), 0, 0, sin(pi/4)}; - Vector exp = {0, -1, 0}; - EXPECT_EQ(exp, rotate(vec, quat)); -} + TEST(QuaternionTest, VectorRotation1) { + Vector vec = {1, 0, 0}; + Quaternion quat = {cos(pi/4), 0, 0, sin(pi/4)}; + Vector exp = {0, -1, 0}; -TEST(QuaternionTest, VectorRotation2) { - Vector vec = {1, 0, 0}; - Quaternion quat = {pi/2, {0, 0, 1}}; - Vector exp = {0, -1, 0}; + EXPECT_EQ(exp, rotate(vec, quat)); + } - EXPECT_EQ(exp, rotate(vec, quat)); -} + TEST(QuaternionTest, VectorRotation2) { + Vector vec = {1, 0, 0}; + Quaternion quat = {pi/2, {0, 0, 1}}; + Vector exp = {0, -1, 0}; -TEST(QuaternionTest, VectorRotation3) { - Vector vec = {1, 0, 0}; - Quaternion quat1 = {pi/2, {1, 0, 0}}; - Quaternion quat2 = {pi/2.6, {1, 0, 0}}; - Vector exp = {1, 0, 0}; + EXPECT_EQ(exp, rotate(vec, quat)); + } - EXPECT_EQ(exp, rotate(vec, quat1)); - EXPECT_EQ(exp, rotate(vec, quat2)); -}; + TEST(QuaternionTest, VectorRotation3) { + Vector vec = {1, 0, 0}; + Quaternion quat1 = {pi/2, {1, 0, 0}}; + Quaternion quat2 = {pi/2.6, {1, 0, 0}}; + Vector exp = {1, 0, 0}; -} \ No newline at end of file + EXPECT_EQ(exp, rotate(vec, quat1)); + EXPECT_EQ(exp, rotate(vec, quat2)); + }; + +} diff --git a/test/vector_unittest.cpp b/test/vector_unittest.cpp index d96cd6f..d8e944c 100644 --- a/test/vector_unittest.cpp +++ b/test/vector_unittest.cpp @@ -1,108 +1,112 @@ #include "gtest/gtest.h" -#include #include "../source/vector.hpp" -TEST(VectorTest, DefaultInitTest) { - cpp_utils::Vector NullVec; - EXPECT_EQ(NullVec.x, 0); - EXPECT_EQ(NullVec.y, 0); - EXPECT_EQ(NullVec.z, 0); -} - -TEST(VectorTest, InitTest) { - cpp_utils::Vector Vec1(1, 2, 3); - EXPECT_EQ(Vec1.x, 1); - EXPECT_EQ(Vec1.y, 2); - EXPECT_EQ(Vec1.z, 3); -} - -TEST(VectorTest, ModTest) { - cpp_utils::Vector Vec1(1, 1, 1); - EXPECT_NEAR(Vec1.mod(), sqrt(3), 0.0001); -} - -TEST(VectorTest, EqualityTest) { - cpp_utils::Vector Vec1(1, 0, 1); - cpp_utils::Vector Vec2(0, 1, 0); - - EXPECT_TRUE(Vec1 == Vec1); - EXPECT_FALSE(Vec1 == Vec2); -} - -TEST(VectorTest, NotEqualityTest) { - cpp_utils::Vector Vec1(1, 0, 1); - cpp_utils::Vector Vec2(0, 1, 0); - - EXPECT_FALSE(Vec1 != Vec1); - EXPECT_TRUE(Vec1 != Vec2); -} - -TEST(VectorTest, AdditionTest) { - cpp_utils::Vector Vec1(1, 0, 1); - cpp_utils::Vector Vec2(0, 1, 0); - - cpp_utils::Vector ExpVec(1, 1, 1); - - EXPECT_EQ(Vec1 + Vec2, ExpVec); -} - -TEST(VectorTest, SubtractionTest) { - cpp_utils::Vector Vec1(1, 0, 1); - cpp_utils::Vector Vec2(0, 1, 1); - - cpp_utils::Vector ExpVec(1, -1, 0); - EXPECT_EQ(Vec1 - Vec2, ExpVec); - EXPECT_EQ(Vec2 - Vec1, -ExpVec); -} - -TEST(VectorTest, NegativeTest) { - cpp_utils::Vector Vec1(1, -2, 3); - cpp_utils::Vector Vec2(-1, 2, -3); - - EXPECT_EQ(-Vec1, Vec2); -} - -TEST(VectorTest, MultiplicationTest) { - cpp_utils::Vector Vec1(1, 2, -1); - - cpp_utils::Vector Exp1(-2, -4, 2); - EXPECT_EQ(Vec1 * int(-2), Exp1) << "Failed to multiply by negative int"; - EXPECT_EQ(Vec1 * float(-2), Exp1) << "Failed to multiply by negative float"; - - cpp_utils::Vector Exp2(0.5, 1.0, -0.5); - cpp_utils::Vector res = Vec1 * float(0.5); - EXPECT_EQ( Vec1 * float(0.5), Exp2) << "Failed to multiply by decimal value"; -} - -TEST(VectorTest, DivisionTest) { - cpp_utils::Vector Vec1(2, 4, -2); - - cpp_utils::Vector Exp1(1, 2, -1); - EXPECT_EQ(Vec1 / float(2), Exp1); - EXPECT_EQ(Vec1 / int(2), Exp1); -} - -TEST(VectorTest, ZeroDivisionTest) { - cpp_utils::Vector Vec1; - std::invalid_argument Excep("Division by zero is not possible"); - -} - -TEST(VectorTest, DotProductTest) { - cpp_utils::Vector Vec1(1, 0, 0); - cpp_utils::Vector Vec2(0, 1, 2); - cpp_utils::Vector Vec3(2, 0, 3); - - EXPECT_NEAR(Vec1 * Vec2, 0, 0.0001); - EXPECT_NEAR(Vec1 * Vec3, 2, 0.0001); - EXPECT_NEAR(Vec2 * Vec3, 6, 0.0001); -} - -TEST(VectorTest, CrossProductTest) { - cpp_utils::Vector Vecx(1, 0, 0); - cpp_utils::Vector Vecy(0, 1, 0); - cpp_utils::Vector Vecz(0, 0, 1); +namespace cpp_utils { + + TEST(VectorTest, DefaultInitTest) { + Vector NullVec; + EXPECT_EQ(NullVec.x, 0); + EXPECT_EQ(NullVec.y, 0); + EXPECT_EQ(NullVec.z, 0); + } + + TEST(VectorTest, InitTest) { + Vector Vec1(1, 2, 3); + EXPECT_EQ(Vec1.x, 1); + EXPECT_EQ(Vec1.y, 2); + EXPECT_EQ(Vec1.z, 3); + } + + TEST(VectorTest, ModTest) { + Vector Vec1(1, 1, 1); + EXPECT_NEAR(Vec1.mod(), sqrt(3), 0.0001); + } + + TEST(VectorTest, EqualityTest) { + Vector Vec1(1, 0, 1); + Vector Vec2(0, 1, 0); + + EXPECT_TRUE(Vec1 == Vec1); + EXPECT_FALSE(Vec1 == Vec2); + } + + TEST(VectorTest, NotEqualityTest) { + Vector Vec1(1, 0, 1); + Vector Vec2(0, 1, 0); + + EXPECT_FALSE(Vec1 != Vec1); + EXPECT_TRUE(Vec1 != Vec2); + } + + TEST(VectorTest, AdditionTest) { + Vector Vec1(1, 0, 1); + Vector Vec2(0, 1, 0); + + Vector ExpVec(1, 1, 1); + EXPECT_EQ(Vec1 + Vec2, ExpVec); + } + + TEST(VectorTest, SubtractionTest) { + Vector Vec1(1, 0, 1); + Vector Vec2(0, 1, 1); + + Vector ExpVec(1, -1, 0); + EXPECT_EQ(Vec1 - Vec2, ExpVec); + EXPECT_EQ(Vec2 - Vec1, -ExpVec); + } + + TEST(VectorTest, NegativeTest) { + Vector Vec1(1, -2, 3); + Vector Vec2(-1, 2, -3); + + EXPECT_EQ(-Vec1, Vec2); + } + + TEST(VectorTest, MultiplicationTest) { + Vector Vec1(1, 2, -1); + + Vector Exp1(-2, -4, 2); + EXPECT_EQ(Vec1 * int(-2), Exp1) << "Failed to multiply by negative int"; + EXPECT_EQ(int(-2) * Vec1, Exp1) << "Failed to multiply by negative int"; + EXPECT_EQ(Vec1 * float(-2), Exp1) << "Failed to multiply by negative float"; + EXPECT_EQ(float(-2) * Vec1, Exp1) << "Failed to multiply by negative float"; + + Vector Exp2(0.5, 1.0, -0.5); + EXPECT_EQ(Vec1 * float(0.5), Exp2) << "Failed to multiply by decimal value"; + EXPECT_EQ(float(0.5) * Vec1, Exp2) << "Failed to multiply by decimal value"; + } + + TEST(VectorTest, DivisionTest) { + Vector Vec1(2, 4, -2); + + Vector Exp1(1, 2, -1); + EXPECT_EQ(Vec1 / float(2), Exp1); + EXPECT_EQ(Vec1 / int(2), Exp1); + } + + TEST(VectorTest, ZeroDivisionTest) { + Vector Vec1; + std::invalid_argument Excep("Division by zero is not possible"); + + } + + TEST(VectorTest, DotProductTest) { + Vector Vec1(1, 0, 0); + Vector Vec2(0, 1, 2); + Vector Vec3(2, 0, 3); + + EXPECT_NEAR(Vec1 * Vec2, 0, 0.0001); + EXPECT_NEAR(Vec1 * Vec3, 2, 0.0001); + EXPECT_NEAR(Vec2 * Vec3, 6, 0.0001); + } + + TEST(VectorTest, CrossProductTest) { + Vector Vecx(1, 0, 0); + Vector Vecy(0, 1, 0); + Vector Vecz(0, 0, 1); + + EXPECT_EQ(Vecx ^ Vecy, Vecz); + EXPECT_EQ(Vecy ^ Vecx, -Vecz); + } - EXPECT_EQ(Vecx ^ Vecy, Vecz); - EXPECT_EQ(Vecy ^ Vecx, -Vecz); }