00001 #ifndef CARDINAL_SPLINE_D_
00002 #define CARDINAL_SPLINE_D_
00003
00004 #include <vnl/vnl_matrix.h>
00005 #include <vnl/vnl_vector_fixed.h>
00006 #include <vnl/vnl_matrix_fixed.h>
00007 #include <vcl_vector.h>
00008 #include <vcl_string.h>
00009 #include <vcl_cassert.h>
00010 #include <vnl/io/vnl_io_vector_fixed.txx>
00011 #include <vnl/io/vnl_io_matrix.txx>
00012 #include <vsl/vsl_binary_io.h>
00013 #include <vsl/vsl_vector_io.h>
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 class CardinalSpline
00032 {
00033 public:
00034 typedef vnl_vector_fixed<double, 3> Vector3D;
00035 CardinalSpline(): Mc(4,4,0.0), s(0.25){};
00036 CardinalSpline(vcl_vector<Vector3D> &cPoints):
00037 controlPoints(cPoints), Mc(4,4,0.0), s(0.25)
00038 {
00039 setMc(s);
00040 };
00041 CardinalSpline(const CardinalSpline &cs):
00042 controlPoints(cs.controlPoints), Mc(cs.Mc), s(cs.s) {};
00043 CardinalSpline &operator =(const CardinalSpline &cs){
00044 if (&cs != this)
00045 {
00046 controlPoints = cs.controlPoints;
00047 Mc = cs.Mc;
00048 s = cs.s;
00049 }
00050 return *this;
00051 };
00052 ~CardinalSpline(){};
00053
00054 Vector3D getPoint(double t) const;
00055 vcl_vector<Vector3D> getPoints(int num_points) const;
00056 vcl_vector<Vector3D> getControlPoints() const {return controlPoints;};
00057 void setT(double t){setMc((1-t)/2.0);};
00058 Vector3D closest_point(const Vector3D &point) const {
00059 double t = closest_point_t(point);
00060 assert(t>=0.0);
00061 assert(t<=1.0);
00062 return getPoint(t);
00063 };
00064 double closest_point_t(const Vector3D &point) const;
00065 Vector3D firstDerivative(double t) const;
00066 Vector3D secondDerivative(double t) const;
00067
00068 Vector3D mean_control_pts() const {
00069 Vector3D mean(0.0);
00070 for (unsigned i=0; i<controlPoints.size(); i++)
00071 mean += controlPoints[i];
00072 mean /= (double)controlPoints.size();
00073 return mean;
00074 };
00075
00076
00077 void b_write(vsl_b_ostream &os) const;
00078 void b_read(vsl_b_istream &os);
00079 short version() const {return 1;};
00080 void print_summary(vcl_ostream &os) const {
00081 os << "Cardinal Spline:\n"
00082 << "\tcontrolPts =\n";
00083 for (unsigned i=0; i<controlPoints.size(); i++)
00084 os << "\t\t" << controlPoints[i] << vcl_endl;
00085 };
00086 vcl_string is_a() const {return vcl_string("CardinalSpline");};
00087 bool is_class(const vcl_string &s){return s==is_a();};
00088
00089 #ifdef VCL_SGI_CC
00090 friend bool operator!=(Vector3D const& a, Vector3D const& b) {
00091 return a[0]!=b[0] || a[1]!=b[1] || a[2]!=b[2];
00092 }
00093 #endif
00094
00095 bool operator==(const CardinalSpline &c){
00096 return (controlPoints==c.controlPoints) && (Mc==c.Mc) && (s==c.s);
00097 };
00098
00099 bool operator!=(const CardinalSpline &c){
00100 return !(*this==c);
00101 };
00102
00103 void translate(const Vector3D &t){
00104 for (unsigned i=0; i<controlPoints.size(); i++)
00105 controlPoints[i] += t;
00106 };
00107
00108 private:
00109 double distanceFunctionFirstDerivative(double t,
00110 const Vector3D &point) const;
00111 double distanceFunctionSecondDerivative(double t,
00112 const Vector3D &point) const;
00113 Vector3D getVal(const vnl_matrix_fixed<double, 1, 4> &uvec, int pk) const;
00114 double convert_t(double t) const{
00115 if (t<0.0)
00116 while (t<0.0) t+=1.0;
00117 else if (t>1.0)
00118 while (t>1.0) t-=1.0;
00119 return t;
00120 };
00121
00122 void setMc(double s_)
00123 {
00124 s = s_;
00125 Mc(0,0)=-s; Mc(0,1)=2-s; Mc(0,2)=s-2; Mc(0,3)=s;
00126 Mc(1,0)=2*s; Mc(1,1)=s-3; Mc(1,2)=3-2*s; Mc(1,3)=-s;
00127 Mc(2,0)=-s; Mc(2,1)=0; Mc(2,2)=s; Mc(2,3)=0;
00128 Mc(3,0)=0; Mc(3,1)=1; Mc(3,2)=0; Mc(3,3)=0;
00129 };
00130 vcl_vector<Vector3D> controlPoints;
00131 vnl_matrix<double> Mc;
00132 double s;
00133 };
00134
00135 void vsl_b_write(vsl_b_ostream &os, const CardinalSpline &e);
00136 void vsl_b_read(vsl_b_istream &is, CardinalSpline &e);
00137 void vsl_print_summary(vcl_ostream &is, const CardinalSpline &e);
00138
00139 #endif // CARDINAL_SPLINE_D_