如何在给定的持续时间内从0..1..0..1..0等创建脉动值?

时间:2010-06-10 21:11:10

标签: c# c++ math pulse sin

我正在处理一些代码,其中我有Time个成员time的对象。 Time.time给出了 我自应用程序启动以来的时间(以秒为单位)(浮点值)。现在我想创建一个介于0和1之间,然后再次从1到0的脉动值,这将继续执行,直到应用程序停止。

我正在考虑使用sin()但不知道要传递给它作为创建此脉冲值的参数。

我如何创建这个脉动值?

亲切的问候, 波吕克斯

5 个答案:

答案 0 :(得分:11)

你提到使用sin(),所以我想你希望它在0和1之间连续脉冲。

这样的事情会:

float pulse(float time) {
    const float pi = 3.14;
    const float frequency = 10; // Frequency in Hz
    return 0.5*(1+sin(2 * pi * frequency * time));
}

1/frequency = 0.1 second是句点,即1点之间的时间。

答案 1 :(得分:4)

x = 1 - x怎么样? 或者,如果您希望它基于时间,请使用Timer%2

哦,你也想要0到1之间的值。 Math.Abs​​怎么样(100 - (Timer%200))/ 100 计时器类似于DateTime.Now.TimeOfDay.TotalMilliseconds

修改 我的测试表明,这是Sin方法的两倍多。对于100万次迭代,sin方法需要0.048秒,而Abs方法需要大约0.023秒。此外,当然,您可以从两者中获得不同的波形。 Sin产生正弦波,而Abs产生三角波。

static void Main(string[] args)
{
   System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
   sw.Start();
   const int count = 1000000;
   float[] results = new float[count];
   for (int i = 0; i < count; i++)
   {
      results[i] = AbsPulse(i/1000000F);
      //results[i] = SinPulse(i / 1000000F);
   }
   sw.Stop();
   Console.WriteLine("Time Elapsed: {0} seconds", sw.Elapsed.TotalSeconds);
   char[,] graph = new char[80, 20];
   for (int y = 0; y <= graph.GetUpperBound(1); y++)
      for (int x = 0; x <= graph.GetUpperBound(0); x++)
         graph[x, y] = ' ';
   for (int x = 0; x < count; x++)
   {
      int col = x * 80 / count;
      graph[col, (int)(results[x] * graph.GetUpperBound(1))] = 'o';
   }
   for (int y = 0; y <= graph.GetUpperBound(1); y++)
   {
      for (int x = 0; x < graph.GetUpperBound(0); x++)
         Console.Write(graph[x, y]);
      Console.WriteLine();
   }
}

static float AbsPulse(float time)
{
   const int frequency = 10; // Frequency in Hz
   const int resolution = 1000; // How many steps are there between 0 and 1
   return Math.Abs(resolution - ((int)(time * frequency * 2 * resolution) % (resolution * 2))) / (float)resolution;
}

static float SinPulse(float time)
{
   const float pi = 3.14F;
   const float frequency = 10; // Frequency in Hz
   return 0.5F * (1 + (float)Math.Sin(2 * pi * frequency * time));
}

答案 2 :(得分:0)

您希望它多久发出一次脉冲?

假设您希望在10秒内从0变为1。

float pulseValueForTime(int sec) {
    int pulsePoint = sec % 10;
    float pulsePercent = (float)pulsePoint / (float)10;
    float pulseInTermsOfPI = (pulsePercent * 2 * PI) - PI;
    float sinVal = MagicalSinFunction(pulseInTermsOfPI); // what framework you use to compute sin is up to you... I'm sure you can google that!
    return (sinVal + 1) / 2; // sin is between 1 and -1, translate to between 0 and 1
}

答案 3 :(得分:0)

我认为正弦函数是理想的,但你需要调整周期和比例。

正弦函数产生的结果介于-1和1之间,但是你希望介于0和1之间。要正确缩放它,你需要(sin(x)+1)/2

正弦函数从零开始,在pi / 2处变为1,在pi处再次变为0,在3 * pi / 2处变为-1,并且在2 * pi处变回零。按比例缩放,第一个零点将在3 * pi / 2处发生,之后的第一个最大值将在5/2 * pi处。因此,上一个公式中的x(2*time + 3) * pi/2

全部放在一起:(sin((2*time.time + 3) * pi/2) + 1) / 2

答案 4 :(得分:0)

了解易用功能。他们以各种方式做这种事 - 线性,多边形,exp,罪等。