college/ws2010/gdi3/p5/Mandelbrot.interface.cpp
2011-10-18 10:28:57 +02:00

103 lines
2.5 KiB
C++

#pragma once
#include "Mandelbrot.interface.h"
#include <complex>
#include <emmintrin.h>
void IMandelbrot::Init(int x_width, int y_height, int iterations, unsigned int threads, bool sse){
int** outarray = (int **) calloc(x_width, sizeof(int *));
for(unsigned int i = 0; i < x_width; i++)
outarray[i] = (int *) calloc(y_height, sizeof(int));
double minRe = -2.0;
double maxRe = 1.0;
double step = (abs(maxRe) + abs(minRe)) / x_width; //Schrittweite der zu überprüfenden komplexen Zahlen
double minIm = -1.2;
double maxIm = (y_height * step) - abs(minIm); //maximaler Imaginärwert
m_Params = new CParams(outarray,minRe,maxRe,minIm,maxIm,step,x_width,y_height,iterations,threads,sse);
}
void IMandelbrot::Exit(){
delete m_Params->m_outarray;
delete m_Params;
}
void IMandelbrot::calculateMandelbrot(){
calc(*m_Params);
}
int** IMandelbrot::getOutArray(){
return m_Params->m_outarray;
}
void IMandelbrot::checkNumber(CParams& params, double real, double imag, int rePos, int imPos){
complex<double> Zn(real, imag); //komplexe zahl, die sich in der schleife ändert
complex<double> actual(real, imag); //Speichere Ausgangszahl
if(params.m_use_sse){
for(int i = 0; i < params.m_iterations; i += 2){
Zn = Zn * Zn; //Zn = Zn^2
Zn = Zn + actual; //Zn = Zn^2 + c
complex<double> Zn2 = Zn * Zn;
Zn2 = Zn2 + actual;
__m128d a;
a = _mm_loadl_pd(a,&Zn.real());
a = _mm_loadh_pd(a,&Zn2.real());
__m128d b;
b = _mm_loadl_pd(b,&Zn.imag());
b = _mm_loadh_pd(b,&Zn2.imag());
a = _mm_mul_pd(a,a);
b = _mm_mul_pd(b,b);
a = _mm_add_pd(a,b);
double _a1;
double _a2;
_mm_storeh_pd(&_a1,a);
_mm_storeh_pd(&_a2,a);
double abs_1 = sqrt(_a1);
double abs_2 = sqrt(_a2);
if(abs_1 > 2 && abs_2 > 2){
params.m_outarray[rePos][imPos] = 0; //nicht in Mandelbrotmenge -> schreibe 0 in ASCII-MAP
return; //Schleifenabbruch
}
}
params.m_outarray[rePos][imPos] = 1; //in Mandelbrotmenge -> schreibe 1 in ASCII-MAP
return;
} else {
for(int i = 0; i < params.m_iterations; i++){
Zn = Zn * Zn; //Zn = Zn^2
Zn = Zn + actual; //Zn = Zn^2 + c
//Betrag Zn berechnen:
double a = Zn.real();
double b = Zn.imag();
a = a * a;
b = b * b;
a = a + b;
double abs = sqrt(a);
if(abs > 2){
params.m_outarray[rePos][imPos] = 0; //nicht in Mandelbrotmenge -> schreibe 0 in ASCII-MAP
return; //Schleifenabbruch
}
}
params.m_outarray[rePos][imPos] = 1; //in Mandelbrotmenge -> schreibe 1 in ASCII-MAP
return;
}
}