我做了一个类似于泡泡屏保的程序 它工作正常,但有点慢 并且是增加气泡的数量,它看起来好像卡住了
建议我该怎么做,以增加速度, 我做的代码:
#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]);
}
答案 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);
}
修复它。边界/碰撞分辨率:
更改“边界分辨率”算法,将气泡夹在有效坐标内。单动,无循环,无法卡住。
稍微类似地更改“碰撞分辨率”算法。选择两个气泡之间的距离矢量,将其延伸到2 * r的长度,然后将气泡延伸到该点。 (忽略二次碰撞,它们将在下一次迭代中处理。)同样,单一动作&amp;没有可能被卡住。
但是,最重要的是,碰撞检测是最重要的。
更快的碰撞检测,需要一种有效的方法来查找附近的气泡。理想情况下,这将是一个四叉树。 https://en.wikipedia.org/wiki/Quadtree
如果您想快速伪造某些内容,可以使用大小为2*r
的HashMap图块&amp;搜索给定气泡的9个周围的瓷砖。 2 * r距离内的任何气泡都必须位于这些区域内,因此这至少可以让您快速减少子集。成本为9次散列查找,可能是5-10次气泡,而不是100次或数千次气泡比较。
请参阅: