实现这种osscilation函数的快速方法是什么。 签名看起来像这样:
public static double Calculate(UInt64 currentCounter, uint duration, uint inDuration, uint outDuration)
结果应该是当currentCounter前进时的两倍,在0和1之间osscination。osscialtion speed由duration
参数(单个oscclation的滴答数)定义。类似地,上升和下降速度通过inDUration
和outDuration
(inDUration
+ outDuration
)来定义。
alt text http://img252.imageshack.us/img252/9457/graphuf.jpg
此图表的x轴当然是currentCounter
。
答案 0 :(得分:2)
正如评论者指出的那样,你必须知道这些功能 程序结构类似于:
// Use modulo to get the counter within the range of the first duration
var phaseCounter = currentCounter % duration;
// Use the appropriate function
if( phaseCounter < inDuration )
{
return InFunction( phaseCounter, inDuration );
}
if( phaseCounter > duration - outDuration )
{
// Normalize the phaseCounter to the domain of definition for OutFunction()
var outDurationOffset = duration - outDuration;
return OutFuntion( phaseCounter - outDurationOffset, outDuration );
}
return 0;
如您所见,您必须填写InFunction()
和OutFunction()
它们都获得两个参数,即定义域中的x位置及其定义域。这样就可以很容易地实现这些功能。
修改强>
quadratic function可能是InFunction
的示例:
double InFunction( uint current, uint range )
{
return Math.Pow( ( current / range ) - 1, 2 );
}
通过将电流除以范围得到0到1之间的值 - 这将确保结果在0和1之间(如您所指定)。
答案 1 :(得分:1)
编辑 - 这是一个新功能,包括在outDuration
和下一个inDuration
之间保持1.0。请注意,我已更改了您的功能签名 - 输入参数现在为inDuration
,holdDuration
和outDuration
。对于inDuration
个样本,函数在outDuration
和holdDuration
之间保持为0,然后在outDuration
之后对于另一个holdDuration
样本保持为1.0。坡道再次是半汉族功能,你可以根据需要改变它们。
public static double Calculate(UInt64 currentCounter, uint inDuration, uint holdDuration, uint outDuration)
{
UInt64 curTime;
double ret;
curTime = currentCounter % (inDuration + 2*holdDuration + outDuration); //this wrapping should really be handled by the caller
if (curTime < inDuration)
{
ret = 0.5 * (1.0 - Math.Cos(2.0 * Math.PI * (inDuration - curTime) / (2.0 * inDuration)));
}
else if (curTime < inDuration + holdDuration)
{
ret = 0.0;
}
else if (curTime < inDuration + holdDuration + outDuration)
{
ret = 0.5 * (1.0 - Math.Cos(2.0 * Math.PI * (curTime - inDuration - holdDuration) / (2.0 * outDuration)));
}
else
{
ret = 1.0;
}
return ret;
}
它具有与先前版本相同的周期性功能。
这是显示该功能的两个周期的图表。测试循环是
for (ctr = 0; ctr < 20000; ctr++)
Calculate(ctr, 2500, 2250, 3000);
alt text http://img16.imageshack.us/img16/4443/oscfnxn2.png
第一个版本
对于像这样的东西,我是Hann function的忠实粉丝。如果这是一个问题,它是连续的和可区分的。这是一个简单的实现:
public static double Calculate(UInt64 currentCounter, uint duration, uint inDuration, uint outDuration)
{
UInt64 curTime;
double ret;
//should check that inDuration + outDuration <= duration
curTime = currentCounter % duration; //this wrapping should really be handled by the caller
if (curTime < inDuration)
{
ret = 0.5 * (1.0 - Math.Cos(2.0 * Math.PI * (inDuration - curTime) / (2.0 * inDuration)));
}
else if (curTime >= (duration - outDuration))
{
ret = 0.5 * (1.0 - Math.Cos(2.0 * Math.PI * (outDuration + duration - curTime) / (2.0 * outDuration)));
}
else
{
ret = 1.0;
}
return ret;
}
这是一个示例图表。这是通过循环生成的
for (ctr = 0; ctr < 10000; ctr++)
Calculate(ctr, 10000, 2500, 3000);
函数从索引0
下降到0到inDuration
,保持为0直到索引duration-outDuration
,然后在索引duration
上升到1.0,所以它是在'持续时间'样本中完全是周期性的。
我不明白你的评论“在一段时间之间,它之间是1。”你不需要另一个参数来指定保持时间吗?