00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "PotentialFunctions.h"
00010 #include "PfieldDatatypes.h"
00011 #include "PfieldGeometry.h"
00012
00013
00014
00015 double PotentialfieldFunction::computeValue(double x, bool smooth)
00016 {
00017 if(x >= range)
00018 {
00019 return 0.0;
00020 }
00021 else if(smooth && (x > smoothingAtBorderPosition))
00022 {
00023 return computeSmoothedValue(smoothingAtBorderPosition, f(smoothingAtBorderPosition),
00024 d(smoothingAtBorderPosition), range, 0.0, gradientAtBorder, x);
00025 }
00026 else if(smooth && (x < smoothingAtObjectPosition))
00027 {
00028 return computeSmoothedValue(0.0, atZero, gradientAtObject,
00029 smoothingAtObjectPosition, f(smoothingAtObjectPosition),
00030 d(smoothingAtObjectPosition), x);
00031 }
00032 else
00033 {
00034 return f(x);
00035 }
00036 }
00037
00038
00039 double PotentialfieldFunction::computeDerivativeValue(double x, bool smooth)
00040 {
00041 if(x >= range)
00042 {
00043 return 0.0;
00044 }
00045 else if(smooth && (x > smoothingAtBorderPosition))
00046 {
00047 return computeSmoothedValue(smoothingAtBorderPosition, d(smoothingAtBorderPosition),
00048 dd(smoothingAtBorderPosition), range, 0.0, 0.0, x);
00049 }
00050 else if(smooth && (x < smoothingAtObjectPosition))
00051 {
00052 return computeSmoothedValue(0.0, atZero, 0.0,
00053 smoothingAtObjectPosition, d(smoothingAtObjectPosition),
00054 dd(smoothingAtObjectPosition), x);
00055 }
00056 else
00057 {
00058 return d(x);
00059 }
00060 }
00061
00062
00063 double PotentialfieldFunction::computeSmoothedValue
00064 (double x1, double fx1, double dx1,
00065 double x2, double fx2, double dx2, double x)
00066 {
00067 double denominator(x2*x2*x2 + 3*x1*x2*(x1-x2) - x1*x1*x1);
00068 double a(dx2*(x2-x1) + dx1*(x2-x1) - 2*fx2 + 2*fx1);
00069 a /= denominator;
00070 double b((dx2 - dx1 - 3*a*(x2*x2-x1*x1))/(2*(x2-x1)));
00071 double c(dx1 - 3*a*x1*x1 - 2*b*x1);
00072 double d(fx1 - a*x1*x1*x1 - b*x1*x1 - c*x1);
00073 return (a*x*x*x + b*x*x + c*x +d);
00074 }
00075
00076
00077 double computeChargeForPointfield(const PfPose& objectPose, const PfPose& testedPose,
00078 PotentialfieldFunction* function)
00079 {
00080 double x = objectPose.pos.distanceTo(testedPose.pos);
00081 return function->computeValue(x);
00082 }
00083
00084
00085 double computeChargeForShapefield(const PfPose& objectPose, const PfPose& testedPose,
00086 PotentialfieldFunction* function,
00087 PfieldGeometricObject* geometry)
00088 {
00089 PfVec dummy;
00090 double x = geometry->distanceTo(objectPose, testedPose.pos, dummy);
00091 if(x == 0.0)
00092 {
00093 return function->computeValue(x, false);
00094 }
00095 else
00096 {
00097 return function->computeValue(x);
00098 }
00099 }
00100
00101
00102 double computeChargeForSectorfield(const PfPose& objectPose, const PfPose& testedPose,
00103 PotentialfieldFunction* function,
00104 const Sector& sector)
00105 {
00106 double dist = objectPose.pos.distanceTo(testedPose.pos);
00107 if((dist > function->getRange()) ||
00108 !sector.pointInside(objectPose, testedPose.pos))
00109 {
00110 return 0.0;
00111 }
00112 double distValue = function->computeValue(dist);
00113 double x = fabs(objectPose.getAngleTo(testedPose.pos));
00114 sector.crossFunction->setParameters(distValue, sector.openingAngle/2.0);
00115 return sector.crossFunction->computeValue(x);
00116 }
00117
00118
00119 PfVec computeGradientForPointfield(const PfPose& objectPose, const PfPose& testedPose,
00120 PotentialfieldFunction* function)
00121 {
00122 PfVec vecToObject = (objectPose.pos - testedPose.pos);
00123 double x = vecToObject.length();
00124 vecToObject.normalize();
00125 PfVec result(0.0,0.0);
00126 double gradient = function->computeDerivativeValue(x);
00127 result = (vecToObject * gradient);
00128 return result;
00129 }
00130
00131
00132 PfVec computeGradientForShapefield(const PfPose& objectPose, const PfPose& testedPose,
00133 PotentialfieldFunction* function,
00134 PfieldGeometricObject* geometry,
00135 ObjectType objectType)
00136 {
00137 PfVec nextObjectPosition;
00138 double x = geometry->distanceTo(objectPose, testedPose.pos, nextObjectPosition);
00139 PfVec result(0.0,0.0);
00140 PfVec vecToObject;
00141 double gradient;
00142 if(x == 0.0)
00143 {
00144 if(objectType == ATTRACTIVE)
00145 {
00146 return result;
00147 }
00148 else
00149 {
00150 vecToObject = (testedPose.pos - nextObjectPosition);
00151 gradient = function->computeDerivativeValue(x, false);
00152 }
00153 }
00154 else
00155 {
00156 vecToObject = (nextObjectPosition - testedPose.pos);
00157 gradient = function->computeDerivativeValue(x);
00158 }
00159 vecToObject.normalize();
00160 result = (vecToObject * gradient);
00161 return result;
00162 }
00163
00164
00165 PfVec computeGradientForSectorfield(const PfPose& objectPose, const PfPose& testedPose,
00166 PotentialfieldFunction* function,
00167 const Sector& sector)
00168 {
00169 PfVec result(0.0,0.0);
00170 double dist = objectPose.pos.distanceTo(testedPose.pos);
00171 if((dist > function->getRange()) ||
00172 !sector.pointInside(objectPose, testedPose.pos))
00173 {
00174 return result;
00175 }
00176 PfVec vecToObject = (objectPose.pos - testedPose.pos);
00177 vecToObject.normalize();
00178 double gradient = function->computeDerivativeValue(dist);
00179 PfVec gradientToOrigin(vecToObject * gradient);
00180
00181 PfVec centerOfSector(1.0,0.0);
00182 centerOfSector.rotate(objectPose.rotation);
00183 PfVec vecToCenter = (objectPose.pos - testedPose.pos + (centerOfSector*dist));
00184 if(vecToCenter.length() == 0.0)
00185 {
00186 return gradientToOrigin;
00187 }
00188 vecToCenter.normalize();
00189 double x = fabs(objectPose.getAngleTo(testedPose.pos))*dist;
00190 double distValue = function->computeValue(dist);
00191 double range = (sector.openingAngle/2.0)*dist;
00192 sector.crossFunction->setParameters(distValue, range);
00193 double cgradient(sector.crossFunction->computeDerivativeValue(x));
00194 result = (gradientToOrigin + (vecToCenter*cgradient));
00195 return result;
00196 }
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229