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

RFunction.h

Go to the documentation of this file.
00001 /**
00002  * @file RFunction.h
00003  * Common base class for unions and intersections; both are defined using
00004  * R-Functions, with only a difference in sign in one of the terms.
00005  *
00006  * @author Steve Zelinka
00007  */
00008 
00009 #ifndef _RFUNCTION_H
00010 #define _RFUNCTION_H
00011 
00012 #include "Blend.h"
00013 
00014 /** 
00015  * A subclass of blending that implements R-functions for CSG.
00016  * R-functions are blending functions that apply CSG operations
00017  * to implicit surfaces. The benefit of R-functions are that they
00018  * smooth the field surrounding the zero-surfaces to eliminate
00019  * the creasing that can result from, say, min and max functions.
00020  */
00021 class RFunction : public Blend
00022 {
00023   protected:
00024     /**
00025      * The continuity to be provided.
00026      * This is stored as a double to avoid integer
00027      * round-offs later.
00028      */
00029     double m_cont;
00030 
00031     /**
00032      * The sign of the second-half of the RFunction.
00033      * This differentiates
00034      * a union (= -1) from an intersection (= 1).
00035      * @note The sign is opposite of that used in the
00036      * original R-function paper where f<0 outside.
00037      */
00038     int m_sign;
00039 
00040     /**
00041      * Evaluates the R-function on the two function values.
00042      *
00043      * @param f  The value of f.
00044      * @param g  The value of g.
00045      * @return (f + g + m_sign*(sqrt(f^2+g^2)))*(f^2+g^2)^(m_cont/2).
00046      */
00047     virtual double h(double f, double g);
00048     virtual Intervald h(Intervald f, Intervald g);
00049 
00050     /**
00051      * Evaluates the partial derivative with respect to f
00052      * on the two function values.
00053      *
00054      * h = (f + g + m_sign*(sqrt(f^2+g^2)))*(f^2+g^2)^(m_cont/2).
00055      * hf = (f^2+g^2)^(m_cont/2)*d(f + g + m_sign*(sqrt(f^2+g^2)))/df +
00056      *      (f + g + m_sign*(sqrt(f^2+g^2)))*d(f^2+g^2)^(m_cont/2)/df
00057      *    = (f^2+g^2)^(m_cont/2)*(1 + m_sign*f/sqrt(f^2+g^2)) +
00058      *      (f + g + m_sign*(sqrt(f^2+g^2)))*m_cont*f*(f^2+g^2)^(m_cont/2 - 1).
00059      *
00060      * @param f The value of f.
00061      * @param g The value of g.
00062      * @return hf.
00063      *
00064      * \note Appears to work fine when tested with particles.
00065      */
00066     virtual double hf(double f, double g);
00067     virtual Intervald hf(Intervald f, Intervald g);
00068 
00069     /**
00070      * Evaluates the partial derivative with respect to g
00071      * on the two function values.
00072      *
00073      * h = (f + g + m_sign*(sqrt(f^2+g^2)))*(f^2+g^2)^(m_cont/2).
00074      * hg = (f^2+g^2)^(m_cont/2)*d(f + g + m_sign*(sqrt(f^2+g^2)))/dg +
00075      *      (f + g + m_sign*(sqrt(f^2+g^2)))*d(f^2+g^2)^(m_cont/2)/dg
00076      *    = (f^2+g^2)^(m_cont/2)*(1 + m_sign*g/sqrt(f^2+g^2)) +
00077      *      (f + g + m_sign*(sqrt(f^2+g^2)))*m_cont*g*(f^2+g^2)^(m_cont/2 - 1).
00078      *
00079      * @param f The value of f.
00080      * @param g The value of g.
00081      * @return hg.
00082      *
00083      * \note Appears to work fine when tested with particles.
00084      */
00085     virtual double hg(double f, double g);
00086     virtual Intervald hg(Intervald f, Intervald g);
00087 
00088     /**
00089      * Evaluates the 2nd partial derivative with respect to f
00090      * and f on the two function values.
00091      *
00092      * fg = sqrt(f^2 + g^2)
00093      * dfg/df = f/fg
00094      * hf  = fg^m_cont*(1 + m_sign*f/fg) +
00095      *       (f + g + m_sign*fg)*m_cont*f*fg^(m_cont - 2)
00096      *     = fg^m_cont + m_sign*f*fg^(m_cont-1) +
00097      *       (f + g + m_sign*fg)*m_cont*f*fg^(m_cont - 2)
00098      * hff = m_cont*fg^(m_cont-1)*dfg/df +
00099      *       m_sign*f*(m_cont-1)*fg^(m_cont-2)*dfg/df +
00100      *       m_sign*fg^(m_cont-1) +
00101      *       (1 + m_sign*dfg/df)*m_cont*f*fg^(m_cont - 2) +
00102      *       (f + g + m_sign*fg)*m_cont*(f*(m_cont - 2)*fg^(m_cont - 3)*dfg/df +
00103      *       fg^(m_cont - 2))
00104      *     = m_cont*f*fg^(m_cont-2) +
00105      *       m_sign*(m_cont-1)*f^2*fg^(m_cont-3) +
00106      *       m_sign*fg^(m_cont-1) +
00107      *       m_cont*f*fg^(m_cont - 2) + m_cont*m_sign*f^2*fg^(m_cont - 3) +
00108      *       m_cont*(f + g + m_sign*fg)*((m_cont - 2)*f^2*fg^(m_cont - 4) + 
00109      *       fg^(m_cont - 2))
00110      * 
00111      * @param f The value of f.
00112      * @param g The value of g.
00113      * @return hff.
00114      *
00115      * \note Needs to be tested.
00116      */
00117     virtual double hff(double f, double g);
00118     virtual Intervald hff(Intervald f, Intervald g);
00119 
00120     /**
00121      * Evaluate the 2nd partial derivative with respect to f
00122      * and g on the two function values.
00123      *
00124      * fg = sqrt(f^2 + g^2)
00125      * dfg/dg = g/fg
00126      * hf  = fg^m_cont*(1 + m_sign*f/fg) +
00127      *       (f + g + m_sign*fg)*m_cont*f*fg^(m_cont - 2)
00128      *     = fg^m_cont + m_sign*f*fg^(m_cont-1) +
00129      *       (f + g + m_sign*fg)*m_cont*f*fg^(m_cont - 2)
00130      * hfg = m_cont*fg^(m_cont-1)*dfg/dg +
00131      *       m_sign*f*(m_cont-1)*fg^(m_cont-2)*dfg/dg +
00132      *       m_sign*fg^(m_cont-1) +
00133      *       (1 + m_sign*dfg/dg)*m_cont*f*fg^(m_cont - 2) +
00134      *       (f + g + m_sign*fg)*m_cont*(f*(m_cont - 2)*fg^(m_cont - 3)*dfg/dg +
00135      *       fg^(m_cont - 2))
00136      *     = m_cont*g*fg^(m_cont-2) +
00137      *       m_sign*(m_cont-1)*f*g*fg^(m_cont-3) +
00138      *       m_sign*fg^(m_cont-1) +
00139      *       m_cont*f*fg^(m_cont - 2) + m_cont*m_sign*f*g*fg^(m_cont - 3) +
00140      *       m_cont*(f + g + m_sign*fg)*((m_cont - 2)*f*g*fg^(m_cont - 4) + 
00141      *       fg^(m_cont - 2))
00142      * 
00143      * @param f The value of f.
00144      * @param g The value of g.
00145      * @return hfg.
00146      *
00147      * \note Needs to be tested.
00148      */
00149     virtual double hfg(double f, double g);
00150     virtual Intervald hfg(Intervald f, Intervald g);
00151 
00152     /**
00153      * Return the 2nd partial derivative with respect to g
00154      * and g on the two function values.
00155      *
00156      * fg = sqrt(f^2 + g^2)
00157      * dfg/dg = g/fg
00158      * hg  = fg^m_cont*(1 + m_sign*g/fg) +
00159      *       (f + g + m_sign*fg)*m_cont*g*fg^(m_cont - 2)
00160      *     = fg^m_cont + m_sign*g*fg^(m_cont-1) +
00161      *       (f + g + m_sign*fg)*m_cont*g*fg^(m_cont - 2)
00162      * hgg = m_cont*fg^(m_cont-1)*dfg/dg +
00163      *       m_sign*g*(m_cont-1)*fg^(m_cont-2)*dfg/dg +
00164      *       m_sign*fg^(m_cont-1) +
00165      *       (1 + m_sign*dfg/dg)*m_cont*g*fg^(m_cont - 2) +
00166      *       (f + g + m_sign*fg)*m_cont*(g*(m_cont - 2)*fg^(m_cont - 3)*dfg/dg +
00167      *       fg^(m_cont - 2))
00168      *     = m_cont*g*fg^(m_cont-2) +
00169      *       m_sign*(m_cont-1)*g^2*fg^(m_cont-3) +
00170      *       m_sign*fg^(m_cont-1) +
00171      *       m_cont*g*fg^(m_cont - 2) + m_cont*m_sign*g^2*fg^(m_cont - 3) +
00172      *       m_cont*(f + g + m_sign*fg)*((m_cont - 2)*g^2*fg^(m_cont - 4) + 
00173      *       fg^(m_cont - 2))
00174      * 
00175      * @param f The value of f.
00176      * @param g The value of g.
00177      * @return hgg.
00178      *
00179      * \note Needs to be tested.
00180      */
00181     virtual double hgg(double f, double g);
00182     virtual Intervald hgg(Intervald f, Intervald g);
00183 };
00184 
00185 #endif
00186 

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