0

我正在尝试制作一个在 10 秒内旋转并绘制 360 度位图的程序,但我发现我用来执行此操作的方法不是即时的,甚至不是关闭的,所以我的函数不会在其中执行预期的时间。为了弥补这一点,我决定确定自从我用来旋转图像并绘制它直到完成的函数开始以来已经过去了多少时间,并将旋转量增加了执行所花费的额外时间。

我研究了计时器,我知道我可以创建一个计时器来增加一个变量来“计算”已经过去了多少时间,但是为了让它足够准确,它必须至少每 50 毫秒使用一次(可能更短)当我希望它是即时或接近即时时,我的重复功能每个周期已经需要大约 0.4 秒才能完成,我觉得这可能会消耗太多额外的资源并想要寻找不同的解决方案。

如果您需要任何代码,它是:

#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;
}
4

3 回答 3

1

Windows 提供了一对用于获取高度精确的经过时间的函数。QueryPerformanceCounter将给出当前计数,并QueryPerformanceFrequency给出每秒的计数。

只需在开始时获取计数,在结束时获取另一个计数,从末尾减去开始,然后除以频率即可得到经过的时间。

于 2013-06-25T15:43:06.823 回答
0

为了解决这个问题,我发现 timeGetTime() 与 timeBeginPeriod() 和 timeEndPeriod() 是最准确的,不会出现严重错误的结果,QueryPerformanceCounter 和 QueryPerformanceFrequency 并没有为我解决问题,他们抛出了看起来很疯狂的结果是随机的,有时甚至会产生负值。

GetTickCount() 的准确度比 timeGetTime 稍差(根据本文),在阅读了有关该主题的许多其他信息后,我得出的结论是 timeGetTime() 在准确性和可靠性方面是最好的通用计时器。

于 2013-06-28T16:19:22.533 回答
-1

我不确定我是否理解你在这里想要做什么。如果我理解正确,您想在 10 秒内将图像旋转 360 度吗?

如果是这种情况,您需要每 27 毫秒旋转一次。虽然在 Windows 中睡眠并不是非常准确(您可能会等待长达 15 毫秒才能“唤醒”),但这可能是您最接近的解决方案。

C# 中的另一个选项(在 C++ 中可能有一种方法可以做到这一点,我只是不知道)是使用事件。例如,在 C# 中,创建一个以毫秒为单位的计时器非常容易,每次达到 27 时,它都会触发对您的旋转函数的异步调用。这将有效地重新绘制图像,同时计时器继续滴答作响。如果 C# 对您来说是一条可行的道路,我很乐意提供一些代码

于 2013-06-25T15:43:08.200 回答