Skip to content

Commit 8f7d2f7

Browse files
committed
Add IntersectionTools::collinear
1 parent f33c96c commit 8f7d2f7

File tree

3 files changed

+57
-0
lines changed

3 files changed

+57
-0
lines changed

Diff for: include/geom/intersection_tools.h

+13
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,19 @@ WithinSegmentResult within_segment(const Point & s1,
6969
const Point & p,
7070
const Real tol = TOLERANCE);
7171

72+
/**
73+
* Checks whether or not the given points are collinear
74+
* @param p1 The first point
75+
* @param p2 The second point
76+
* @param p3 The third point
77+
* @param tol The tolerance to use
78+
* @return Whether or not the given points are collinear
79+
*/
80+
bool collinear(const Point & p1,
81+
const Point & p2,
82+
const Point & p3,
83+
const Real tol = TOLERANCE);
84+
7285
} // namespace IntersectionTools
7386
} // namespace libMesh
7487

Diff for: src/geom/intersection_tools.C

+14
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "libmesh/intersection_tools.h"
2121

2222
#include "libmesh/point.h"
23+
#include "libmesh/int_range.h"
2324

2425
namespace libMesh::IntersectionTools
2526
{
@@ -62,6 +63,19 @@ WithinSegmentResult within_segment(const Point & s1,
6263
return within_segment(s1, s2, (s1 - s2).norm(), p, tol);
6364
}
6465

66+
bool collinear(const Point & p1,
67+
const Point & p2,
68+
const Point & p3,
69+
const Real tol)
70+
{
71+
// (p1 -> p2) X (p1 - > p3) should be == the zero vector
72+
const auto p1p2_cross_p1p3 = (p2 - p1).cross(p3 - p1);
73+
for (const auto i : make_range(LIBMESH_DIM))
74+
if (std::abs(p1p2_cross_p1p3(i)) > tol)
75+
return false;
76+
return true;
77+
}
78+
6579
} // namespace libMesh::IntersectionTools
6680

6781

Diff for: tests/geom/intersection_tools_test.C

+30
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ class IntersectionToolsTest : public CppUnit::TestCase
1212
public:
1313
LIBMESH_CPPUNIT_TEST_SUITE( IntersectionToolsTest );
1414
CPPUNIT_TEST( within_segment );
15+
CPPUNIT_TEST( collinear );
1516
CPPUNIT_TEST_SUITE_END();
1617

1718
public:
@@ -47,6 +48,35 @@ public:
4748
IntersectionTools::WithinSegmentResult::NOT_WITHIN);
4849
}
4950

51+
void collinear()
52+
{
53+
LOG_UNIT_TEST;
54+
55+
const auto do_assert = [](const Point & p1,
56+
const Point & p2,
57+
const Point & p3,
58+
const bool collinear)
59+
{
60+
CPPUNIT_ASSERT_EQUAL(IntersectionTools::collinear(p1, p2, p3), collinear);
61+
CPPUNIT_ASSERT_EQUAL(IntersectionTools::collinear(p1, p3, p2), collinear);
62+
CPPUNIT_ASSERT_EQUAL(IntersectionTools::collinear(p2, p1, p3), collinear);
63+
CPPUNIT_ASSERT_EQUAL(IntersectionTools::collinear(p2, p3, p1), collinear);
64+
CPPUNIT_ASSERT_EQUAL(IntersectionTools::collinear(p3, p1, p2), collinear);
65+
CPPUNIT_ASSERT_EQUAL(IntersectionTools::collinear(p3, p2, p1), collinear);
66+
};
67+
68+
// two of the same points
69+
do_assert(Point(1, 2, 3), Point(1, 2, 3), Point(4, 5, 6), true);
70+
71+
// three of the same points
72+
do_assert(Point(1, 2, 3), Point(1, 2, 3), Point(1, 2, 3), true);
73+
74+
// all in a line
75+
do_assert(Point(1, 1, 2), Point(1, 1, 3), Point(1, 1, 0), true);
76+
77+
// not collinear
78+
do_assert(Point(0, 1, 2), Point(0, 1, 3), Point(1, 5, 10), false);
79+
}
5080
};
5181

5282
CPPUNIT_TEST_SUITE_REGISTRATION( IntersectionToolsTest );

0 commit comments

Comments
 (0)