00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef HxBSplineCurve_h
00012 #define HxBSplineCurve_h
00013
00014 #include "HxBSplineBasis.h"
00015 #include "HxPointR2.h"
00016 #include "HxVectorR2.h"
00017 #include "HxPointSetR2.h"
00018 #include "HxVec2Double.h"
00019 #include "HxPolyline2d.h"
00020
00021 #pragma warning (disable : 4786)
00022
00023 #include <vector>
00024 using std::vector;
00025 #include "HxIoFwd.h"
00026
00027
00037 class HxBSplineCurve {
00038 public:
00040 HxBSplineCurve();
00041
00045 HxBSplineCurve(const HxBSplineBasis& basis,
00046 const HxPointSetR2& cp);
00047
00049 static HxBSplineCurve makeUniform(HxPolyline2d cp, int degree);
00050
00052 static HxBSplineCurve makeInterpolating(HxPolyline2d cp);
00053
00055 ~HxBSplineCurve();
00056
00058 int ident() const;
00059
00061 HxBSplineBasis basis() const;
00062
00064 HxBSplineType curveType() const;
00065
00067 int degree() const;
00068
00070 double minT() const;
00071
00073 double maxT() const;
00074
00076 HxBSplineInterval getInterval(double t1, double t2) const;
00077
00079 int numP() const;
00080
00082 HxPointR2 P(int i) const;
00083
00085 HxPointSetR2 allP() const;
00086
00088 HxPolyline2d controlP() const;
00089
00091 double B(int i, double t) const;
00092
00094 double dB(int order, int i, double t) const;
00095
00099 HxBSplineInterval pathAffectedBy(int index) const;
00100
00104 vector<int> PThatAffectCAt(double t) const;
00105
00109 vector<int> PThatAffectCAt(const HxBSplineInterval& interval) const;
00110
00112 HxPointR2 C(double t) const;
00113
00115 HxVectorR2 dC(int order, double t) const;
00116
00118 double kAtC(double t) const;
00119
00121 double dTurnAngleAtC(double t) const;
00122
00126 double length(int n=50) const;
00127
00129 double length(const HxBSplineInterval& interval, int n=50) const;
00130
00132 HxPointR2 center() const;
00133
00135 HxPolyline2d sampleC(int n=50) const;
00136
00137
00138
00139
00140
00142 HxBSplineCurve changeAllP(const HxPointSetR2& p) const;
00143
00145 HxBSplineCurve translateAllP(const HxVectorR2& v) const;
00146
00148 HxBSplineCurve scaleAllP(double s) const;
00149
00154 HxBSplineCurve translateCurve(const HxVectorR2& v, double t) const;
00155
00160 HxBSplineCurve translateCurve(const HxPointR2& pDest, double t) const;
00161
00166 HxBSplineCurve translateCurve2(const HxVectorR2& v, double t) const;
00167
00172 HxBSplineCurve insertKnot(double t, int n=1) const;
00173
00175 STD_OSTREAM& dump(STD_OSTREAM&) const;
00176
00177 private:
00178 HxBSplineBasis _basis;
00179 HxPointSetR2 _PVec;
00180 int _ident;
00181
00182 static int _nr;
00183
00184 void makeDefault();
00185 void message(charPtr msg=0) const;
00186 HxPointR2 civ(int i,int order) const;
00187 int indexPVec(int i) const;
00188 double knot(int j) const;
00189 };
00190
00191
00192 inline STD_OSTREAM&
00193 operator<<(STD_OSTREAM& os, const HxBSplineCurve& b)
00194 {
00195 return b.dump(os);
00196 }
00197
00198 inline int
00199 HxBSplineCurve::ident() const
00200 {
00201 return _ident;
00202 }
00203
00204 inline HxBSplineBasis
00205 HxBSplineCurve::basis() const
00206 {
00207 return _basis;
00208 }
00209
00210 inline HxBSplineType
00211 HxBSplineCurve::curveType() const
00212 {
00213 return _basis.curveType();
00214 }
00215
00216 inline int
00217 HxBSplineCurve::degree() const
00218 {
00219 return _basis.degree();
00220 }
00221
00222 inline double
00223 HxBSplineCurve::minT() const
00224 {
00225 return _basis.minT();
00226 }
00227
00228 inline double
00229 HxBSplineCurve::maxT() const
00230 {
00231 return _basis.maxT();
00232 }
00233
00234 inline HxBSplineInterval
00235 HxBSplineCurve::getInterval(double t1, double t2) const
00236 {
00237 return HxBSplineInterval(t1, t2,
00238 _basis.minT(), _basis.maxT(), _basis.curveType());
00239 }
00240
00241 inline double
00242 HxBSplineCurve::B(int i, double t) const
00243 {
00244 return _basis.B(i, t);
00245 }
00246
00247 inline double
00248 HxBSplineCurve::dB(int order, int i, double t) const
00249 {
00250 return _basis.dB(order, i, t);
00251 }
00252
00253 inline HxBSplineInterval
00254 HxBSplineCurve::pathAffectedBy(int index) const
00255 {
00256 return _basis.pathAffectedBy(index);
00257 }
00258
00259 inline int
00260 HxBSplineCurve::numP() const
00261 {
00262 return _basis.numB();
00263 }
00264
00265 inline HxPointR2
00266 HxBSplineCurve::P(int i) const
00267 {
00268 if ( i < 0 || i >= numP() ) {
00269 message("(P) invalid index - setting to 0");
00270 i = 0;
00271 }
00272 return _PVec[i];
00273 }
00274
00275 inline HxPointSetR2
00276 HxBSplineCurve::allP() const
00277 {
00278 return _PVec;
00279 }
00280
00281 inline HxPolyline2d
00282 HxBSplineCurve::controlP() const
00283 {
00284 return HxPolyline2d(_PVec, (curveType() == closed));
00285 }
00286
00287 inline HxBSplineCurve
00288 HxBSplineCurve::changeAllP(const HxPointSetR2& p) const
00289 {
00290 return HxBSplineCurve(_basis, p);
00291 }
00292
00293 inline HxPointR2
00294 HxBSplineCurve::C(double t) const
00295 {
00296 HxVectorR2 tmp = dC( 0, t);
00297 return HxPointR2(tmp.x(), tmp.y());
00298 }
00299
00300 inline HxBSplineCurve
00301 HxBSplineCurve::translateCurve(const HxPointR2& pDest, double t) const
00302 {
00303 return translateCurve( HxVectorR2(pDest, C(t)), t);
00304 }
00305
00306 inline double
00307 HxBSplineCurve::knot(int j) const
00308 {
00309 return _basis._knotsVec[j];
00310 }
00311
00312 inline HxString
00313 makeString(const HxBSplineCurve& i)
00314 {
00315 return HxString("HxBSplineCurve") + makeString(i.ident());
00316 }
00317
00318 #pragma warning (default : 4251)
00319
00320 #endif