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();