线性插值、Sin插值、震荡插值

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013183287/article/details/81170891

线性插值:根据开始时间、结束时间和当前时间,线性的计算开始值、结束值之间的一个数

/*
*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;
}

猜你喜欢

转载自blog.csdn.net/u013183287/article/details/81170891