泡泡---提高效率

时间:2013-11-17 06:28:16

标签: c++

我做了一个类似于泡泡屏保的程序 它工作正常,但有点慢 并且是增加气泡的数量,它看起来好像卡住了

建议我该怎么做,以增加速度, 我做的代码:

#include<dos.h>
#include<math.h>
#include<stdio.h>
#include<conio.h>
#include<iostream.h>
#include<stdlib.h>
#include<process.h>
#include<graphics.h>

void movement(int&,int&,int);
void bubbles(int,int,int,int);
void clearbubbles(int,int,int);


void main()
{
    int gdriver = DETECT,gmode;
    initgraph(&gdriver,&gmode,"C:\\Turboc3\\BGI");
    int x[10],y[10],r=40,d[10],i,j,k,l,c[10],n=10,t=100;
    randomize();
    // Initial Position, Direction & Color of Bubbles
    for(i=0;i<n;i++)
    {
        x[i]=random(getmaxx()-80)+41;
        y[i]=random(getmaxy()-80)+41;
        d[i] = random(8);
        c[i] = random(15)+1;
    }

    // Everything else

    for(i=0;i<=t;i++)   // Motiton of Bubbles
    {
        for(j=0;j<n;j++)        // Number of Bubbles
        {
            clearbubbles(x[j],y[j],r);
            // Checking Bubble Boundary Limits
            while(x[j] <= 1 || y[j] <= 1 || x[j] >= getmaxx()-1 || y[j] >= getmaxy()-1)
            {
                d[j] = random(8);
                movement(x[j],y[j],d[j]);
            }


            // Checking Collasion of Bubbles
            for(k=0;k<=n;k++)
            {
                clearbubbles(x[j],y[j],r);
                l = sqrt(pow(x[j]-x[k],2)+pow(y[j]-y[k],2));
                if(j != k)
                {
                    while(l <= 2*r)
                    {
                        d[j] = random(8);
                        movement(x[j],y[j],d[j]);
                        l = sqrt(pow(x[j]-x[k],2)+pow(y[j]-y[k],2));
                    }
                }
                movement(x[j],y[j],d[j]);
                bubbles(x[j],y[j],r,c[j]);
            }
        }
    }
    getch();
    closegraph();


}


void movement(int &x,int &y,int d)
{
    switch(d)
    {
        case 0: // Top Direction
            y = y - 1;
            break;
        case 1: // Top Right Direction
            x = x + 1;
            y = y - 1;
            break;
        case 2: // Right Direction
            x =x +1;
            break;
        case 3: // Bottom Right Direction
            x=x+1;
            y=y+1;
            break;
        case 4: // Bottom Direction
            y = y + 1;
            break;
        case 5: // Bottom Left Direction
            x = x-1;
            y=y+1;
            break;
        case 6: // Left Direction
            x=x-1;
            break;
        case 7: // Top Left Direction
            x=x-1;
            y=y-1;
            break;
    }
}

void bubbles(int x,int y,int r,int c)
{
    setcolor(c);
    circle(x,y,r);
}

void clearbubbles(int x,int y,int r)
{
    setcolor(BLACK);
    circle(x,y,r);
}

在完成所有建议后,我在代码中做了一些更改 但是,现在程序暂停一段时间后控件不会返回

我改变的部分:

// Checking Collasion of Bubbles
     for(k=j+1;k<n;k++)
     {
      clearbubbles(x[j],y[j],r);
      l = ((x[j]-x[k])*(x[j]-x[k]))+((y[j]-y[k])*(y[j]-y[k]));
       while(l <= 4*r*r)
       {
        d[j] = random(8);
        movement(x[j],y[j],d[j]);
        l = ((x[j]-x[k])*(x[j]-x[k]))+((y[j]-y[k])*(y[j]-y[k]));
       }
      movement(x[j],y[j],d[j]);
      bubbles(x[j],y[j],r,c[j]);
     }

1 个答案:

答案 0 :(得分:3)

您的N ^ 2算法非常低效。它需要的时间至少与气泡数的 square 成比例,以检查碰撞。

'边界检查'和'碰撞解决'算法也可能会进入非生产性循环,因为它们依靠随机运动来解决问题 - 而不是采取定向行动。

您还应该使用乘法而不是pow()来计算功率2.效率存在巨大差异。

您可以尝试使用函数来计算距离,和/或您可以识别出使用距离而不是将其与2 * r进行比较。这可能会削减sqrt并需要浮点。

例如,在伪代码中:

const int TWO_R_SQUARED = r * r * 4;

int distanceSq (int dx, int dy) {
    return (dx * dx) + (dy * dy);
}

修复它。边界/碰撞分辨率:

  1. 更改“边界分辨率”算法,将气泡夹在有效坐标内。单动,无循环,无法卡住。

  2. 稍微类似地更改“碰撞分辨率”算法。选择两个气泡之间的距离矢量,将其延伸到2 * r的长度,然后将气泡延伸到该点。 (忽略二次碰撞,它们将在下一次迭代中处理。)同样,单一动作&amp;没有可能被卡住。

  3. 但是,最重要的是,碰撞检测是最重要的。

    1. 更快的碰撞检测,需要一种有效的方法来查找附近的气泡。理想情况下,这将是一个四叉树。 https://en.wikipedia.org/wiki/Quadtree

    2. 如果您想快速伪造某些内容,可以使用大小为2*r的HashMap图块&amp;搜索给定气泡的9个周围的瓷砖。 2 * r距离内的任何气泡都必须位于这些区域内,因此这至少可以让您快速减少子集。成本为9次散列查找,可能是5-10次气泡,而不是100次或数千次气泡比较。

    3. 请参阅: