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

Blinn.cpp

Go to the documentation of this file.
00001 /**
00002  * @file Blinn.cpp
00003  * Implementation of Blinn class
00004  */
00005 
00006 #include <math.h>
00007 #include "Blinn.h"
00008 
00009 REGISTER_IMPLICIT(Blinn,"UnaryOp:Blob:Blinn");
00010 
00011 /**
00012  *  Called by the various constructors to allow for a single location for
00013  *  the init of a Blinn object.
00014  */
00015 void Blinn::init(Quadric *f, double b, double r)
00016 {
00017   m_f = f;
00018   m_r = r;
00019   m_b = b;
00020 }
00021 
00022 /// Default constructor.
00023 Blinn::Blinn()
00024 {
00025   init(NULL,1.0,1.0);
00026 }
00027 
00028 /**
00029  * Class Constructor
00030  * Takes a pointer to an arbitrary quadric 
00031  * as an argument and initializes Blobbiness 
00032  * and Radius to 1
00033  */
00034 Blinn::Blinn(Quadric *f)
00035 {
00036   init(f,1.0,1.0);
00037 }
00038 
00039 /**
00040  * Class Constructor:
00041  * Takes a pointer to an arbitrary quadric 
00042  * and scalar Blobbiness b as agruments and
00043  * initializes Radius to 1
00044  */
00045 Blinn::Blinn(Quadric *f, double b)
00046 {
00047   init(f,b,1.0);
00048 }
00049 
00050 /**
00051  * Class Constructor:
00052  * Takes a pointer to an arbitrary quadric, 
00053  * a scalar Blobbiness b, and a scalar Blob
00054  * Radius r as agruments
00055  */
00056 Blinn::Blinn(Quadric *f, double b, double r)
00057 {
00058   init(f,b,r);
00059 }
00060 
00061 /**
00062  * Returns the evaluation of the Blob at 
00063  * the specified 3-space point
00064  *
00065  * The Blinn Blob f(v) is defined as:
00066  *    f(v) = exp (-(B/R^2)r^2 + B)
00067  *
00068  *    where r^2 = quadric f(v)
00069  */
00070 double Blinn::kernel(double r2)
00071 {
00072   double blob;
00073 
00074   // definiton of Blinn Blob:
00075   blob = exp ((-1.0f * (m_b / (m_r * m_r)) * r2 + m_b));        
00076 
00077   return blob;
00078 }
00079 
00080 /**
00081  * Kernel derivative of the Blinn Blob is
00082  * defined as follows:
00083  *
00084  *    d/dr^2 = (-B/R^2) f(r^2)
00085  *
00086  *    where f(r^2) = kernel eval'd at r^2
00087  *           B = blobbiness
00088  *           R = rest radius
00089  */
00090 double Blinn::dkernel(double r2)
00091 {
00092   double c = -1.0f * m_b / (m_r * m_r); 
00093   return c * kernel(r2);
00094 }
00095 
00096 /**
00097  * Kernel second derivative of the Blinn Blob  
00098  * is defined as follows:
00099  *
00100  *    d/d2r^2 = (-B/R^2)(-B/R^2) f(r^2)
00101  *
00102  *    where f(r^2) = kernel eval'd at r^2
00103  */
00104 double Blinn::d2kernel(double r2)
00105 {
00106   double c = -1.0f * m_b / (m_r * m_r); 
00107   return c * dkernel(r2);
00108 }
00109 
00110 Intervald Blinn::kernel(Intervald r2)
00111 {
00112   Intervald blob;
00113 
00114   blob = Intervald(-1.0) * Intervald(m_b / (m_r * m_r)) * r2 + Intervald(m_b);
00115   return blob.exp();
00116 }
00117 
00118 Intervald Blinn::dkernel(Intervald r2)
00119 {
00120   double c = -1.0f * m_b / (m_r * m_r);
00121   return kernel(r2) * Intervald(c);
00122 }
00123 
00124 Intervald Blinn::d2kernel(Intervald r2)
00125 {
00126   double c = -1.0f * m_b / (m_r * m_r);
00127   return dkernel(r2) * Intervald(c);
00128 }
00129 
00130 /**
00131  * Function qlen returns the parameter list 
00132  * for the definition of a Blob
00133  */
00134 int Blinn::qlen(void)
00135 {
00136   // queue length equal to length of 
00137   // queue for the radius function plus
00138   // rest radius and blobbiness variables
00139   int retval = 2;
00140   if (m_f)
00141     retval += m_f->qlen();
00142   return retval;
00143 }
00144 
00145 /**
00146  * Function _setq sets the parameters
00147  * defining the Blob to those specified
00148  * by array q
00149  * @note Does not alter q
00150  */
00151 void Blinn::_setq(double *q)
00152 {
00153   m_r = q[0];
00154   m_b = q[1];
00155 
00156   if (m_f == NULL)
00157     return;
00158 
00159   double *m_fq = new double[m_f->qlen()];
00160 
00161   // alter queue parameters of the
00162   // radius function
00163   for (int i = 2; i < qlen (); i++)
00164     m_fq[i - 2] = q[i];
00165 
00166   m_f->_setq(m_fq);
00167 
00168   delete[] m_fq;
00169 }
00170 
00171 /**
00172  * Function getq returns an array q of the 
00173  * parameter values defining the present
00174  * Blob
00175  *
00176  * Array length required to be at least 
00177  * this->qlen () in size
00178  */
00179 void Blinn::getq(double *q)
00180 {
00181   q[0] = m_r;
00182   q[1] = m_b;
00183 
00184   if (m_f == NULL)
00185     return;
00186 
00187   double *m_fq = new double[m_f->qlen()];
00188   m_f->getq(m_fq);
00189 
00190   // add queue parameters specified
00191   // by the radius function
00192   for (int i = 2; i < qlen (); i++)
00193     q[i] = m_fq[i - 2];
00194 
00195   delete[] m_fq;
00196 }
00197 
00198 /**
00199  * Function getqname returns an array of 
00200  * strings defining in english the names
00201  * of parameters for the Blob
00202  *
00203  * Array required to have at least qlen ()
00204  * pointers to strings
00205  */
00206 void Blinn::getqname(char** qn)
00207 {
00208   qn[0] = "Rest radius R";
00209   qn[1] = "Blobbiness  B"; 
00210 
00211   if (m_f != NULL)
00212     {
00213       char **m_fqname = new char*[m_f->qlen()];
00214       m_f->getqname(m_fqname);
00215 
00216       for (int i = 2; i < qlen (); i++)
00217         qn[i] = m_fqname[i - 2];
00218 
00219       delete[] m_fqname;
00220    }
00221 }
00222 
00223 /**
00224  * Derivatives of parameters defined 
00225  * as follows:
00226  *
00227  *    d/dB   = f(v)(-(1/R^2)r^2 + 1) 
00228  *    d/dR   = f(v)((2B/R^3)r^2)
00229  *    d/dr^2 = f(v)(-(B/R^2)(df/dq r^2))
00230  *
00231  *    where f(v) = exp (-(B/R^2)r^2 + B)
00232  *           r^2 = quadric radius function
00233  */
00234 void  Blinn::procq(gmVector3 x, double* dfdq)
00235 {
00236   // an operand surface is defined
00237   if (m_f != NULL)
00238     {
00239       double R2   = m_r * m_r;
00240       double r2   = m_f->proc(x);
00241       double blob = m_f->proc(x);
00242 
00243       dfdq[0] = blob * (( 2.0f * r2 * m_b) / (R2 * m_r));
00244       dfdq[1] = blob * ((-1.0f * r2)                 /  R2+ 1.0f);
00245 
00246       double *m_fdfdq = new double[m_f->qlen ()];
00247       m_f->procq (x, m_fdfdq);
00248 
00249       for (int i = 2; i < qlen (); i++)
00250         dfdq[i] = blob * ((-1.0f * m_fdfdq[i - 2] * m_b) / R2);
00251 
00252       delete[] m_fdfdq;
00253     }
00254 }
00255 

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