DefuzzifierFactory::DefuzzifierFactory() { registerClass(Bisector().className(), &(Bisector::constructor)); registerClass(Centroid().className(), &(Centroid::constructor)); registerClass(LargestOfMaximum().className(), &(LargestOfMaximum::constructor)); registerClass(MeanOfMaximum().className(), &(MeanOfMaximum::constructor)); registerClass(SmallestOfMaximum().className(), &(SmallestOfMaximum::constructor)); registerClass(WeightedAverage().className(), &(WeightedAverage::constructor)); registerClass(WeightedSum().className(), &(WeightedSum::constructor)); }
static void WhiskerStep( double& xstep, // out: x dist to move one pix along whisker double& ystep, // out: y dist to move one pix along whisker const Shape& shape, // in int ipoint) // in: index of the current point { int prev, next; PrevAndNextLandmarks(prev, next, ipoint, shape); if ((Equal(shape(prev, IX), shape(ipoint, IX)) && Equal(shape(prev, IY), shape(ipoint, IY))) || (Equal(shape(next, IX), shape(ipoint, IX)) && Equal(shape(next, IY), shape(ipoint, IY)))) { // The prev or next point is on top of the current point. // Arbitrarily point the whisker in a horizontal direction. // TODO Revisit, this is common at low resolution pyramid levels. xstep = 1; ystep = 0; } else { const VEC whisker_direction(Bisector(shape.row(prev), shape.row(ipoint), shape.row(next))); xstep = -whisker_direction(IX); ystep = -whisker_direction(IY); // normalize so either xstep or ystep will be +-1, // and the other will be smaller than +-1 const double abs_xstep = ABS(xstep); const double abs_ystep = ABS(ystep); if (abs_xstep >= abs_ystep) { xstep /= abs_xstep; ystep /= abs_xstep; } else { xstep /= abs_ystep; ystep /= abs_ystep; } } }
Real DistPoint3Ellipsoid3<Real>::SqrDistanceSpecial (const Real e[3], const Real y[3], Real x[3]) { Real sqrDistance; Real ePos[3], yPos[3], xPos[3]; int numPos = 0; int i; for (i = 0; i < 3; ++i) { if (y[i] > (Real)0) { ePos[numPos] = e[i]; yPos[numPos] = y[i]; ++numPos; } else { x[i] = (Real)0; } } if (y[2] > (Real)0) { sqrDistance = Bisector(numPos, ePos, yPos, xPos); } else // y[2] = 0 { Real e2Sqr = e[2]*e[2]; Real denom[2], ey[2]; for (i = 0; i < numPos; ++i) { denom[i] = ePos[i]*ePos[i] - e2Sqr; ey[i] = ePos[i]*yPos[i]; } bool inAABBSubEllipse = true; for (i = 0; i < numPos; ++i) { if (ey[i] >= denom[i]) { inAABBSubEllipse = false; break; } } // Initialize to avoid C4701 in MSVS 2008. The compiler cannot // determine that sqrDistance is assigned a value in all cases. sqrDistance = (Real)0; bool inSubEllipse = false; if (inAABBSubEllipse) { // yPos[] is inside the axis-aligned bounding box of the // subellipse. This intermediate test is designed to guard // against the division by zero when ePos[i] == e[N-1] for some i. Real xde[2], discr = (Real)1; for (i = 0; i < numPos; ++i) { xde[i] = ey[i]/denom[i]; discr -= xde[i]*xde[i]; } if (discr > (Real)0) { // yPos[] is inside the subellipse. The closest ellipsoid // point has x[2] > 0. sqrDistance = (Real)0; for (i = 0; i < numPos; ++i) { xPos[i] = ePos[i]*xde[i]; Real diff = xPos[i] - yPos[i]; sqrDistance += diff*diff; } x[2] = e[2]*sqrt(discr); sqrDistance += x[2]*x[2]; inSubEllipse = true; } } if (!inSubEllipse) { // yPos[] is outside the subellipse. The closest ellipsoid // point has x[2] == 0 and is on the domain-boundary ellipse. x[2] = (Real)0; sqrDistance = Bisector(numPos, ePos, yPos, xPos); } } // Fill in those x[] values that were not zeroed out initially. for (i = 0, numPos = 0; i < 3; ++i) { if (y[i] > (Real)0) { x[i] = xPos[numPos]; ++numPos; } } return sqrDistance; }