LineClosestPoint_test.cc
Go to the documentation of this file.
1 /**
2  * @file LineClosestPoint_test.cc
3  * @brief Test of `LineClosestPoint.h` utilities.
4  * @author Gianluca Petrillo (petrillo@slac.stanford.edu)
5  * @date June 29, 2021
6  * @see `larcorealg/Geometry/LineClosestPoint.h`
7  */
8 
9 
10 // Boost libraries
11 #define BOOST_TEST_MODULE LineClosestPoint_test
12 #include <cetlib/quiet_unit_test.hpp> // BOOST_AUTO_TEST_CASE(), BOOST_TEST()
13 #include <boost/test/test_tools.hpp> // BOOST_CHECK(), BOOST_CHECK_CLOSE()
14 
15 // LArSoft libraries
18 
19 // C++ standard library
20 #include <utility> // std::pair<>
21 #include <type_traits> // std::is_same_v<>
22 #include <cmath> // std::sqrt()
23 
24 
25 // =============================================================================
27 
28  auto const tol = boost::test_tools::tolerance(0.001);
29 
31  geo::origin() - geo::Zaxis() - 3.0 * geo::Xaxis(), geo::Xaxis(),
32  geo::origin() + geo::Zaxis() + 2.0 * geo::Yaxis(), geo::Yaxis()
33  );
34 
35  BOOST_TEST(p.X() == 0.0, tol);
36  BOOST_TEST(p.Y() == 0.0, tol);
37  BOOST_TEST(p.Z() == -1.0, tol);
38 
39 } // LineClosestPointSimple_test()
40 
41 
42 // -----------------------------------------------------------------------------
44 
45  auto const tol = boost::test_tools::tolerance(0.001);
46 
49  geo::origin() + geo::Yaxis(), (geo::Xaxis() + geo::Zaxis()) / std::sqrt(2.0)
50  );
51 
52  BOOST_TEST(p.X() == 0.0, tol);
53  BOOST_TEST(p.Y() == 0.0, tol);
54  BOOST_TEST(p.Z() == 0.0, tol);
55 
56 } // LineClosestPointSimple45_test()
57 
58 
59 // -----------------------------------------------------------------------------
61 
62  auto const tol = boost::test_tools::tolerance(0.001);
63 
64  auto const [ p, ofsA, ofsB ] = geo::LineClosestPointAndOffsets(
65  geo::origin() - 3.0 * geo::Xaxis(), geo::Xaxis(),
66  geo::origin() + geo::Zaxis() + 2.0 * geo::Yaxis(), geo::Yaxis()
67  );
68 
69  BOOST_TEST(p.X() == 0.0, tol);
70  BOOST_TEST(p.Y() == 0.0, tol);
71  BOOST_TEST(p.Z() == 0.0, tol);
72  BOOST_TEST(ofsA == +3.0, tol);
73  BOOST_TEST(ofsB == -2.0, tol);
74 
75 } // LineClosestPointAndOffsets_test()
76 
77 
78 // -----------------------------------------------------------------------------
80 
81  auto const tol = boost::test_tools::tolerance(0.001);
82 
83  auto const [ p, ofsA, ofsB ] = geo::LineClosestPointAndOffsets(
84  geo::origin() - 3.0 * geo::Xaxis(), 2.0 * geo::Xaxis(),
85  geo::origin() + geo::Zaxis() + 2.0 * geo::Yaxis(), -2.0 * geo::Yaxis()
86  );
87 
88  BOOST_TEST(p.X() == 0.0, tol);
89  BOOST_TEST(p.Y() == 0.0, tol);
90  BOOST_TEST(p.Z() == 0.0, tol);
91  BOOST_TEST(ofsA == (+3.0 / 2.0), tol);
92  BOOST_TEST(ofsB == (-2.0 / -2.0), tol);
93 
94 } // LineClosestPointWithScaledDirs_test()
95 
96 
97 // -----------------------------------------------------------------------------
99 
100  auto const tol = boost::test_tools::tolerance(0.001);
101 
102  auto const [ p, ofsA, ofsB ] = geo::LineClosestPointAndOffsets(
103  geo::origin() - 3.0 * geo::Xaxis(), 1.5 * geo::Xaxis(),
104  geo::origin() + geo::Zaxis() + 2.0 * geo::Yaxis(), -2.0 * geo::Yaxis()
105  );
106 
107  BOOST_TEST(p.X() == 0.0, tol);
108  BOOST_TEST(p.Y() == 0.0, tol);
109  BOOST_TEST(p.Z() == 0.0, tol);
110  BOOST_TEST(ofsA == (+3.0 / 1.5), tol);
111  BOOST_TEST(ofsB == (-2.0 / -2.0), tol);
112 
113 } // LineClosestPointWithNonHomogeneousDirs_test()
114 
115 
116 // -----------------------------------------------------------------------------
118 
119  auto const tol = boost::test_tools::tolerance(0.001);
120 
121  /*
122  * The promise:
123  *
124  * --- 8< --------------------------------------------------------------------
125  * The return value is a triplet, which is most easily unpacked immediately:
126  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
127  * auto [ point, offsetA, offsetB ] = geo::LineClosestPointAndOffsets(
128  * geo::Point_t{ 2, 0, 1 }, geo::Vector_t{ 0.0, 0.5, 0.0 },
129  * geo::Point_t{ 0, 1, 0 }, geo::Vector_t{ 0.866, 0.0, 0.0 }
130  * );
131  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
132  * will set `point` to `geo::Point{ 2, 1, 1 }`, `offsetA` to `2` and `offsetB`
133  * to `2.309...`.
134  * To reassign the variables after they have been defined, instead:
135  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
136  * auto const xsectAndOfs = geo::LineClosestPointAndOffsets(
137  * geo::Point_t{ 0, 1, 0 }, geo::Vector_t{ 0.866, 0.0, 0.0 },
138  * geo::Point_t{ 2, 0, 1 }, geo::Vector_t{ 0.0, 0.5, 0.0 }
139  * );
140  * point = xsectAndOfs.point;
141  * offsetA = xsectAndOfs.offset1;
142  * offsetB = xsectAndOfs.offset2;
143  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
144  * (`point` to `geo::Point{ 2, 1, 0 }`, `offsetA` to `2.039...` and `offsetB`
145  * to `2`, because the intersection point is always on the first line).
146  * --- 8< --------------------------------------------------------------------
147  */
148 
149  auto [ point, offsetA, offsetB ] = geo::LineClosestPointAndOffsets(
150  geo::Point_t{ 2, 0, 1 }, geo::Vector_t{ 0.0, 0.5, 0.0 },
151  geo::Point_t{ 0, 1, 0 }, geo::Vector_t{ 0.866, 0.0, 0.0 }
152  );
153 
154  // a way to check we did not mess with the assignment above too much
155  static_assert
156  (std::is_same_v<decltype(point), geo::Point_t>, "Unexpected point type");
157  static_assert
158  (std::is_same_v<decltype(offsetA), double>, "Unexpected first offset type");
159  static_assert
160  (std::is_same_v<decltype(offsetB), double>, "Unexpected second offset type");
161 
162  BOOST_TEST(point.X() == 2.0, tol);
163  BOOST_TEST(point.Y() == 1.0, tol);
164  BOOST_TEST(point.Z() == 1.0, tol);
165  BOOST_TEST(offsetA == 2.0, tol);
166  BOOST_TEST(offsetB == (2.0/0.866), tol);
167 
168  auto const xsectAndOfs = geo::LineClosestPointAndOffsets(
169  geo::Point_t{ 0, 1, 0 }, geo::Vector_t{ 0.866, 0.0, 0.0 },
170  geo::Point_t{ 2, 0, 1 }, geo::Vector_t{ 0.0, 0.5, 0.0 }
171  );
172  point = xsectAndOfs.point;
173  offsetA = xsectAndOfs.offset1;
174  offsetB = xsectAndOfs.offset2;
175 
176  BOOST_TEST(point.X() == 2.0, tol);
177  BOOST_TEST(point.Y() == 1.0, tol);
178  BOOST_TEST(point.Z() == 0.0, tol);
179  BOOST_TEST(offsetA == 2.0/0.866, tol);
180  BOOST_TEST(offsetB == 2.0, tol);
181 
182  // actually we _can_ assign with `std::tie()`:
183  std::tie(point, offsetA, offsetB) = geo::LineClosestPointAndOffsets(
184  geo::Point_t{ 2, 0, 1 }, geo::Vector_t{ 0.0, 0.5, 0.0 },
185  geo::Point_t{ 0, 1, 0 }, geo::Vector_t{ 0.866, 0.0, 0.0 }
186  );
187 
188  BOOST_TEST(point.X() == 2.0, tol);
189  BOOST_TEST(point.Y() == 1.0, tol);
190  BOOST_TEST(point.Z() == 1.0, tol);
191  BOOST_TEST(offsetA == 2.0, tol);
192  BOOST_TEST(offsetB == (2.0/0.866), tol);
193 
194 } // LineClosestPointAndOffsetsDocumentation_test()
195 
196 
197 // =============================================================================
199 
200  auto const tol = boost::test_tools::tolerance(0.001);
201 
203  geo::origin() - geo::Zaxis() - 3.0 * geo::Xaxis(), geo::Xaxis(),
204  geo::origin() + geo::Zaxis() + 2.0 * geo::Yaxis(), geo::Yaxis()
205  );
206 
207  BOOST_TEST(p.X() == 0.0, tol);
208  BOOST_TEST(p.Y() == 0.0, tol);
209  BOOST_TEST(p.Z() == -1.0, tol);
210 
211 } // LineClosestPointWithUnitVectorsSimple_test()
212 
213 
214 // -----------------------------------------------------------------------------
216 
217  auto const tol = boost::test_tools::tolerance(0.001);
218 
220  geo::origin(), geo::Xaxis(),
221  geo::origin() + geo::Yaxis(), (geo::Xaxis() + geo::Zaxis()) / std::sqrt(2.0)
222  );
223 
224  BOOST_TEST(p.X() == 0.0, tol);
225  BOOST_TEST(p.Y() == 0.0, tol);
226  BOOST_TEST(p.Z() == 0.0, tol);
227 
228 } // LineClosestPointWithUnitVectorsSimple45_test()
229 
230 
231 // -----------------------------------------------------------------------------
233 
234  auto const tol = boost::test_tools::tolerance(0.001);
235 
236  auto const [ p, ofsA, ofsB ] = geo::LineClosestPointAndOffsetsWithUnitVectors(
237  geo::origin() - 3.0 * geo::Xaxis(), geo::Xaxis(),
238  geo::origin() + geo::Zaxis() + 2.0 * geo::Yaxis(), geo::Yaxis()
239  );
240 
241  BOOST_TEST(p.X() == 0.0, tol);
242  BOOST_TEST(p.Y() == 0.0, tol);
243  BOOST_TEST(p.Z() == 0.0, tol);
244  BOOST_TEST(ofsA == +3.0, tol);
245  BOOST_TEST(ofsB == -2.0, tol);
246 
247 } // LineClosestPointWithUnitVectorsAndOffsets_test()
248 
249 
250 // -----------------------------------------------------------------------------
252 
253  auto const tol = boost::test_tools::tolerance(0.001);
254 
255  /*
256  * The promise:
257  *
258  * --- 8< --------------------------------------------------------------------
259  * The return value is a triplet, which is most easily unpacked immediately:
260  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
261  * auto [ point, offsetA, offsetB ] = geo::LineClosestPointAndOffsetsWithUnitVectors(
262  * geo::Point_t{ 2, 0, 1 }, geo::Vector_t{ 0, 1, 0 },
263  * geo::Point_t{ 0, 1, 0 }, geo::Vector_t{ 1, 0, 0 }
264  * );
265  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
266  * will set `point` to `geo::Point{ 2, 1, 1 }`, `offsetA` to `1` and `offsetB`
267  * to `2`.
268  * To reassign the variables after they have been defined, instead:
269  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
270  * auto const xsectAndOfs = geo::LineClosestPointAndOffsetsWithUnitVectors(
271  * geo::Point_t{ 0, 1, 0 }, geo::Vector_t{ 1, 0, 0 },
272  * geo::Point_t{ 2, 0, 1 }, geo::Vector_t{ 0, 1, 0 }
273  * );
274  * point = xsectAndOfs.point;
275  * offsetA = xsectAndOfs.offset1;
276  * offsetB = xsectAndOfs.offset2;
277  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
278  * (`point` to `geo::Point{ 2, 1, 0 }`, `offsetA` to `2` and `offsetB` to `1`,
279  * because the intersection point is always on the first line).
280  * --- 8< --------------------------------------------------------------------
281  */
282 
283  auto [ point, offsetA, offsetB ] = geo::LineClosestPointAndOffsetsWithUnitVectors(
284  geo::Point_t{ 2, 0, 1 }, geo::Vector_t{ 0, 1, 0 },
285  geo::Point_t{ 0, 1, 0 }, geo::Vector_t{ 1, 0, 0 }
286  );
287 
288  // a way to check we did not mess with the assignment above too much
289  static_assert
290  (std::is_same_v<decltype(point), geo::Point_t>, "Unexpected point type");
291  static_assert
292  (std::is_same_v<decltype(offsetA), double>, "Unexpected first offset type");
293  static_assert
294  (std::is_same_v<decltype(offsetB), double>, "Unexpected second offset type");
295 
296  BOOST_TEST(point.X() == 2.0, tol);
297  BOOST_TEST(point.Y() == 1.0, tol);
298  BOOST_TEST(point.Z() == 1.0, tol);
299  BOOST_TEST(offsetA == 1.0, tol);
300  BOOST_TEST(offsetB == 2.0, tol);
301 
302  auto const xsectAndOfs = geo::LineClosestPointAndOffsetsWithUnitVectors(
303  geo::Point_t{ 0, 1, 0 }, geo::Vector_t{ 1, 0, 0 },
304  geo::Point_t{ 2, 0, 1 }, geo::Vector_t{ 0, 1, 0 }
305  );
306  point = xsectAndOfs.point;
307  offsetA = xsectAndOfs.offset1;
308  offsetB = xsectAndOfs.offset2;
309 
310  BOOST_TEST(point.X() == 2.0, tol);
311  BOOST_TEST(point.Y() == 1.0, tol);
312  BOOST_TEST(point.Z() == 0.0, tol);
313  BOOST_TEST(offsetA == 2.0, tol);
314  BOOST_TEST(offsetB == 1.0, tol);
315 
316  // actually we _can_ assign with `std::tie()`:
317  std::tie(point, offsetA, offsetB) = geo::LineClosestPointAndOffsetsWithUnitVectors(
318  geo::Point_t{ 2, 0, 1 }, geo::Vector_t{ 0, 1, 0 },
319  geo::Point_t{ 0, 1, 0 }, geo::Vector_t{ 1, 0, 0 }
320  );
321 
322  BOOST_TEST(point.X() == 2.0, tol);
323  BOOST_TEST(point.Y() == 1.0, tol);
324  BOOST_TEST(point.Z() == 1.0, tol);
325  BOOST_TEST(offsetA == 1.0, tol);
326  BOOST_TEST(offsetB == 2.0, tol);
327 
328 } // LineClosestPointAndOffsetsWithUnitVectorsDocumentation_test()
329 
330 
331 // =============================================================================
332 BOOST_AUTO_TEST_CASE(LineClosestPointTestCase) {
333 
340 
341 } // BOOST_AUTO_TEST_CASE(LineClosestPointTestCase)
342 
343 
344 // -----------------------------------------------------------------------------
345 BOOST_AUTO_TEST_CASE(LineClosestPointWithUnitVectorsTestCase) {
346 
351 
352 } // BOOST_AUTO_TEST_CASE(LineClosestPointWithUnitVectorsTestCase)
353 
354 
355 // -----------------------------------------------------------------------------
void LineClosestPointWithScaledDirs_test()
void LineClosestPointWithUnitVectorsAndOffsets_test()
auto const tol
Definition: SurfXYZTest.cc:16
void LineClosestPointAndOffsetsDocumentation_test()
auto const tolerance
constexpr Vector Yaxis()
Returns a y axis vector of the specified type.
Definition: geo_vectors.h:219
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space.
Definition: geo_vectors.h:164
void LineClosestPointSimple45_test()
IntersectionPointAndOffsets< Point > LineClosestPointAndOffsets(Point const &startA, Vector const &dirA, Point const &startB, Vector const &dirB)
Returns the point of a line that is closest to a second line.
void LineClosestPointWithNonHomogeneousDirs_test()
IntersectionPointAndOffsets< Point > LineClosestPointAndOffsetsWithUnitVectors(Point const &startA, UnitVector const &dirA, Point const &startB, UnitVector const &dirB)
Returns the point of a line that is closest to a second line.
Utility for intersection of two 3D lines.
void LineClosestPointAndOffsetsWithUnitVectorsDocumentation_test()
p
Definition: test.py:223
constexpr Vector Xaxis()
Returns a x axis vector of the specified type.
Definition: geo_vectors.h:215
void LineClosestPointWithUnitVectorsSimple45_test()
Point LineClosestPointWithUnitVectors(Point const &startA, UnitVector const &dirA, Point const &startB, UnitVector const &dirB)
Returns the point of a line that is closest to a second line.
constexpr Vector Zaxis()
Returns a z axis vector of the specified type.
Definition: geo_vectors.h:223
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
Definition: geo_vectors.h:184
void LineClosestPointSimple_test()
void LineClosestPointWithUnitVectorsSimple_test()
Definitions of geometry vector data types.
Point LineClosestPoint(Point const &startA, Vector const &dirA, Point const &startB, Vector const &dirB)
Returns the point of a line that is closest to a second line.
void LineClosestPointAndOffsets_test()
BOOST_AUTO_TEST_CASE(LineClosestPointTestCase)
constexpr Point origin()
Returns a origin position with a point of the specified type.
Definition: geo_vectors.h:227