需要帮助更改算法 [英] Need help altering an algorithm

查看:52
本文介绍了需要帮助更改算法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要制作一个可以扫描屏幕上每个像素的像素.

I need to make a that scans every pixel on the screen.

我当前正在使用此

public static void Spiral()
{

    // starting point
    x = ((int)Math.Floor(Screen.PrimaryScreen.Bounds.Height / 2.0)) - 1;
    y = ((int)Math.Floor(Screen.PrimaryScreen.Bounds.Width / 2.0)) - 1;

    for (int j = Screen.PrimaryScreen.Bounds.Height; j <= 2; k--)
    {
        for (int k = 0; k < (k < (Screen.PrimaryScreen.Bounds.Height - 1) ? 2 : 3); j++)
        {
            for (int i = 0; i < s; i++)
            {
                c++;
            }
            d = (d + 1) % 2;
        }
        s = s + 1;
    }
}

虽然此方法有效,但它仅适用于偶数尺寸(例如:400x400),但对于我的用例,我还需要使其支持不均匀的尺寸(例如:1920x1080).我不知道如何更改此算法来实现这一目标.

While this works, it only works with even dimensions (eg: 400x400) but for my use case i need to have it support uneven dimensions as well (eg: 1920x1080). I don't know how to alter this algorithm to make that happen.

我希望有人可以帮我解决这个问题,因为这对我来说很难

I hope someone can help me with this since this kinda stuff is hard for me

显然,由于问题已经解决,我还不清楚.我会雄辩(我希望它能很快重新打开):

apparently i wasn't clear enough about what the issue is since it got closed? i'll eloborate (i hope it gets reopened soon):

让我们说出这张图片:

现在,由于只有最小的尺寸可以检测到,因此目前仅能检测到该部分:

now currently only this part gets detected since the lowest dimension is the only one it can detect:

但是我需要更改算法以支持整个图像,而不管它是否平方.希望有人可以帮助我解决这个问题

but i need the algorithm changed to support the whole image regardless if it's squared or not. Hope someone can help me solve this

推荐答案

让我们将其转换为简单的点序列.

Let's turn this into a simple sequence of points.

我们知道我们将朝四个方向之一前进.

We know that we are going in one of four directions.

var steps = new (int dx, int dy)[] { (1, 0), (0, 1), (-1, 0), (0, -1) };

要创建螺旋,我们将第一个方向移动一次,然后将第二个方向移动一次;然后是接下来的两次,然后是接下来的两个三倍,然后是接下来的两个四倍,依此类推.如果我们到达列表的末尾,那么我们将循环回到起点.因此,如果我们以 n = 0 开始,那么我们将每个方向重复 n/2 + 1 次(知道这是整数数学).

To create a spiral we move the first direction once, then the second once; then the next two twice, then the next two three times, then the next two four times, etc. If we hit the end of the list we then cycle back to the start. So if we start with n = 0 then we repeat each direction n / 2 + 1 times (knowing that this is integer maths).

这是我的 Spiral 生成器方法:

public IEnumerable<Point> Spiral(int x, int y)
{
    yield return new Point(x, y);
    var steps = new(int dx, int dy)[] { (1, 0), (0, 1), (-1, 0), (0, -1) };
    var i = 0;
    var n = 0;
    while (true)
    {
        for (var j = 0; j < n / 2 + 1; j++)
        {
            var (sx, sy) = steps[i];
            x += sx;
            y += sy;
            yield return new Point(x, y);
        }
        if (++i >= steps.Length)
            i = 0;
        n++;
    }
}

前50个点(即 Spiral(0,0).Take(50))是这样的:

The first 50 points (i.e. Spiral(0, 0).Take(50)) are then this:

