Jump to content
  • Advertisement
Sign in to follow this  
Kerubu

Real-Time Animation of a Pointer

This topic is 2770 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello,

I'm new to animation etc but am attempting to create a crude simulation of a dial pointer moving over a scale, for example a car speed-o-meter, a rotary temperature gauge etc.

However I need the pointer to respond to real-time data and rotate smoothly from it's current position to the desired (commanded) position. It is also possible that the initial command signal may change before the pointer reaches the correct position and I would like my code to respond immediately to this change i.e. the pointer does not go to commanded position1 before attempting to get to commanded position2 but go straight to commanded position 2.

I'm not looking for any code for this but an algorithm or indication how I can achieve this 'instantaneous' response. This may seem like a 'homework' question but that is not the case.

As a bit of an outline I have thought along these lines;

1. There is a GUI thread that will be responsible for painting the pointer only.
2. I have a separate thread that acts as an 'summation' unit to produce an error signal i.e. a difference between actual and desired pointer position and calculates a series of pointer angles i.e. a new pointer angle per frame.
3. I thought about having a 3rd thread act as a frame scheduler i.e. it constantly checks for new pointer angles and dispatches them to the GUI thread at regular intervals (to ensure smooth animation).

The trouble with having 3 threads is that they do need to interact carefully with one another. Ideally I need to make it a closed loop system but I get confused when I think about all these threads!!

Anybody give me a few ideas or hints how I can achieve my aim?

Share this post


Link to post
Share on other sites
Advertisement

However I need the pointer to respond to real-time data and rotate smoothly from it's current position to the desired (commanded) position. It is also possible that the initial command signal may change before the pointer reaches the correct position and I would like my code to respond immediately to this change i.e. the pointer does not go to commanded position1 before attempting to get to commanded position2 but go straight to commanded position 2.


Real-time means "by a certain deadline". Not "fast", "smooth" or similar.

If you decide that 60Hz is sufficient resolution, then the first priority is to design a system that is capable of updating and rendering at that rate.

I'm not looking for any code for this but an algorithm or indication how I can achieve this 'instantaneous' response.[/quote]You can't. You can only achieve arbitrary discrete resolution. Everything else will be bound by that.

1. There is a GUI thread that will be responsible for painting the pointer only.[/quote]Most graphics systems run UI on main thread or use built-in UI thread.

2. I have a separate thread that acts as an 'summation' unit to produce an error signal i.e. a difference between actual and desired pointer position and calculates a series of pointer angles i.e. a new pointer angle per frame.[/quote]Threads do not buy you anything. They merely increase the load on scheduler and add exponentially increasing probability of thread contention, preemption, deadlock, stalls or more.

Anybody give me a few ideas or hints how I can achieve my aim?[/quote]In your main event loop, either window loop or on_paint() like event, depends on language, OS, API, ..., you have something like this:struct State {
float value;
float time;
}

State current_state, displayed_state;


Displays are mostly incapable of updating more than 60Hz, so rendering needs to be done at that rate. This means that each frame rendered must take 16.6ms or less. Preferably much less.

The main loop is now like this:while (running) {
current_state = ... // get needle value
current_state.time = now(); // current time

delta = current_state.time - displayed_state.time;
if (delta > 2*16.6) // real-time error, we didn't update soon enough,
// in hard real time this would stop the application or similar
// not needed just for animation

if (delta > 16.6) { // next update
displayed_state = current_state;
render();
}
}


Now all that's left is to ensure the above runs at least once 16.6ms.

Share this post


Link to post
Share on other sites
Using threads here is overkill.

I think you should implement either direct rendering of the state and forego animation from one state to another, or else set a time limit on how long it takes to move to the current state.

Something like


class Dial {
private :
double old_angle;
double angle;
double dest_angle;
double angular_velocity;
double time_elapsed;
double time_to_move;
public :
void SetNewAngle(double new_angle , double time) {
time_to_move = time;
time_elapsed = 0.0;
old_angle = angle;
dest_angle = new_angle;
angular_velocity = (RelativeAngle(new_angle - old_angle)/time);
}
void Update(double tsec) {
time_elapsed += tsec;
if (time_elapsed >= time_to_move) {
angle = dest_angle;
} else {
angle = old_angle + angular_velocity*time_elapsed;
}
}
}


[quote name='Kerubu']
However I need the pointer to respond to real-time data and rotatesmoothly from it's current position to the desired (commanded)position. It is also possible that the initial command signal maychange before the pointer reaches the correct position and I would likemy code to respond immediately to this change i.e. the pointer does notgo to commanded position1 before attempting to get to commandedposition2 but go straight to commanded position 2.
[/quote]
The above code will stop moving towards it's original destination and start moving towards it's new destination as soon as you call SetNewAngle. All you have to do is provide a reasonable amount of time to the function, say 1/4 to 1/2 a second.

Share this post


Link to post
Share on other sites
Edgar & Antheus,

Thanks for your replies they have helped me think through the problem clearly.

I've come up with a 2 thread solution to my problem even though I understand a thread doesn't actually gain truly independent execution. However I've considered the 'bigger picture' in which my animation must run and by using 2 threads I maintain the responsiveness of my application.

Once again many thanks for your replies.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!