Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define _WIN32_WINNT 0x0500
- #include <windows.h>
- #include <iostream>
- #include <vector>
- #include <cstdlib>
- #include <ctime>
- #include <cmath>
- typedef void (*Callback)(double[2][2], double[2], int, int, int, int, int, int);
- struct Color
- {
- static const int Default = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
- static const int White = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY;
- static const int Red = FOREGROUND_RED | FOREGROUND_INTENSITY;
- static const int Green = FOREGROUND_GREEN | FOREGROUND_INTENSITY;
- static const int Blue = FOREGROUND_BLUE | FOREGROUND_INTENSITY;
- };
- struct Bitmap
- {
- int width;
- int height;
- std::vector<int> data;
- Bitmap(int width_ = 1, int height_ = 1, int color_ = Color::White) :
- width(width_), height(height_), data(width_ * height_, color_) {}
- int & operator()(int x, int y) { return data[x * height + y]; }
- int operator()(int x, int y) const { return data[x * height + y]; }
- };
- Bitmap RandomBitmap(int width, int height)
- {
- Bitmap bmp(width, height);
- struct Local
- {
- static void RandomColorDrops(Bitmap & bmp, int color)
- {
- int x, y;
- const int max_drops = 1 + (bmp.width + bmp.height) / 2;
- for (int count = 0; count < max_drops; ++count)
- {
- x = rand() % (bmp.width - 6) + 3;
- y = rand() % (bmp.height - 6) + 3;
- for (int i = -1; i <= 1; ++i)
- for (int j = -1; j <= 1; ++j)
- bmp(x + i, y + j) = color;
- }
- }
- };
- Local::RandomColorDrops(bmp, Color::Red);
- Local::RandomColorDrops(bmp, Color::Green);
- Local::RandomColorDrops(bmp, Color::Blue);
- return bmp;
- }
- struct Console
- {
- static HANDLE console;
- static CHAR_INFO * buffer;
- static int width;
- static int height;
- static void ClearBuffer()
- {
- for (int i = 0; i < width; ++i)
- for (int j = 0; j < height; ++j)
- buffer[i * height + j].Char.AsciiChar = ' ';
- }
- static void Init()
- {
- console = GetStdHandle(STD_OUTPUT_HANDLE);
- width = 80;
- height = 25;
- buffer = new CHAR_INFO[80 * 25];
- }
- static void Destroy()
- {
- delete[] buffer;
- }
- static void Resize(int x, int y)
- {
- delete[] buffer;
- width = x;
- height = y;
- buffer = new CHAR_INFO[x * y];
- COORD size = { x, y };
- SetConsoleScreenBufferSize(console, size);
- }
- static void DrawOnBuffer(const Bitmap & bmp)
- {
- for (int y = 0; y < bmp.height; ++y)
- {
- for (int x = 0; x < bmp.width; ++x)
- {
- buffer[y * width + x].Char.AsciiChar = '#';
- buffer[y * width + x].Attributes = bmp(x, y);
- }
- }
- }
- static void DisplayBuffer()
- {
- COORD buffer_size = { width, height };
- COORD buffer_coord = { 0, 0 };
- SMALL_RECT rect;
- rect.Top = 0;
- rect.Left = 0;
- rect.Right = width;
- rect.Bottom = height;
- WriteConsoleOutput(console, buffer, buffer_size, buffer_coord, &rect);
- }
- };
- HANDLE Console::console;
- CHAR_INFO * Console::buffer;
- int Console::width;
- int Console::height;
- void Invert(double a[2][2], double b[2])
- {
- double det = a[0][0] * a[1][1] - a[0][1] * a[1][0];
- double temp = a[0][0];
- a[0][0] = a[1][1];
- a[1][1] = temp;
- a[0][1] = - a[0][1];
- a[1][0] = - a[1][0];
- a[0][0] /= det;
- a[0][1] /= det;
- a[1][0] /= det;
- a[1][1] /= det;
- temp = b[0];
- b[0] = - (a[0][0] * b[0] + a[0][1] * b[1]);
- b[1] = - (a[1][0] * temp + a[1][1] * b[1]);
- }
- Bitmap Transform(const Bitmap & input, Callback matrix_setup, int frame, int max_frame)
- {
- double matrix_a[2][2] = { 1, 0, 0, 1 };
- double matrix_b[2] = { 0, 0 };
- const int old_width = input.width;
- const int old_height = input.height;
- int max_new_x = matrix_b[0];
- int min_new_x = matrix_b[0];
- int max_new_y = matrix_b[1];
- int min_new_y = matrix_b[1];
- int new_x, new_y;
- int old_x, old_y;
- for (int old_x = 0; old_x < old_width; ++old_x)
- {
- for (int old_y = 0; old_y < old_height; ++old_y)
- {
- matrix_setup(matrix_a, matrix_b, old_x, old_y, old_width, old_height, frame, max_frame);
- new_x = matrix_a[0][0] * old_x + matrix_a[0][1] * old_y + matrix_b[0];
- new_y = matrix_a[1][0] * old_x + matrix_a[1][1] * old_y + matrix_b[1];
- if (new_x < min_new_x) min_new_x = new_x;
- if (new_x > max_new_x) max_new_x = new_x;
- if (new_y < min_new_y) min_new_y = new_y;
- if (new_y > max_new_y) max_new_y = new_y;
- }
- }
- const int new_width = max_new_x - min_new_x + 1;
- const int new_height = max_new_y - min_new_y + 1;
- Bitmap output(new_width, new_height);
- for (int new_x = 0; new_x < new_width; ++new_x)
- {
- for (int new_y = 0; new_y < new_height; ++new_y)
- {
- matrix_setup(matrix_a, matrix_b, new_x, new_y, new_width, new_height, frame, max_frame);
- Invert(matrix_a, matrix_b);
- old_x = matrix_a[0][0] * new_x + matrix_a[0][1] * new_y + matrix_b[0];
- old_y = matrix_a[1][0] * new_x + matrix_a[1][1] * new_y + matrix_b[1];
- if (old_x >= 0 && old_x < old_width && old_y >=0 && old_y < old_height)
- output(new_x, new_y) = input(old_x, old_y);
- }
- }
- return output;
- }
- void shear(double a[2][2], double b[2], int x, int y, int max_x, int max_y, int frame, int max_frame)
- {
- a[0][1] = frame * 2.0 / max_frame;
- }
- void grow_top(double a[2][2], double b[2], int x, int y, int max_x, int max_y, int frame, int max_frame)
- {
- a[0][0] = 1 + (1 - y * 1.0 / max_y) * frame * 3.0 / max_frame;
- }
- void shrink_left(double a[2][2], double b[2], int x, int y, int max_x, int max_y, int frame, int max_frame)
- {
- a[1][1] = 1 - (1 - x * 1.0 / max_x) * frame * 0.67 / max_frame;
- }
- void magnifying_glass(double a[2][2], double b[2], int x, int y, int max_x, int max_y, int frame, int max_frame)
- {
- a[0][0] = 1;
- a[1][1] = 1;
- b[0] = 0;
- b[1] = 0;
- if ( (x - (15 + frame * 15.0 / max_frame )) * (x - (15 + frame * 15.0 / max_frame ))
- + (y - (20 + frame * 15.0 / max_frame )) * (y - (20 + frame * 15.0 / max_frame )) < 225)
- {
- a[0][0] = 2;
- a[1][1] = 2;
- b[0] = (- 10 - frame * 35.0 / max_frame);
- b[1] = (- 10 - frame * 35.0 / max_frame);
- }
- }
- void Animate(const Bitmap & bmp, Callback transformation)
- {
- const int max_frame = 60;
- const int delay = 25;
- Bitmap animation[max_frame + 1];
- for (int i = 0; i <= max_frame; ++i)
- animation[i] = Transform(bmp, transformation, i, max_frame);
- for (int i = 0; i <= max_frame; ++i)
- {
- Console::ClearBuffer();
- Console::DrawOnBuffer(animation[i]);
- Console::DisplayBuffer();
- Sleep(delay);
- }
- for (int i = max_frame; i >=0; --i)
- {
- Console::ClearBuffer();
- Console::DrawOnBuffer(animation[i]);
- Console::DisplayBuffer();
- Sleep(delay);
- }
- }
- int main()
- {
- srand(time(0));
- Console::Init();
- Console::Resize(100, 100);
- ShowWindow(GetConsoleWindow(), SW_SHOWMAXIMIZED);
- Bitmap small_bmp = RandomBitmap(25, 25);
- Bitmap big_bmp = RandomBitmap(50, 50);
- Animate(small_bmp, shear);
- Animate(small_bmp, grow_top);
- Animate(big_bmp, shrink_left);
- Animate(big_bmp, magnifying_glass);
- Console::ClearBuffer();
- Console::DrawOnBuffer(big_bmp);
- Console::DisplayBuffer();
- Console::Destroy();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement