线性插值、Sin插值、震荡插值
程序员文章站
2024-03-24 11:50:34
...
线性插值:根据开始时间、结束时间和当前时间,线性的计算开始值、结束值之间的一个数
/*
*fStart:开始值
*fEnd:结束值
*dwStart:开始时间
*dwEnd:结束时间
*dwTemp:当前时间
*/
//参数采用引用了,可以不用引用
float CTouchControlFreeRotation::LinearInterpolation(float& fStart, float& fEnd, DWORD& dwStart, DWORD& dwEnd, DWORD& dwTemp)
{
float fInterpolation = 0.0f;
float fScale = (dwTemp - dwStart) / ((dwEnd - dwStart) * 1.0f);
fInterpolation = fStart + ((fEnd - fStart) * fScale);
return fInterpolation;
}
Sin插值:根据开始时间、结束时间和当前时间,Sin特性计算开始值、结束值之间的一个数
//参数含义与上面的函数一样
float CTouchControlFreeRotation::SinInterpolation(float& fStart, float& fEnd, DWORD& dwStart, DWORD& dwEnd, DWORD& dwTemp)
{
float fInterpolation = 0.0f;
float fTemp = ((dwTemp - dwStart) / ((dwEnd - dwStart) * 1.0f)) * (float)(M_PI / 2.0f);
fInterpolation = fStart + ((fEnd - fStart) * sin(fTemp));
return fInterpolation;
}
震荡插值:根据开始时间、结束时间和当前时间,震荡特性计算开始值、结束值之间的一个数,这个特性是:在最终停止的位置会发生来回震荡的效果,类似钟摆最终停止的效果。(只是模拟的效果)
//nNum:震荡次数
//fWaveHeight:振幅
float CTouchControlFreeRotation::ShockInterpolation(float& fStart, float& fEnd, DWORD& dwStart, DWORD& dwEnd, DWORD& dwTemp, int nNum, float fWaveHeight)
{
float fInterpolation = 0.0f;
//一个周期是4,(因为在震荡之前有1/4个周期),计算单位时间
//nNum * 4:所有震荡次数一共所占比例
//(1 / (fWaveHeight / 100.0f))):前1/4周期所占的比例
float fUnit = ((dwEnd - dwStart) / ((float)(nNum * 4 + (1 / (fWaveHeight / 100.0f)))));
//前1/4个周期的结束时间
DWORD fPre = (DWORD)(fUnit * (1 / (fWaveHeight / 100.0f))) + dwStart;
//说明时间在前1/4个周期的范围内
if (dwTemp <= fPre)
{
//将时间映射到 π/2到π(因为在该阶段中,速度变化应该是越来越快的)
float fAngle = (float)((dwTemp - dwStart) / ((fPre - dwStart)* 1.0f) * (M_PI / 2) + M_PI / 2);
//用sin模拟计算位置
fInterpolation = fEnd + ((fStart - fEnd) * sin(fAngle));
}
else
{
//根据振幅计算最大的新的开始位置
float fStartNew = fEnd + (fStart - fEnd) * (fWaveHeight / 100.0f);
//得到当前时间所在阶段的开始时间和结束时间
DWORD dwBegin = 0;
DWORD dwStop = fPre;
int i = 0;
while (dwStop < dwTemp && i <= nNum)
{
i++;
dwBegin = dwStop;
dwStop = (DWORD)(fUnit * (i * 4) + fPre);;
}
//根据当前时间段,计算出新的开始位置
fStartNew = (fStartNew - fEnd) * (1 - (i - 1) / ((float)nNum)) + fEnd;
if (dwBegin != dwStop)
{
//将时间映射到 -π到π
float fAngle = (float)((dwTemp - dwBegin) / ((dwStop - dwBegin)* 1.0f) * M_PI_D - M_PI);
//用sin模拟计算位置
fInterpolation = fEnd + ((fStartNew - fEnd) * sin(fAngle));
}
}
return fInterpolation;
}
上一篇: hessian序列化bug
下一篇: jsonObject转换出错