Conjunto de Mandelbrot (Fractal)
Publicado por Perfil removido (última atualização em 17/11/2010)
[ Hits: 8.576 ]
Como uma pequena homenagem ao matemático Benoît Mandelbrot , falecido no dia 14 do mês passado, um programa que gera um arquivo bitmap do conjunto de Mandelbrot. Para poupar espaço aqui, você pode encontrar maiores informações aqui:
http://en.wikipedia.org/wiki/Mandelbrot_set
Espero que o programa seja útil.
//=============================================================================== // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. // // Produces a bitmap picture of the Mandelbrot set. // // You can compile this code with the command // g++ fractal.cc -o fractal.x // // You can play with the command line parameters; a nice set is // // ./fractal.x 1024 768 -0.7 0 300 fractal.bmp // // I think this program is quite portable, and you can modify to build // your own fractal. If you find something cool (or have any complain, question // or suggestion about the code), please email me =) // // Author: Victor Santos // Email: victor_santos@fisica.ufc.br //=============================================================================== // Probably you want to keep all this code in a separate file. // bitmap.h // BMP (BitMap Files) are image files that have a relatively simple format: // // The first 54 bytes contain file header information: // * The first two bytes (0 and 1) must be BM // * Next 4 bytes stores the file size // * Bytes 18 through 21 contain the image width in pixels // * Bytes 22 through 25 contain the image height in pixels // * Byte 28 must be 24 for 24 bit BMP files // There are a few other required bytes. // // Image data is stored in the following format: // * Scan lines are stored bottom to top // * Each scan line is padded to the next four byte boundary. // * RGB vales are stored in reverse order: Blue, Green, and Red. //#ifndef BITMAP_H //#define BITMAP_H #include <iostream> #include <cstdlib> #include <fstream> using std::cout; using std::cerr; using std::endl; using std::ofstream; // Converte um a variável inteira num em um binário de 4 bytes. O byte mais // significativo é armazenado primeiro no array s void int_to_4byte(char *s, int num) { // Extrai o byte mais significativo s[3] = (unsigned char)(num/0x1000000); num %= 0x1000000; s[2] = (unsigned char)(num/0x10000); num %= 0x10000; s[1] = (unsigned char)(num/0x100); num %= 0x100; // Byte menos significativo s[0] = (unsigned char)(num); } // Classe bitmap ==============================================================80 class bitmap { protected: int width, height; // Largura e altura do bitmap (em pixels) unsigned char *pixels; // Armazena os dados referentes aos pixels char header[54]; // Armazena o cabeçalho do arquivo bitmap public: // Construtores bitmap(); // Padrão bitmap(const int&, const int&); // Sobrecarregado bitmap(const bitmap&); // Cópia // Destrutor virtual ~bitmap(); // Cria o cabeçalho para o arquivo bitmap void fill_header(void); // Ajusta a cor de um pixel void set_rgbcolor(const unsigned int&, const unsigned int&, const unsigned int&, const unsigned int&, const unsigned int&); // Salva o bitmap em um arquivo no disco void save_on_disk(const char *); }; //=============================================================================80 bitmap::bitmap() : width(0), height(0), pixels(NULL) {} bitmap::bitmap(const int& _width, const int& _height) : width(_width), height(_height), pixels(new unsigned char[3*_width*_height]) { if(pixels == NULL) { cerr << "Error: could not allocate memory for the bitmap." << endl; exit(1); } } bitmap::bitmap(const bitmap& copy) : width(copy.width), height(copy.height), pixels(copy.pixels) {} bitmap::~bitmap() { delete [] pixels; width = 0; height = 0; pixels = 0; } void bitmap::fill_header(void) { int n_extra = 4 - ((3*width) % 4); if(n_extra == 4) n_extra = 0; int padding = ((width * 3) + n_extra) * height; int fileSize = 54 + padding; for(int i = 2; i < 54; i++) // set all bytes to null header[i] = '{FONTE}'; header[0] = 'B'; header[1] = 'M'; header[10] = 54; header[14] = 40; header[26] = 1; int_to_4byte(header + 2, fileSize); int_to_4byte(header + 18, width); int_to_4byte(header + 22, height); header[28] = 24; } void bitmap::set_rgbcolor(const unsigned int& x_coord, const unsigned int& y_coord, const unsigned int& red, const unsigned int& green, const unsigned int& blue) { // Verifica se o pixel em questão está dentro da imagem if((x_coord < 0) || (x_coord >= width) || (y_coord < 0) || (y_coord >= height)) { throw("Invalid pixel"); } unsigned int r = red, g = green, b = blue; if(r > 255) { r = 255; } else if (r < 0) { r = 0; } if(g > 255) { g = 255; } else if (g < 0) { g = 0; } if(b > 255) { b = 255; } else if (b < 0) { b = 0; } pixels[(3*x_coord) + 0 + (3*y_coord*width)] = r; pixels[(3*x_coord) + 1 + (3*y_coord*width)] = g; pixels[(3*x_coord) + 2 + (3*y_coord*width)] = b; } void bitmap::save_on_disk(const char *filename) { unsigned int n_extra = 4 - ((3*width) % 4); if(n_extra == 4) n_extra = 0; ofstream out_stream(filename); if(!out_stream.is_open()) { throw("Could not open bitmap file for writting"); } fill_header(); out_stream.write(header, 54); for(int y = (height - 1); y >= 0; y--) // BMPs are written bottom to top. { for(int x = 0; x <= (width - 1); x++) { // Also, it's written in (b,g,r) format... out_stream << char(pixels[(3*x) + 2 + (3 * y * width)]) << char(pixels[(3*x) + 1 + (3 * y * width)]) << char(pixels[(3*x) + 0 + (3 * y * width)]); } if(n_extra) // See above - BMP lines must be of lengths divisible by 4. { for(int n = 1; n <= n_extra; n++) { out_stream << char(0); } } } out_stream.close(); } //#endif // BITMAP_H // Maximum number of iterations to decide whether a points belongs (or not) // to the set. Large numbers are better, but turns the program execution slow. const unsigned MAX_ITERATIONS = 512; int main(int argc, char **argv) { const unsigned width = unsigned(atoi(argv[1])); const unsigned height = unsigned(atoi(argv[2])); const unsigned centre_x = unsigned(atoi(argv[3])); const unsigned centre_y = unsigned(atoi(argv[4])); const unsigned zoom = unsigned(atoi(argv[5])); const char* outfile = argv[6]; bitmap out(width, height); const double startx = centre_x - double(width)/double(2*zoom); const double endx = centre_x + double(width)/double(2*zoom); const double starty = centre_y - double(height)/double(2*zoom); const double endy = centre_y + double(height)/double(2*zoom); const double dx = endx - startx; const double dy = endy - starty; const double dx_over_width = dx / width; for(double x = startx, xtoplot = 0; xtoplot < width; (x += dx_over_width) && (xtoplot += 1.0)) { for(double y = starty, ytoplot = 0; ytoplot < height; (y += dx_over_width) && (ytoplot += 1.0)) { double r = x; double s = y; for(int n = 0; n <= MAX_ITERATIONS; n++) { const double nextr = (r*r - s*s) + x; const double nexts = (2*r*s) + y; r = nextr; s = nexts; if(n == MAX_ITERATIONS) { out.set_rgbcolor(xtoplot, ytoplot, 0, 0, 0); } else if((r*r + s*s) > 4) { out.set_rgbcolor(xtoplot, ytoplot, unsigned(10*n), unsigned(20*n), unsigned(0)); break; } } } } out.save_on_disk(outfile); return 0; }
CalDOS - 60 funções em uma calculadora
Patch para Zsnes 1.51 com GCC>=4.3
Compartilhando a tela do Computador no Celular via Deskreen
Como Configurar um Túnel SSH Reverso para Acessar Sua Máquina Local a Partir de uma Máquina Remota
Configuração para desligamento automatizado de Computadores em um Ambiente Comercial
Como renomear arquivos de letras maiúsculas para minúsculas
Imprimindo no formato livreto no Linux
Vim - incrementando números em substituição
Efeito "livro" em arquivos PDF
Como resolver o erro no CUPS: Unable to get list of printer drivers
Vou voltar moderar conteúdos de Dicas e Artigos (1)
SysAdmin ou DevOps: Qual curso inicial pra essa área? (3)
É cada coisa que me aparece! - não é só 3% (3)
Melhorando a precisão de valores flutuantes em python[AJUDA] (5)
[Python] Automação de scan de vulnerabilidades
[Python] Script para analise de superficie de ataque
[Shell Script] Novo script para redimensionar, rotacionar, converter e espelhar arquivos de imagem
[Shell Script] Iniciador de DOOM (DSDA-DOOM, Doom Retro ou Woof!)
[Shell Script] Script para adicionar bordas às imagens de uma pasta