Frage

I have a general programming challenge for you all. I've been scratching my head trying to figure out the best way to do this...

I'm working in C and I've got a "speed" value that is passed to my program. It ranges from 0-255. This speed value needs to correspond to a millisecond time delay built into the program.

    unsigned char currentSpeed; //this is passed into my function, range 0-255
    unsigned long SlowestSpeedMillis = 3000; //in milliseconds
    if (currentSpeed > 0)
    {
       unsigned long Interval = ((256 - currentSpeed)*SlowestSpeedMillis)/255;

    }else{ //currentSpeed = 0
       //When Interval is zero, the program will freeze
       Interval = 0;
    }

Here's some sample results:
currentSpeed of 1 results in 3000 milliseconds (slowest)
currentSpeed of 128 results in ~1500 milliseconds (exactly half)
currentSpeed of 255 results in ~11 milliseconds (fastest)

The problem is that I would like it to be a curved result where it stays in the lower numbers and then quickly goes to 3000 at the end... I want the user to have the choice to make the program go as slow as 3000, but most values leading up to it aren't as important. Such as this:
currentSpeed of 1 results in 3000 milliseconds (slowest)
currentSpeed of 128 results in ~750 milliseconds (1/4th of potential)
currentSpeed of 255 results in ~11 milliseconds (fastest, anything close to zero)

Any ideas how to do this programmatically? Perhaps with some kind of equation?

War es hilfreich?

Lösung

Normally in math you might do something like:

(currentSpeed / 255) * 3000

for linear, and to get a bit of a curve use a power:

((currentSpeed / 255) * (currentSpeed / 255)) * 3000

But, in integer math that doesn't work because (currentSpeed / 255) will almost always be zero.

To do this without floating point you have to scale up first before division.

((3000 * currentSpeed) * currentSpeed) / (255 * 255)

Andere Tipps

You can use

unsigned char currentSpeed; // range 0-255
unsigned long SlowestSpeedMillis = 3000; // in milliseconds
unsigned long Interval;
if (currentSpeed > 0)
{
   Interval = SlowestSpeedMillis/currentSpeed;

} else {
   Interval = 0;
}

1 is mapped to 3000, and 255 is mapped to 11.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top