Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

hspline.C

Go to the documentation of this file.
00001 /*************************************************************************
00002  *    NAME: J.D. Northrup
00003  *    USER: jdn
00004  *    FILE: hspline.C
00005  *    DATE: Wed Jul 29 12:58:54 US/Eastern 1998
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    // see Farin: curves and surfaces for CAGD,
00069    // 3rd ed., section 8.3 (pp 126-128)
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    // first piece
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    // middle pieces
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    // last piece
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    // copied from _point3d_list::interpolate_length()
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 /* end of file hspline.C */

Generated on Mon Sep 18 11:39:31 2006 for jot by  doxygen 1.4.4