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_RAY_3D_INL
00046 #define LASS_GUARDIAN_OF_INCLUSION_PRIM_RAY_3D_INL
00047
00048
00049
00050
00051 #include "ray_3d.h"
00052
00053
00054
00055 namespace lass
00056 {
00057
00058 namespace prim
00059 {
00060
00061 template <typename T, class NP, class PP>
00062 Ray3D<T, NP, PP>::Ray3D():
00063 support_(),
00064 direction_()
00065 {
00066 LASS_ASSERT(support_.isZero());
00067 LASS_ASSERT(direction_.isZero());
00068 }
00069
00070
00071
00072 template <typename T, class NP, class PP>
00073 Ray3D<T, NP, PP>::Ray3D(const TPoint& iSupport, const TVector& iDirection):
00074 support_(iSupport),
00075 direction_(iDirection)
00076 {
00077 NP::normalize(direction_);
00078 }
00079
00080
00081
00082 template <typename T, class NP, class PP>
00083 Ray3D<T, NP, PP>::Ray3D(const TPoint& iSupport, const TVector& iNormalizedDirection,
00084 IsAlreadyNormalized):
00085 support_(iSupport),
00086 direction_(iNormalizedDirection)
00087 {
00088 }
00089
00090
00091
00092 template <typename T, class NP, class PP>
00093 Ray3D<T, NP, PP>::Ray3D(const TPoint& iSupport, const TPoint& iLookAt):
00094 support_(iSupport),
00095 direction_(iLookAt - iSupport)
00096 {
00097 NP::normalize(direction_);
00098 }
00099
00100
00101
00102 template <typename T, class NP, class PP>
00103 template <class NP2, class PP2>
00104 Ray3D<T, NP, PP>::Ray3D(const Ray3D<T, NP2, PP2>& iOther):
00105 support_(iOther.support()),
00106 direction_(iOther.direction())
00107 {
00108 NP::normalize(direction_);
00109 }
00110
00111
00112
00113
00114
00115
00116 template <typename T, class NP, class PP>
00117 const typename Ray3D<T, NP, PP>::TPoint&
00118 Ray3D<T, NP, PP>::support() const
00119 {
00120 return support_;
00121 }
00122
00123
00124
00125
00126
00127
00128 template <typename T, class NP, class PP>
00129 typename Ray3D<T, NP, PP>::TPoint&
00130 Ray3D<T, NP, PP>::support()
00131 {
00132 return support_;
00133 }
00134
00135
00136
00137
00138
00139 template <typename T, class NP, class PP>
00140 const typename Ray3D<T, NP, PP>::TVector&
00141 Ray3D<T, NP, PP>::direction() const
00142 {
00143 return direction_;
00144 }
00145
00146
00147
00148
00149
00150 template <typename T, class NP, class PP>
00151 void Ray3D<T, NP, PP>::setDirection(const TVector& iDirection)
00152 {
00153 direction_ = iDirection;
00154 NP::normalize(direction_);
00155 }
00156
00157
00158
00159
00160
00161 template <typename T, class NP, class PP>
00162 void Ray3D<T, NP, PP>::lookAt(const TPoint& iLookAt)
00163 {
00164 direction_ = iLookAt - support_;
00165 NP::normalize(direction_);
00166 }
00167
00168
00169
00170
00171
00172
00173
00174
00175 template <typename T, class NP, class PP>
00176 const typename Ray3D<T, NP, PP>::TPoint
00177 Ray3D<T, NP, PP>::point(TParam iT) const
00178 {
00179 TParameterPolicy::enforceRange(iT, TNumTraits::zero);
00180 return support_ + iT * direction_;
00181 }
00182
00183
00184
00185
00186
00187
00188 template <typename T, class NP, class PP>
00189 const typename Ray3D<T, NP, PP>::TValue
00190 Ray3D<T, NP, PP>::t(const TPoint& iPoint) const
00191 {
00192 return NP::divideBySquaredNorm(dot(iPoint - support_, direction_), direction_);
00193 }
00194
00195
00196
00197
00198
00199
00200 template <typename T, class NP, class PP>
00201 const typename Ray3D<T, NP, PP>::TVector
00202 Ray3D<T, NP, PP>::project(const TVector& iVector) const
00203 {
00204 return direction_ * NP::divideBySquaredNorm(dot(iVector, direction_), direction_);
00205 }
00206
00207
00208
00209
00210
00211 template <typename T, class NP, class PP>
00212 const typename Ray3D<T, NP, PP>::TVector
00213 Ray3D<T, NP, PP>::reject(const TVector& iVector) const
00214 {
00215 return iVector - project(iVector);
00216 }
00217
00218
00219
00220
00221
00222 template <typename T, class NP, class PP>
00223 const typename Ray3D<T, NP, PP>::TVector
00224 Ray3D<T, NP, PP>::reflect(const TVector& iVector) const
00225 {
00226 return 2 * project(iVector) - iVector;
00227 }
00228
00229
00230
00231
00232
00233
00234 template <typename T, class NP, class PP>
00235 const typename Ray3D<T, NP, PP>::TPoint
00236 Ray3D<T, NP, PP>::project(const TPoint& iPoint) const
00237 {
00238 return support_ + project(iPoint - support_);
00239 }
00240
00241
00242
00243
00244
00245 template <typename T, class NP, class PP>
00246 const typename Ray3D<T, NP, PP>::TVector
00247 Ray3D<T, NP, PP>::reject(const TPoint& iPoint) const
00248 {
00249 return reject(iPoint - support_);
00250 }
00251
00252
00253
00254
00255
00256 template <typename T, class NP, class PP>
00257 const typename Ray3D<T, NP, PP>::TPoint
00258 Ray3D<T, NP, PP>::reflect(const TPoint& iPoint) const
00259 {
00260 return support_ + reflect(iPoint - support_);
00261 }
00262
00263
00264
00265
00266
00267 template <typename T, class NP, class PP>
00268 const bool Ray3D<T, NP, PP>::isValid() const
00269 {
00270 return !direction_.isZero();
00271 }
00272
00273
00274
00275
00276
00277 template<typename T, class NP>
00278 std::ostream& operator<<(std::ostream& ioOStream, const Ray3D<T, NP>& iRay)
00279 {
00280 LASS_ENFORCE(ioOStream) << "{O=" << iRay.origin() << ", D=" << iRay.direction() << "}";
00281 return ioOStream;
00282 }
00283
00284
00285
00286
00287
00288 template<typename T, class NP>
00289 io::XmlOStream& operator<<(io::XmlOStream& ioOStream, const Ray3D<T, NP>& iRay)
00290 {
00291 LASS_ENFORCE_STREAM(ioOStream)
00292 << "<Ray3D>\n"
00293 << "<support>" << iRay.support() << "</support>\n"
00294 << "<direction>" << iRay.direction() << "</direction>\n"
00295 << "</Ray3D>\n";
00296 return ioOStream;
00297 }
00298
00299
00300
00301 }
00302
00303 }
00304
00305 #endif
00306
00307