00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef GENERATOR_H
00024 #define GENERATOR_H
00025
00033 #include <QtGui>
00034 #include <complex>
00035
00041 class Generator : public QThread
00042 {
00043 Q_OBJECT
00044
00045 public slots:
00049 void run()
00050 {
00051 hasToStop = false;
00052 begin = QTime::currentTime();
00053
00054 render.fill(QColor(0, 0, 0).rgb());
00055
00056 if(set == "Mandelbrot")
00057 mandelbrot();
00058 if(set == "Complex Map Buddhabrot")
00059 buddhabrot();
00060
00061 end = QTime::currentTime();
00062 emit genEnd();
00063 }
00067 void mandelbrot()
00068 {
00069 int w = width;
00070 int h = height;
00071
00072 render = QImage(QSize(w, h), QImage::Format_RGB32);
00073
00074 double imagMax = (3.0) * h / w - 1.2;
00075 double realF = (3.0) / (w - 1);
00076 double imagF = (imagMax + 1.2) / (h - 1);
00077
00078 for(int y = 0; y < h; y++)
00079 {
00080 std::complex<double> c;
00081 c.imag() = imagMax - y * imagF;
00082 QRgb *line = reinterpret_cast<QRgb *>(render.scanLine(y));
00083 for(int x = 0; x < w; x++)
00084 {
00085 c.real() = x * realF - 2.0;
00086 std::complex<double> z(c.real(), c.imag());
00087 double n;
00088 for(n = 0; n < it; n++)
00089 {
00090 std::complex<double> zn(z.real() * z.real(), z.imag() * z.imag());
00091 if(zn.real() + zn.imag() > 4) break;
00092 z.imag() = 2 * z.real() * z.imag() + c.imag();
00093 z.real() = zn.real() - zn.imag() + c.real();
00094 }
00095 double red = n / it * r;
00096 double green = n / it * g;
00097 double blue = n / it * b;
00098 if(n == it) line[x] = qRgb(0, 0, 0);
00099 else line[x] = qRgb(red, green, blue);
00100 if(hasToStop) return;
00101 }
00102 }
00103 }
00107 void buddhabrot()
00108 {
00109 int w = width;
00110 int h = height;
00111
00112 render = QImage(QSize(w, h), QImage::Format_RGB32);
00113
00114 double imagMax = (3.0) * h / w - 2.0;
00115 double realF = (3.0) / (w - 1);
00116 double imagF = (imagMax + 2.0) / (h - 1);
00117
00118 int maxFreq = 0;
00119
00120 int **table = new int *[h];
00121 for(int y = 0; y < h ; y++)
00122 {
00123 table[y] = new int[w];
00124 for(int x = 0; x < h ; x++)
00125 table[y][x] = 0;
00126 }
00127 for(int y = 0; y < h; y++)
00128 {
00129 std::complex<double> c;
00130 c.imag() = imagMax - y * imagF;
00131 for(int x = 0; x < w; x++)
00132 {
00133 c.real() = x * realF - 2.0;
00134 std::complex<double> z(c.real(), c.imag());
00135 double n;
00136 for(n = 0; n < it; n++)
00137 {
00138 std::complex<double> zn(z.real() * z.real(), z.imag() * z.imag());
00139 if(zn.real() + zn.imag() > 4) break;
00140 z.imag() = 2 * z.real() * z.imag() + c.imag();
00141 z.real() = zn.real() - zn.imag() + c.real();
00142 int y_ = qvariant_cast<int>(qAbs(z.imag() / imagF + h / 2));
00143 int x_ = qvariant_cast<int>(qAbs(z.real() / realF + w / 2));
00144 if(y_ < h && x_ < w)
00145 {
00146 table[y_][x_]++;
00147 if(table[y_][x_] > maxFreq)
00148 maxFreq = table[y_][x_];
00149 }
00150 }
00151 if(hasToStop) return;
00152 }
00153 }
00154 for(int y = 0; y < h; y++)
00155 {
00156 QRgb *line = reinterpret_cast<QRgb *>(render.scanLine(y));
00157 for(int x = 0; x < w; x++)
00158 {
00159 double red = qMin(r, qvariant_cast<int>(std::pow(qvariant_cast<double>(table[y][x]) / maxFreq, gamma) * r));
00160 double green = qMin(g, qvariant_cast<int>(std::pow(qvariant_cast<double>(table[y][x]) / maxFreq, gamma) * g));
00161 double blue = qMin(b, qvariant_cast<int>(std::pow(qvariant_cast<double>(table[y][x]) / maxFreq, gamma) * b));
00162 line[x] = qRgb(red, green, blue);
00163 }
00164 delete[] table[y];
00165 }
00166 delete[] table;
00167 }
00171 QTime getBegin()
00172 {
00173 return begin;
00174 }
00178 QTime getEnd()
00179 {
00180 return end;
00181 }
00185 QImage getImage()
00186 {
00187 return render;
00188 }
00195 void setColor(int red, int green, int blue)
00196 {
00197 r = red;
00198 g = green;
00199 b = blue;
00200 }
00205 void setCurrentSet(QString str)
00206 {
00207 set = str;
00208 }
00213 void setGamma(double value)
00214 {
00215 gamma = value;
00216 }
00221 void setItNum(int nb)
00222 {
00223 it = nb;
00224 }
00230 void setSize(int w, int h)
00231 {
00232 width = w;
00233 height = h;
00234 if(height > width) height = width;
00235 if(height < width) width = height;
00236 }
00240 void stop()
00241 {
00242 hasToStop = true;
00243 }
00244
00245 signals:
00249 void genEnd();
00250
00251 private:
00252 QTime begin;
00253 QTime end;
00254 QImage render;
00255 QString set;
00256 bool hasToStop;
00257 double gamma;
00258 int height;
00259 int width;
00260 int b;
00261 int g;
00262 int it;
00263 int r;
00264 };
00265
00266 #endif