137 lines
4.0 KiB
C++
137 lines
4.0 KiB
C++
#include <cmath>
|
|
#include <fstream>
|
|
#include <iomanip>
|
|
#include <iostream>
|
|
#include <mpi.h>
|
|
#include <string>
|
|
#include <tclDecls.h>
|
|
#include <vector>
|
|
|
|
#define MCW MPI_COMM_WORLD
|
|
using namespace std;
|
|
|
|
const int Master = 0;
|
|
|
|
struct Color {
|
|
int red;
|
|
int green;
|
|
int blue;
|
|
};
|
|
|
|
struct MandelbrotConfig {
|
|
int width;
|
|
int height;
|
|
double xComplexMin;
|
|
double xComplexMax;
|
|
double yComplexMin;
|
|
double yComplexMax;
|
|
double maxIterations;
|
|
Color colorOne;
|
|
Color colorTwo;
|
|
string outputFileName;
|
|
};
|
|
|
|
MandelbrotConfig readConfig(string configFile){
|
|
ifstream fin;
|
|
MandelbrotConfig config;
|
|
|
|
fin.open(configFile);
|
|
if (fin){
|
|
fin >> config.width >> config.height;
|
|
fin >> config.xComplexMin >> config.xComplexMax;
|
|
fin >> config.yComplexMin >> config.yComplexMax;
|
|
fin >> config.maxIterations;
|
|
fin >> config.colorOne.red >> config.colorOne.green >> config.colorOne.blue;
|
|
fin >> config.colorTwo.red >> config.colorTwo.green >> config.colorTwo.blue;
|
|
fin >> config.outputFileName;
|
|
fin.close();
|
|
|
|
}
|
|
if(!fin){
|
|
cout << "Could not open File";
|
|
}
|
|
return config;
|
|
}
|
|
Color getPixelColor(Color color1, Color color2, double iterations, double maxIterations) {
|
|
Color colorReturn;
|
|
double myColorR = static_cast<double>((color2.red - color1.red) / maxIterations);
|
|
double myColorG = static_cast<double>((color2.green - color1.green) / maxIterations);
|
|
double myColorB = static_cast<double>((color2.blue - color1.blue) / maxIterations);
|
|
colorReturn.red = (color1.red + (iterations * myColorR));
|
|
colorReturn.green = (color1.green + (iterations * myColorG));
|
|
colorReturn.blue = (color1.blue + (iterations * myColorB));
|
|
return colorReturn;
|
|
}
|
|
|
|
void writeFile(MandelbrotConfig config, std::vector<std::vector<Color>> array){
|
|
ofstream fout;
|
|
fout.open(config.outputFileName);
|
|
fout << "P3" << endl;
|
|
fout << config.width << " " << config.height << endl;
|
|
fout << "255" << endl;
|
|
for(int i = 0; i < config.height; i++){
|
|
for(int j = 0; j < config.width; j++){
|
|
Color Pixel = array[i][j];
|
|
fout << Pixel.red << " " << Pixel.green << " " << Pixel.blue << " ";
|
|
}
|
|
fout << endl;
|
|
}
|
|
fout.close();
|
|
}
|
|
|
|
void drawMandelbrot(MandelbrotConfig config, int world_rank){
|
|
double pixelWidth = ((config.xComplexMax-config.xComplexMin)/config.width);
|
|
double pixelHeight = ((config.yComplexMax-config.yComplexMin)/config.height);
|
|
std::vector<std::vector<Color>> pixels(config.height, std::vector<Color> (config.width));
|
|
std::vector<Color> sub_pixels;
|
|
for (int i = 0; i < config.height; i++){
|
|
if(world_rank == 0){
|
|
MPI_Scatter(*pixels, config.width, MPI_Vector, sub_pixels,
|
|
config.width, MPI_Vector, 0, MCW);
|
|
}
|
|
else{
|
|
for (int j = 0; j< config.width; j++) {
|
|
double x0 = config.xComplexMin + j * pixelWidth;
|
|
double y0 = config.yComplexMin + i * pixelHeight;
|
|
double x = 0;
|
|
double y = 0;
|
|
double iteration = 0;
|
|
while ((x * x) + (y * y) < (2 * 2) &&
|
|
iteration < config.maxIterations) {
|
|
double xtemp = (x * x) - (y * y) + x0;
|
|
y = 2 * x * y + y0;
|
|
x = xtemp;
|
|
iteration = iteration + 1;
|
|
}
|
|
Color Pixel = getPixelColor(config.colorOne, config.colorTwo,
|
|
iteration, config.maxIterations);
|
|
pixels[i][j] = Pixel;
|
|
}
|
|
}
|
|
}
|
|
writeFile(config, pixels);
|
|
}
|
|
|
|
int main(int argc, char *argv[]) {
|
|
string configFile;
|
|
MandelbrotConfig config;
|
|
|
|
// Read in config file location from user
|
|
cout << "Mandelbrot Config File: ";
|
|
cin >> configFile;
|
|
// Read config file contents into MandelbrotConfig struct instance
|
|
config = readConfig(configFile);
|
|
// Compute and write specified mandelbrot image to PPM file
|
|
// drawMandelbrot(config);
|
|
int rank , size;
|
|
int data;
|
|
MPI_Init (&argc , &argv);
|
|
MPI_Comm_rank(MCW , &rank);
|
|
MPI_Comm_size(MCW , &size);
|
|
|
|
|
|
drawMandelbrot(config);
|
|
MPI_Finalize();
|
|
return 0;
|
|
}
|