Conjunto de Mandelbrot (Fractal)
Publicado por Perfil removido (última atualização em 17/11/2010)
[ Hits: 8.940 ]
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;
}
Integração numérica - Método da Quadratura Gaussiana
Ler N números e ver qual é o maior
Como extrair chaves TOTP 2FA a partir de QRCODE (Google Authenticator)
Linux em 2025: Segurança prática para o usuário
Desktop Linux em alta: novos apps, distros e privacidade marcam o sábado
IA chega ao desktop e impulsiona produtividade no mundo Linux
Novos apps de produtividade, avanços em IA e distros em ebulição agitam o universo Linux
Como instalar o repositório do DBeaver no Ubuntu
Como instalar o Plex Media Server no Ubuntu
Digitando underscore com "shift" + "barra de espaços"
Como ativar a lixeira e recuperar aquivos deletados em um servidor Linux
Como mudar o nome de dispositivos Bluetooth via linha de comando
O programa assinador digital (0)
dpkg: erro: gatilho de arquivo duplicado chamado pelo arquivo de nome (6)
Instalação não está resolvendo as dependencias (2)
Captação de áudio no zorin linux começa a diminuir com o tempo (5)









