|
@ -10,17 +10,17 @@ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
/**
|
|
|
* Integer variant of the sinus function which takes an integer based angle |
|
|
* Integer variant of the sine function which takes an integer based angle |
|
|
* (range from 0 to 63) where sin_i(64) corresponds to sin(2 * M_PI) * 64 and |
|
|
* (range from 0 to 63) where sin_i(64) corresponds to sin(2 * M_PI) * 64 and |
|
|
* sin_i(16) corresponds to sin(0.5 * M_PI) * 64 (each excluding the fractional |
|
|
* sin_i(16) corresponds to sin(M_PI_2) * 64 (each excluding the fractional |
|
|
* part). It uses a lookup table which models one quarter of a full sinus period |
|
|
* part). It uses a lookup table which models one quarter of a full sine period |
|
|
* and calculates the rest of the function from that quarter. |
|
|
* and calculates the rest of the function from that quarter. |
|
|
* @param angle angle based on an integer (range from 0 to 63) |
|
|
* @param angle angle based on an integer (range from 0 to 63) |
|
|
* @return result of the sinus function normalized to a range from -64 to 64 |
|
|
* @return result of the sine function normalized to a range from -64 to 64 |
|
|
*/ |
|
|
*/ |
|
|
static signed char sin_i(unsigned char angle) { |
|
|
static signed char sin_i(signed char angle) { |
|
|
// the aforementioned lookup table
|
|
|
// the aforementioned lookup table
|
|
|
static signed char const sinus_table[] PROGMEM = |
|
|
static signed char const sine_table[] PROGMEM = |
|
|
{0, 6, 12, 19, 24, 30, 36, 41, 45, 49, 53, 56, 59, 61, 63, 64}; |
|
|
{0, 6, 12, 19, 24, 30, 36, 41, 45, 49, 53, 56, 59, 61, 63, 64}; |
|
|
|
|
|
|
|
|
// determine correct index for the lookup table depending on the given angle
|
|
|
// determine correct index for the lookup table depending on the given angle
|
|
@ -36,17 +36,17 @@ static signed char sin_i(unsigned char angle) { |
|
|
index = 63 - angle; |
|
|
index = 63 - angle; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return (signed char)(PGM(sinus_table[index])) * (angle < 32 ? 1 : -1); |
|
|
return (signed char)(PGM(sine_table[index])) * (angle < 32 ? 1 : -1); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
/**
|
|
|
* Integer variant of the cosinus function which takes an integer based angle |
|
|
* Integer variant of the cosine function which takes an integer based angle |
|
|
* (range from 0 to 63) where cos_i(64) corresponds to cos(2 * M_PI) * 64 and |
|
|
* (range from 0 to 63) where cos_i(64) corresponds to cos(2 * M_PI) * 64 and |
|
|
* cos_i(16) corresponds to cos(0.5 * M_PI) * 64. It uses the sin_i function and |
|
|
* cos_i(16) corresponds to cos(M_PI_2) * 64. It uses the sin_i function and |
|
|
* shifts the given angle by 16 (which corresponds to 90 degrees). |
|
|
* shifts the given angle by 16 (which corresponds to a delta of 90 degrees). |
|
|
* @param angle angle based on an integer (range from 0 to 63) |
|
|
* @param angle angle based on an integer (range from 0 to 63) |
|
|
* @return result of the cosinus function normalized to a range from -64 to 64 |
|
|
* @return result of the cosine function normalized to a range from -64 to 64 |
|
|
*/ |
|
|
*/ |
|
|
static signed char cos_i(unsigned char const angle) { |
|
|
static signed char cos_i(unsigned char const angle) { |
|
|
return sin_i(angle + 16); |
|
|
return sin_i(angle + 16); |
|
@ -60,32 +60,22 @@ static signed char cos_i(unsigned char const angle) { |
|
|
* Draws a black hole like pattern (viewed from different perspectives). |
|
|
* Draws a black hole like pattern (viewed from different perspectives). |
|
|
*/ |
|
|
*/ |
|
|
void blackhole(void) { |
|
|
void blackhole(void) { |
|
|
pixel circlePoints[NUM_CIRCLE][8]; |
|
|
signed char firstRadius = 80, helpRadius, angle = 0, add = 0; |
|
|
unsigned char add = 0; |
|
|
|
|
|
signed char firstRadius = 80, helpRadius, angle = 0, x, y; |
|
|
|
|
|
// initialize data
|
|
|
// initialize data
|
|
|
for (int k = 0; k < 800; k++) { |
|
|
for (unsigned int k = 0; k < 800; k++) { |
|
|
if (k > 300) |
|
|
if (k > 300) { |
|
|
add = k / 16; |
|
|
add = k / 16; |
|
|
|
|
|
} |
|
|
helpRadius = firstRadius; |
|
|
helpRadius = firstRadius; |
|
|
for (unsigned char i = 0; i < NUM_CIRCLE; i++) { |
|
|
for (signed char i = 0; i < NUM_CIRCLE; i++) { |
|
|
for (unsigned char j = 0; j < 8; j++) { |
|
|
for (signed char j = 0; j < 64; j += 8) { |
|
|
if (j & 1) { |
|
|
signed char a = (j & 0x08) ? 0 : 4; |
|
|
circlePoints[i][j].x = 64 |
|
|
pixel p; |
|
|
+ (cos_i(angle + j * 8) * helpRadius) / 64; |
|
|
p.x = (64 + cos_i(angle + j + a) * helpRadius / 64) >> 3; |
|
|
circlePoints[i][j].y = 64 |
|
|
p.y = (64 + sin_i(angle + add + j + a) * helpRadius / 64) >> 3; |
|
|
+ (sin_i(angle + add + j * 8) * helpRadius) / 64; |
|
|
if ((p.x < NUM_COLS) && (p.y < NUM_ROWS)) { |
|
|
|
|
|
setpixel(p, 3); |
|
|
} else { |
|
|
|
|
|
circlePoints[i][j].x = 64 + |
|
|
|
|
|
(cos_i(angle + j * 8 + 4) * helpRadius) / 64; |
|
|
|
|
|
circlePoints[i][j].y = 64 + |
|
|
|
|
|
(sin_i(angle + add + j * 8 + 4) * helpRadius) / 64; |
|
|
|
|
|
} |
|
|
} |
|
|
x = circlePoints[i][j].x / 8; |
|
|
|
|
|
y = circlePoints[i][j].y / 8; |
|
|
|
|
|
if (x < 16 && y < 16) |
|
|
|
|
|
setpixel((pixel){x, y}, 3); |
|
|
|
|
|
} |
|
|
} |
|
|
helpRadius = (helpRadius * 2) / 3; |
|
|
helpRadius = (helpRadius * 2) / 3; |
|
|
} |
|
|
} |
|
@ -93,7 +83,8 @@ void blackhole(void) { |
|
|
clear_screen(0); |
|
|
clear_screen(0); |
|
|
angle++; |
|
|
angle++; |
|
|
firstRadius += 2; |
|
|
firstRadius += 2; |
|
|
if (firstRadius > 119) |
|
|
if (firstRadius > 119) { |
|
|
firstRadius = 80; |
|
|
firstRadius = 80; |
|
|
} |
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|