41 #include <boost/filesystem.hpp> 43 #include <gtest/gtest.h> 44 #include "resources/config.h" 52 const Eigen::Quaterniond
r({ quat[3], quat[0], quat[1], quat[2] });
54 return Eigen::Isometry3d::TranslationType(t) *
r;
57 #define EXPECT_VECTORS_EQUAL(v1, v2, error) \ 58 EXPECT_NEAR((v1)[0], (v2)[0], (error)); \ 59 EXPECT_NEAR((v1)[1], (v2)[1], (error)); \ 60 EXPECT_NEAR((v1)[2], (v2)[2], (error)); 62 #define CHECK_NO_INTERSECTION(body, origin, direction) \ 64 EigenSTL::vector_Vector3d intersections; \ 65 Eigen::Vector3d o origin; \ 66 Eigen::Vector3d d direction; \ 67 const auto result = (body).intersectsRay(o, d, &intersections, 2); \ 68 EXPECT_FALSE(result); \ 69 EXPECT_EQ(0u, intersections.size()); \ 72 #define CHECK_INTERSECTS(body, origin, direction, numIntersections) \ 74 EigenSTL::vector_Vector3d intersections; \ 75 Eigen::Vector3d o origin; \ 76 Eigen::Vector3d d direction; \ 77 const auto result = (body).intersectsRay(o, d, &intersections, 2); \ 78 EXPECT_TRUE(result); \ 79 EXPECT_EQ(static_cast<size_t>((numIntersections)), intersections.size()); \ 82 #define CHECK_INTERSECTS_ONCE(body, origin, direction, intersection, error) \ 84 EigenSTL::vector_Vector3d intersections; \ 85 Eigen::Vector3d o origin; \ 86 Eigen::Vector3d d direction; \ 87 Eigen::Vector3d i intersection; \ 88 const auto result = (body).intersectsRay(o, d, &intersections, 2); \ 89 EXPECT_TRUE(result); \ 90 EXPECT_EQ(1u, intersections.size()); \ 91 if (intersections.size() == 1u) \ 93 EXPECT_VECTORS_EQUAL(intersections.at(0), i, (error)); \ 97 #define CHECK_INTERSECTS_TWICE(body, origin, direction, intersc1, intersc2, error) \ 99 EigenSTL::vector_Vector3d intersections; \ 100 Eigen::Vector3d o origin; \ 101 Eigen::Vector3d d direction; \ 102 Eigen::Vector3d i1 intersc1; \ 103 Eigen::Vector3d i2 intersc2; \ 104 const auto result = (body).intersectsRay(o, d, &intersections, 2); \ 105 EXPECT_TRUE(result); \ 106 EXPECT_EQ(2u, intersections.size()); \ 107 if (intersections.size() == 2u) \ 109 if (fabs(static_cast<double>((intersections.at(0) - i1).norm())) < (error)) \ 111 EXPECT_VECTORS_EQUAL(intersections.at(0), i1, (error)); \ 112 EXPECT_VECTORS_EQUAL(intersections.at(1), i2, (error)); \ 116 EXPECT_VECTORS_EQUAL(intersections.at(0), i2, (error)); \ 117 EXPECT_VECTORS_EQUAL(intersections.at(1), i1, (error)); \ 122 TEST(SphereRayIntersection, OriginInside)
128 CHECK_INTERSECTS_ONCE(sphere, (0, 0, 0), ( 1, 0, 0), ( 1, 0, 0), 1e-6)
129 CHECK_INTERSECTS_ONCE(sphere, (0, 0, 0), (-1, 0, 0), (-1, 0, 0), 1e-6)
130 CHECK_INTERSECTS_ONCE(sphere, (0, 0, 0), ( 0, 1, 0), ( 0, 1, 0), 1e-6)
131 CHECK_INTERSECTS_ONCE(sphere, (0, 0, 0), ( 0, -1, 0), ( 0, -1, 0), 1e-6)
132 CHECK_INTERSECTS_ONCE(sphere, (0, 0, 0), ( 0, 0, 1), ( 0, 0, 1), 1e-6)
133 CHECK_INTERSECTS_ONCE(sphere, (0, 0, 0), ( 0, 0, -1), ( 0, 0, -1), 1e-6)
140 CHECK_INTERSECTS_ONCE(sphere, (0, 0, 0), ( 1, 0, 0), ( 1.1, 0, 0), 1e-6)
141 CHECK_INTERSECTS_ONCE(sphere, (0, 0, 0), (-1, 0, 0), (-1.1, 0, 0), 1e-6)
142 CHECK_INTERSECTS_ONCE(sphere, (0, 0, 0), ( 0, 1, 0), ( 0, 1.1, 0), 1e-6)
143 CHECK_INTERSECTS_ONCE(sphere, (0, 0, 0), ( 0, -1, 0), ( 0, -1.1, 0), 1e-6)
144 CHECK_INTERSECTS_ONCE(sphere, (0, 0, 0), ( 0, 0, 1), ( 0, 0, 1.1), 1e-6)
145 CHECK_INTERSECTS_ONCE(sphere, (0, 0, 0), ( 0, 0, -1), ( 0, 0, -1.1), 1e-6)
151 CHECK_INTERSECTS_ONCE(sphere, (0.5, 0 , 0 ), ( 1, 0, 0), ( 1.1, 0, 0), 1e-6)
152 CHECK_INTERSECTS_ONCE(sphere, (0.5, 0 , 0 ), (-1, 0, 0), (-1.1, 0, 0), 1e-6)
153 CHECK_INTERSECTS_ONCE(sphere, (0 , 0.5, 0 ), ( 0, 1, 0), ( 0, 1.1, 0), 1e-6)
154 CHECK_INTERSECTS_ONCE(sphere, (0 , 0.5, 0 ), ( 0, -1, 0), ( 0, -1.1, 0), 1e-6)
155 CHECK_INTERSECTS_ONCE(sphere, (0 , 0 , 0.5), ( 0, 0, 1), ( 0, 0, 1.1), 1e-6)
156 CHECK_INTERSECTS_ONCE(sphere, (0 , 0 , 0.5), ( 0, 0, -1), ( 0, 0, -1.1), 1e-6)
161 Eigen::Isometry3d pose = Eigen::Translation3d(0.5, 0, 0) * Eigen::Quaterniond::Identity();
164 CHECK_INTERSECTS_ONCE(sphere, (0, 0, 0), ( 1, 0, 0), ( 1.6, 0, 0), 1e-6)
165 CHECK_INTERSECTS_ONCE(sphere, (0, 0, 0), (-1, 0, 0), (-0.6, 0, 0), 1e-6)
168 pose = Eigen::Translation3d(0, 0.5, 0) * Eigen::Quaterniond::Identity();
171 CHECK_INTERSECTS_ONCE(sphere, (0, 0, 0), ( 0, 1, 0), (0, 1.6, 0), 1e-6)
172 CHECK_INTERSECTS_ONCE(sphere, (0, 0, 0), ( 0, -1, 0), (0, -0.6, 0), 1e-6)
175 pose = Eigen::Translation3d(0, 0, 0.5) * Eigen::Quaterniond::Identity();
178 CHECK_INTERSECTS_ONCE(sphere, (0, 0, 0), ( 0, 0, 1), (0, 0, 1.6), 1e-6)
179 CHECK_INTERSECTS_ONCE(sphere, (0, 0, 0), ( 0, 0, -1), (0, 0, -0.6), 1e-6)
184 sphere.
setPose(Eigen::Isometry3d::Identity());
188 const auto sq3 = sqrt(pow(1 + 0.1, 2) / 3);
189 const auto dir3 = Eigen::Vector3d::Ones().normalized();
201 const auto sq2 = sqrt(pow(1 + 0.1, 2) / 2);
202 const auto dir2 = 1 / sqrt(2);
204 CHECK_INTERSECTS_ONCE(sphere, ( 0, 0, 0), ( dir2, dir2, 0), ( sq2, sq2, 0), 1e-4)
205 CHECK_INTERSECTS_ONCE(sphere, ( 0, 0, 0), (-dir2, -dir2, 0), (-sq2, -sq2, 0), 1e-4)
206 CHECK_INTERSECTS_ONCE(sphere, ( 0.5, 0.5, 0), ( dir2, dir2, 0), ( sq2, sq2, 0), 1e-4)
207 CHECK_INTERSECTS_ONCE(sphere, ( 0.5, 0.5, 0), (-dir2, -dir2, 0), (-sq2, -sq2, 0), 1e-4)
208 CHECK_INTERSECTS_ONCE(sphere, (-0.5, -0.5, 0), ( dir2, dir2, 0), ( sq2, sq2, 0), 1e-4)
209 CHECK_INTERSECTS_ONCE(sphere, (-0.5, -0.5, 0), (-dir2, -dir2, 0), (-sq2, -sq2, 0), 1e-4)
211 CHECK_INTERSECTS_ONCE(sphere, ( 0, 0, 0), ( 0, dir2, dir2), ( 0, sq2, sq2), 1e-4)
212 CHECK_INTERSECTS_ONCE(sphere, ( 0, 0, 0), ( 0, -dir2, -dir2), ( 0, -sq2, -sq2), 1e-4)
213 CHECK_INTERSECTS_ONCE(sphere, ( 0, 0.5, 0.5), ( 0, dir2, dir2), ( 0, sq2, sq2), 1e-4)
214 CHECK_INTERSECTS_ONCE(sphere, ( 0, 0.5, 0.5), ( 0, -dir2, -dir2), ( 0, -sq2, -sq2), 1e-4)
215 CHECK_INTERSECTS_ONCE(sphere, ( 0, -0.5, -0.5), ( 0, dir2, dir2), ( 0, sq2, sq2), 1e-4)
216 CHECK_INTERSECTS_ONCE(sphere, ( 0, -0.5, -0.5), ( 0, -dir2, -dir2), ( 0, -sq2, -sq2), 1e-4)
218 CHECK_INTERSECTS_ONCE(sphere, ( 0, 0, 0), ( dir2, 0, dir2), ( sq2, 0, sq2), 1e-4)
219 CHECK_INTERSECTS_ONCE(sphere, ( 0, 0, 0), (-dir2, 0, -dir2), (-sq2, 0, -sq2), 1e-4)
220 CHECK_INTERSECTS_ONCE(sphere, ( 0.5, 0, 0.5), ( dir2, 0, dir2), ( sq2, 0, sq2), 1e-4)
221 CHECK_INTERSECTS_ONCE(sphere, ( 0.5, 0, 0.5), (-dir2, 0, -dir2), (-sq2, 0, -sq2), 1e-4)
222 CHECK_INTERSECTS_ONCE(sphere, (-0.5, 0, -0.5), ( dir2, 0, dir2), ( sq2, 0, sq2), 1e-4)
223 CHECK_INTERSECTS_ONCE(sphere, (-0.5, 0, -0.5), (-dir2, 0, -dir2), (-sq2, 0, -sq2), 1e-4)
228 for (
size_t i = 0; i < 1000; ++i)
235 Eigen::Vector3d origin;
242 const Eigen::Vector3d dir = Eigen::Vector3d::Random().normalized();
248 if (intersections.size() == 1)
252 EXPECT_NEAR(0.0, (Eigen::ParametrizedLine<double, 3>(origin, dir).distance(intersections[0])), 1e-6);
253 EXPECT_LT(0.0, (intersections[0] - origin).normalized().dot(dir));
258 GTEST_NONFATAL_FAILURE_((
"No intersection in iteration " + std::to_string(i)).c_str());
263 TEST(SphereRayIntersection, OriginOutside)
269 CHECK_INTERSECTS_TWICE(sphere, (-2, 0, 0), ( 1, 0, 0), ( 1, 0, 0), (-1, 0, 0), 1e-6)
270 CHECK_INTERSECTS_TWICE(sphere, ( 2, 0, 0), (-1, 0, 0), (-1, 0, 0), ( 1, 0, 0), 1e-6)
271 CHECK_INTERSECTS_TWICE(sphere, ( 0, -2, 0), ( 0, 1, 0), ( 0, 1, 0), ( 0, -1, 0), 1e-6)
272 CHECK_INTERSECTS_TWICE(sphere, ( 0, 2, 0), ( 0, -1, 0), ( 0, -1, 0), ( 0, 1, 0), 1e-6)
273 CHECK_INTERSECTS_TWICE(sphere, ( 0, 0, -2), ( 0, 0, 1), ( 0, 0, 1), ( 0, 0, -1), 1e-6)
274 CHECK_INTERSECTS_TWICE(sphere, ( 0, 0, 2), ( 0, 0, -1), ( 0, 0, -1), ( 0, 0, 1), 1e-6)
279 CHECK_INTERSECTS_ONCE(sphere, (-1, -1, 0), ( 0, 1, 0), (-1, 0, 0), 1e-6)
280 CHECK_INTERSECTS_ONCE(sphere, (-1, 1, 0), ( 0, -1, 0), (-1, 0, 0), 1e-6)
281 CHECK_INTERSECTS_ONCE(sphere, ( 1, -1, 0), ( 0, 1, 0), ( 1, 0, 0), 1e-6)
282 CHECK_INTERSECTS_ONCE(sphere, ( 1, 1, 0), ( 0, -1, 0), ( 1, 0, 0), 1e-6)
283 CHECK_INTERSECTS_ONCE(sphere, ( 0, -1, -1), ( 0, 0, 1), ( 0, -1, 0), 1e-6)
284 CHECK_INTERSECTS_ONCE(sphere, ( 0, -1, 1), ( 0, 0, -1), ( 0, -1, 0), 1e-6)
285 CHECK_INTERSECTS_ONCE(sphere, ( 0, 1, -1), ( 0, 0, 1), ( 0, 1, 0), 1e-6)
286 CHECK_INTERSECTS_ONCE(sphere, ( 0, 1, 1), ( 0, 0, -1), ( 0, 1, 0), 1e-6)
287 CHECK_INTERSECTS_ONCE(sphere, (-1, 0, -1), ( 1, 0, 0), ( 0, 0, -1), 1e-6)
288 CHECK_INTERSECTS_ONCE(sphere, ( 1, 0, -1), (-1, 0, 0), ( 0, 0, -1), 1e-6)
289 CHECK_INTERSECTS_ONCE(sphere, (-1, 0, 1), ( 1, 0, 0), ( 0, 0, 1), 1e-6)
290 CHECK_INTERSECTS_ONCE(sphere, ( 1, 0, 1), (-1, 0, 0), ( 0, 0, 1), 1e-6)
311 for (
size_t i = 0; i < 1000; ++i)
319 const Eigen::Vector3d dir = Eigen::Vector3d::Random().normalized();
326 const Eigen::Vector3d origin = s.
center + -dir * 1.5 * s.
radius;
333 if (intersections.size() == 2)
339 EXPECT_NEAR(0.0, (Eigen::ParametrizedLine<double, 3>(origin, dir).distance(intersections[0])), 1e-6);
340 EXPECT_LT(0.0, (intersections[0] - origin).normalized().dot(dir));
341 EXPECT_NEAR(0.0, (Eigen::ParametrizedLine<double, 3>(origin, dir).distance(intersections[1])), 1e-6);
342 EXPECT_LT(0.0, (intersections[1] - origin).normalized().dot(dir));
347 GTEST_NONFATAL_FAILURE_((
"No intersection in iteration " + std::to_string(i)).c_str());
356 Eigen::Vector3d perpDir = dir.cross(Eigen::Vector3d({ dir.z(), dir.z(), -dir.x() - dir.y() }));
357 if (perpDir.norm() < 1e-6)
358 perpDir = dir.cross(Eigen::Vector3d({ -dir.y() - dir.z(), dir.x(), dir.x() }));
362 const Eigen::Vector3d origin2 = origin + g.
uniformReal(1e-6, s.
radius - 1e-4) * perpDir;
364 intersections.clear();
368 if (intersections.size() == 2)
374 EXPECT_NEAR(0.0, (Eigen::ParametrizedLine<double, 3>(origin2, dir).distance(intersections[0])), 1e-6);
375 EXPECT_LT(0.0, (intersections[0] - origin2).normalized().dot(dir));
376 EXPECT_NEAR(0.0, (Eigen::ParametrizedLine<double, 3>(origin2, dir).distance(intersections[1])), 1e-6);
377 EXPECT_LT(0.0, (intersections[1] - origin2).normalized().dot(dir));
382 GTEST_NONFATAL_FAILURE_((
"No intersection in iteration " + std::to_string(i)).c_str());
387 TEST(SphereRayIntersection, SimpleRay1)
393 CHECK_INTERSECTS_TWICE(sphere, (5, 0, 0), (-1, 0, 0), (1.05, 0, 0), (-1.05, 0, 0), 1e-6)
396 TEST(SphereRayIntersection, SimpleRay2)
405 TEST(CylinderRayIntersection, OriginInside)
411 CHECK_INTERSECTS_ONCE(cylinder, (0, 0, 0), ( 1, 0, 0), ( 1, 0, 0), 1e-6)
412 CHECK_INTERSECTS_ONCE(cylinder, (0, 0, 0), (-1, 0, 0), (-1, 0, 0), 1e-6)
413 CHECK_INTERSECTS_ONCE(cylinder, (0, 0, 0), ( 0, 1, 0), ( 0, 1, 0), 1e-6)
414 CHECK_INTERSECTS_ONCE(cylinder, (0, 0, 0), ( 0, -1, 0), ( 0, -1, 0), 1e-6)
415 CHECK_INTERSECTS_ONCE(cylinder, (0, 0, 0), ( 0, 0, 1), ( 0, 0, 1), 1e-6)
416 CHECK_INTERSECTS_ONCE(cylinder, (0, 0, 0), ( 0, 0, -1), ( 0, 0, -1), 1e-6)
423 CHECK_INTERSECTS_ONCE(cylinder, (0, 0, 0), ( 1, 0, 0), ( 1.1, 0, 0), 1e-6)
424 CHECK_INTERSECTS_ONCE(cylinder, (0, 0, 0), (-1, 0, 0), (-1.1, 0, 0), 1e-6)
425 CHECK_INTERSECTS_ONCE(cylinder, (0, 0, 0), ( 0, 1, 0), ( 0, 1.1, 0), 1e-6)
426 CHECK_INTERSECTS_ONCE(cylinder, (0, 0, 0), ( 0, -1, 0), ( 0, -1.1, 0), 1e-6)
427 CHECK_INTERSECTS_ONCE(cylinder, (0, 0, 0), ( 0, 0, 1), ( 0, 0, 1.1), 1e-6)
428 CHECK_INTERSECTS_ONCE(cylinder, (0, 0, 0), ( 0, 0, -1), ( 0, 0, -1.1), 1e-6)
434 CHECK_INTERSECTS_ONCE(cylinder, (0.5, 0 , 0 ), ( 1, 0, 0), ( 1.1, 0, 0), 1e-6)
435 CHECK_INTERSECTS_ONCE(cylinder, (0.5, 0 , 0 ), (-1, 0, 0), (-1.1, 0, 0), 1e-6)
436 CHECK_INTERSECTS_ONCE(cylinder, (0 , 0.5, 0 ), ( 0, 1, 0), ( 0, 1.1, 0), 1e-6)
437 CHECK_INTERSECTS_ONCE(cylinder, (0 , 0.5, 0 ), ( 0, -1, 0), ( 0, -1.1, 0), 1e-6)
438 CHECK_INTERSECTS_ONCE(cylinder, (0 , 0 , 0.5), ( 0, 0, 1), ( 0, 0, 1.1), 1e-6)
439 CHECK_INTERSECTS_ONCE(cylinder, (0 , 0 , 0.5), ( 0, 0, -1), ( 0, 0, -1.1), 1e-6)
444 Eigen::Isometry3d pose = Eigen::Translation3d(0.5, 0, 0) * Eigen::Quaterniond::Identity();
447 CHECK_INTERSECTS_ONCE(cylinder, (0, 0, 0), ( 1, 0, 0), ( 1.6, 0, 0), 1e-6)
448 CHECK_INTERSECTS_ONCE(cylinder, (0, 0, 0), (-1, 0, 0), (-0.6, 0, 0), 1e-6)
451 pose = Eigen::Translation3d(0, 0.5, 0) * Eigen::Quaterniond::Identity();
454 CHECK_INTERSECTS_ONCE(cylinder, (0, 0, 0), ( 0, 1, 0), (0, 1.6, 0), 1e-6)
455 CHECK_INTERSECTS_ONCE(cylinder, (0, 0, 0), ( 0, -1, 0), (0, -0.6, 0), 1e-6)
458 pose = Eigen::Translation3d(0, 0, 0.5) * Eigen::Quaterniond::Identity();
461 CHECK_INTERSECTS_ONCE(cylinder, (0, 0, 0), ( 0, 0, 1), (0, 0, 1.6), 1e-6)
462 CHECK_INTERSECTS_ONCE(cylinder, (0, 0, 0), ( 0, 0, -1), (0, 0, -0.6), 1e-6)
467 cylinder.
setPose(Eigen::Isometry3d::Identity());
472 const auto sq2 = sqrt(pow(1 + 0.1, 2) / 2);
474 const auto dir3 = Eigen::Vector3d({ sq2, sq2, 1.1 }).normalized();
487 const auto dir2 = 1 / sqrt(2);
489 CHECK_INTERSECTS_ONCE(cylinder, ( 0, 0, 0), ( dir2, dir2, 0), ( sq2, sq2, 0), 1e-4)
490 CHECK_INTERSECTS_ONCE(cylinder, ( 0, 0, 0), (-dir2, -dir2, 0), (-sq2, -sq2, 0), 1e-4)
491 CHECK_INTERSECTS_ONCE(cylinder, ( 0.5, 0.5, 0), ( dir2, dir2, 0), ( sq2, sq2, 0), 1e-4)
492 CHECK_INTERSECTS_ONCE(cylinder, ( 0.5, 0.5, 0), (-dir2, -dir2, 0), (-sq2, -sq2, 0), 1e-4)
493 CHECK_INTERSECTS_ONCE(cylinder, (-0.5, -0.5, 0), ( dir2, dir2, 0), ( sq2, sq2, 0), 1e-4)
494 CHECK_INTERSECTS_ONCE(cylinder, (-0.5, -0.5, 0), (-dir2, -dir2, 0), (-sq2, -sq2, 0), 1e-4)
496 CHECK_INTERSECTS_ONCE(cylinder, ( 0, 0, 0), ( 0, dir2, dir2), ( 0, 1.1, 1.1), 1e-4)
497 CHECK_INTERSECTS_ONCE(cylinder, ( 0, 0, 0), ( 0, -dir2, -dir2), ( 0, -1.1, -1.1), 1e-4)
498 CHECK_INTERSECTS_ONCE(cylinder, ( 0, 0.5, 0.5), ( 0, dir2, dir2), ( 0, 1.1, 1.1), 1e-4)
499 CHECK_INTERSECTS_ONCE(cylinder, ( 0, 0.5, 0.5), ( 0, -dir2, -dir2), ( 0, -1.1, -1.1), 1e-4)
500 CHECK_INTERSECTS_ONCE(cylinder, ( 0, -0.5, -0.5), ( 0, dir2, dir2), ( 0, 1.1, 1.1), 1e-4)
501 CHECK_INTERSECTS_ONCE(cylinder, ( 0, -0.5, -0.5), ( 0, -dir2, -dir2), ( 0, -1.1, -1.1), 1e-4)
503 CHECK_INTERSECTS_ONCE(cylinder, ( 0, 0, 0), ( dir2, 0, dir2), ( 1.1, 0, 1.1), 1e-4)
504 CHECK_INTERSECTS_ONCE(cylinder, ( 0, 0, 0), (-dir2, 0, -dir2), (-1.1, 0, -1.1), 1e-4)
505 CHECK_INTERSECTS_ONCE(cylinder, ( 0.5, 0, 0.5), ( dir2, 0, dir2), ( 1.1, 0, 1.1), 1e-4)
506 CHECK_INTERSECTS_ONCE(cylinder, ( 0.5, 0, 0.5), (-dir2, 0, -dir2), (-1.1, 0, -1.1), 1e-4)
507 CHECK_INTERSECTS_ONCE(cylinder, (-0.5, 0, -0.5), ( dir2, 0, dir2), ( 1.1, 0, 1.1), 1e-4)
508 CHECK_INTERSECTS_ONCE(cylinder, (-0.5, 0, -0.5), (-dir2, 0, -dir2), (-1.1, 0, -1.1), 1e-4)
513 for (
size_t i = 0; i < 1000; ++i)
520 Eigen::Vector3d origin;
527 const Eigen::Vector3d dir = Eigen::Vector3d::Random().normalized();
533 if (intersections.size() == 1)
535 EXPECT_GE(s.
radius, (s.
center - intersections[0]).norm());
537 EXPECT_NEAR(0.0, (Eigen::ParametrizedLine<double, 3>(origin, dir).distance(intersections[0])), 1e-6);
538 EXPECT_LT(0.0, (intersections[0] - origin).normalized().dot(dir));
543 GTEST_NONFATAL_FAILURE_((
"No intersection in iteration " + std::to_string(i)).c_str());
548 TEST(CylinderRayIntersection, OriginOutside)
556 CHECK_INTERSECTS_TWICE(cylinder, (-4, 0, 0), ( 1, 0, 0), ( 2, 0, 0), (-2, 0, 0), 1e-6)
557 CHECK_INTERSECTS_TWICE(cylinder, ( 4, 0, 0), (-1, 0, 0), (-2, 0, 0), ( 2, 0, 0), 1e-6)
558 CHECK_INTERSECTS_TWICE(cylinder, ( 0, -4, 0), ( 0, 1, 0), ( 0, 2, 0), ( 0, -2, 0), 1e-6)
559 CHECK_INTERSECTS_TWICE(cylinder, ( 0, 4, 0), ( 0, -1, 0), ( 0, -2, 0), ( 0, 2, 0), 1e-6)
560 CHECK_INTERSECTS_TWICE(cylinder, ( 0, 0, -4), ( 0, 0, 1), ( 0, 0, 2), ( 0, 0, -2), 1e-6)
561 CHECK_INTERSECTS_TWICE(cylinder, ( 0, 0, 4), ( 0, 0, -1), ( 0, 0, -2), ( 0, 0, 2), 1e-6)
566 CHECK_INTERSECTS_ONCE(cylinder, (-2, -2, 0), ( 0, 1, 0), (-2, 0, 0), 1e-6)
567 CHECK_INTERSECTS_ONCE(cylinder, (-2, 2, 0), ( 0, -1, 0), (-2, 0, 0), 1e-6)
568 CHECK_INTERSECTS_ONCE(cylinder, ( 2, -2, 0), ( 0, 1, 0), ( 2, 0, 0), 1e-6)
569 CHECK_INTERSECTS_ONCE(cylinder, ( 2, 2, 0), ( 0, -1, 0), ( 2, 0, 0), 1e-6)
570 CHECK_INTERSECTS_ONCE(cylinder, (-2, -2, 0), ( 1, 0, 0), ( 0, -2, 0), 1e-6)
571 CHECK_INTERSECTS_ONCE(cylinder, ( 2, -2, 0), (-1, 0, 0), ( 0, -2, 0), 1e-6)
572 CHECK_INTERSECTS_ONCE(cylinder, (-2, 2, 0), ( 1, 0, 0), ( 0, 2, 0), 1e-6)
573 CHECK_INTERSECTS_ONCE(cylinder, ( 2, 2, 0), (-1, 0, 0), ( 0, 2, 0), 1e-6)
574 CHECK_INTERSECTS_TWICE(cylinder, ( 0, -2, -3), ( 0, 0, 1), ( 0, -2, -2), ( 0, -2, 2), 1e-6)
575 CHECK_INTERSECTS_TWICE(cylinder, ( 0, -2, 3), ( 0, 0, -1), ( 0, -2, 2), ( 0, -2, -2), 1e-6)
576 CHECK_INTERSECTS_TWICE(cylinder, ( 0, 2, -3), ( 0, 0, 1), ( 0, 2, -2), ( 0, 2, 2), 1e-6)
577 CHECK_INTERSECTS_TWICE(cylinder, ( 0, 2, 3), ( 0, 0, -1), ( 0, 2, 2), ( 0, 2, -2), 1e-6)
578 CHECK_INTERSECTS_TWICE(cylinder, (-2, 0, -3), ( 0, 0, 1), (-2, 0, -2), (-2, 0, 2), 1e-6)
579 CHECK_INTERSECTS_TWICE(cylinder, (-2, 0, 3), ( 0, 0, -1), (-2, 0, 2), (-2, 0, -2), 1e-6)
580 CHECK_INTERSECTS_TWICE(cylinder, ( 2, 0, -3), ( 0, 0, 1), ( 2, 0, -2), ( 2, 0, 2), 1e-6)
581 CHECK_INTERSECTS_TWICE(cylinder, ( 2, 0, 3), ( 0, 0, -1), ( 2, 0, 2), ( 2, 0, -2), 1e-6)
602 for (
size_t i = 0; i < 1000; ++i)
610 const Eigen::Vector3d dir = Eigen::Vector3d::Random().normalized();
617 const Eigen::Vector3d origin = s.
center + -dir * 1.5 * s.
radius;
624 if (intersections.size() == 2)
626 EXPECT_GE(s.
radius, (s.
center - intersections[0]).norm());
627 EXPECT_GE(s.
radius, (s.
center - intersections[1]).norm());
630 EXPECT_NEAR(0.0, (Eigen::ParametrizedLine<double, 3>(origin, dir).distance(intersections[0])), 1e-6);
631 EXPECT_LT(0.0, (intersections[0] - origin).normalized().dot(dir));
632 EXPECT_NEAR(0.0, (Eigen::ParametrizedLine<double, 3>(origin, dir).distance(intersections[1])), 1e-6);
633 EXPECT_LT(0.0, (intersections[1] - origin).normalized().dot(dir));
638 GTEST_NONFATAL_FAILURE_((
"No intersection in iteration " + std::to_string(i)).c_str());
647 Eigen::Vector3d perpDir = dir.cross(Eigen::Vector3d({ dir.z(), dir.z(), -dir.x() - dir.y() }));
648 if (perpDir.norm() < 1e-6)
649 perpDir = dir.cross(Eigen::Vector3d({ -dir.y() - dir.z(), dir.x(), dir.x() }));
658 const Eigen::Vector3d origin2 = origin + g.
uniformReal(1e-6, minRadius - 1e-4) * perpDir;
660 intersections.clear();
664 if (intersections.size() == 2)
666 EXPECT_GT(s.
radius, (s.
center - intersections[0]).norm());
667 EXPECT_GT(s.
radius, (s.
center - intersections[1]).norm());
668 EXPECT_LT(minRadius, (s.
center - intersections[0]).norm());
669 EXPECT_LT(minRadius, (s.
center - intersections[1]).norm());
672 EXPECT_NEAR(0.0, (Eigen::ParametrizedLine<double, 3>(origin2, dir).distance(intersections[0])), 1e-6);
673 EXPECT_LT(0.0, (intersections[0] - origin2).normalized().dot(dir));
674 EXPECT_NEAR(0.0, (Eigen::ParametrizedLine<double, 3>(origin2, dir).distance(intersections[1])), 1e-6);
675 EXPECT_LT(0.0, (intersections[1] - origin2).normalized().dot(dir));
680 GTEST_NONFATAL_FAILURE_((
"No intersection in iteration " + std::to_string(i)).c_str());
685 TEST(CylinderRayIntersection, SimpleRay1)
691 CHECK_INTERSECTS_TWICE(cylinder, (5, 0, 0), (-1, 0, 0), (1.05, 0, 0), (-1.05, 0, 0), 1e-6)
694 TEST(CylinderRayIntersection, SimpleRay2)
703 TEST(BoxRayIntersection, SimpleRay1)
709 CHECK_INTERSECTS_TWICE(box, (10, 0.449, 0), (-1, 0, 0), (0.475, 0.449, 0), (-0.475, 0.449, 0), 1e-4)
712 TEST(BoxRayIntersection, SimpleRay2)
717 Eigen::Isometry3d pose(Eigen::AngleAxisd(0, Eigen::Vector3d::UnitX()));
718 pose.translation() = Eigen::Vector3d(0, 0.005, 0.6);
721 const Eigen::Vector3d ray_d(0, -5.195, -0.77);
726 TEST(BoxRayIntersection, SimpleRay3)
731 Eigen::Isometry3d pose(Eigen::AngleAxisd(0, Eigen::Vector3d::UnitX()));
732 pose.translation() = Eigen::Vector3d(0.45, -0.195, 0.6);
735 const Eigen::Vector3d ray_d(0, 1.8, -0.669);
740 TEST(BoxRayIntersection, Regression109)
747 const auto rot = Eigen::AngleAxisd(
M_PI * 2 / 3, Eigen::Vector3d(1.0, -1.0, 1.0).normalized());
748 box.
setPose(Eigen::Isometry3d(rot));
750 CHECK_INTERSECTS_TWICE(box, (-2, 0, 0), (1, 0, 0), (0.5, 0, 0), (-0.5, 0, 0), 1e-6)
753 TEST(BoxRayIntersection, OriginInside)
759 CHECK_INTERSECTS_ONCE(box, (0, 0, 0), ( 1, 0, 0), ( 1, 0, 0), 1e-6)
760 CHECK_INTERSECTS_ONCE(box, (0, 0, 0), (-1, 0, 0), (-1, 0, 0), 1e-6)
761 CHECK_INTERSECTS_ONCE(box, (0, 0, 0), ( 0, 1, 0), ( 0, 1, 0), 1e-6)
762 CHECK_INTERSECTS_ONCE(box, (0, 0, 0), ( 0, -1, 0), ( 0, -1, 0), 1e-6)
763 CHECK_INTERSECTS_ONCE(box, (0, 0, 0), ( 0, 0, 1), ( 0, 0, 1), 1e-6)
764 CHECK_INTERSECTS_ONCE(box, (0, 0, 0), ( 0, 0, -1), ( 0, 0, -1), 1e-6)
771 CHECK_INTERSECTS_ONCE(box, (0, 0, 0), ( 1, 0, 0), ( 1.1, 0, 0), 1e-6)
772 CHECK_INTERSECTS_ONCE(box, (0, 0, 0), (-1, 0, 0), (-1.1, 0, 0), 1e-6)
773 CHECK_INTERSECTS_ONCE(box, (0, 0, 0), ( 0, 1, 0), ( 0, 1.1, 0), 1e-6)
774 CHECK_INTERSECTS_ONCE(box, (0, 0, 0), ( 0, -1, 0), ( 0, -1.1, 0), 1e-6)
775 CHECK_INTERSECTS_ONCE(box, (0, 0, 0), ( 0, 0, 1), ( 0, 0, 1.1), 1e-6)
776 CHECK_INTERSECTS_ONCE(box, (0, 0, 0), ( 0, 0, -1), ( 0, 0, -1.1), 1e-6)
782 CHECK_INTERSECTS_ONCE(box, (0.5, 0 , 0 ), ( 1, 0, 0), ( 1.1, 0, 0), 1e-6)
783 CHECK_INTERSECTS_ONCE(box, (0.5, 0 , 0 ), (-1, 0, 0), (-1.1, 0, 0), 1e-6)
784 CHECK_INTERSECTS_ONCE(box, (0 , 0.5, 0 ), ( 0, 1, 0), ( 0, 1.1, 0), 1e-6)
785 CHECK_INTERSECTS_ONCE(box, (0 , 0.5, 0 ), ( 0, -1, 0), ( 0, -1.1, 0), 1e-6)
786 CHECK_INTERSECTS_ONCE(box, (0 , 0 , 0.5), ( 0, 0, 1), ( 0, 0, 1.1), 1e-6)
787 CHECK_INTERSECTS_ONCE(box, (0 , 0 , 0.5), ( 0, 0, -1), ( 0, 0, -1.1), 1e-6)
792 Eigen::Isometry3d pose(Eigen::Translation3d(0.5, 0, 0));
795 CHECK_INTERSECTS_ONCE(box, (0, 0, 0), ( 1, 0, 0), ( 1.6, 0, 0), 1e-6)
796 CHECK_INTERSECTS_ONCE(box, (0, 0, 0), (-1, 0, 0), (-0.6, 0, 0), 1e-6)
799 pose = Eigen::Translation3d(0, 0.5, 0);
802 CHECK_INTERSECTS_ONCE(box, (0, 0, 0), ( 0, 1, 0), (0, 1.6, 0), 1e-6)
803 CHECK_INTERSECTS_ONCE(box, (0, 0, 0), ( 0, -1, 0), (0, -0.6, 0), 1e-6)
806 pose = Eigen::Translation3d(0, 0, 0.5);
809 CHECK_INTERSECTS_ONCE(box, (0, 0, 0), ( 0, 0, 1), (0, 0, 1.6), 1e-6)
810 CHECK_INTERSECTS_ONCE(box, (0, 0, 0), ( 0, 0, -1), (0, 0, -0.6), 1e-6)
815 box.
setPose(Eigen::Isometry3d::Identity());
819 const auto dir3 = Eigen::Vector3d::Ones().normalized();
831 const auto dir2 = 1 / sqrt(2);
833 CHECK_INTERSECTS_ONCE(box, ( 0, 0, 0), ( dir2, dir2, 0), ( 1.1, 1.1, 0), 1e-4)
834 CHECK_INTERSECTS_ONCE(box, ( 0, 0, 0), (-dir2, -dir2, 0), (-1.1, -1.1, 0), 1e-4)
835 CHECK_INTERSECTS_ONCE(box, ( 0.5, 0.5, 0), ( dir2, dir2, 0), ( 1.1, 1.1, 0), 1e-4)
836 CHECK_INTERSECTS_ONCE(box, ( 0.5, 0.5, 0), (-dir2, -dir2, 0), (-1.1, -1.1, 0), 1e-4)
837 CHECK_INTERSECTS_ONCE(box, (-0.5, -0.5, 0), ( dir2, dir2, 0), ( 1.1, 1.1, 0), 1e-4)
838 CHECK_INTERSECTS_ONCE(box, (-0.5, -0.5, 0), (-dir2, -dir2, 0), (-1.1, -1.1, 0), 1e-4)
840 CHECK_INTERSECTS_ONCE(box, ( 0, 0, 0), ( 0, dir2, dir2), ( 0, 1.1, 1.1), 1e-4)
841 CHECK_INTERSECTS_ONCE(box, ( 0, 0, 0), ( 0, -dir2, -dir2), ( 0, -1.1, -1.1), 1e-4)
842 CHECK_INTERSECTS_ONCE(box, ( 0, 0.5, 0.5), ( 0, dir2, dir2), ( 0, 1.1, 1.1), 1e-4)
843 CHECK_INTERSECTS_ONCE(box, ( 0, 0.5, 0.5), ( 0, -dir2, -dir2), ( 0, -1.1, -1.1), 1e-4)
844 CHECK_INTERSECTS_ONCE(box, ( 0, -0.5, -0.5), ( 0, dir2, dir2), ( 0, 1.1, 1.1), 1e-4)
845 CHECK_INTERSECTS_ONCE(box, ( 0, -0.5, -0.5), ( 0, -dir2, -dir2), ( 0, -1.1, -1.1), 1e-4)
847 CHECK_INTERSECTS_ONCE(box, ( 0, 0, 0), ( dir2, 0, dir2), ( 1.1, 0, 1.1), 1e-4)
848 CHECK_INTERSECTS_ONCE(box, ( 0, 0, 0), (-dir2, 0, -dir2), (-1.1, 0, -1.1), 1e-4)
849 CHECK_INTERSECTS_ONCE(box, ( 0.5, 0, 0.5), ( dir2, 0, dir2), ( 1.1, 0, 1.1), 1e-4)
850 CHECK_INTERSECTS_ONCE(box, ( 0.5, 0, 0.5), (-dir2, 0, -dir2), (-1.1, 0, -1.1), 1e-4)
851 CHECK_INTERSECTS_ONCE(box, (-0.5, 0, -0.5), ( dir2, 0, dir2), ( 1.1, 0, 1.1), 1e-4)
852 CHECK_INTERSECTS_ONCE(box, (-0.5, 0, -0.5), (-dir2, 0, -dir2), (-1.1, 0, -1.1), 1e-4)
857 for (
size_t i = 0; i < 1000; ++i)
867 sizes += 2 * box.
getPadding() * Eigen::Vector3d::Ones();
870 const auto minRadius = sizes.minCoeff() / 2;
871 const auto maxRadius = (sizes / 2).norm();
873 const Eigen::Vector3d boxCenter = box.
getPose().translation();
875 Eigen::Vector3d origin;
878 const Eigen::Vector3d dir = Eigen::Vector3d::Random().normalized();
884 if (intersections.size() == 1)
887 EXPECT_GE(maxRadius, (boxCenter - intersections[0]).norm());
888 EXPECT_LE(minRadius, (boxCenter - intersections[0]).norm());
890 EXPECT_NEAR(0.0, (Eigen::ParametrizedLine<double, 3>(origin, dir).distance(intersections[0])), 1e-6);
891 EXPECT_LT(0.0, (intersections[0] - origin).normalized().dot(dir));
896 GTEST_NONFATAL_FAILURE_((
"No intersection in iteration " + std::to_string(i)).c_str());
901 TEST(BoxRayIntersection, OriginOutsideIntersects)
907 CHECK_INTERSECTS_TWICE(box, (-2, 0, 0), ( 1, 0, 0), ( 1, 0, 0), (-1, 0, 0), 1e-6)
908 CHECK_INTERSECTS_TWICE(box, ( 2, 0, 0), (-1, 0, 0), (-1, 0, 0), ( 1, 0, 0), 1e-6)
909 CHECK_INTERSECTS_TWICE(box, (0, -2, 0), ( 0, 1, 0), ( 0, 1, 0), ( 0, -1, 0), 1e-6)
910 CHECK_INTERSECTS_TWICE(box, (0, 2, 0), ( 0, -1, 0), ( 0, -1, 0), ( 0, 1, 0), 1e-6)
911 CHECK_INTERSECTS_TWICE(box, (0, 0, -2), ( 0, 0, 1), ( 0, 0, 1), ( 0, 0, -1), 1e-6)
912 CHECK_INTERSECTS_TWICE(box, (0, 0, 2), ( 0, 0, -1), ( 0, 0, -1), ( 0, 0, 1), 1e-6)
917 CHECK_INTERSECTS_TWICE(box, (-1, -2, 0), ( 0, 1, 0), (-1, -1, 0), (-1, 1, 0), 1e-6)
918 CHECK_INTERSECTS_TWICE(box, (-1, 2, 0), ( 0, -1, 0), (-1, 1, 0), (-1, -1, 0), 1e-6)
919 CHECK_INTERSECTS_TWICE(box, ( 1, -2, 0), ( 0, 1, 0), ( 1, -1, 0), ( 1, 1, 0), 1e-6)
920 CHECK_INTERSECTS_TWICE(box, ( 1, 2, 0), ( 0, -1, 0), ( 1, 1, 0), ( 1, -1, 0), 1e-6)
921 CHECK_INTERSECTS_TWICE(box, ( 0, -1, -2), ( 0, 0, 1), ( 0, -1, -1), ( 0, -1, 1), 1e-6)
922 CHECK_INTERSECTS_TWICE(box, ( 0, -1, 2), ( 0, 0, -1), ( 0, -1, 1), ( 0, -1, -1), 1e-6)
923 CHECK_INTERSECTS_TWICE(box, ( 0, 1, -2), ( 0, 0, 1), ( 0, 1, -1), ( 0, 1, 1), 1e-6)
924 CHECK_INTERSECTS_TWICE(box, ( 0, 1, 2), ( 0, 0, -1), ( 0, 1, 1), ( 0, 1, -1), 1e-6)
925 CHECK_INTERSECTS_TWICE(box, (-2, 0, -1), ( 1, 0, 0), (-1, 0, -1), ( 1, 0, -1), 1e-6)
926 CHECK_INTERSECTS_TWICE(box, ( 2, 0, -1), (-1, 0, 0), ( 1, 0, -1), (-1, 0, -1), 1e-6)
927 CHECK_INTERSECTS_TWICE(box, (-2, 0, 1), ( 1, 0, 0), (-1, 0, 1), ( 1, 0, 1), 1e-6)
928 CHECK_INTERSECTS_TWICE(box, ( 2, 0, 1), (-1, 0, 0), ( 1, 0, 1), (-1, 0, 1), 1e-6)
949 for (
size_t i = 0; i < 1000; ++i)
957 const Eigen::Vector3d dir = Eigen::Vector3d::Random().normalized();
962 sizes += 2 * box.
getPadding() * Eigen::Vector3d::Ones();
965 const auto minRadius = sizes.minCoeff() / 2;
966 const auto maxRadius = (sizes / 2).norm();
968 const Eigen::Vector3d boxCenter = box.
getPose().translation();
971 const Eigen::Vector3d origin = boxCenter + -dir * 1.5 * maxRadius;
978 if (intersections.size() == 2)
981 EXPECT_GE(maxRadius, (boxCenter - intersections[0]).norm());
982 EXPECT_LE(minRadius, (boxCenter - intersections[0]).norm());
983 EXPECT_GE(maxRadius, (boxCenter - intersections[1]).norm());
984 EXPECT_LE(minRadius, (boxCenter - intersections[1]).norm());
987 EXPECT_NEAR(0.0, (Eigen::ParametrizedLine<double, 3>(origin, dir).distance(intersections[0])), 1e-6);
988 EXPECT_LT(0.0, (intersections[0] - origin).normalized().dot(dir));
989 EXPECT_NEAR(0.0, (Eigen::ParametrizedLine<double, 3>(origin, dir).distance(intersections[1])), 1e-6);
990 EXPECT_LT(0.0, (intersections[1] - origin).normalized().dot(dir));
995 GTEST_NONFATAL_FAILURE_((
"No intersection in iteration " + std::to_string(i)).c_str());
1004 Eigen::Vector3d perpDir = dir.cross(Eigen::Vector3d({ dir.z(), dir.z(), -dir.x() - dir.y() }));
1005 if (perpDir.norm() < 1e-6)
1006 perpDir = dir.cross(Eigen::Vector3d({ -dir.y() - dir.z(), dir.x(), dir.x() }));
1007 perpDir.normalize();
1010 const Eigen::Vector3d origin2 = origin + g.
uniformReal(1e-6, minRadius - 1e-4) * perpDir;
1012 intersections.clear();
1016 if (intersections.size() == 2)
1019 EXPECT_GE(maxRadius, (boxCenter - intersections[0]).norm());
1020 EXPECT_LE(minRadius, (boxCenter - intersections[0]).norm());
1021 EXPECT_GE(maxRadius, (boxCenter - intersections[1]).norm());
1022 EXPECT_LE(minRadius, (boxCenter - intersections[1]).norm());
1025 EXPECT_NEAR(0.0, (Eigen::ParametrizedLine<double, 3>(origin2, dir).distance(intersections[0])), 1e-6);
1026 EXPECT_LT(0.0, (intersections[0] - origin2).normalized().dot(dir));
1027 EXPECT_NEAR(0.0, (Eigen::ParametrizedLine<double, 3>(origin2, dir).distance(intersections[1])), 1e-6);
1028 EXPECT_LT(0.0, (intersections[1] - origin2).normalized().dot(dir));
1033 GTEST_NONFATAL_FAILURE_((
"No intersection in iteration " + std::to_string(i)).c_str());
1038 TEST(ConvexMeshRayIntersection, SimpleRay1)
1046 CHECK_INTERSECTS_TWICE(mesh, (10, 0.449, 0), (-1, 0, 0), (0.475, 0.449, 0), (-0.475, 0.449, 0), 1e-4)
1049 TEST(ConvexMeshRayIntersection, SimpleRay2)
1056 Eigen::Isometry3d pose(Eigen::AngleAxisd(0, Eigen::Vector3d::UnitX()));
1057 pose.translation() = Eigen::Vector3d(0, 0.005, 0.6);
1060 const Eigen::Vector3d ray_d(0, -5.195, -0.77);
1065 TEST(ConvexMeshRayIntersection, SimpleRay3)
1072 Eigen::Isometry3d pose(Eigen::AngleAxisd(0, Eigen::Vector3d::UnitX()));
1073 pose.translation() = Eigen::Vector3d(0.45, -0.195, 0.6);
1076 const Eigen::Vector3d ray_d(0, 1.8, -0.669);
1081 TEST(ConvexMeshRayIntersection, OriginInside)
1089 CHECK_INTERSECTS_ONCE(mesh, (0, 0, 0), ( 1, 0, 0), ( 1, 0, 0), 1e-6)
1090 CHECK_INTERSECTS_ONCE(mesh, (0, 0, 0), (-1, 0, 0), (-1, 0, 0), 1e-6)
1091 CHECK_INTERSECTS_ONCE(mesh, (0, 0, 0), ( 0, 1, 0), ( 0, 1, 0), 1e-6)
1092 CHECK_INTERSECTS_ONCE(mesh, (0, 0, 0), ( 0, -1, 0), ( 0, -1, 0), 1e-6)
1093 CHECK_INTERSECTS_ONCE(mesh, (0, 0, 0), ( 0, 0, 1), ( 0, 0, 1), 1e-6)
1094 CHECK_INTERSECTS_ONCE(mesh, (0, 0, 0), ( 0, 0, -1), ( 0, 0, -1), 1e-6)
1101 CHECK_INTERSECTS_ONCE(mesh, (0, 0, 0), ( 1, 0, 0), ( 1.1, 0, 0), 1e-6)
1102 CHECK_INTERSECTS_ONCE(mesh, (0, 0, 0), (-1, 0, 0), (-1.1, 0, 0), 1e-6)
1103 CHECK_INTERSECTS_ONCE(mesh, (0, 0, 0), ( 0, 1, 0), ( 0, 1.1, 0), 1e-6)
1104 CHECK_INTERSECTS_ONCE(mesh, (0, 0, 0), ( 0, -1, 0), ( 0, -1.1, 0), 1e-6)
1105 CHECK_INTERSECTS_ONCE(mesh, (0, 0, 0), ( 0, 0, 1), ( 0, 0, 1.1), 1e-6)
1106 CHECK_INTERSECTS_ONCE(mesh, (0, 0, 0), ( 0, 0, -1), ( 0, 0, -1.1), 1e-6)
1112 CHECK_INTERSECTS_ONCE(mesh, (0.5, 0 , 0 ), ( 1, 0, 0), ( 1.1, 0, 0), 1e-6)
1113 CHECK_INTERSECTS_ONCE(mesh, (0.5, 0 , 0 ), (-1, 0, 0), (-1.1, 0, 0), 1e-6)
1114 CHECK_INTERSECTS_ONCE(mesh, (0 , 0.5, 0 ), ( 0, 1, 0), ( 0, 1.1, 0), 1e-6)
1115 CHECK_INTERSECTS_ONCE(mesh, (0 , 0.5, 0 ), ( 0, -1, 0), ( 0, -1.1, 0), 1e-6)
1116 CHECK_INTERSECTS_ONCE(mesh, (0 , 0 , 0.5), ( 0, 0, 1), ( 0, 0, 1.1), 1e-6)
1117 CHECK_INTERSECTS_ONCE(mesh, (0 , 0 , 0.5), ( 0, 0, -1), ( 0, 0, -1.1), 1e-6)
1122 Eigen::Isometry3d pose(Eigen::Translation3d(0.5, 0, 0));
1125 CHECK_INTERSECTS_ONCE(mesh, (0, 0, 0), ( 1, 0, 0), ( 1.6, 0, 0), 1e-6)
1126 CHECK_INTERSECTS_ONCE(mesh, (0, 0, 0), (-1, 0, 0), (-0.6, 0, 0), 1e-6)
1129 pose = Eigen::Translation3d(0, 0.5, 0);
1132 CHECK_INTERSECTS_ONCE(mesh, (0, 0, 0), ( 0, 1, 0), (0, 1.6, 0), 1e-6)
1133 CHECK_INTERSECTS_ONCE(mesh, (0, 0, 0), ( 0, -1, 0), (0, -0.6, 0), 1e-6)
1136 pose = Eigen::Translation3d(0, 0, 0.5);
1139 CHECK_INTERSECTS_ONCE(mesh, (0, 0, 0), ( 0, 0, 1), (0, 0, 1.6), 1e-6)
1140 CHECK_INTERSECTS_ONCE(mesh, (0, 0, 0), ( 0, 0, -1), (0, 0, -0.6), 1e-6)
1145 mesh.
setPose(Eigen::Isometry3d::Identity());
1150 const double s = 1.0 + 0.1 / sqrt(3);
1152 const auto dir3 = Eigen::Vector3d::Ones().normalized();
1164 const auto dir2 = 1 / sqrt(2);
1166 CHECK_INTERSECTS_ONCE(mesh, ( 0, 0, 0), ( dir2, dir2, 0), ( s, s, 0), 1e-4)
1167 CHECK_INTERSECTS_ONCE(mesh, ( 0, 0, 0), (-dir2, -dir2, 0), (-s, -s, 0), 1e-4)
1168 CHECK_INTERSECTS_ONCE(mesh, ( 0.5, 0.5, 0), ( dir2, dir2, 0), ( s, s, 0), 1e-4)
1169 CHECK_INTERSECTS_ONCE(mesh, ( 0.5, 0.5, 0), (-dir2, -dir2, 0), (-s, -s, 0), 1e-4)
1170 CHECK_INTERSECTS_ONCE(mesh, (-0.5, -0.5, 0), ( dir2, dir2, 0), ( s, s, 0), 1e-4)
1171 CHECK_INTERSECTS_ONCE(mesh, (-0.5, -0.5, 0), (-dir2, -dir2, 0), (-s, -s, 0), 1e-4)
1173 CHECK_INTERSECTS_ONCE(mesh, ( 0, 0, 0), ( 0, dir2, dir2), ( 0, s, s), 1e-4)
1174 CHECK_INTERSECTS_ONCE(mesh, ( 0, 0, 0), ( 0, -dir2, -dir2), ( 0, -s, -s), 1e-4)
1175 CHECK_INTERSECTS_ONCE(mesh, ( 0, 0.5, 0.5), ( 0, dir2, dir2), ( 0, s, s), 1e-4)
1176 CHECK_INTERSECTS_ONCE(mesh, ( 0, 0.5, 0.5), ( 0, -dir2, -dir2), ( 0, -s, -s), 1e-4)
1177 CHECK_INTERSECTS_ONCE(mesh, ( 0, -0.5, -0.5), ( 0, dir2, dir2), ( 0, s, s), 1e-4)
1178 CHECK_INTERSECTS_ONCE(mesh, ( 0, -0.5, -0.5), ( 0, -dir2, -dir2), ( 0, -s, -s), 1e-4)
1180 CHECK_INTERSECTS_ONCE(mesh, ( 0, 0, 0), ( dir2, 0, dir2), ( s, 0, s), 1e-4)
1181 CHECK_INTERSECTS_ONCE(mesh, ( 0, 0, 0), (-dir2, 0, -dir2), (-s, 0, -s), 1e-4)
1182 CHECK_INTERSECTS_ONCE(mesh, ( 0.5, 0, 0.5), ( dir2, 0, dir2), ( s, 0, s), 1e-4)
1183 CHECK_INTERSECTS_ONCE(mesh, ( 0.5, 0, 0.5), (-dir2, 0, -dir2), (-s, 0, -s), 1e-4)
1184 CHECK_INTERSECTS_ONCE(mesh, (-0.5, 0, -0.5), ( dir2, 0, dir2), ( s, 0, s), 1e-4)
1185 CHECK_INTERSECTS_ONCE(mesh, (-0.5, 0, -0.5), (-dir2, 0, -dir2), (-s, 0, -s), 1e-4)
1190 for (
size_t i = 0; i < 1000; ++i)
1198 Eigen::Vector3d sizes = { box.
size[0], box.
size[1], box.
size[2] };
1200 sizes += 2 * mesh.
getPadding() / sqrt(3) * Eigen::Vector3d::Ones();
1203 const auto minRadius = sizes.minCoeff() / 2;
1204 const auto maxRadius = (sizes / 2).norm();
1206 const Eigen::Vector3d meshCenter = mesh.
getPose().translation();
1208 Eigen::Vector3d origin;
1211 const Eigen::Vector3d dir = Eigen::Vector3d::Random().normalized();
1217 if (intersections.size() == 1)
1220 EXPECT_GE(maxRadius, (meshCenter - intersections[0]).norm());
1221 EXPECT_LE(minRadius, (meshCenter - intersections[0]).norm());
1223 EXPECT_NEAR(0.0, (Eigen::ParametrizedLine<double, 3>(origin, dir).distance(intersections[0])), 1e-6);
1224 EXPECT_LT(0.0, (intersections[0] - origin).normalized().dot(dir));
1229 GTEST_NONFATAL_FAILURE_((
"No intersection in iteration " + std::to_string(i)).c_str());
1234 TEST(ConvexMeshRayIntersection, OriginOutsideIntersects)
1242 CHECK_INTERSECTS_TWICE(mesh, (-2, 0, 0), ( 1, 0, 0), ( 1, 0, 0), (-1, 0, 0), 1e-6)
1243 CHECK_INTERSECTS_TWICE(mesh, ( 2, 0, 0), (-1, 0, 0), (-1, 0, 0), ( 1, 0, 0), 1e-6)
1244 CHECK_INTERSECTS_TWICE(mesh, (0, -2, 0), ( 0, 1, 0), ( 0, 1, 0), ( 0, -1, 0), 1e-6)
1245 CHECK_INTERSECTS_TWICE(mesh, (0, 2, 0), ( 0, -1, 0), ( 0, -1, 0), ( 0, 1, 0), 1e-6)
1246 CHECK_INTERSECTS_TWICE(mesh, (0, 0, -2), ( 0, 0, 1), ( 0, 0, 1), ( 0, 0, -1), 1e-6)
1247 CHECK_INTERSECTS_TWICE(mesh, (0, 0, 2), ( 0, 0, -1), ( 0, 0, -1), ( 0, 0, 1), 1e-6)
1252 CHECK_INTERSECTS_TWICE(mesh, (-1, -2, 0), ( 0, 1, 0), (-1, -1, 0), (-1, 1, 0), 1e-6)
1253 CHECK_INTERSECTS_TWICE(mesh, (-1, 2, 0), ( 0, -1, 0), (-1, 1, 0), (-1, -1, 0), 1e-6)
1254 CHECK_INTERSECTS_TWICE(mesh, ( 1, -2, 0), ( 0, 1, 0), ( 1, -1, 0), ( 1, 1, 0), 1e-6)
1255 CHECK_INTERSECTS_TWICE(mesh, ( 1, 2, 0), ( 0, -1, 0), ( 1, 1, 0), ( 1, -1, 0), 1e-6)
1256 CHECK_INTERSECTS_TWICE(mesh, ( 0, -1, -2), ( 0, 0, 1), ( 0, -1, -1), ( 0, -1, 1), 1e-6)
1257 CHECK_INTERSECTS_TWICE(mesh, ( 0, -1, 2), ( 0, 0, -1), ( 0, -1, 1), ( 0, -1, -1), 1e-6)
1258 CHECK_INTERSECTS_TWICE(mesh, ( 0, 1, -2), ( 0, 0, 1), ( 0, 1, -1), ( 0, 1, 1), 1e-6)
1259 CHECK_INTERSECTS_TWICE(mesh, ( 0, 1, 2), ( 0, 0, -1), ( 0, 1, 1), ( 0, 1, -1), 1e-6)
1260 CHECK_INTERSECTS_TWICE(mesh, (-2, 0, -1), ( 1, 0, 0), (-1, 0, -1), ( 1, 0, -1), 1e-6)
1261 CHECK_INTERSECTS_TWICE(mesh, ( 2, 0, -1), (-1, 0, 0), ( 1, 0, -1), (-1, 0, -1), 1e-6)
1262 CHECK_INTERSECTS_TWICE(mesh, (-2, 0, 1), ( 1, 0, 0), (-1, 0, 1), ( 1, 0, 1), 1e-6)
1263 CHECK_INTERSECTS_TWICE(mesh, ( 2, 0, 1), (-1, 0, 0), ( 1, 0, 1), (-1, 0, 1), 1e-6)
1284 for (
size_t i = 0; i < 1000; ++i)
1292 const Eigen::Vector3d dir = Eigen::Vector3d::Random().normalized();
1295 Eigen::Vector3d sizes = { box.
size[0], box.
size[1], box.
size[2] };
1297 sizes += 2 * mesh.
getPadding() / sqrt(3) * Eigen::Vector3d::Ones();
1300 const auto minRadius = sizes.minCoeff() / 2;
1301 const auto maxRadius = (sizes / 2).norm();
1303 const Eigen::Vector3d meshCenter = mesh.
getPose().translation();
1306 const Eigen::Vector3d origin = meshCenter + -dir * 1.5 * maxRadius;
1313 if (intersections.size() == 2)
1316 EXPECT_GE(maxRadius, (meshCenter - intersections[0]).norm());
1317 EXPECT_LE(minRadius, (meshCenter - intersections[0]).norm());
1318 EXPECT_GE(maxRadius, (meshCenter - intersections[1]).norm());
1319 EXPECT_LE(minRadius, (meshCenter - intersections[1]).norm());
1322 EXPECT_NEAR(0.0, (Eigen::ParametrizedLine<double, 3>(origin, dir).distance(intersections[0])), 1e-6);
1323 EXPECT_LT(0.0, (intersections[0] - origin).normalized().dot(dir));
1324 EXPECT_NEAR(0.0, (Eigen::ParametrizedLine<double, 3>(origin, dir).distance(intersections[1])), 1e-6);
1325 EXPECT_LT(0.0, (intersections[1] - origin).normalized().dot(dir));
1330 GTEST_NONFATAL_FAILURE_((
"No intersection in iteration " + std::to_string(i)).c_str());
1339 Eigen::Vector3d perpDir = dir.cross(Eigen::Vector3d({ dir.z(), dir.z(), -dir.x() - dir.y() }));
1340 if (perpDir.norm() < 1e-6)
1341 perpDir = dir.cross(Eigen::Vector3d({ -dir.y() - dir.z(), dir.x(), dir.x() }));
1342 perpDir.normalize();
1345 const Eigen::Vector3d origin2 = origin + g.
uniformReal(1e-6, minRadius - 1e-4) * perpDir;
1347 intersections.clear();
1351 if (intersections.size() == 2)
1354 EXPECT_GE(maxRadius, (meshCenter - intersections[0]).norm());
1355 EXPECT_LE(minRadius, (meshCenter - intersections[0]).norm());
1356 EXPECT_GE(maxRadius, (meshCenter - intersections[1]).norm());
1357 EXPECT_LE(minRadius, (meshCenter - intersections[1]).norm());
1360 EXPECT_NEAR(0.0, (Eigen::ParametrizedLine<double, 3>(origin2, dir).distance(intersections[0])), 1e-6);
1361 EXPECT_LT(0.0, (intersections[0] - origin2).normalized().dot(dir));
1362 EXPECT_NEAR(0.0, (Eigen::ParametrizedLine<double, 3>(origin2, dir).distance(intersections[1])), 1e-6);
1363 EXPECT_LT(0.0, (intersections[1] - origin2).normalized().dot(dir));
1368 GTEST_NONFATAL_FAILURE_((
"No intersection in iteration " + std::to_string(i)).c_str());
1375 testing::InitGoogleTest(&argc, argv);
1376 return RUN_ALL_TESTS();
#define CHECK_INTERSECTS_TWICE(body, origin, direction, intersc1, intersc2, error)
bool intersectsRay(const Eigen::Vector3d &origin, const Eigen::Vector3d &dir, EigenSTL::vector_Vector3d *intersections=nullptr, unsigned int count=0) const override
Check if a ray intersects the body, and find the set of intersections, in order, along the ray...
virtual bool samplePointInside(random_numbers::RandomNumberGenerator &rng, unsigned int max_attempts, Eigen::Vector3d &result) const
Sample a point that is included in the body using a given random number generator.
void setPose(const Eigen::Isometry3d &pose)
Set the pose of the body. Default is identity.
Definition of a cylinder Length is along z axis. Origin is at center of mass.
std::vector< Eigen::Vector3d, Eigen::aligned_allocator< Eigen::Vector3d > > vector_Vector3d
bool intersectsRay(const Eigen::Vector3d &origin, const Eigen::Vector3d &dir, EigenSTL::vector_Vector3d *intersections=nullptr, unsigned int count=0) const override
Check if a ray intersects the body, and find the set of intersections, in order, along the ray...
Definition of a cylinder.
void quaternion(double value[4])
double size[3]
x, y, z dimensions of the box (axis-aligned)
Eigen::Isometry3d getRandomPose(random_numbers::RandomNumberGenerator &g)
int main(int argc, char **argv)
bool samplePointInside(random_numbers::RandomNumberGenerator &rng, unsigned int max_attempts, Eigen::Vector3d &result) const override
Sample a point that is included in the body using a given random number generator.
void setScale(double scale)
If the dimension of the body should be scaled, this method sets the scale. Default is 1...
#define EXPECT_NEAR(a, b, prec)
bool samplePointInside(random_numbers::RandomNumberGenerator &rng, unsigned int max_attempts, Eigen::Vector3d &result) const override
Sample a point that is included in the body using a given random number generator.
Definition of a sphere that bounds another object.
Definition of a convex mesh. Convex hull is computed for a given shape::Mesh.
Definition of a cylinder.
void computeBoundingCylinder(BoundingCylinder &cylinder) const override
Compute the bounding cylinder for the body, in its current pose. Scaling and padding are accounted fo...
double uniformReal(double lower_bound, double upper_bound)
void computeBoundingSphere(BoundingSphere &sphere) const override
Compute the bounding radius for the body, in its current pose. Scaling and padding are accounted for...
bool intersectsRay(const Eigen::Vector3d &origin, const Eigen::Vector3d &dir, EigenSTL::vector_Vector3d *intersections=nullptr, unsigned int count=0) const override
Check if a ray intersects the body, and find the set of intersections, in order, along the ray...
void computeBoundingSphere(BoundingSphere &sphere) const override
Compute the bounding radius for the body, in its current pose. Scaling and padding are accounted for...
double getScale() const
Retrieve the current scale.
double getPadding() const
Retrieve the current padding.
Definition of a triangle mesh By convention the "center" of the shape is at the origin. For a mesh this implies that the AABB of the mesh is centered at the origin. Some methods may not work with arbitrary meshes whose AABB is not centered at the origin. Padding is not applied to vertices plainly coordinate-wise, but instead the padding value is added to the length of the direction vector between centroid and each vertex.
#define CHECK_NO_INTERSECTION(body, origin, direction)
Definition of a box Aligned with the XYZ axes.
#define CHECK_INTERSECTS_ONCE(body, origin, direction, intersection, error)
bool samplePointInside(random_numbers::RandomNumberGenerator &rng, unsigned int max_attempts, Eigen::Vector3d &result) const override
Sample a point that is included in the body using a given random number generator.
const Eigen::Isometry3d & getPose() const
Retrieve the pose of the body.
#define CHECK_INTERSECTS(body, origin, direction, numIntersections)
bool intersectsRay(const Eigen::Vector3d &origin, const Eigen::Vector3d &dir, EigenSTL::vector_Vector3d *intersections=nullptr, unsigned int count=0) const override
Check if a ray intersects the body, and find the set of intersections, in order, along the ray...
Mesh * createMeshFromShape(const Shape *shape)
Construct a mesh from a primitive shape that is NOT already a mesh. This call allocates a new object...
TEST(SphereRayIntersection, OriginInside)
void setPadding(double padd)
If constant padding should be added to the body, this method sets the padding. Default is 0...
std::vector< double > getDimensions() const override
Get the length & width & height (x, y, z) of the box.