EDIT - 这是一个新功能,包括在 outDuration 和下一个 inDuration 之间保持 1.0。请注意,我已经更改了您的函数签名 - 输入参数现在是 inDuration、holdDuration 和 outDuration。对于holdDuration 样本,该函数在inDuration 和outDuration 之间保持在0,然后在outDuration 之后保持在1.0,对于另一个holdDuration 样本。斜坡又是半汉恩函数,您可以根据需要更改它们。
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);
Graph with duration = 10000, in = 2500, out = 3000 http://img269.imageshack.us/img269/2969/oscfnxn.png
函数从索引 0 到 inDuration 从 1.0 下降到 0,在索引 duration-outDuration 之前保持在 0,然后在索引 duration 处上升到 1.0,因此它在“持续时间”样本中是完全周期性的。
我不明白您的评论“在一段时间内,在出入之间为 1”。不需要另外一个参数来指定保持时间吗?