43#ifndef LASS_GUARDIAN_OF_INCLUSION_PRIM_LINE_SEGMENT_2D_INL
44#define LASS_GUARDIAN_OF_INCLUSION_PRIM_LINE_SEGMENT_2D_INL
55template <
typename T,
class PP>
56LineSegment2D<T, PP>::LineSegment2D():
60 LASS_ASSERT(tail_.isZero());
61 LASS_ASSERT(head_.isZero());
66template <
typename T,
class PP>
67LineSegment2D<T, PP>::LineSegment2D(
const TPoint& tail,
const TPoint& head):
75template <
typename T,
class PP>
inline
76const typename LineSegment2D<T, PP>::TPoint&
77LineSegment2D<T, PP>::tail()
const
84template <
typename T,
class PP>
inline
85typename LineSegment2D<T, PP>::TPoint&
86LineSegment2D<T, PP>::tail()
93template <
typename T,
class PP>
inline
94const typename LineSegment2D<T, PP>::TPoint&
95LineSegment2D<T, PP>::head()
const
102template <
typename T,
class PP>
inline
103typename LineSegment2D<T, PP>::TPoint&
104LineSegment2D<T, PP>::head()
114template <
typename T,
class PP>
115const typename LineSegment2D<T, PP>::TPoint
118 TParameterPolicy::enforceRange(
t, TNumTraits::zero, TNumTraits::one);
127template <
typename T,
class PP>
128const typename LineSegment2D<T, PP>::TValue
131 const TVector v =
vector();
132 const TValue t1 = dot(
point - tail_, v);
133 const TValue t2 = -dot(
point - head_, v);
134 const TValue
t = std::max(t1,t2) / (t1 + t2);
135 return t1 > t2 ?
t : TNumTraits::one -
t;
142template <
typename T,
class PP>
143const typename LineSegment2D<T, PP>::TVector
146 return head_ - tail_;
153template <
typename T,
class PP>
154const typename LineSegment2D<T, PP>::TValue
157 const TVector v =
vector();
163template <
typename T,
class PP>
166 typedef typename LineSegment2D<T, PP>::TVector TVector;
167 typedef typename LineSegment2D<T, PP>::TValue TValue;
169 const TVector edge = segment.
vector();
170 const TVector v = point - segment.tail();
171 const TValue t = dot(v, edge);
172 const TValue tMax = dot(edge, edge);
175 return v.squaredNorm();
179 return squaredDistance(segment.head(), point);
181 return (v - edge * (t / tMax)).squaredNorm();
186template <
typename T,
class PP>
187T distance(
const LineSegment2D<T, PP>& segment,
const Point2D<T>& point)
189 return num::sqrt(squaredDistance(segment, point));
207template <
typename T,
class PPa,
class PPb>
208Result intersect(
const LineSegment2D<T, PPa>& a,
const LineSegment2D<T, PPb>& b, T& tA, T& tB)
210 typedef typename LineSegment2D<T, PPa>::TVector TVector;
211 typedef typename LineSegment2D<T, PPa>::TValue TValue;
212 typedef typename LineSegment2D<T, PPa>::TNumTraits TNumTraits;
213 typedef num::Consistent<TValue> TConsistent;
215 const TVector dirA(a.
vector());
216 const TVector dirB(b.
vector());
218 const TValue denominator = -perpDot(dirA, dirB);
219 if (denominator == TNumTraits::zero)
221 const TValue tTail = a.
t(b.tail());
222 const TValue tHead = b.
t(b.head());
223 if ((tTail < TNumTraits::zero && tHead < TNumTraits::zero) ||
224 (tTail > TNumTraits::one && tHead > TNumTraits::one))
232 if (doubleTriangleArea(a.tail(), a.head(), b.tail()) == TNumTraits::zero)
244 const TVector difference = b.tail() - a.tail();
245 const TConsistent candidateA = -perpDot(difference, dirB) / denominator;
246 const TConsistent candidateB = perpDot(dirA, difference) / denominator;
247 if (candidateA < TNumTraits::zero || candidateA > TNumTraits::one ||
248 candidateB < TNumTraits::zero || candidateB > TNumTraits::one)
254 tA = candidateA.value();
255 tB = candidateB.value();
275template <
typename T,
class PPa,
class PPb>
284 intersection += b.
point(tB);
290template <
typename T,
class PPa,
class PPb>
295 return intersect(a, b, tA, tB) !=
rNone;
300template <
typename T,
class PPa,
class PPb>
bool operator==(
const LineSegment2D<T, PPa>& a,
const LineSegment2D<T, PPb>& b)
302 return a.tail()==b.tail() && a.head()==b.head();
307template <
typename T,
class PPa,
class PPb>
bool operator!=(
const LineSegment2D<T, PPa>& a,
const LineSegment2D<T, PPb>& b)
315template<
typename T,
class PP>
316std::ostream& operator<<(std::ostream& stream,
const LineSegment2D<T, PP>& segment)
318 LASS_ENFORCE_STREAM(stream) <<
"{T=" << segment.tail() <<
", H=" << segment.head() <<
"}";
326template<
typename T,
class PP>
327io::XmlOStream& operator<<(io::XmlOStream& stream,
const LineSegment2D<T, PP>& segment)
329 LASS_ENFORCE_STREAM(stream)
330 <<
"<LineSegment2D>\n"
331 <<
"<tail>" << segment.tail() <<
"</tail>\n"
332 <<
"<head>" << segment.head() <<
"</head>\n"
333 <<
"</LineSegment2D>\n";
341template<
typename T,
class PP>
344 LASS_ENFORCE_STREAM(stream) <<
"lasthandle = line(";
345 stream <<
"[" << segment.tail().x <<
"," << segment.head().x <<
"],";
346 stream <<
"[" << segment.tail().y <<
"," << segment.head().y <<
"],";
347 stream <<
"'Color'," << stream.color() <<
");\n";
Output stream for writing a selection of geometric primitives to matlab M files.
Result intersect(const LineSegment2D< T, PPa > &a, const LineSegment2D< T, PPb > &b, Point2D< T > &point)
intersection of two line segments
Result intersect(const Line2D< T, EPa, NPa > &iA, const Line2D< T, EPb, NPb > &iB, T &oTa, T &oTb)
const TVector vector() const
Return vector from tail to head.
const TPoint point(TParam t) const
Return point on ray by it's parameter.
const TValue length() const
Return length of line segment.
const TValue t(const TPoint &point) const
Return parameter of projection of iPoint on line segment.
Result intersect(const LineSegment2D< T, PPa > &a, const LineSegment2D< T, PPb > &b, T &tA, T &tB)
intersection of two line segments
const TPoint point(TParam iT) const
set of geometrical primitives
Result
meta information on the result you have from an operation like an intersection ...
@ rInfinite
there are infinite many solutions, output arguments are meaningless
@ rNone
operation has no answer, output arguments are meaningless
@ rOne
there's exactly one answer, 1 output argument contains the answer
Library for Assembled Shared Sources.
const Point2D< T > affine() const
Return rescaled version of point with weight = 1.
const TValue norm() const
Return norm of vector.