简体   繁体   中英

How to determine how much time has passed without a timer?

I'm trying to make a program that rotates and draws a bitmap 360 degrees over exactly 10 seconds , but I've found that the method I'm using to do this is not instant or even close, so my function will not execute within the expected time. To compensate for this I decided to determine how much time has passed since the start of the function I use to rotate the image and draw it until it's finished and increase the amount it's rotated by the extra time it took to execute.

I looked into timers and I know I could just create a timer that increases a variable to "count" how much time has gone by, but in order for it to be accurate enough it would have to be used at least every 50 ms (probably shorter) when my repeating function already takes around 0.4 seconds per cycle to finish when I want it to be instant or near instant, I feel this may consume too much extra resources and want to look for a different solution.

In case you need any code here it is:

#include <windows.h>
#include <tgmath.h>

void rotatebmp (HDC hdc_x, float q, float x0, float y0)
{
  q = (q * 0.01745333055);
  XFORM blah;
  blah.eM11 = cos(q);
  blah.eM12 = sin(q);
  blah.eM21 = -sin(q);
  blah.eM22 = cos(q);
  blah.eDx = x0 - cos(q)*x0 + sin(q)*y0;
  blah.eDy = y0 - cos(q)*y0 - sin(q)*x0;
  SetWorldTransform(hdc_x, &blah);
  return;
}

int main()
{
  float q = 0;
  HDC hdc = CreateCompatibleDC(NULL);
  HBITMAP cross = (HBITMAP)LoadImage(NULL, ("C:\\Documents and Settings\\Death\\My Documents\\45Hand.bmp") ,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
  HBITMAP crossmask = (HBITMAP)LoadImage(NULL, ("C:\\Documents and Settings\\Death\\My Documents\\45Hand2.bmp") ,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
  while (1)
  {
    q = (q + 3.6);
    HDC hdc_x = GetDC(HWND_DESKTOP);
    SetGraphicsMode(hdc_x, GM_ADVANCED);
    SelectObject(hdc, crossmask);
    rotatebmp (hdc_x, q, 850, 375);
    BitBlt(hdc_x,550,0,600,527,hdc,0,0, SRCAND);
    ReleaseDC(HWND_DESKTOP,hdc_x);
    hdc_x = GetDC(HWND_DESKTOP);
    SetGraphicsMode(hdc_x, GM_ADVANCED);
    SelectObject(hdc, cross);
    rotatebmp (hdc_x, q, 850, 375);
    BitBlt(hdc_x,550,0,600,527,hdc,0,0, SRCPAINT);
    ReleaseDC(HWND_DESKTOP,hdc_x);
    Sleep(10);
  }
  return 0;
}

Windows provides a pair of functions for getting elapsed time that is highly precise. QueryPerformanceCounter will give the current count, and QueryPerformanceFrequency gives the number of counts per second.

Simply get the count at the start, get another count at the end, subtract the start from the end, and divide by the frequency to get the elapsed time.

To solve this problem I found timeGetTime() with timeBeginPeriod() and timeEndPeriod() to be the most accurate without the possibility of severely erroneous results, QueryPerformanceCounter and QueryPerformanceFrequency didn't do the trick for me, they threw out crazy results that appeared to be random and sometimes even negative values were produced.

GetTickCount() is slighlty less accurate then timeGetTime (according to this article) and after reading a lot of other information on the subject I've come to the conclusion that timeGetTime() is the best general purpose timer in terms of accuracy and reliability.

I'm not sure I understand what you're trying to do here. If I understand it correctly you want to rotate an image 360 degrees over exactly 10 seconds?

If that's the case you need to do a rotation every 27 milliseconds. While Sleep in windows isn't terribly accurate (you could potentially wait up to 15 milliseconds to "wake up") this is likely to be your closest solution.

Another option in C# (and there may be a way to do this in C++ I'm just not aware of it) is to use events. For example in C# it's very easy to create a timer that ticks on milliseconds, and every time it gets to 27, it triggers an asynchronous call to your rotate function. This would effectively re-draw the image while the timer continued ticking. If C# is a viable path for you I'm happy to provide some code

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM