点击测试矩形

Jos*_*osh 4 c++ windows winapi hit detection

我正在开发一个项目,我有几个矩形,我希望每个都有悬停效果.现在我知道我可以捕获WM_MOUSEMOVE消息并遍历每个矩形.但是,如果我有很多矩形(如果50很多),该怎么办?
我可能错了,但不会迭代那么多,并且每次鼠标移动缓慢应用程序一点点时测试每一个?

然后我开始想知道操作系统(例如windows)是如何做到这一点的,现在我的屏幕上有100多个东西,当我将鼠标悬停在它们上面时,它们都有某种动画.而且我不认为每次鼠标移动像素时窗口都会遍历所有窗口.

基本上:
1.如果我有大约50个矩形,我怎么能弄清楚我的鼠标在哪个矩形上面,并考虑到性能.
2. Windows如何做到这一点?(我对任何东西都更好奇,但如果它不复杂,也许我可以在我自己的程序中实现类似的东西?)

哦,它们都是矩形,它们不会旋转或任何东西.

Igo*_*hov 8

在明确一段代码创建真正的瓶颈之前,我不会对性能感到困扰.让我们假设你有这样的瓶颈,并测量下面代码的性能(它在C#中,但我很确定C++不会慢):

public class Rectangle
{
    public int X { get; set; }
    public int Y { get; set; }
    public int W { get; set; }
    public int H { get; set; }

    public bool HitTest(int x, int y)
    {
        return x >= X && x < X + W && y >= Y && y < Y + H ? true : false;
    }
}
Run Code Online (Sandbox Code Playgroud)

我们对该HitTest()方法的性能感兴趣,所以让我们测量它!

void PerformanceTest()
{
    const int Iterations = 1000000;
    Random rnd = new Random();
    var rectangles = Enumerable.Range(1, 50).Select(
            r => new Rectangle {
                X = rnd.Next(1000),
                Y = rnd.Next(1000),
                W = rnd.Next(1000),
                H = rnd.Next(1000)}).ToList();

    Stopwatch sw = new Stopwatch();
    sw.Start();
    for (int i = 0; i < Iterations; i++)
    {
        rectangles.ForEach(r => r.HitTest(500, 500));
    }
    sw.Stop();

    Console.WriteLine("Elapsed time: {0}ms. ({1}us per one iteration)",
        sw.ElapsedMilliseconds,
        (float)sw.ElapsedMilliseconds * 1000 / Iterations);
}
Run Code Online (Sandbox Code Playgroud)

在我的电脑上,以上代码打印:

经过的时间:701ms.(每次迭代0.701us)

如您所见,测试50个矩形所需的时间不到1微秒.你真的认为这比制作花哨的悬停效果和你的程序所做的其他时间要长吗?当然,只有你能回答这个问题.

但我的故事的寓意是:不要试图预先优化,不要花时间试图解决可能根本不存在的问题.