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

# Tools/PotentialFields/PotentialFunctions.h

Go to the documentation of this file.

    00001 /**
    00002 * @file PotentialFunctions.h
    00003 *
    00004 * Definition of several functions used by potential fields
    00005 *
    00006 * @author <a href="mailto:timlaue@informatik.uni-bremen.de">Tim Laue</a>
    00007 */
    00008
    00009 #ifndef POTENTIAL_FUNCTIONS_H_
    00010 #define POTENTIAL_FUNCTIONS_H_
    00011
    00012
    00013 #include <cmath>
    00014 #include <cassert>
    00015
    00016 class PfPose;
    00017 class PfVec;
    00018 class Sector;
    00019 class Polygon;
    00020 class PfieldGeometricObject;
    00021
    00022
    00023 /** The object types */
    00024 enum ObjectType {ATTRACTIVE, REPULSIVE};
    00025
    00026 /** The function types */
    00027 enum FunctionType {NO_FUNCTION, LINEAR_FUNCTION, PARABOLIC_FUNCTION, ASYMPTOTIC_FUNCTION};
    00028
    00029 /** The field types */
    00030 enum FieldType {POINT_FIELD, SHAPE_FIELD, SECTOR_FIELD};
    00031
    00032
    00033 /**
    00034 * @class PotentialfieldFunction
    00035 *
    00036 * An abstract class representing a function in a potential field
    00037 */
    00038 class PotentialfieldFunction
    00039 {
    00040 public:
    00041   /** Computes the value of the function for a given x
    00042   * including range checking and smoothing
    00043   * @param x The distance for which to compute the value of the function
    00044   * @param smooth Flag: Use smoothing, if true
    00045   * @return The value of the function
    00046   */
    00047   virtual double computeValue(double x, bool smooth=true);
    00048
    00049   /** Computes the value of the derivative of the function for a given x
    00050   * including range checking and smoothing
    00051   * @param x The distance for which to compute the value of the function
    00052   * @param smooth Flag: Use smoothing, if true
    00053   * @return The value of the function
    00054   */
    00055   virtual double computeDerivativeValue(double x, bool smooth=false);
    00056
    00057   /** Clones a function object
    00058   * @return A pointer to a copy of the object
    00059   */
    00060   virtual PotentialfieldFunction* clone() = 0;
    00061
    00062   /** Returns the range of the function
    00063   * @return The range
    00064   */
    00065   double getRange()
    00066   { return range;}
    00067
    00068   /** Sets the two main parameters, recomputes smoothing parameters
    00069   * @param atZero The value of f(0)
    00070   * @param range At range, f(range) is 0
    00071   */
    00072   void setParameters(double atZero, double range)
    00073   {
    00074     this->atZero = atZero;
    00075     this->range = range;
    00076     smoothingAtObjectPosition = smoothingAtObjectPercentage*range;
    00077     smoothingAtBorderPosition = range - smoothingAtBorderPercentage*range;
    00078     init();
    00079   }
    00080
    00081   /** Sets parameters for smoothing at the end of the function's interval
    00082   *   Both values have a range from 0.0 to 1.0
    00083   * @param smoothingAtObject Smoothing near the object
    00084   * @param smoothingAtBorder Smoothing near the end of the range
    00085   * @param gradientAtObject The gradient at the object
    00086   * @param gradientAtBorder The gradient at (range,0)
    00087   */
    00088   void setSmoothingParameters(double smoothingAtObject,
    00089                               double smoothingAtBorder,
    00090                               double gradientAtObject,
    00091                               double gradientAtBorder)
    00092   {
    00093     this->gradientAtObject = gradientAtObject;
    00094     this->gradientAtBorder = gradientAtBorder;
    00095     smoothingAtObjectPercentage = smoothingAtObject;
    00096     smoothingAtBorderPercentage = smoothingAtBorder;
    00097     smoothingAtObjectPosition = smoothingAtObject*range;
    00098     smoothingAtBorderPosition = range - smoothingAtBorder*range;
    00099   }
    00100
    00101 protected:
    00102   /** Last position of smoothing near object*/
    00103   double smoothingAtObjectPosition;
    00104   /** First position of smoothing near the end of the range*/
    00105   double smoothingAtBorderPosition;
    00106   /** The gradient at the object (used together with smoothing)*/
    00107   double gradientAtObject;
    00108   /** The gradient at (range,0) (used together with smoothing)*/
    00109   double gradientAtBorder;
    00110   /** Smoothing near object [0.0, .., 1.0] */
    00111   double smoothingAtObjectPercentage;
    00112   /** Smoothing near the end of the range [0.0, .., 1.0] */
    00113   double smoothingAtBorderPercentage;
    00114   /** The value of f(0) */
    00115   double atZero;
    00116   /** f(range) = 0 */
    00117   double range;
    00118   /** Internal variable for faster computation set by init()*/
    00119   double a;
    00120   /** Internal variable for faster computation set by init()*/
    00121   double b;
    00122
    00123   /** Generates a smooth curve between two points and computes function value
    00124   *   of a given x.
    00125   * @param x1 x component of the left end of the curve
    00126   * @param fx1 y component of the left end of the curve
    00127   * @param dx1 Gradient at (x1,fx1)
    00128   * @param x2 x component of the right end of the curve
    00129   * @param fx2 y component of the right end of the curve
    00130   * @param dx2 Gradient at (x2,fx22)
    00131   * @param x The position for which f(x) is computed
    00132   * @return A smoothed f(x)
    00133   */
    00134   double computeSmoothedValue(double x1, double fx1, double dx1,
    00135                               double x2, double fx2, double dx2,
    00136                               double x);
    00137
    00138   /** Computes the value of the function for a given x
    00139   * @param x The distance for which to compute the value of the function
    00140   * @return The value of the function
    00141   */
    00142   virtual double f(double x) const
    00143   { return 0.0;}
    00144
    00145   /** Computes the value of the derivative of the function for a given x
    00146   * @param x The distance for which to compute the value of the function
    00147   * @return The value of the function
    00148   */
    00149   virtual double d(double x) const
    00150   { return 0.0;}
    00151
    00152   /** Computes the value of the second derivative of the function for a given x
    00153   * @param x The distance for which to compute the value of the function
    00154   * @return The value of the function
    00155   */
    00156   virtual double dd(double x) const
    00157   { return 0.0;}
    00158
    00159   /** Computes the values of a and b*/
    00160   virtual void init() {}
    00161
    00162   /** Sets standard parameters from other function
    00163   * @param other The other function
    00164   */
    00165   void getStandardParameters(PotentialfieldFunction* other)
    00166   { this->smoothingAtObjectPosition = other->smoothingAtObjectPosition;
    00167     this->smoothingAtBorderPosition = other->smoothingAtBorderPosition;
    00168     this->gradientAtObject = other->gradientAtObject;
    00169     this->gradientAtBorder = other->gradientAtBorder;
    00170     this->smoothingAtObjectPercentage = other->smoothingAtObjectPercentage;
    00171     this->smoothingAtBorderPercentage = other->smoothingAtBorderPercentage;}
    00172 };
    00173
    00174
    00175 /**
    00176 * @class LinearFunction
    00177 *
    00178 * A class representing a linear function in a potential field
    00179 * f(x) = a*x +b
    00180 */
    00181 class LinearFunction: public PotentialfieldFunction
    00182 {
    00183 public:
    00184   /**
    00185   * Constructor
    00186   * @param range The range of the function
    00187   * @param atZero The value of the function for x having the value 0
    00188   */
    00189   LinearFunction(double range, double atZero)
    00190   {
    00191     this->atZero = atZero;
    00192     this->range = range;
    00193     init();
    00194   }
    00195
    00196   /** Clones a function object
    00197   * @return A pointer to a copy of the object
    00198   */
    00199   virtual PotentialfieldFunction* clone()
    00200   {
    00201     LinearFunction* newFunction = new LinearFunction(range,atZero);
    00202     newFunction->getStandardParameters(this);
    00203     return newFunction;
    00204   }
    00205
    00206 protected:
    00207   /** Computes the value of the function for a given x
    00208   * @param x The distance for which to compute the value of the function
    00209   * @return The value of the function
    00210   */
    00211   double f(double x) const
    00212   {
    00213     return (a*x + b);
    00214   }
    00215
    00216   /** Computes the value of the derivative of the function for a given x
    00217   * @param x The distance for which to compute the value of the function
    00218   * @return The value of the function
    00219   */
    00220   double d(double x) const
    00221   {
    00222     return a;
    00223   }
    00224
    00225   /** Computes the value of the second derivative of the function for a given x
    00226   * @param x The distance for which to compute the value of the function
    00227   * @return The value of the function
    00228   */
    00229   virtual double dd(double x) const
    00230   {
    00231     return 0.0;
    00232   }
    00233
    00234   /** Computes the values of a and b*/
    00235   virtual void init()
    00236   {
    00237     assert(range != 0.0);
    00238     a = -atZero/range;
    00239     b = atZero;
    00240   }
    00241 };
    00242
    00243
    00244 /**
    00245 * @class ParabolicFunction
    00246 *
    00247 * A class representing a parabolic function in a potential field
    00248 * f(x) = a*x*x +b
    00249 */
    00250 class ParabolicFunction: public PotentialfieldFunction
    00251 {
    00252 public:
    00253   /**
    00254   * Constructor
    00255   * @param range The range of the function
    00256   * @param atZero The value of the function for x having the value 0
    00257   */
    00258   ParabolicFunction(double range, double atZero)
    00259   {
    00260     this->atZero = atZero;
    00261     this->range = range;
    00262     init();
    00263   }
    00264
    00265   /** Clones a function object
    00266   * @return A pointer to a copy of the object
    00267   */
    00268   virtual PotentialfieldFunction* clone()
    00269   {
    00270     ParabolicFunction* newFunction = new ParabolicFunction(range,atZero);
    00271     newFunction->getStandardParameters(this);
    00272     return newFunction;
    00273   }
    00274
    00275 protected:
    00276   /** Computes the value of the function for a given x
    00277   * @param x The distance for which to compute the value of the function
    00278   * @return The value of the function
    00279   */
    00280   double f(double x) const
    00281   {
    00282     return (a*x*x + b);
    00283   }
    00284
    00285   /** Computes the value of the derivative of the function for a given x
    00286   * @param x The distance for which to compute the value of the function
    00287   * @return The value of the function
    00288   */
    00289   double d(double x) const
    00290   {
    00291     return (2.0*a*x);
    00292   }
    00293
    00294   /** Computes the value of the second derivative of the function for a given x
    00295   * @param x The distance for which to compute the value of the function
    00296   * @return The value of the function
    00297   */
    00298   virtual double dd(double x) const
    00299   {
    00300     return (2.0*a);
    00301   }
    00302
    00303   /** Computes the values of a and b*/
    00304   virtual void init()
    00305   {
    00306     assert(range != 0.0);
    00307     a = -atZero/(range*range);
    00308     b = atZero;
    00309   }
    00310 };
    00311
    00312
    00313 /**
    00314 * @class AsymptoticFunction
    00315 *
    00316 * A class representing an asymptotic function in a potential field
    00317 * f(x) = a/x +b
    00318 */
    00319 class AsymptoticFunction: public PotentialfieldFunction
    00320 {
    00321 public:
    00322   /**
    00323   * Constructor
    00324   * @param range The range of the function
    00325   * @param atZero The value of the function for x having the value 0
    00326   * @param solidCenter f(x) = atZero for x < solidCenter
    00327   */
    00328   AsymptoticFunction(double range, double atZero, double solidCenter)
    00329   {
    00330     this->atZero = atZero;
    00331     this->range = range;
    00332     this->solidCenter = solidCenter;
    00333     init();
    00334    }
    00335
    00336   /** Clones a function object
    00337   * @return A pointer to a copy of the object
    00338   */
    00339   virtual PotentialfieldFunction* clone()
    00340   {
    00341     AsymptoticFunction* newFunction = new AsymptoticFunction(range,atZero,solidCenter);
    00342     newFunction->getStandardParameters(this);
    00343     return newFunction;
    00344   }
    00345
    00346 protected:
    00347   /** f(x) = atZero for x <= solidCenter */
    00348   double solidCenter;
    00349
    00350   /** Computes the value of the function for a given x
    00351   * @param x The distance for which to compute the value of the function
    00352   * @return The value of the function
    00353   */
    00354   double f(double x) const
    00355   {
    00356     if(x <= solidCenter)
    00357     {
    00358       return atZero;
    00359     }
    00360     else
    00361     {
    00362       return (a/x + b);
    00363     }
    00364   }
    00365
    00366   /** Computes the value of the derivative of the function for a given x
    00367   * @param x The distance for which to compute the value of the function
    00368   * @return The value of the function
    00369   */
    00370   double d(double x) const
    00371   {
    00372     if(x <= solidCenter)
    00373     {
    00374       return (-a/solidCenter*solidCenter);
    00375     }
    00376     else
    00377     {
    00378       return (-a/(x*x));
    00379     }
    00380   }
    00381
    00382   /** Computes the value of the second derivative of the function for a given x
    00383   * @param x The distance for which to compute the value of the function
    00384   * @return The value of the function
    00385   */
    00386   virtual double dd(double x) const
    00387   {
    00388     return (2.0*a/(x*x*x));
    00389   }
    00390
    00391   /** Computes the values of a and b*/
    00392   virtual void init()
    00393   {
    00394     assert((range != 0.0) && (solidCenter != 0.0) && (range != solidCenter));
    00395     a = atZero/(1.0/solidCenter - 1.0/range);
    00396     b = -a/range;
    00397   }
    00398 };
    00399
    00400
    00401 /**
    00402 * @class SocialFunction
    00403 *
    00404 * A class representing a social function in a potential field
    00405 */
    00406 class SocialFunction: public PotentialfieldFunction
    00407 {
    00408 public:
    00409   /**
    00410   * Constructor
    00411   * @param repC A repulsive constant
    00412   * @param repOm A repulsive quotient
    00413   * @param attC An attractive constant
    00414   * @param attOm An attractive quotient
    00415   * @param epsilon The minimum possible x
    00416   * @param k A constant value for value computation
    00417   */
    00418   SocialFunction(double repC, double repOm, double attC, double attOm,
    00419                  double epsilon, double k)
    00420   {
    00421     this->repC = repC;
    00422     this->repOm = repOm;
    00423     this->attC = attC;
    00424     this->attOm = attOm;
    00425     this->epsilon = epsilon;
    00426     this->k = k;
    00427   }
    00428
    00429   /** Computes the value of the function for a given x
    00430   * @param x The distance for which to compute the value of the function
    00431   * @param smooth flag, not used here
    00432   * @return The value of the function
    00433   */
    00434   virtual double computeValue(double x, bool smooth=true)
    00435   {
    00436     if(x < epsilon)
    00437     {
    00438       x = epsilon;
    00439     }
    00440     double repValue;
    00441     double attValue;
    00442     if(repOm == 1.0)
    00443     {
    00444       repValue = repC * log(x);
    00445     }
    00446     else
    00447     {
    00448       repValue = (repC / (-repOm + 1.0)) * pow(x, -repOm+1.0);
    00449     }
    00450     if(attOm == 1.0)
    00451     {
    00452       attValue = attC * log(x);
    00453     }
    00454     else
    00455     {
    00456       attValue = (attC / (-attOm + 1.0)) * pow(x, -attOm+1.0);
    00457     }
    00458     return (-repValue + attValue + k);
    00459   }
    00460
    00461   /** Computes the value of the derivative of the function for a given x
    00462   * @param x The distance for which to compute the value of the function
    00463   * @param smooth flag, not used here
    00464   * @return The value of the function
    00465   */
    00466   double computeDerivativeValue(double x, bool smooth=false)
    00467   {
    00468     if(x < epsilon)
    00469     {
    00470       x = epsilon;
    00471     }
    00472     return ((-repC/pow(x,repOm))+(attC/pow(x,attOm)));
    00473   }
    00474
    00475   /** Clones a function object
    00476   * @return A pointer to a copy of the object
    00477   */
    00478   virtual PotentialfieldFunction* clone()
    00479   {
    00480     SocialFunction* newFunction = new SocialFunction(repC,repOm,attC,attOm, epsilon, k);
    00481     newFunction->getStandardParameters(this);
    00482     return newFunction;
    00483   }
    00484
    00485 private:
    00486   /** A repulsive constant */
    00487   double repC;
    00488   /** A repulsive quotient */
    00489   double repOm;
    00490   /** An attractive constant */
    00491   double attC;
    00492   /** An attractive quotient */
    00493   double attOm;
    00494   /** The minimum possible x*/
    00495   double epsilon;
    00496   /** A constant value for value computation*/
    00497   double k;
    00498 };
    00499
    00500
    00501 /**
    00502 * @class NoFunction
    00503 *
    00504 * A class representing an empty function
    00505 */
    00506 class NoFunction: public PotentialfieldFunction
    00507 {
    00508 public:
    00509   /** Computes the value of the function for a given x
    00510   * @param x The distance for which to compute the value of the function
    00511   * @param smooth flag, not used here
    00512   * @return The value of the function
    00513   */
    00514   double computeValue(double x, bool smooth=true)
    00515   {
    00516     return 0.0;
    00517   }
    00518
    00519   /** Computes the value of the derivative of the function for a given x
    00520   * @param x The distance for which to compute the value of the function
    00521   * @param smooth flag, not used here
    00522   * @return The value of the function
    00523   */
    00524   double computeDerivativeValue(double x, bool smooth=false)
    00525   {
    00526     return 0.0;
    00527   }
    00528
    00529   /** Clones a function object
    00530   * @return A pointer to a copy of the object
    00531   */
    00532   virtual PotentialfieldFunction* clone()
    00533   {
    00534     NoFunction* newFunction = new NoFunction();
    00535     return newFunction;
    00536   }
    00537 };
    00538
    00539
    00540 /** Computes the charge at a position in a Pointfield
    00541 * @param objectPose The pose of the object to which the field belongs
    00542 * @param testedPose The pose for which the charge is computed
    00543 * @param function The function
    00544 * @return The charge
    00545 */
    00546 double computeChargeForPointfield(const PfPose& objectPose, const PfPose& testedPose,
    00547                                   PotentialfieldFunction* function);
    00548
    00549
    00550 /** Computes the charge at a position in a Shapefield
    00551 * @param objectPose The pose of the object to which the field belongs
    00552 * @param testedPose The pose for which the charge is computed
    00553 * @param function The function
    00554 * @param geometry The geometric shape of the object
    00555 * @return The charge
    00556 */
    00557 double computeChargeForShapefield(const PfPose& objectPose, const PfPose& testedPose,
    00558                                   PotentialfieldFunction* function,
    00559                                   PfieldGeometricObject* geometry);
    00560
    00561 /** Computes the charge at a position in a Sectorfield
    00562 * @param objectPose The pose of the object to which the field belongs
    00563 * @param testedPose The pose for which the charge is computed
    00564 * @param function The function
    00565 * @param sector The sector of the field
    00566 * @return The charge
    00567 */
    00568 double computeChargeForSectorfield(const PfPose& objectPose, const PfPose& testedPose,
    00569                                    PotentialfieldFunction* function,
    00570                                    const Sector& sector);
    00571
    00572 /** Computes the gradient at a position in a Pointfield
    00573 * @param objectPose The pose of the object to which the field belongs
    00574 * @param testedPose The pose for which the charge is computed
    00575 * @param function The function
    00576 * @return The gradient
    00577 */
    00578 PfVec computeGradientForPointfield(const PfPose& objectPose, const PfPose& testedPose,
    00579                                    PotentialfieldFunction* function);
    00580
    00581 /** Computes the gradient at a position in a Shapefield
    00582 * @param objectPose The pose of the object to which the field belongs
    00583 * @param testedPose The pose for which the charge is computed
    00584 * @param function The function
    00585 * @param geometry The geometric shape of the object
    00586 * @param objectType The type of the object
    00587 * @return The gradient
    00588 */
    00589 PfVec computeGradientForShapefield(const PfPose& objectPose, const PfPose& testedPose,
    00590                                    PotentialfieldFunction* function,
    00591                                    PfieldGeometricObject* geometry,
    00592                                    ObjectType objectType);
    00593
    00594 /** Computes the gradient at a position in a Sectorfield
    00595 * @param objectPose The pose of the object to which the field belongs
    00596 * @param testedPose The pose for which the charge is computed
    00597 * @param function The function
    00598 * @param sector The sector of the field
    00599 * @return The gradient
    00600 */
    00601 PfVec computeGradientForSectorfield(const PfPose& objectPose, const PfPose& testedPose,
    00602                                     PotentialfieldFunction* function,
    00603                                     const Sector& sector);
    00604
    00605
    00606 #endif //POTENTIAL_FUNCTIONS_H_