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

Algebraic.cpp

Go to the documentation of this file.
00001 /** \file Algebraic.cpp 
00002  * Implementation of the algebraic implicit surface class methods.
00003  * \author Jeff Decker (plus extensive comments by John C. Hart)
00004  * \date Fall 2000.
00005  */
00006 
00007 #include "Algebraic.h"
00008 
00009 /** Add Algebraic to the ImplicitFactory
00010  */
00011 REGISTER_IMPLICIT(Algebraic,"Algebraic");
00012 
00013 /**
00014  * Initialization routine called by constructors.  This function allows all
00015  * of the main object init code to be in one place.
00016  */
00017 void Algebraic::init(int deg)
00018 {
00019   m_d = deg;
00020 
00021   calcNumCoef();  // Should return 1
00022   m_a = new double[m_numCoef];
00023   m_x = new int[m_numCoef];
00024   m_y = new int[m_numCoef];
00025   m_z = new int[m_numCoef];
00026   m_xPow = new double[m_d+1];
00027   m_yPow = new double[m_d+1];
00028   m_zPow = new double[m_d+1];
00029 
00030   initPowerArrays();
00031   for (int i=0; i<m_numCoef; i++)
00032     m_a[i] = 0.0;
00033 }
00034 
00035 /** Constucts a constant Algebraic.
00036  */
00037 Algebraic::Algebraic() : Implicit()
00038 {
00039   init(0);
00040 }
00041 
00042 Algebraic::Algebraic(int deg) : Implicit()
00043 {
00044   init(deg);
00045 }
00046 
00047 void Algebraic::degree(int deg)
00048 {
00049   int i;
00050 
00051   double* m_a_back;
00052   m_a_back = m_a;
00053   int* m_x_back = m_x;
00054   int* m_y_back = m_y;
00055   int* m_z_back = m_z;
00056   double* m_xPow_back = m_xPow;
00057   double* m_yPow_back = m_yPow;
00058   double* m_zPow_back = m_zPow;
00059 
00060   int old_numCoef = m_numCoef;
00061   int old_m_d = m_d;
00062 
00063   m_d = deg;
00064 
00065   calcNumCoef();
00066 
00067   m_a = new double[m_numCoef];
00068   m_x = new int[m_numCoef];
00069   m_y = new int[m_numCoef];
00070   m_z = new int[m_numCoef];
00071   m_xPow = new double[m_d+1];
00072   m_yPow = new double[m_d+1];
00073   m_zPow = new double[m_d+1];
00074 
00075   for (i = 0; i < gmMin(old_numCoef, m_numCoef); i++)
00076     {
00077       m_a[i] = m_a_back[i];
00078       m_x[i] = m_x_back[i];
00079       m_y[i] = m_y_back[i];
00080       m_z[i] = m_z_back[i];
00081     }
00082 
00083   for (i = 0; i < gmMin(old_m_d+1, m_d+1); i++)
00084     {
00085       m_xPow[i] = m_xPow_back[i];
00086       m_yPow[i] = m_yPow_back[i];
00087       m_zPow[i] = m_zPow_back[i];
00088     }
00089 
00090   for (i = (int)gmMin(old_numCoef, m_numCoef); i < m_numCoef; i++)
00091     m_a[i] = 0.0;
00092 
00093   initPowerArrays();
00094 
00095   delete[] m_a_back;
00096   delete[] m_x_back;
00097   delete[] m_y_back;
00098   delete[] m_z_back;
00099   delete[] m_xPow_back;
00100   delete[] m_yPow_back;
00101   delete[] m_zPow_back;
00102 }
00103 
00104 Algebraic::~Algebraic()
00105 {
00106   delete[] m_a;
00107   delete[] m_x;
00108   delete[] m_y;
00109   delete[] m_z;
00110 
00111   delete[] m_xPow;
00112   delete[] m_yPow;
00113   delete[] m_zPow;
00114 }
00115 
00116 /**
00117  * Convenience function for the calculation of a LRP over a time interval
00118  * for a particular m_a.  We use the "current" and the "last" coefficients
00119  * to calculate an interval of the coefficients over a given time interval.
00120  * This is used for 4D critical point finding.
00121  */
00122 Intervald Algebraic::m_alrp(int i, Intervald t)
00123 {
00124   double* m_aold = (double *) malloc(m_numCoef * sizeof(double));
00125   getqold(m_aold);
00126   Intervald retval = t * (m_a[i] - m_aold[i]) + Intervald(m_aold[i]);
00127   delete m_aold;
00128   return retval;
00129 }
00130 
00131 #ifndef INTERVAL_EVAL_ONLY
00132 double Algebraic::proc(gmVector3 v)
00133 {
00134   int i;
00135   double val = 0.0;
00136 
00137   initXYZPowerArrays(v);
00138   for (i=0; i<m_numCoef; i++)
00139     val += m_a[i] * m_xPow[m_x[i]] * m_yPow[m_y[i]] * m_zPow[m_z[i]];
00140   return val;
00141 }
00142 
00143 gmVector3 Algebraic::grad(gmVector3 v)
00144 {
00145   return gmVector3(dx(v), dy(v), dz(v));
00146 }
00147 
00148 gmMatrix3 Algebraic::hess(gmVector3 v)
00149 {
00150     double dfdxy = dxdy(v), dfdxz = dxdz(v), dfdyz = dydz(v);
00151     double dfdxx = dx2(v),  dfdyy = dy2(v),  dfdzz = dz2(v);
00152 
00153     gmMatrix3 hess(dfdxx,   dfdxy,  dfdxz,
00154                    dfdxy,   dfdyy,  dfdyz,
00155                    dfdxz,   dfdyz,  dfdzz);
00156     return hess;
00157 }
00158 #endif
00159 
00160 
00161 /** proc of an interval-vector (aka a Box) X.
00162  * If X is a 4D box then
00163  * we assume q is lerp between qold and q.
00164  *
00165  * x[3] = [told,t]
00166  * m_alrp (i,x[3]) returns [(a_i)old,a_i]
00167  * 
00168  */
00169 Intervald Algebraic::proc(Box<double> x)
00170 {
00171   int i;
00172   Intervald val(0.0);
00173 
00174   for (i=0; i<m_numCoef; i++) 
00175     val += ((x.size() == 3) ? Intervald(m_a[i]) : m_alrp(i,x[3])) *
00176            x[0].pow(m_x[i]) * x[1].pow(m_y[i]) * x[2].pow(m_z[i]);
00177   return val;
00178 }
00179 
00180 Box3d Algebraic::grad(Box<double> x)
00181 {
00182   Box3d dx(0.0);
00183   Intervald m_atemp;
00184 
00185   for (int i = 0; i < m_numCoef; i++) 
00186     {
00187       m_atemp = ((x.size() == 3) ? Intervald(m_a[i]) : m_alrp(i,x[3]));
00188       if (m_x[i] >= 1) 
00189         dx[0] += m_atemp * Intervald(m_x[i]) *
00190                  (x[0].pow(m_x[i]-1)*x[1].pow(m_y[i])  *x[2].pow(m_z[i]));
00191       if (m_y[i] >= 1) 
00192         dx[1] += m_atemp * Intervald(m_y[i]) *
00193                  (x[0].pow(m_x[i])  *x[1].pow(m_y[i]-1)*x[2].pow(m_z[i]));
00194       if (m_z[i] >= 1) 
00195         dx[2] += m_atemp * Intervald(m_z[i]) *
00196                  (x[0].pow(m_x[i])  *x[1].pow(m_y[i])  *x[2].pow(m_z[i]-1));
00197     }
00198   return dx;
00199 }
00200 
00201 IMatrix3d Algebraic::hess(Box<double> x)
00202 {
00203   IMatrix3d Vx;
00204   int i;
00205 
00206   // Calc lower triangle
00207   for (i = 0; i < m_numCoef; i++) 
00208     {
00209       if (m_x[i] >= 2) 
00210         Vx[0][0] += Intervald(m_a[i]*m_x[i]*(m_x[i]-1))*
00211                     (x[0].pow(m_x[i]-2)*x[1].pow(m_y[i])  *x[2].pow(m_z[i]));
00212       if (m_y[i] >= 2) 
00213         Vx[1][1] += Intervald(m_a[i]*m_y[i]*(m_y[i]-1))*
00214                     (x[0].pow(m_x[i])  *x[1].pow(m_y[i]-2)*x[2].pow(m_z[i]));
00215       if (m_z[i] >= 2) 
00216         Vx[2][2] += Intervald(m_a[i]*m_z[i]*(m_z[i]-1))*
00217                     (x[0].pow(m_x[i])  *x[1].pow(m_y[i])  *x[2].pow(m_z[i]-2));
00218       if (m_x[i] >= 1 && m_y[i] >= 1) 
00219         Vx[1][0] += Intervald(m_a[i]*m_x[i]*m_y[i])*
00220                     (x[0].pow(m_x[i]-1)*x[1].pow(m_y[i]-1)*x[2].pow(m_z[i]));
00221       if (m_y[i] >= 1 && m_z[i] >= 1) 
00222         Vx[2][1] += Intervald(m_a[i]*m_y[i]*m_z[i])*
00223                     (x[0].pow(m_x[i])  *x[1].pow(m_y[i]-1)*x[2].pow(m_z[i]-1));
00224       if (m_x[i] >= 1 && m_z[i] >= 1) 
00225         Vx[2][0] += Intervald(m_a[i]*m_x[i]*m_z[i])*
00226                     (x[0].pow(m_x[i]-1)*x[1].pow(m_y[i])  *x[2].pow(m_z[i]-1));
00227     }
00228 
00229   // Make symmetric
00230   Vx[0][1] = Vx[1][0];
00231   Vx[1][2] = Vx[2][1];
00232   Vx[0][2] = Vx[2][0];
00233 
00234   return Vx;
00235 }
00236 
00237 /** Returns scalar factor of the x^i y^j z^k term.
00238  * \param i exponent for x.
00239  * \param j exponent for y.
00240  * \param k exponent for z.
00241  * \return scalar factor of the x^i y^j z^k term.
00242  */
00243 double Algebraic::getCoef(int i, int j, int k)
00244 {
00245   return m_a[getCoefIndex(i, j, k)];
00246 }
00247 
00248 /** Sets coefficient of x^i y^j z^k to a.
00249  * \param i exponent for x.
00250  * \param j exponent for y.
00251  * \param k exponent for z.
00252  * \param a Coefficient for x^i y^j z^k.
00253  */
00254 void Algebraic::setCoef(int i, int j, int k, double a)
00255 {
00256   m_a[getCoefIndex(i, j, k)] = a;
00257 }
00258 
00259 int Algebraic::getNumCoef()
00260 {
00261   return m_numCoef;
00262 }
00263 
00264 int Algebraic::degree()
00265 {
00266   return m_d;
00267 }
00268 
00269 /** Compute the number of terms for a degree d trivariate polynomial.
00270  * Degree d algebraic has (d^3 + 6d^2 + 11d + 6)/6 coefficients.
00271  *
00272  * 0: 1
00273  * 1: 3 + 1 = 4
00274  * 2: 6 + 4 = 10
00275  * 3: 10 + 10 = 20
00276  *
00277  * # of terms of degree d = d+1 + # of terms of degree d-1.
00278  * Why? Multiply x times terms of degree d-1, then all that
00279  * is left are terms containing only y and z. There are d+1
00280  * of these. E.g. yyy yyz yzz zzz
00281  *
00282  * Hence terms(d) = d+1 + terms(d-1) and terms(0) = 1.
00283  * This yields terms(d) = sum[i = 1..d+1] i
00284  * = (d+2)*(d+1)/2  (Recall sum[i = 1..n] i = (n+1)*n/2)
00285  * = 1/2 d^2 + 3/2 d + 1.
00286  *
00287  * The # of terms of degree d or less is thus
00288  *   sum[i = 0..d] terms(i)
00289  * = sum[i = 0..d] 1/2 d^2 + 3/2 d + 1
00290  * = 1/2 * d*(d+1)*(2d+1)/6 + 3/2 * d*(d+1)/2 + d+1
00291  *            (Recall sum[i = 1..n] i^2 = n(n+1)(2n+1)/6)
00292  * = 1/12 * (2d^3 + 3d^2 + d) + 3/4 * (d^2 + d) + d + 1
00293  * = d^3/6 + d^2 + 1 10/12 d + 1.
00294  */
00295 int Algebraic::coefficients(int d)
00296 {
00297   return (6 + d * (11 + d * (6 + d))) / 6;
00298 }
00299 
00300 /** Set the number of coefficients in m_numCoef
00301  * based on the current degree held in m_d.
00302  */
00303 void Algebraic::calcNumCoef()
00304 {
00305   m_numCoef = coefficients(m_d);
00306 }
00307 
00308 /** Returns coefficient-order index for x^i y^j z^k term. Resulting
00309  * index used for m_a, m_x, m_y, m_z, m_xPow, m_yPow and m_zPow.
00310  *
00311  * Coefficient order is constant first, then x, then y, then z. For a
00312  * quadric, coefficient order is: 1, x, y, x^2, xy, y^2, z, xz, yz, z^2.
00313  *
00314  * \todo: Coefficient order should be by degree, so for a quadric it should
00315  * be: 1 x y z x^2 xy y^2 xz yz z^2. This way changing the degree means reducing
00316  * or extending the parameter list without necessarily reordering the lower
00317  * degree elements.
00318  *
00319  * 1 \\
00320  *
00321  * x y \\
00322  * z
00323  *
00324  * xx xy yy \\
00325  * xz yz \\
00326  * zz
00327  *
00328  * xxx xxy xyy yyy \\
00329  * xxz xyz yyz \\
00330  * xzz yzz \\
00331  * zzz
00332  *
00333  * Coordinates:
00334  *   level: d = i+j+k (degree)
00335  *   horizontal: j
00336  *   vertical: k
00337  *
00338  * Answer is:
00339  *   coefficients(d) - sum[kk=1..d+1-k](kk) + j
00340  * = coefficients(d) - sum[kk=1..i+j+1](kk) + j (since d = i+j+k)
00341  * = coefficients(d) - (i+j+1)(i+j+2)/2 + j
00342  * = coefficients(d) - (i*i + 2*i*j + j*j + 3*i + 3*j + 2)/2 + j
00343  *
00344  * \param i exponent of x
00345  * \param j exponent of y
00346  * \param k exponent of z
00347  * \return coefficient-order index for x^i y^j z^k.
00348  */
00349 int Algebraic::getCoefIndex(int i, int j, int k)
00350 {
00351     /* return (3*j + 3*(j*j + 2*i*j + i*(i + 3)) + k*(k*k - 3*(m_d + 2)*k + 3*m_d*(m_d + 4) + 11))/6; */
00352   // swapped j <-> i to get correct xyz order of coefficients.
00353     /* return (3*i + 3*(i*i + 2*j*i + j*(j + 3)) + k*(k*k - 3*(m_d + 2)*k + 3*m_d*(m_d + 4) + 11))/6; */
00354 
00355   /* Using above derivation */
00356   return coefficients(i+j+k) - (i*i + 2*i*j + j*j + 3*i + 3*j + 2)/2 + j;
00357 }
00358 
00359 /** Initialize the m_x,m_y and m_z arrays to their corresponding
00360  * exponents in coefficient order.
00361  */
00362 void Algebraic::initPowerArrays()
00363 {
00364   int i, j, k;
00365   int coefIndex;
00366 
00367   for (i=0; i<=m_d; i++) 
00368     for (j=0; j<=m_d-i; j++) 
00369       for (k=0; k<=m_d-(i+j); k++) 
00370         {
00371           coefIndex = getCoefIndex(i, j, k);
00372           m_x[coefIndex] = i;
00373           m_y[coefIndex] = j;
00374           m_z[coefIndex] = k;
00375         }
00376 }
00377 
00378 /** Fills m_[xyz]Pow cache with powers of x, y and z.
00379  * Efficiently computes powers by using results of lower powers.
00380  * \param v The input x,y,z.
00381  * \note Remembers last v to avoid recomputation.
00382  * \todo Could memoize (hash) v to possibly avoid more recomputation.
00383  * Need to build a general datastructure to handle this. Perhaps this
00384  * should be handled at a higher level (e.g. as in Bloomenthal's marching
00385  * cubes implementation).
00386  */
00387 void Algebraic::initXYZPowerArrays(gmVector3 v)
00388 {
00389   int i;
00390 
00391   // Check to see if m_[xyz]Pow[] arrays already contain correct answer.
00392   if ((m_xPow[1] == v[0]) && (m_yPow[1] == v[1]) && (m_zPow[1] == v[2])) 
00393     return;
00394 
00395   m_xPow[0] = m_yPow[0] = m_zPow[0] = 1;
00396   for (i=1; i<=m_d; i++) 
00397     {
00398       m_xPow[i] = m_xPow[i-1] * v[0];
00399       m_yPow[i] = m_yPow[i-1] * v[1];
00400       m_zPow[i] = m_zPow[i-1] * v[2];
00401     }
00402 }
00403 
00404 double Algebraic::dx(gmVector3 v)
00405 {
00406   double deriv = 0.0;
00407 
00408   initXYZPowerArrays(v);
00409   for (int i=0; i<m_numCoef; i++) 
00410     {
00411       if (m_x[i] >= 1) 
00412         deriv += m_a[i] * m_x[i] * 
00413                  m_xPow[m_x[i]-1] * m_yPow[m_y[i]] * m_zPow[m_z[i]];
00414     }
00415   return deriv;
00416 }
00417 
00418 double Algebraic::dy(gmVector3 v)
00419 {
00420   double deriv = 0.0;
00421 
00422   initXYZPowerArrays(v);
00423   for (int i=0; i<m_numCoef; i++) 
00424     {
00425       if (m_y[i] >= 1)
00426         deriv += m_a[i] * m_y[i] * 
00427                  m_xPow[m_x[i]] * m_yPow[m_y[i]-1] * m_zPow[m_z[i]];
00428     }
00429   return deriv;
00430 }
00431 
00432 double Algebraic::dz(gmVector3 v)
00433 {
00434   double deriv = 0.0;
00435 
00436   initXYZPowerArrays(v);
00437   for (int i=0; i<m_numCoef; i++) 
00438     {
00439       if (m_z[i] >= 1) 
00440         deriv += m_a[i] * m_z[i] * 
00441                  m_xPow[m_x[i]] * m_yPow[m_y[i]] * m_zPow[m_z[i]-1];
00442     }
00443   return deriv;
00444 }
00445 
00446 double Algebraic::dx2(gmVector3 v)
00447 {
00448   double deriv = 0.0;
00449 
00450   initXYZPowerArrays(v);
00451   for (int i=0; i<m_numCoef; i++) 
00452     {
00453       if (m_x[i] >= 2) 
00454         deriv += m_a[i] * m_x[i] * (m_x[i]-1) * 
00455                  m_xPow[m_x[i]-2] * m_yPow[m_y[i]] * m_zPow[m_z[i]];
00456     }
00457   return deriv;
00458 }
00459 
00460 double Algebraic::dy2(gmVector3 v)
00461 {
00462   double deriv = 0.0;
00463 
00464   initXYZPowerArrays(v);
00465   for (int i=0; i<m_numCoef; i++) 
00466     {
00467       if (m_y[i] >= 2) 
00468         deriv += m_a[i] * m_y[i] * (m_y[i]-1) * 
00469                  m_xPow[m_x[i]] * m_yPow[m_y[i]-2] * m_zPow[m_z[i]];
00470     }
00471   return deriv;
00472 }
00473 
00474 double Algebraic::dz2(gmVector3 v)
00475 {
00476   double deriv = 0.0;
00477 
00478   initXYZPowerArrays(v);
00479   for (int i=0; i<m_numCoef; i++) 
00480     {
00481       if (m_z[i] >= 2) 
00482         deriv += m_a[i] * m_z[i] * (m_z[i]-1) * 
00483                  m_xPow[m_x[i]] * m_yPow[m_y[i]] * m_zPow[m_z[i]-2];
00484     }
00485   return deriv;
00486 }
00487 
00488 double Algebraic::dxdy(gmVector3 v)
00489 {
00490   double deriv = 0.0;
00491 
00492   initXYZPowerArrays(v);
00493   for (int i=0; i<m_numCoef; i++) 
00494     {
00495       if ((m_x[i] >= 1) && (m_y[i] >= 1)) 
00496         deriv += m_a[i] * m_x[i] * m_y[i] * 
00497                  m_xPow[m_x[i]-1] * m_yPow[m_y[i]-1] * m_zPow[m_z[i]];
00498     }
00499   return deriv;
00500 }
00501 
00502 double Algebraic::dxdz(gmVector3 v)
00503 {
00504   double deriv = 0.0;
00505 
00506   initXYZPowerArrays(v);
00507   for (int i=0; i<m_numCoef; i++) 
00508     {
00509       if ((m_x[i] >= 1) && (m_z[i] >= 1)) 
00510         deriv += m_a[i] * m_x[i] * m_z[i] * 
00511                  m_xPow[m_x[i]-1] * m_yPow[m_y[i]] * m_zPow[m_z[i]-1];
00512     }
00513   return deriv;
00514 }
00515 
00516 double Algebraic::dydz(gmVector3 v)
00517 {
00518   double deriv = 0.0;
00519 
00520   initXYZPowerArrays(v);
00521   for (int i=0; i<m_numCoef; i++) 
00522     {
00523       if ((m_y[i] >= 1) && (m_z[i] >= 1)) 
00524         deriv += m_a[i] * m_y[i] * m_z[i] * 
00525                  m_xPow[m_x[i]] * m_yPow[m_y[i]-1] * m_zPow[m_z[i]-1];
00526     }
00527   return deriv;
00528 }
00529 
00530 /** Computes dproc()/dq for an algebraic.
00531  *  Each term of the algebraic is of the form a x^i y^j z^k so
00532  *  its derivative with respect to a is just x^i y^j z^k.
00533  */
00534 void Algebraic::procq(gmVector3 x, double* dfdq) 
00535 {
00536   int i;
00537 
00538   initXYZPowerArrays(x);
00539   for (i=0; i<m_numCoef; i++) 
00540     dfdq[i] = m_xPow[m_x[i]] * m_yPow[m_y[i]] * m_zPow[m_z[i]];  
00541     // dfdq is just the x^i y^j z^k of term with the given q as coefficient
00542 }
00543 
00544 /** Computes dproc()/dq in Interval form for an algebraic.
00545  *  Each term of the algebraic is of the form a x^i y^j z^k so
00546  *  its derivative with respect to a is just x^i y^j z^k.
00547  */
00548 void Algebraic::procq(Box<double> x, Intervald* dfdq)
00549 {
00550   int i;
00551 
00552   for (i=0; i<m_numCoef; i++) 
00553     dfdq[i] = x[0].pow(m_x[i]) * x[1].pow(m_y[i]) * x[2].pow(m_z[i]);
00554 }
00555 
00556 /** Computes dgrad()/dq = d^2proc/dxdq and stores it in
00557  * three arrays.
00558  *
00559  * \param dfdxdq returns Intervald x components of dgrad()/dq
00560  * \param dfdydq returns Intervald y components of dgrad()/dq
00561  * \param dfdzdq returns Intervald z components of dgrad()/dq
00562  *
00563  * Arrays should be preallocated to length qlen().
00564  *
00565  * Assume f(x,y,z) = a x^i y^j z^k.
00566  * Then df/dx = a i x^(i-1) y^j z^k.
00567  * Then d^2f/dxda = i x^(i-1) y^j z^k.
00568  */
00569 
00570 void Algebraic::gradq(Box<double> x, 
00571                       Intervald* dfdxdq, Intervald* dfdydq, Intervald* dfdzdq)
00572 {
00573   for (int i = 0; i < m_numCoef; i++) 
00574     {
00575       dfdxdq[i] = (Intervald(m_x[i]) *
00576                    x[0].pow(m_x[i]-1)*x[1].pow(m_y[i])  *x[2].pow(m_z[i]));
00577       dfdydq[i] = (Intervald(m_y[i]) *
00578                    x[0].pow(m_x[i])  *x[1].pow(m_y[i]-1)*x[2].pow(m_z[i]));
00579       dfdzdq[i] = (Intervald(m_z[i]) *
00580                    x[0].pow(m_x[i])  *x[1].pow(m_y[i])  *x[2].pow(m_z[i]-1));
00581     }
00582 }
00583 
00584 void Algebraic::getq(double* q) 
00585 {
00586   int i;
00587 
00588   for (i=0; i<m_numCoef; i++)
00589     q[i] = m_a[i];
00590 }
00591 
00592 void Algebraic::_setq(double* q)
00593 {
00594   for (int i=0; i<m_numCoef; i++) 
00595     m_a[i] = q[i];
00596 }
00597 
00598 int Algebraic::qlen() 
00599 {
00600   return m_numCoef;
00601 }
00602 
00603 void Algebraic::getqname(char** qn)
00604 {
00605   int i;
00606   char s[32];
00607 
00608   for (i = 0; i < m_numCoef; i++)
00609     {
00610       qn[i] = new char[32];
00611       qn[i][0] = '\0';
00612       if (m_x[i]) 
00613         {
00614           if (m_x[i] == 1) 
00615             strcat(qn[i],"x");
00616           else 
00617             {
00618               sprintf(s,"x^%d",m_x[i]);
00619               strcat(qn[i],s);
00620             }
00621         }
00622       if (m_y[i]) 
00623         {
00624           if (!qn[i][0])
00625             strcat(qn[i]," ");
00626           if (m_y[i] == 1) 
00627             strcat(qn[i],"y");
00628           else 
00629             {
00630               sprintf(s,"y^%d",m_y[i]);
00631               strcat(qn[i],s);
00632             }
00633         }
00634       if (m_z[i]) 
00635         {
00636           if (!qn[i][0])
00637             strcat(qn[i]," ");
00638           if (m_z[i] == 1) 
00639             strcat(qn[i],"z");
00640           else 
00641             {
00642               sprintf(s,"z^%d",m_z[i]);
00643               strcat(qn[i],s);
00644             }
00645         }
00646       if (!qn[i][0])
00647         strcat(qn[i],"1");
00648     }
00649 }
00650 

Generated on Mon Jun 28 14:58:12 2004 for Advanced Surface Library by doxygen 1.3.4