Library of Assembled Shared Sources
line_2d.inl
Go to the documentation of this file.
1/** @file
2 * @author Bram de Greve (bram@cocamware.com)
3 * @author Tom De Muer (tom@cocamware.com)
4 *
5 * *** BEGIN LICENSE INFORMATION ***
6 *
7 * The contents of this file are subject to the Common Public Attribution License
8 * Version 1.0 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://lass.sourceforge.net/cpal-license. The License is based on the
11 * Mozilla Public License Version 1.1 but Sections 14 and 15 have been added to cover
12 * use of software over a computer network and provide for limited attribution for
13 * the Original Developer. In addition, Exhibit A has been modified to be consistent
14 * with Exhibit B.
15 *
16 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
17 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
18 * language governing rights and limitations under the License.
19 *
20 * The Original Code is LASS - Library of Assembled Shared Sources.
21 *
22 * The Initial Developer of the Original Code is Bram de Greve and Tom De Muer.
23 * The Original Developer is the Initial Developer.
24 *
25 * All portions of the code written by the Initial Developer are:
26 * Copyright (C) 2004-2011 the Initial Developer.
27 * All Rights Reserved.
28 *
29 * Contributor(s):
30 *
31 * Alternatively, the contents of this file may be used under the terms of the
32 * GNU General Public License Version 2 or later (the GPL), in which case the
33 * provisions of GPL are applicable instead of those above. If you wish to allow use
34 * of your version of this file only under the terms of the GPL and not to allow
35 * others to use your version of this file under the CPAL, indicate your decision by
36 * deleting the provisions above and replace them with the notice and other
37 * provisions required by the GPL License. If you do not delete the provisions above,
38 * a recipient may use your version of this file under either the CPAL or the GPL.
39 *
40 * *** END LICENSE INFORMATION ***
41 */
42
43
44
45#ifndef LASS_GUARDIAN_OF_INCLUSION_PRIM_LINE_2D_INL
46#define LASS_GUARDIAN_OF_INCLUSION_PRIM_LINE_2D_INL
47
48
49
50
51#include "line_2d.h"
52
53
54
55namespace lass
56{
57
58namespace prim
59{
60
61template<typename T, typename EP, typename NP>
62Line2D<T, EP, NP>::Line2D():
63 TImpl()
64{
65}
66
67
68
69
70template<typename T, typename EP, typename NP>
71Line2D<T, EP, NP>::Line2D(const TPoint& iSupport, const TPoint& iPoint):
72 TImpl(iSupport, iPoint)
73{
74}
75
76
77
78template<typename T, typename EP, typename NP>
79Line2D<T, EP, NP>::Line2D(const TPoint& iSupport, const TVector& iDirection):
80 TImpl(iSupport, iDirection)
81{
82}
83
84
85
86template<typename T, typename EP, typename NP>
87Line2D<T, EP, NP>::Line2D(const TVector& iNormal, const TPoint& iSupport):
88 TImpl(iNormal, iSupport)
89{
90}
91
92
93
94template<typename T, typename EP, typename NP>
95Line2D<T, EP, NP>::Line2D(const TVector& iNormal, TParam iD):
96 TImpl(iNormal, iD)
97{
98}
99
100
101
102/** Return on what side a point is located.
103 */
104template<typename T, typename EP, typename NP>
105Side Line2D<T, EP, NP>::classify(const TPoint& iPoint) const
106{
107 const TValue eq = this->equation(iPoint);
108 return eq > TNumTraits::zero ? sFront : (eq < TNumTraits::zero ? sBack : sSurface);
109}
110
111
112
113/** Return signed distance of point to line.
114 * negative value means point is in the back.
115 */
116template<typename T, typename EP, typename NP>
117const typename Line2D<T, EP, NP>::TValue
118Line2D<T, EP, NP>::signedDistance(const TPoint& iPoint) const
119{
120 return NP::divideByNorm(this->equation(iPoint), this->normal());
121}
122
123
124
125/** Return signed distance of point to line.
126 * negative value means point is in the back.
127 */
128template<typename T, typename EP, typename NP>
129const typename Line2D<T, EP, NP>::TValue
130Line2D<T, EP, NP>::squaredDistance(const TPoint& iPoint) const
131{
132 return num::sqr(this->signedDistance(iPoint));
133}
134
135
136
137/** Return on what side a point is located.
138 */
139template<typename T, typename EP, typename NP>
140Side Line2D<T, EP, NP>::classify(const TPoint& iPoint, TParam iRelativeTolerance) const
141{
142 const TValue eq = this->equation(iPoint, iRelativeTolerance);
143 return eq > TNumTraits::zero ? sFront : (eq < TNumTraits::zero ? sBack : sSurface);
144}
145
146
147
148/** Return signed distance of point to line.
149 * negative value means point is in the back.
150 */
151template<typename T, typename EP, typename NP>
152const typename Line2D<T, EP, NP>::TValue
153Line2D<T, EP, NP>::signedDistance(const TPoint& iPoint, TParam iRelativeTolerance) const
154{
155 return NP::divideByNorm(this->equation(iPoint, iRelativeTolerance), this->normal());
156}
157
158
159
160/** Return signed distance of point to line.
161 * negative value means point is in the back.
162 */
163template<typename T, typename EP, typename NP>
164const typename Line2D<T, EP, NP>::TValue
165Line2D<T, EP, NP>::squaredDistance(const TPoint& iPoint, TParam iRelativeTolerance) const
166{
167 return num::sqr(this->signedDistance(iPoint, iRelativeTolerance));
168}
169
170
171
172// --- protected -----------------------------------------------------------------------------------
173
174
175
176// --- private -------------------------------------------------------------------------------------
177
178
179
180// --- free ----------------------------------------------------------------------------------------
181
182/** absolute distance between point and line.
183 * @relates Line2D
184 * @param iA point
185 * @param iB line
186 * @return absolute distance.
187 */
188template <typename T, class EP, class NP>
189T distance(const Point2D<T>& iA, const Line2D<T, EP, NP>& iB)
190{
191 return num::abs(iB.signedDistance(iA));
192}
193
194
195
196/** absolute distance between two lines
197 * @relates Line2D
198 * @param iA line A
199 * @param iB line B
200 * @return absolute distance.
201 */
202template <typename T, class EPa, class NPa, class EPb, class NPb>
203T distance(const Line2D<T, EPa, NPa>& iA, const Line2D<T, EPb, NPb>& iB)
204{
205 LASS_ASSERT(iA.isValid() && iB.isValid());
206
207 typedef typename Line2D<T, EPa, NPa>::TNumTraits TNumTraits;
208
209 if (perpDot(iA.direction(), iB.direction()) == TNumTraits::zero)
210 {
211 return num::abs(iA.signedDistance(iB.support())); // parallel
212 }
213 else
214 {
215 return TNumTraits::zero; // intersecting
216 }
217}
218
219
220
221/** intersection of two lines
222 * @relates Line2D
223 * @param iA line A
224 * @param iB line B
225 * @param oTa parameter of intersection point on line A
226 * @param oTb parameter of intersection point on line B
227 * @return @arg rNone the lines don't intersect, they have no points in common.
228 * @a oTa and @a oTb are not assigned.
229 * @arg rOne both lines have exactly one point in common.
230 * @a oTa and @a oTb contain parameters of intersection point.
231 * @arg rInfinite the lines are coincident, they have all points in common.
232 * @a oTa and @a oTb are not assigned.
233 */
234template <typename T, class EPa, class NPa, class EPb, class NPb>
235Result intersect(const Line2D<T, EPa, NPa>& iA, const Line2D<T, EPb, NPb>& iB,
236 T& oTa, T& oTb)
237{
238 LASS_ASSERT(iA.isValid() && iB.isValid());
239
240 typedef typename Line2D<T, EPa, NPa>::TVector TVector;
241 typedef typename Line2D<T, EPa, NPa>::TValue TValue;
242 typedef typename Line2D<T, EPa, NPa>::TNumTraits TNumTraits;
243
244 const TVector dirA(iA.direction());
245 const TVector dirB(iB.direction());
246
247 const TValue denominator = -perpDot(dirA, dirB);
248 if (denominator == TNumTraits::zero)
249 {
250 switch (iA.classify(iB.support()))
251 {
252 case sFront:
253 case sBack:
254 return rNone; // parallel
255 case sSurface:
256 return rInfinite; // coincident
257 default:
258 return rInvalid;
259 }
260 }
261 else
262 {
263 const TVector difference = iB.support() - iA.support();
264 oTa = -perpDot(difference, dirB) / denominator;
265 oTb = perpDot(dirA, difference) / denominator;
266 return rOne; // intersecting
267 }
268}
269
270
271
272/** intersection of two lines
273 * @relates Line2D
274 * @param iA line A
275 * @param iB line B
276 * @param oPoint intersection point
277 * @return @arg rNone the lines don't intersect, they have no points in common.
278 * @a oPoint is not assigned.
279 * @arg rOne both lines have exactly one point in common.
280 * @a oPoint contains intersection point.
281 * @arg rInfinite the lines are coincident, they have all points in common.
282 * @a oPoint is not assigned.
283 */
284template <typename T, class EPa, class NPa, class EPb, class NPb>
285Result intersect(const Line2D<T, EPa, NPa>& iA, const Line2D<T, EPb, NPb>& iB,
286 Point2D<T>& oPoint)
287{
288 T tA = 0;
289 T tB = 0;
290 Result result = intersect(iA, iB, tA, tB);
291 if (result == rOne)
292 {
293 oPoint = (iA.point(tA) + iB.point(tB)).affine(); // take average for more stable point.
294 }
295 return result;
296}
297
298
299
300/** @relates Line2D
301 */
302template <typename T>
303io::XmlOStream& operator<<(io::XmlOStream& ioOStream, const Line2D<T, Cartesian>& iLine)
304{
305 LASS_ENFORCE_STREAM(ioOStream)
306 << "<Line2D>\n"
307 << "<normal>" << iLine.normal() << "</normal>\n"
308 << "<d>" << iLine.d() << "</d>\n"
309 << "</Line2D>\n";
310
311 return ioOStream;
312}
313
314
315
316/** @relates Line2D
317 */
318template <typename T>
319io::XmlOStream& operator<<(io::XmlOStream& ioOStream, const Line2D<T, Parametric>& iLine)
320{
321 LASS_ENFORCE_STREAM(ioOStream)
322 << "<Line2D>\n"
323 << "<support>" << iLine.support() << "</support>\n"
324 << "<direction>" << iLine.direction() << "</direction>\n"
325 << "</Line2D>\n";
326
327 return ioOStream;
328}
329
330
331
332/** @relates Line2D
333 */
334template <typename T>
335io::XmlOStream& operator<<(io::XmlOStream& ioOStream, const Line2D<T, Combined>& iLine)
337 LASS_ENFORCE_STREAM(ioOStream)
338 << "<Line2D>\n"
339 << "<support>" << iLine.support() << "</support>\n"
340 << "<direction>" << iLine.direction() << "</direction>\n"
341 << "<normal>" << iLine.normal() << "</normal>\n"
342 << "<d>" << iLine.d() << "</d>\n"
343 << "</Line2D>\n";
344
345 return ioOStream;
346}
347
348
349
350}
351
352}
353
354#endif
355
356// EOF
Output stream for writing a selection of geometric primitives to XML files.
const TValue signedDistance(const TPoint &iPoint) const
Return signed distance of point to line.
Definition line_2d.inl:118
const TValue squaredDistance(const TPoint &iPoint) const
Return signed distance of point to line.
Definition line_2d.inl:130
Side classify(const TPoint &iPoint) const
Return on what side a point is located.
Definition line_2d.inl:105
Result intersect(const Line2D< T, EPa, NPa > &iA, const Line2D< T, EPb, NPb > &iB, T &oTa, T &oTb)
intersection of two lines
Definition line_2d.inl:235
Result intersect(const Line2D< T, EPa, NPa > &iA, const Line2D< T, EPb, NPb > &iB, Point2D< T > &oPoint)
intersection of two lines
Definition line_2d.inl:285
T distance(const Line2D< T, EPa, NPa > &iA, const Line2D< T, EPb, NPb > &iB)
absolute distance between two lines
Definition line_2d.inl:203
T distance(const Point2D< T > &iA, const Line2D< T, EP, NP > &iB)
absolute distance between point and line.
Definition line_2d.inl:189
const TPoint support() const
return generated support point.
bool isValid() const
return true if line is a valid line (no normal or direction vectors that are zero).
const TPoint point(TParam iT) const
return point by filling in parameter in generated parametric equation
const TValue equation(const TPoint &iPoint) const
const TVector direction() const
return generated direction vector.
T sqr(const T &x)
return x * x
Definition basic_ops.h:162
T abs(const T &x)
if x < 0 return -x, else return x.
Definition basic_ops.h:145
set of geometrical primitives
Definition aabb_2d.h:81
Side
Different sides of a surface.
Definition side.h:79
@ sFront
in front of the surface
Definition side.h:81
@ sBack
in back of the surface
Definition side.h:83
@ sSurface
right on the surface
Definition side.h:87
Result
meta information on the result you have from an operation like an intersection ...
Definition result.h:74
@ rInfinite
there are infinite many solutions, output arguments are meaningless
Definition result.h:79
@ rInvalid
0 is an invalid value, nothing is known.
Definition result.h:75
@ rNone
operation has no answer, output arguments are meaningless
Definition result.h:76
@ rOne
there's exactly one answer, 1 output argument contains the answer
Definition result.h:77
Library for Assembled Shared Sources.
Definition config.h:53