#include "CppUnitTest.h" #include "../Eule/TrapazoidalPrismCollider.h" #include "../Eule/Quaternion.h" #include "../_TestingUtilities/HandyMacros.h" #include #include #include using namespace Microsoft::VisualStudio::CppUnitTestFramework; using namespace Eule; using TPC = TrapazoidalPrismCollider; namespace Colliders { TEST_CLASS(_TrapazoidalPrismCollider) { private: std::mt19937 rng; public: // Constructor _TrapazoidalPrismCollider() { rng = std::mt19937((std::random_device())()); return; } // Tests that all vertices can be set individually, and at once TEST_METHOD(Can_Set_Each_Vertex) { // All vertex values are unique TPC tpc; tpc.SetVertex(TPC::FRONT | TPC::LEFT | TPC::BOTTOM, Vector3d(-1, -1, 1) * 1); tpc.SetVertex(TPC::FRONT | TPC::LEFT | TPC::TOP, Vector3d(-1, 1, 1) * 2); tpc.SetVertex(TPC::BACK | TPC::LEFT | TPC::BOTTOM, Vector3d(-1, -1, -1) * 3); tpc.SetVertex(TPC::BACK | TPC::LEFT | TPC::TOP, Vector3d(-1, 1, -1) * 4); tpc.SetVertex(TPC::FRONT | TPC::RIGHT | TPC::BOTTOM, Vector3d(1, -1, 1) * 5); tpc.SetVertex(TPC::FRONT | TPC::RIGHT | TPC::TOP, Vector3d(1, 1, 1) * 6); tpc.SetVertex(TPC::BACK | TPC::RIGHT | TPC::BOTTOM, Vector3d(1, -1, -1) * 7); tpc.SetVertex(TPC::BACK | TPC::RIGHT | TPC::TOP, Vector3d(1, 1, -1) * 8); Assert::IsTrue(tpc.GetVertex(TPC::FRONT | TPC::LEFT | TPC::BOTTOM) == (Vector3d(-1, -1, 1) * 1), L"FRONT|LEFT|BOTTOM"); Assert::IsTrue(tpc.GetVertex(TPC::FRONT | TPC::LEFT | TPC::TOP) == (Vector3d(-1, 1, 1) * 2), L"FRONT|LEFT|TOP"); Assert::IsTrue(tpc.GetVertex(TPC::BACK | TPC::LEFT | TPC::BOTTOM) == (Vector3d(-1, -1, -1) * 3), L"BACK|LEFT|BOTTOM"); Assert::IsTrue(tpc.GetVertex(TPC::BACK | TPC::LEFT | TPC::TOP) == (Vector3d(-1, 1, -1) * 4), L"BACK|LEFT|TOP"); Assert::IsTrue(tpc.GetVertex(TPC::FRONT | TPC::RIGHT | TPC::BOTTOM) == (Vector3d(1, -1, 1) * 5), L"FRONT|RIGHT|BOTTOM"); Assert::IsTrue(tpc.GetVertex(TPC::FRONT | TPC::RIGHT | TPC::TOP) == (Vector3d(1, 1, 1) * 6), L"FRONT|RIGHT|TOP"); Assert::IsTrue(tpc.GetVertex(TPC::BACK | TPC::RIGHT | TPC::BOTTOM) == (Vector3d(1, -1, -1) * 7), L"BACK|RIGHT|BOTTOM"); Assert::IsTrue(tpc.GetVertex(TPC::BACK | TPC::RIGHT | TPC::TOP) == (Vector3d(1, 1, -1) * 8), L"BACK|RIGHT|TOP"); return; } // Tests that points inside work. // For this, we define a few points around [0,0,0] and check if they are contained. // We then rotate the collider, and check again // Gets repeated for every possible rotation with a min-distance per axis of 2 deg TEST_METHOD(Points_Inside) { // Setup // Define known-inside points std::array knownInsides = { Vector3d( 1,-1, 1), Vector3d(-1,-1, 1), Vector3d( 1, 1, 1), Vector3d(-1, 1, 1), Vector3d( 1,-1,-1), Vector3d(-1,-1,-1), Vector3d( 1, 1,-1), Vector3d(-1, 1,-1), Vector3d( 0, 0, 0), }; // Create collider, a cube of size 10^3 around the center TPC tpc; // Exercise // Now check that these points are inside for all these possible angles #ifndef _DEBUG constexpr double stepSize = 2; #else constexpr double stepSize = 32; #endif for (double theta = 0; theta < 360.01; theta += stepSize) for (double phi = 0; phi < 360.01; phi += 2) for (double alpha = 0; alpha < 360.01; alpha += stepSize) { // Rotate box tpc.SetVertex(TPC::FRONT | TPC::LEFT | TPC::BOTTOM, Quaternion({theta, phi, alpha}) * (Vector3d(-1, -1, 1) * 10)); tpc.SetVertex(TPC::FRONT | TPC::LEFT | TPC::TOP, Quaternion({theta, phi, alpha}) * (Vector3d(-1, 1, 1) * 10)); tpc.SetVertex(TPC::BACK | TPC::LEFT | TPC::BOTTOM, Quaternion({theta, phi, alpha}) * (Vector3d(-1, -1, -1) * 10)); tpc.SetVertex(TPC::BACK | TPC::LEFT | TPC::TOP, Quaternion({theta, phi, alpha}) * (Vector3d(-1, 1, -1) * 10)); tpc.SetVertex(TPC::FRONT | TPC::RIGHT | TPC::BOTTOM, Quaternion({theta, phi, alpha}) * (Vector3d(1, -1, 1) * 10)); tpc.SetVertex(TPC::FRONT | TPC::RIGHT | TPC::TOP, Quaternion({theta, phi, alpha}) * (Vector3d(1, 1, 1) * 10)); tpc.SetVertex(TPC::BACK | TPC::RIGHT | TPC::BOTTOM, Quaternion({theta, phi, alpha}) * (Vector3d(1, -1, -1) * 10)); tpc.SetVertex(TPC::BACK | TPC::RIGHT | TPC::TOP, Quaternion({theta, phi, alpha}) * (Vector3d(1, 1, -1) * 10)); // Verify // Verify that all are inside for (const Vector3d& v : knownInsides) Assert::IsTrue(tpc.Contains(v)); } return; } // Tests that points outside work. // For this, we define a few points that are definitely outside for various reasons and check if they are not contained. // We then rotate the collider, and check again // Gets repeated for every possible rotation with a min-distance per axis of 2 deg TEST_METHOD(Points_Outside) { // Setup // Define known-inside points std::array knownOutsides = { Vector3d(-199, 0, 0), Vector3d(0, -199, 0), Vector3d(0, 0, -199), Vector3d(199, 0, 0), Vector3d(0, 199, 0), Vector3d(0, 0, 199), Vector3d( 20, -20, 0), Vector3d(50, 50, 50), Vector3d(50, -50, 0), Vector3d( 0, 0, 29), Vector3d( 2, 1, -18), Vector3d( -1, 29, -1), Vector3d( 0, -50, -50), Vector3d( -50, -50, -50) }; // Create collider, a cube of size 10^3 around the center TPC tpc; // Exercise // Now check that these points are inside for all these possible angles #ifndef _DEBUG constexpr double stepSize = 2; #else constexpr double stepSize = 32; #endif for (double theta = 0; theta < 360.01; theta += stepSize) for (double phi = 0; phi < 360.01; phi += 2) for (double alpha = 0; alpha < 360.01; alpha += stepSize) { // Rotate box tpc.SetVertex(TPC::FRONT | TPC::LEFT | TPC::BOTTOM, Quaternion({ theta, phi, alpha }) * (Vector3d(-1, -1, 1) * 10)); tpc.SetVertex(TPC::FRONT | TPC::LEFT | TPC::TOP, Quaternion({ theta, phi, alpha }) * (Vector3d(-1, 1, 1) * 10)); tpc.SetVertex(TPC::BACK | TPC::LEFT | TPC::BOTTOM, Quaternion({ theta, phi, alpha }) * (Vector3d(-1, -1, -1) * 10)); tpc.SetVertex(TPC::BACK | TPC::LEFT | TPC::TOP, Quaternion({ theta, phi, alpha }) * (Vector3d(-1, 1, -1) * 10)); tpc.SetVertex(TPC::FRONT | TPC::RIGHT | TPC::BOTTOM, Quaternion({ theta, phi, alpha }) * (Vector3d(1, -1, 1) * 10)); tpc.SetVertex(TPC::FRONT | TPC::RIGHT | TPC::TOP, Quaternion({ theta, phi, alpha }) * (Vector3d(1, 1, 1) * 10)); tpc.SetVertex(TPC::BACK | TPC::RIGHT | TPC::BOTTOM, Quaternion({ theta, phi, alpha }) * (Vector3d(1, -1, -1) * 10)); tpc.SetVertex(TPC::BACK | TPC::RIGHT | TPC::TOP, Quaternion({ theta, phi, alpha }) * (Vector3d(1, 1, -1) * 10)); // Verify // Verify that all are inside for (const Vector3d& v : knownOutsides) Assert::IsFalse(tpc.Contains(v)); } return; } }; }