How to create pulsating value from 0..1..0..1..0 etc for a given duration?
Asked Answered
A

5

6

I'm working on some code where I have a Time object with a member time. Time.time gives me the time since my application started in seconds (float value). Now I want to create a pulsating value between 0 and 1 and then from 1 to 0 again, which continues doing thins untill the application stops.

I was thinking to use sin() but don't know what to pass to it as paramters to create this pulsing value.

How would I create this pulsating value?

Kind regards, Pollux

Antevert answered 10/6, 2010 at 21:11 Comment(5)
Are you programming in C++, C#, or don't you know?Flintlock
Why don't you modulate your time in seconds by 2, and use that?Leavy
Very simple, you add a lot of sine waves to one another until you get a good approximation to a square wave. You give it the proper frequency and amplitude and offset it a little along the y-axis and there you are. :)Histaminase
Can't you simply save last Time.time you flipped the pulse from 0 to 1 or vice-versa, and when it's been period/2 time since then you just flip the pulse again? That sounds much simpler and quick than sine, and the only problem would be that your period needs to be a multiple of your time's granularity. (The unitary value for each tic.)Protanopia
Like a programmatic flip flop?Whitecap
N
22

You mention using sin(), so I guess you want it to pulse continuously between 0 and 1.

Something like this will do:

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 is the period, which is the time between 1's.

Nelsonnema answered 10/6, 2010 at 21:15 Comment(5)
Much cleaner than my version - very nice!Helbonia
Kleist, so the frequence would be the framerate?Antevert
Oh and would it be (1/frequency)*Time.time*(TWO_PI)Antevert
How is it slow? Compared to what?Nelsonnema
I amended my answer to compare Sin to another formula that runs about twice as fast.Clavicytherium
C
4

How about x = 1 - x? Or if you want it to be time based use Timer % 2

Oh, you wanted the values between 0 and 1 as well. how about Math.Abs(100 - (Timer % 200)) / 100 Where timer is something like DateTime.Now.TimeOfDay.TotalMilliseconds

Edit: My tests indicate that this is more than twice as fast as the Sin method. For 1 million iterations, the sin method takes .048 seconds while the Abs method takes about .023 seconds. Also, you get different waveforms out of the two, of course. Sin produces a Sine wave, while Abs produces a triangular wave.

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));
}
Clavicytherium answered 10/6, 2010 at 21:12 Comment(0)
A
3

A sine function would be ideal I think, but you need to adjust the period and the scale.

The sine function produces results between -1 and 1, but you want to go between 0 and 1. To scale it properly you want (sin(x)+1)/2.

The sine function starts at zero, goes to 1 at pi/2, zero again at pi, -1 at 3*pi/2, and back to zero at 2*pi. Scaled, the first zero will happen at 3*pi/2 and the first maximum after that will be at 5/2*pi. So x in the previous formula is (2*time + 3) * pi/2.

Putting it all together: (sin((2*time.time + 3) * pi/2) + 1) / 2

Aubrey answered 10/6, 2010 at 21:31 Comment(0)
H
0

How often do you want it to pulse?

Let's say you want to go from 0 to 1 over 10 seconds.

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
}
Helbonia answered 10/6, 2010 at 21:20 Comment(4)
glowcoder, thanks, I'm doing something like now, though this does not work with a set duration. I want to be able to get a pulse every X-seconds. I think I needs Kleist example from above. BTW, you are not using pulsePoint in you code.Antevert
The idea behind it was you would do pulseValueForTime(getTimeInSec()); and the pulsePoint should be used for the first float (you'll notice pulse is never declared). I will fix the error, although Kliest's version, as you already noticed, is much cleaner than this if same in concept.Helbonia
You can do pulsePoint / 10F instead of (float)pulsePoint / (float)10: int/float yields float, and 10f is float - see msdn.microsoft.com/en-us/library/b1e65aza%28VS.71%29.aspxProtanopia
I'm sure it will. I see the readability of explicitly putting the float casts in there to be a plus. I'm certain any compiler would handle the rest in a decent fashion.Helbonia
W
0

Look into Ease functions. They do this sort of thing in all sorts of manners - linear, poly, exp, sin, etc.

Watchdog answered 11/6, 2010 at 14:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.