All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
LineClosestPoint.h
Go to the documentation of this file.
1 /**
2  * @file larcorealg/Geometry/LineClosestPoint.h
3  * @brief Utility for intersection of two 3D lines.
4  * @author Gianluca Petrillo (petrillo@slac.stanford.edu)
5  * @see larcorealg/Geometry/LineClosestPoint.tcc,
6  * larcorealg/Geometry/WireGeo.h
7  *
8  * This utility is used as implementation of detector wires, but it can stand on
9  * its own.
10  *
11  * This library is header-only and (likely) no additional linkage.
12  */
13 
14 
15 #ifndef LARCOREALG_GEOMETRY_LINECLOSESTPOINT_H
16 #define LARCOREALG_GEOMETRY_LINECLOSESTPOINT_H
17 
18 
19 // C++ standard library
20 #include <utility> // std::pair<>
21 
22 
23 // -----------------------------------------------------------------------------
24 namespace geo {
25 
26 
27  /// Data structure for return values of `LineClosestPointAndOffsets()`.
28  template <typename Point>
30 
31  Point point; ///< Intersection point.
32  double offset1; ///< Distance from reference point of first line.
33  double offset2; ///< Distance from reference point of second line.
34 
35  /// Helper to assign to `std::tie()`.
36  operator std::tuple<Point&, double&, double&>() noexcept
37  { return { point, offset1, offset2 }; }
38 
39  }; // IntersectionPointAndOffsets<>
40 
41 
42 
43  /**
44  * @brief Returns the point of a line that is closest to a second line.
45  * @tparam Point a type describing a point
46  * @tparam Vector a type describing a direction (displacement vector)
47  * @param refA a reference point on the first line
48  * @param dirA the direction of the first line
49  * @param refB a reference point on the second line
50  * @param dirB the direction of the second line
51  * @return a data structure with three fields:
52  * `point`: the point of `A` closest to `B`,
53  * `offset1`: its offset on `A` in units of `dirA`,
54  * `offset2`: its offset on `B` in units of `dirB`
55  * @see `LineClosestPointWithUnitVectors()`
56  * @see `LineClosestPointAndOffsets()`
57  *
58  * The point of line `A` that is closest to line `B` is returned.
59  *
60  * This function is equivalent to `LineClosestPoint()`, but it
61  * returns in addition the offsets of the intersection point from the
62  * reference points of the two lines, in the direction specified by
63  * `dirA`/`dirB`.
64  *
65  * The return value is a data structure of type
66  * `geo::IntersectionPointAndOffsets`, which is most easily unpacked
67  * immediately:
68  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
69  * auto [ point, offsetA, offsetB ] = geo::LineClosestPointAndOffsets(
70  * geo::Point_t{ 2, 0, 1 }, geo::Vector_t{ 0.0, 0.5, 0.0 },
71  * geo::Point_t{ 0, 1, 0 }, geo::Vector_t{ 0.866, 0.0, 0.0 }
72  * );
73  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
74  * will set `point` to `geo::Point{ 2, 1, 1 }`, `offsetA` to `2` and `offsetB`
75  * to `2.309...`.
76  * To reassign the variables after they have been defined, though, a temporary
77  * structure is needed:
78  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
79  * auto const xsectAndOfs = geo::LineClosestPointAndOffsets(
80  * geo::Point_t{ 0, 1, 0 }, geo::Vector_t{ 0.866, 0.0, 0.0 },
81  * geo::Point_t{ 2, 0, 1 }, geo::Vector_t{ 0.0, 0.5, 0.0 }
82  * );
83  * point = xsectAndOfs.point;
84  * offsetA = xsectAndOfs.offset1;
85  * offsetB = xsectAndOfs.offset2;
86  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
87  * (`point` to `geo::Point{ 2, 1, 0 }`, `offsetA` to `2.039...` and `offsetB`
88  * to `2`, because the intersection point is always on the first line).
89  *
90  */
91  template <typename Point, typename Vector>
92  IntersectionPointAndOffsets<Point> LineClosestPointAndOffsets(
93  Point const& startA, Vector const& dirA,
94  Point const& startB, Vector const& dirB
95  );
96 
97 
98  /**
99  * @brief Returns the point of a line that is closest to a second line.
100  * @tparam Point a type describing a point
101  * @tparam Vector a type describing a direction (displacement vector)
102  * @param refA a reference point on the first line
103  * @param dirA the direction of the first line
104  * @param refB a reference point on the second line
105  * @param dirB the direction of the second line
106  * @return the point of `A` closest to `B`
107  * @see LineClosestPointAndOffsets(), LineClosestPointWithUnitVectors()
108  *
109  * The point of line `A` that is closest to line `B` is returned.
110  *
111  * The two lines are _assumed_ not to be parallel, and when this prerequisite
112  * is not met the behaviour is undefined.
113  *
114  * @note This formulation is valid for lines in a Euclidean space of any
115  * dimension; the minimized distance is the Euclidean one.
116  *
117  * A separate function, `LineClosestPointAndOffsets()`,
118  * also returns the offset of the intersection from the two reference points.
119  *
120  *
121  * Requirements
122  * -------------
123  *
124  * The following operations between points, vectors and scalars must be
125  * defined:
126  *
127  * * `Vector operator- (Point, Point)`: the difference of two points always
128  * exists and it returns a `Vector`;
129  * * `Point operator+ (Point, Vector)`: translation of a point by a
130  * displacement vector;
131  * * `Vector operator* (Vector, double)`: vector scaling by a real factor;
132  * * `double dot(Vector, Vector)`: scalar (inner) product of two vectors.
133  *
134  */
135  template <typename Point, typename Vector>
137  Point const& startA, Vector const& dirA,
138  Point const& startB, Vector const& dirB
139  );
140 
141 
142  /**
143  * @brief Returns the point of a line that is closest to a second line.
144  * @tparam Point a type describing a point
145  * @tparam UnitVector a type describing a direction (unit vector)
146  * @param refA a reference point on the first line
147  * @param dirA the direction of the first line (unity-normed)
148  * @param refB a reference point on the second line
149  * @param dirB the direction of the second line (unity-normed)
150  * @return a data structure with three fields:
151  * `point`: the point of `A` closest to `B`,
152  * `offset1`: its offset on `A` in units of `dirA` (i.e. unity),
153  * `offset2`: its offset on `B` in units of `dirB` (i.e. unity)
154  * @see `LineClosestPointWithUnitVectors()`
155  * @see `LineClosestPointAndOffsets()`
156  *
157  * The point of line `A` that is closest to line `B` is returned.
158  *
159  * The return value is a data structure of type
160  * `geo::IntersectionPointAndOffsets`, which is most easily unpacked
161  * immediately:
162  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
163  * auto [ point, offsetA, offsetB ] = geo::LineClosestPointAndOffsetsWithUnitVectors(
164  * geo::Point_t{ 2, 0, 1 }, geo::Vector_t{ 0, 1, 0 },
165  * geo::Point_t{ 0, 1, 0 }, geo::Vector_t{ 1, 0, 0 }
166  * );
167  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
168  * will set `point` to `geo::Point{ 2, 1, 1 }`, `offsetA` to `1` and `offsetB`
169  * to `2`.
170  * To reassign the variables after they have been defined, instead:
171  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
172  * auto const xsectAndOfs = geo::LineClosestPointAndOffsetsWithUnitVectors(
173  * geo::Point_t{ 0, 1, 0 }, geo::Vector_t{ 1, 0, 0 },
174  * geo::Point_t{ 2, 0, 1 }, geo::Vector_t{ 0, 1, 0 }
175  * );
176  * point = xsectAndOfs.point;
177  * offsetA = xsectAndOfs.offset1;
178  * offsetB = xsectAndOfs.offset2;
179  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
180  * (`point` to `geo::Point{ 2, 1, 0 }`, `offsetA` to `2` and `offsetB` to `1`,
181  * because the intersection point is always on the first line).
182  *
183  */
184  template <typename Point, typename UnitVector>
185  IntersectionPointAndOffsets<Point> LineClosestPointAndOffsetsWithUnitVectors(
186  Point const& startA, UnitVector const& dirA,
187  Point const& startB, UnitVector const& dirB
188  );
189 
190 
191  /**
192  * @brief Returns the point of a line that is closest to a second line.
193  * @tparam Point a type describing a point
194  * @tparam UnitVector a type describing a direction (unit vector)
195  * @param refA a reference point on the first line
196  * @param dirA the direction of the first line (unity-normed)
197  * @param refB a reference point on the second line
198  * @param dirB the direction of the second line (unity-normed)
199  * @return the point of `A` closest to `B`
200  * @see LineClosestPointAndOffsetsWithUnitVectors(), LineClosestPoint()
201  *
202  * The point of line `A` that is closest to line `B` is returned.
203  *
204  * The two lines are _assumed_ not to be parallel, and when this prerequisite
205  * is not met the behaviour is undefined.
206  *
207  * The two directions are _required_ to have norm `1`. While formally if this
208  * prerequisite is not met the result is undefined, the result will be still
209  * mostly correct if their norm departs from unity only by a rounding error.
210  * The more the vectors deviate from that condition, the larger the error
211  * in the result.
212  *
213  * @note This formulation is valid for lines in a Euclidean space of any
214  * dimension; the minimized distance is the Euclidean one.
215  *
216  * A separate function, `LineClosestPointAndOffsetsWithUnitVectors()`,
217  * also returne the offset of the intersection from the two reference points.
218  *
219  *
220  * Requirements
221  * -------------
222  *
223  * The following operations between points, vectors and scalars must be
224  * defined:
225  *
226  * * `Vector operator* (UnitVector, double)`: scaling of a unit vector by a
227  * real factor to produce a non-unit vector;
228  * * `Vector operator- (Point, Point)`: the difference of two points always
229  * exists and it returns a `Vector`;
230  * * `Point operator+ (Point, Vector)`: translation of a point by a
231  * displacement vector;
232  * * `double dot(Vector, UnitVector)`, `double dot(UnitVector, UnitVector)`:
233  * scalar (inner) product of one unit vector and a vector, or two unit
234  * vectors.
235  *
236  */
237  template <typename Point, typename UnitVector>
239  Point const& startA, UnitVector const& dirA,
240  Point const& startB, UnitVector const& dirB
241  );
242 
243 
244 } // namespace geo
245 
246 
247 // -----------------------------------------------------------------------------
248 // --- template implementation
249 // -----------------------------------------------------------------------------
250 #include "larcorealg/Geometry/LineClosestPoint.tcc"
251 
252 // -----------------------------------------------------------------------------
253 
254 
255 #endif // LARCOREALG_GEOMETRY_LINECLOSESTPOINT_H
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.
double offset2
Distance from reference point of second line.
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.
std::tuple< double, double, const reco::ClusterHit3D * > Point
Definitions used by the VoronoiDiagram algorithm.
Definition: DCEL.h:44
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.
Point point
Intersection point.
Data structure for return values of LineClosestPointAndOffsets().
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.
double offset1
Distance from reference point of first line.