(0,0),(1,0),(1,1),(0,1),(-1,1),(-1,0),(-1,-1),(0,-1),(1,-1),(2,-1),(2,0),(2,1),(2,2),(1,2),(0,2),(-1,2),(-2,2),(-2,1),(-2,0),(-2,-1),(-2,-2),(-1,-2),(0,-2),(1,-2),(2,-2),(3,-2),(3,-1),(3、0),(3、1),(3,2),(3,3),(2,3),(1,3),(0,3),(-1,3),(-2,3),(-3,3),(-3,2),(-3,1),(-3,0),(-3,-1),(-3,-2),(-3,-3),(-2,-3),(-1,-3),(0,-3),(1,-3),(2,-3),(3,-3),(4,-3)

(0, 0), (1, 0), (1, 1), (0, 1), (-1, 1), (-1, 0), (-1, -1), (0, -1), (1, -1), (2, -1), (2, 0), (2, 1), (2, 2), (1, 2), (0, 2), (-1, 2), (-2, 2), (-2, 1), (-2, 0), (-2, -1), (-2, -2), (-1, -2), (0, -2), (1, -2), (2, -2), (3, -2), (3, -1), (3, 0), (3, 1), (3, 2), (3, 3), (2, 3), (1, 3), (0, 3), (-1, 3), (-2, 3), (-3, 3), (-3, 2), (-3, 1), (-3, 0), (-3, -1), (-3, -2), (-3, -3), (-2, -3), (-1, -3), (0, -3), (1, -3), (2, -3), (3, -3), (4, -3)

现在,生成所需螺旋非常容易.

Now, it's super easy to generate the spiral you want.

如果我假设您是从屏幕中间开始的,那么就是这样:

If I assume that you're starting at the middle of the screen, then this is it:

IEnumerable<Point> query =
    Spiral(1920 / 2, 1080 / 2)
        .Where(z => z.X >= 0 && z.X < 1920)
        .Where(z => z.Y >= 0 && z.Y < 1080)
        .Take(1920 * 1080);

如果我们要使用您的问题中给出的较小屏幕进行验证,则该代码应如下所示:

If we want to verify with the smaller screen as given in your question, the that looks like this:

IEnumerable<Point> query =
    Spiral(0, 0)
        .Where(z => z.Y >= -1 && z.Y <= 1)
        .Where(z => z.X >= -2 && z.X <= 2)
        .Take(5 * 3);

给出:

(0,0),(1,0),(1,1),(0,1),(-1,1),(-1,0),(-1,-1),(0,-1),(1,-1),(2,-1),(2,0),(2,1),(-2,1),(-2,0),(-2,-1)

(0, 0), (1, 0), (1, 1), (0, 1), (-1, 1), (-1, 0), (-1, -1), (0, -1), (1, -1), (2, -1), (2, 0), (2, 1), (-2, 1), (-2, 0), (-2, -1)


这里将其包装为一个方法:


Here it is wrapped up in a single method:

public static void Spiral()
{
    IEnumerable<Point> SpiralPoints(int x, int y)
    {
        yield return new Point(x, y);
        var steps = new(int dx, int dy)[] { (1, 0), (0, 1), (-1, 0), (0, -1) };
        var i = 0;
        var n = 0;
        while (true)
        {
            for (var j = 0; j < n / 2 + 1; j++)
            {
                var (sx, sy) = steps[i];
                x += sx;
                y += sy;
                yield return new Point(x, y);
            }
            if (++i >= steps.Length)
                i = 0;
            n++;
        }
    }

    var w = Screen.PrimaryScreen.Bounds.Width;
    var h = Screen.PrimaryScreen.Bounds.Height;
    var l = Screen.PrimaryScreen.Bounds.Left;
    var r = Screen.PrimaryScreen.Bounds.Right;
    var t = Screen.PrimaryScreen.Bounds.Top;
    var b = Screen.PrimaryScreen.Bounds.Bottom;

    foreach (Point point in SpiralPoints(w / 2, h / 2)
        .Where(z => z.X >= l && z.X < r)
        .Where(z => z.Y >= t && z.Y < b)
        .Take(w * h))
    {
        /* Do Stuff With Each Point Here */
    }

}

这篇关于需要帮助更改算法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