00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef GUNU_PARAMETRIZE_H
00021 #define GUNU_PARAMETRIZE_H
00022
00023 #include "gul_vector.h"
00024
00025 namespace gunu {
00026
00027 template< class T, class EP >
00028 inline T ChordLength( int nQ, const gul::Ptr<EP>& Q, gul::Ptr<T>& d )
00029 {
00030 T sum = (T)0;
00031 d[0] = (T)0;
00032
00033 for( int i = 1; i < nQ; i++ )
00034 {
00035 d[i] = gul::distance( Q[i], Q[i-1] );
00036 sum += d[i];
00037 }
00038 return sum;
00039 }
00040
00041 template< class T, class EP >
00042 inline T ColumnChordLength(
00043 int nRows, int nCols, const gul::Ptr< gul::Ptr<EP> >& Q,
00044 int iCol, gul::Ptr<T>& d )
00045 {
00046 T sum = (T)0;
00047 d[0] = (T)0;
00048
00049 for( int i = 1; i < nRows; i++ )
00050 {
00051 d[i] = gul::distance( Q[i][iCol], Q[i-1][iCol] );
00052 sum += d[i];
00053 }
00054 return sum;
00055 }
00056
00057 template< class T >
00058 inline void ChordLengthParameters( int nQ, const T& dsum, const gul::Ptr<T>& d,
00059 gul::Ptr<T>& Uq )
00060 {
00061 Uq[0] = (T)0;
00062 for( int i = 1; i < nQ-1; i++ )
00063 Uq[i] = Uq[i-1] + d[i]/dsum;
00064 Uq[nQ-1] = (T)1;
00065 }
00066
00067 template< class T >
00068 inline void KnotVectorByAveraging( int nQ, const gul::Ptr<T>& Uq, int p,
00069 gul::Ptr<T>& U )
00070 {
00071 int i,j;
00072 T p_inv,sum;
00073 int n = nQ-1, m = nQ+p;
00074
00075 for( i = 0; i <= p; i++ ) U[i] = (T)0;
00076 for( i = m-p; i <= m; i++ ) U[i] = (T)1;
00077
00078 p_inv = (T)1/(T)p;
00079 for( j = 1; j <= n-p; j++ )
00080 {
00081 sum = (T)0;
00082 for( i = j; i < j+p; i++ )
00083 sum += Uq[i];
00084 U[j+p] = sum * p_inv;
00085 }
00086 }
00087
00088
00089
00090
00091
00092 template< class T >
00093 inline int KnotVectorByAveraging( int nQ, const gul::Ptr<T>& Uq,
00094 int n, int p, gul::Ptr<T>& U )
00095 {
00096 T tid,tidf,d,alpha;
00097 int i,ii;
00098
00099 for( i = 0; i <= p; i++ )
00100 {
00101 U[i] = 0.0;
00102 U[n+1+i] = 1.0;
00103 }
00104
00105 d = (T)nQ / (T)(n - p + 1);
00106 if( d < (T)1 ) return 0;
00107
00108 for( i = 1; i <= n - p; i++ )
00109 {
00110 tid = (T)i * d;
00111 tidf = gul::rtr<T>::floor(tid);
00112
00113 ii = (int)tidf;
00114
00115 alpha = tid - tidf;
00116
00117 U[p+i] = ((T)1 - alpha) * Uq[ii-1] + alpha * Uq[ii];
00118 }
00119 return ((int)gul::rtr<T>::ceil(d))+1;
00120 }
00121
00122 template< class T, class EP >
00123 inline bool ChordLengthMeshParams(
00124 int nRows, int nCols, const gul::Ptr< gul::Ptr<EP> > &Q,
00125 gul::Ptr<T>& Uq, gul::Ptr<T>& Vq )
00126 {
00127 int nnzero,i,j,nu,nv;
00128 T f,dtotal,dsum;
00129 gul::Ptr<T> d;
00130
00131 d.reserve_pool( gul::Max(nRows,nCols) );
00132
00133 nu = nCols-1;
00134 nv = nRows-1;
00135
00136
00137
00138 nnzero = nv+1;
00139
00140 for( i = 0; i < nu; i++ ) Uq[i] = (T)0;
00141 Uq[nu] = (T)1;
00142
00143 for( i = 0; i <= nv; i++ )
00144 {
00145 dtotal = ChordLength( nu+1, Q[i], d );
00146
00147 if( dtotal == (T)0 )
00148 {
00149 nnzero--;
00150 }
00151 else
00152 {
00153 dsum = (T)0;
00154 for( j = 1; j < nu; j++ )
00155 {
00156 dsum += d[j];
00157 Uq[j] += dsum/dtotal;
00158 }
00159 }
00160 }
00161 if( nnzero == 0 ) return false;
00162
00163 f = (T)1/(T)nnzero;
00164
00165 for( i = 1; i < nu; i++ )
00166 Uq[i] *= f;
00167
00168
00169
00170 nnzero = nu+1;
00171
00172 for( i = 0; i < nv; i++ ) Vq[i] = (T)0;
00173 Vq[nv] = (T)1;
00174
00175 for( i = 0; i <= nu; i++ )
00176 {
00177 dtotal = ColumnChordLength( nv+1, nu+1, Q, i, d );
00178
00179 if( dtotal == (T)0 )
00180 {
00181 nnzero--;
00182 }
00183 else
00184 {
00185 dsum = (T)0;
00186 for( j = 1; j < nv; j++ )
00187 {
00188 dsum += d[j];
00189 Vq[j] += dsum/dtotal;
00190 }
00191 }
00192 }
00193 if( nnzero == 0 ) return false;
00194
00195 f = (T)1/(T)nnzero;
00196
00197 for( i = 1; i < nv; i++ )
00198 Vq[i] *= f;
00199
00200 return true;
00201 }
00202
00203 }
00204
00205 #endif
00206
00207