41 #include <gtest/gtest.h> 
   45 namespace libccd_extension {
 
   48 using Vector3Ccd = Vector3<ccd_real_t>;
 
   61   return Vector3Ccd{vector.v};
 
   64 class DoSimplex2Test : 
public ::testing::Test {
 
   66   void SetUp()
 override {
 
   69     phat_OB_ = Vector3Ccd(1, -2, 3).normalized();
 
   79   ::testing::AssertionResult SetValidSimplex(
const ccd_vec3_t& A,
 
   81                                              bool validate = 
true) {
 
   82     const Vector3Ccd p_OA(A.v);
 
   83     const Vector3Ccd p_OB(B.v);
 
   86     if (validate && p_OA.dot(p_OB) > p_OB.squaredNorm() * eps) {
 
   87       return ::testing::AssertionFailure()
 
   88              << 
"Simplex points are not valid; A is not in region 1: " 
   89              << 
"\n  p_OA: " << p_OA.transpose()
 
   90              << 
"\n  p_OB: " << p_OB.transpose();
 
   98     dir_ = {{-1.23, 4.56, 7.89}};
 
   99     return ::testing::AssertionSuccess();
 
  107   void ConfigureDeathTest(
double u, 
double v) {
 
  139 TEST_F(DoSimplex2Test, OriginInSimplex) {
 
  141   const double delta = 
kEps * 2;
 
  176 TEST_F(DoSimplex2Test, NeedMoreComputing) {
 
  177   auto is_valid_dir = [](
const Vector3Ccd& p_OA, 
const Vector3Ccd& p_OB,
 
  178                          const Vector3Ccd& dir) {
 
  181     const ccd_real_t eps =
 
  182         std::max({ccd_real_t(1), p_OA.norm(), p_OB.norm()}) * 
kEps;
 
  183     const Vector3Ccd phat_AB = (p_OB - p_OA).normalized();
 
  184     const Vector3Ccd dir_hat = dir.normalized();
 
  185     if (std::abs(dir_hat.dot(phat_AB)) > eps) {
 
  186       return ::testing::AssertionFailure()
 
  187              << 
"Direction is not perpendicular to the line segments:" 
  188              << 
"\n  dir: " << dir.transpose()
 
  189              << 
"\n  p_OA: " << p_OA.transpose()
 
  190              << 
"\n  p_OB: " << p_OB.transpose()
 
  191              << 
"\n  dir_hat.dot(phat_AB): " << dir_hat.dot(phat_AB)
 
  192              << 
" bigger than tolerance << " << eps;
 
  196     if (dir_hat.dot(p_OA) >= eps) {
 
  197       return ::testing::AssertionFailure()
 
  198              << 
"Direction does not point toward origin:" 
  199              << 
"\n  dir: " << dir.transpose()
 
  200              << 
"\n  p_OA: " << p_OA.transpose()
 
  201              << 
"\n  p_OB: " << p_OB.transpose()
 
  202              << 
"\n  dir_hat.dot(p_OA): " << dir_hat.dot(p_OA)
 
  203              << 
"; should be negative";
 
  205     if (std::abs(dir.dot(p_OA.normalized().cross(phat_AB))) > eps) {
 
  206       return ::testing::AssertionFailure()
 
  207              << 
"Direction does not lie on the plane formed by OAB:" 
  208              << 
"\n  dir: " << dir.transpose()
 
  209              << 
"\n  p_OA: " << p_OA.transpose()
 
  210              << 
"\n  p_OB: " << p_OB.transpose()
 
  211              << 
"\n  dir.dot(phat_OA.cross(phat_AB)): " 
  212              << dir.dot(p_OA.normalized().cross(phat_AB))
 
  213              << 
" bigger than tolerance << " << eps;
 
  215     return ::testing::AssertionSuccess();
 
  219   const double delta = 
kEps * 2;
 
  223     const ccd_real_t offset = delta * 2 * 
dist_OB_;
 
  232     const ccd_real_t offset = delta * 2 * 
dist_OB_;
 
  285 TEST_F(DoSimplex2Test, Region1Boundary1) {
 
  286   ::testing::FLAGS_gtest_death_test_style = 
"threadsafe";
 
  291                "p_OA.dot\\(p_OB\\) <= p_OB.squaredNorm\\(\\) \\* eps.*");
 
  295 TEST_F(DoSimplex2Test, Region1Boundary2) {
 
  296   ::testing::FLAGS_gtest_death_test_style = 
"threadsafe";
 
  301   ConfigureDeathTest(dist_OA * 2 * 
kEps, dist_OA);
 
  305                "p_OA.dot\\(p_OB\\) <= p_OB.squaredNorm\\(\\) \\* eps.*");
 
  309 TEST_F(DoSimplex2Test, Region1Boundary3) {
 
  310   ::testing::FLAGS_gtest_death_test_style = 
"threadsafe";
 
  311   const double dist_OA = 100 * 
dist_OB_;
 
  315   ConfigureDeathTest(dist_OA * 2 * 
kEps, dist_OA);
 
  319                "p_OA.dot\\(p_OB\\) <= p_OB.squaredNorm\\(\\) \\* eps.*");
 
  330 int main(
int argc, 
char* argv[]) {
 
  331   ::testing::InitGoogleTest(&argc, argv);
 
  332   return RUN_ALL_TESTS();