It is a screen saver for a lcd.
See video of it here to get a better idea of what it is doing.
http://www.youtube.com/watch?feature=pl ... x8SnwvDbKg
In the code below which works fine for me but is brutally slow. Its not the LCD library i am using as i get 25fps.
I have commented a line in the code "// Comment this out and these loops fly. "
for you math guys, does anything jump out at you that could make these loops faster in doing the math.
Thanks for you time.
Code: Select all
#define MAX(a,b) ((a) > (b) ? a : b)
#define MIN(a,b) ((a) < (b) ? a : b)
#define BALL_COUNT 3
struct MetaBall
{
int x;
int y;
int r;
int rsq;
int dx;
int dy;
};
struct MetaBall balls[BALL_COUNT];
float calculateThreshold(struct MetaBall *pBall, int x, int y);
int RLP_MetaBalls(void);
//*********************************************************************
//**************************** TASK 2 *******************************
//*********************************************************************
int RLP_MetaBalls(void)
{
const int width = 320;
const int height = 240;
const int maxRadius = 35;
const int leftLimit = 80; //80
const int rightLimit = width - 80; //80
const int topLimit = 60; //60
const int bottomLimit = height - 60; //60
const int surfaceWidth = rightLimit - leftLimit;
const int surfaceHeight = bottomLimit - topLimit;
WORD t=0;
// Initialize the balls
for (int i = 0; i < BALL_COUNT; ++i)
{
struct MetaBall *pBall = &balls[i];
pBall->x = (rand() % surfaceWidth) + maxRadius;
pBall->y = (rand() % surfaceHeight) + maxRadius;
pBall->r = 20;
pBall->rsq = pBall->r * pBall->r;
pBall->dx = (rand() % 4) + 1;
pBall->dy = (rand() % 4) + 1;
}
// Run the animation loop
for (;;)
{
int minX = width;
int minY = height;
int maxX = 0;
int maxY = 0;
// Move the balls and find the extream ball locations
for (int i = 0; i < BALL_COUNT; ++i)
{
struct MetaBall *pBall = &balls[i];
if ((pBall->x <= leftLimit && pBall->dx < 0) || (pBall->x >= rightLimit && pBall->dx > 0)) pBall->dx = -pBall->dx;
if ((pBall->y <= topLimit && pBall->dy < 0) || (pBall->y >= bottomLimit && pBall->dy > 0)) pBall->dy = -pBall->dy;
pBall->x += pBall->dx;
pBall->y += pBall->dy;
minX = MIN(minX, pBall->x);
minY = MIN(minY, pBall->y);
maxX = MAX(maxX, pBall->x);
maxY = MAX(maxY, pBall->y);
}
// Calculate bounding rect based on extream ball locations
minX -= maxRadius;
minY -= maxRadius;
maxX += maxRadius;
maxY += maxRadius;
// Clear the back buffer
memset(lcd_ram, 0, width * height * sizeof(short));
// Iterate the pixels in the bounding rect
// to calculate the influence of each of the balls
// on each pixel
for (int y = minY; y < maxY; y++)
{
for (int x = minX; x < maxX; x++)
{
// Calculate the sum of influence of each ball on the current pixel
float sum = 0.0;
for (int i = 0; i < BALL_COUNT; ++i)
{
int dx = x - balls[i].x;
int dy = y - balls[i].y;
if (dx != 0 && dy != 0)
{
// Comment this out and these loops fly.
sum += balls[i].rsq / (float)((dx * dx) + (dy * dy));
}
}
// Check if the pixel should be lit up.
if (sum > 0.9 && sum < 1.0)
{
lcd_ram[x][y] = 0x001f;
}
}
}
ShowLcdRam();
}
return 0;
}