public class CommFuncSimpleSpline implements ICommStrengthFunc { double m_lfMin; double m_lfMax; double m_lfMed; double m_lfScale; public CommFuncSimpleSpline() { m_lfMin = 0.0; m_lfMax = 1.0; m_lfMed = 0.5; m_lfScale = 1.0; } public CommFuncSimpleSpline(double lfMinRange, double lfMaxRange) { if(lfMinRange > lfMaxRange) { double lfTmp = lfMinRange; lfMinRange = lfMaxRange; lfMaxRange = lfTmp; } m_lfMin = lfMinRange; m_lfMax = lfMaxRange; m_lfMed = (m_lfMax + m_lfMin)*0.5; m_lfScale = 1.0/(m_lfMax - m_lfMin); } double getScaledParam(double lfDist) { return m_lfScale*(lfDist - m_lfMin); } public double getGrad(double lfDist) { if(lfDist <= m_lfMin || lfDist >= m_lfMax) { return 0.0; } double lfSDist = 1.0-getScaledParam(lfDist); // 3x^2 - 2x^3 // 6x - 6x^2 // 3 a^2 x^2 - 2 a^3 x^3 // 6 a^2 x - 6 a^3 x^2 // 6 a (ax)( 1 - (ax) ) return -1.0*m_lfScale*6.0*lfSDist*(1.0-lfSDist); } public double getStrength(double lfDist) { if(lfDist < m_lfMin) { return 1.0; } if( lfDist > m_lfMax) { return 0.0; } double lfSDist = 1.0-getScaledParam(lfDist); // 3x^2 - 2x^3 // 6x - 6x^2 return lfSDist*lfSDist*(3.0-2.0*lfSDist); } public boolean isMonotonic() { return true; } public ICommStrengthFunc makeCopy() { return new CommFuncSimpleSpline(m_lfMin, m_lfMax); } public double maxDerivRange(double lfMin, double lfMax) { if((lfMin - m_lfMed ) * ( lfMax - m_lfMed) <= 0.0) { return getGrad(m_lfMed); } return Math.min(getGrad(lfMin), getGrad(lfMax)); } public double maxStrengthRange(double lfMinD, double lfMaxD) { return getStrength(Math.min(lfMaxD, lfMinD)); } public double minDerivRange(double lfMin, double lfMax) { return Math.max(getGrad(lfMin), getGrad(lfMax)); } public double minStrengthRange(double lfMinD, double lfMaxD) { return getStrength(Math.max(lfMaxD, lfMinD)); } }