00001
00002
00003
00004
00005
00006
00007 #include "hspline.H"
00008
00009 using mlib::CWpt;
00010 using mlib::CWpt_list;
00011 using mlib::Wvec;
00012 using mlib::CWvec;
00013
00014 const HSpline::HermiteBasis HSpline::_HemiteBasisConst;
00015
00016 void
00017 HSpline::HermiteGeometry::set(CWpt& p1, CWpt& p2, CWvec& v1, CWvec& v2)
00018 {
00019 for (int i = 0; i < 3; i++) {
00020 row[i][0] = p1[i];
00021 row[i][1] = p2[i];
00022 row[i][2] = v1[i];
00023 row[i][3] = v2[i];
00024 }
00025 row[3][0] = 0;
00026 row[3][1] = 0;
00027 row[3][2] = 0;
00028 row[3][3] = 0;
00029 }
00030
00031 void
00032 CRSpline::clear(int all)
00033 {
00034 if (all) {
00035 _pts.clear();
00036 _u.clear();
00037 }
00038 while (!_H.empty())
00039 delete _H.pop();
00040 _valid = 0;
00041 }
00042
00043 void
00044 CRSpline::set(CWpt_list& p, CARRAY<double> &u)
00045 {
00046 clear();
00047
00048 if (p.num() != u.num()) {
00049 err_msg("CRSpline::set: points and parameter vals don't match");
00050 return;
00051 }
00052 _pts = p;
00053 _u = u;
00054 }
00055
00056 void
00057 CRSpline::add(CWpt& p, double u)
00058 {
00059 _pts += p;
00060 _u += u;
00061
00062 clear(0);
00063 }
00064
00065 int
00066 CRSpline::_update()
00067 {
00068
00069
00070
00071 if (_valid)
00072 return 1;
00073
00074 if (num() < 3) {
00075 err_msg("CRSpline::_update: too few points (%d)", num());
00076 return 0;
00077 }
00078
00079
00080 Wvec m1 = m(1);
00081 double di = delt(0);
00082 Wvec m0 = (_pts[1] - _pts[0])*(2/di) - m1;
00083 _H += new HSpline(_pts[0], _pts[1], di*m0, di*m1);
00084
00085
00086 int i;
00087 for (i=1; i<num()-2; i++) {
00088 m0 = m1;
00089 m1 = m(i+1);
00090 di = delt(i);
00091 _H += new HSpline(_pts[i], _pts[i+1], di*m0, di*m1);
00092 }
00093
00094
00095 m0 = m1;
00096 di = delt(i);
00097 m1 = (_pts[i+1] - _pts[i])*(2/di) - m0;
00098 _H += new HSpline(_pts[i], _pts[i+1], di*m0, di*m1);
00099
00100 _valid = 1;
00101 return 1;
00102 }
00103
00104 void
00105 CRSpline::get_seg(double u, int& seg, double& t) const
00106 {
00107
00108
00109 assert(num() > 1);
00110
00111 if (u <= _u[0]) {
00112 seg = 0;
00113 t = 0;
00114 return;
00115 }
00116 if (u >= _u.last()) {
00117 seg = num()-2;
00118 t = 1;
00119 return;
00120 }
00121
00122 int l=0, r=num()-1, m;
00123 while ((m = (l+r) >> 1) != l) {
00124 if (u < _u[m])
00125 r = m;
00126 else l = m;
00127 }
00128 seg = m;
00129 t = (u-_u[m])/delt(m);
00130 }
00131
00132