00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #ifndef LASS_GUARDIAN_OF_INCLUSION_PRIM_LINE_SEGMENT_3D_INL
00046 #define LASS_GUARDIAN_OF_INCLUSION_PRIM_LINE_SEGMENT_3D_INL
00047
00048 #include "line_segment_3d.h"
00049
00050
00051
00052 namespace lass
00053 {
00054
00055 namespace prim
00056 {
00057
00058 template <typename T, class PP>
00059 LineSegment3D<T, PP>::LineSegment3D():
00060 tail_(),
00061 head_()
00062 {
00063 LASS_ASSERT(tail_.isZero());
00064 LASS_ASSERT(head_.isZero());
00065 }
00066
00067
00068
00069 template <typename T, class PP>
00070 LineSegment3D<T, PP>::LineSegment3D(const TPoint& iTail, const TPoint& iHead):
00071 tail_(iTail),
00072 head_(iHead)
00073 {
00074 }
00075
00076
00077
00078 template <typename T, class PP>
00079 template <typename PP2>
00080 LineSegment3D<T, PP>::LineSegment3D(const LineSegment3D<T, PP2>& iOther):
00081 tail_(iOther.tail()),
00082 head_(iOther.head())
00083 {
00084 }
00085
00086
00087
00088 template <typename T, class PP> inline
00089 const typename LineSegment3D<T, PP>::TPoint&
00090 LineSegment3D<T, PP>::tail() const
00091 {
00092 return tail_;
00093 }
00094
00095
00096
00097 template <typename T, class PP> inline
00098 typename LineSegment3D<T, PP>::TPoint&
00099 LineSegment3D<T, PP>::tail()
00100 {
00101 return tail_;
00102 }
00103
00104
00105
00106 template <typename T, class PP> inline
00107 const typename LineSegment3D<T, PP>::TPoint&
00108 LineSegment3D<T, PP>::head() const
00109 {
00110 return head_;
00111 }
00112
00113
00114
00115 template <typename T, class PP> inline
00116 typename LineSegment3D<T, PP>::TPoint&
00117 LineSegment3D<T, PP>::head()
00118 {
00119 return head_;
00120 }
00121
00122
00123
00124
00125
00126
00127 template <typename T, class PP>
00128 const typename LineSegment3D<T, PP>::TPoint
00129 LineSegment3D<T, PP>::point(TParam iT) const
00130 {
00131 TParameterPolicy::enforceRange(iT, TNumTraits::zero, TNumTraits::one);
00132 return tail_ + iT * vector();
00133 }
00134
00135
00136
00137
00138
00139
00140 template <typename T, class PP>
00141 const typename LineSegment3D<T, PP>::TValue
00142 LineSegment3D<T, PP>::t(const TPoint& iPoint) const
00143 {
00144 const TVector v = vector();
00145 const TValue t1 = dot(iPoint - tail_, v);
00146 const TValue t2 = -dot(iPoint - head_, v);
00147 const TValue t = std::max(t1,t2) / (t1 + t2);
00148 return t1 > t2 ? t : TNumTraits::one - t;
00149 }
00150
00151
00152
00153 template <typename T, class PP>
00154 const typename LineSegment3D<T, PP>::TVector
00155 LineSegment3D<T, PP>::vector() const
00156 {
00157 return head_ - tail_;
00158 }
00159
00160
00161
00162
00163
00164 template <typename T, class PP>
00165 const typename LineSegment3D<T, PP>::TValue
00166 LineSegment3D<T, PP>::length() const
00167 {
00168 const TVector v = vector();
00169 return v.norm();
00170 }
00171
00172
00173 template <typename T, class PP>
00174 const typename LineSegment3D<T, PP>::TValue
00175 LineSegment3D<T, PP>::closestsPoint(const TPoint &iPoint, T &oT) const
00176 {
00177 oT = this->t(iPoint);
00178 if(oT < 0)
00179 {
00180 oT = 0.0;
00181 return (iPoint - tail_).squaredNorm();
00182 }
00183 if(oT > 1)
00184 {
00185 oT = 1.0;
00186 return (iPoint - head_).squaredNorm();
00187 }
00188 return (iPoint - this->point(oT)).squaredNorm();
00189 }
00190
00191
00192
00193 template <typename T, class PP>
00194 const typename LineSegment3D<T, PP>::TValue
00195 LineSegment3D<T, PP>::squaredDistance(const TPoint& iPoint) const
00196 {
00197 TParam t = this->t(iPoint);
00198 if(t < 0)
00199 return (iPoint - tail_).squaredNorm();
00200 if(t > 1)
00201 return (iPoint - head_).squaredNorm();
00202 return (iPoint - this->point(t)).squaredNorm();
00203 }
00204
00205
00206
00207 template <typename T, class PP>
00208 const typename LineSegment3D<T, PP>::TValue
00209 LineSegment3D<T, PP>::distance(const TPoint& iPoint) const
00210 {
00211 TValue squaredDistance = this->squaredDistance(iPoint);
00212 return lass::num::sqrt(squaredDistance);
00213 }
00214
00215
00216
00217 template <typename T, class PPa, class PPb> bool operator==(const LineSegment3D<T, PPa>& iA, const LineSegment3D<T, PPb>& iB)
00218 {
00219 return iA.tail()==iB.tail() && iA.head()==iB.head();
00220 }
00221
00222
00223
00224 template <typename T, class PPa, class PPb> bool operator!=(const LineSegment3D<T, PPa>& iA, const LineSegment3D<T, PPb>& iB)
00225 {
00226 return !(iA==iB);
00227 }
00228
00229
00230
00231
00232 template<typename T, class PP>
00233 std::ostream& operator<<(std::ostream& ioOStream, const LineSegment3D<T, PP>& iLineSegment)
00234 {
00235 LASS_ENFORCE_STREAM(ioOStream) << "{T=" << iLineSegment.tail() << ", H=" << iLineSegment.head() << "}";
00236 return ioOStream;
00237 }
00238
00239
00240
00241
00242
00243 template<typename T, class PP>
00244 io::XmlOStream& operator<<(io::XmlOStream& ioOStream, const LineSegment3D<T, PP>& iLineSegment)
00245 {
00246 LASS_ENFORCE_STREAM(ioOStream)
00247 << "<LineSegment3D>\n"
00248 << "<tail>" << iLineSegment.tail() << "</tail>\n"
00249 << "<head>" << iLineSegment.head() << "</head>\n"
00250 << "</LineSegment3D>\n";
00251
00252 return ioOStream;
00253 }
00254
00255
00256
00257 }
00258
00259 }
00260
00261 #endif