Domanda

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?

È stato utile?

Soluzione

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)

Altri suggerimenti

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top