Advertisement
balsa0

Fractal zoomer (image save version)

Mar 19th, 2013
210
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.03 KB | None | 0 0
  1. //main.cpp
  2.  
  3. #include <QtGui/QApplication>
  4. #include "frakablak.h"
  5.  
  6. void delay();
  7.  
  8. int main(int argc, char *argv[])
  9. {
  10.     QApplication a(argc, argv);
  11.     // További adatokat olvashatsz le innen:
  12.     // http://www.tankonyvtar.hu/informatika/javat-tanitok-2-3-080904
  13.     FrakAblak w1;
  14.     w1.show();
  15.  
  16.     return a.exec();
  17. }
  18.  
  19. // frakablak.cpp
  20. //
  21. // Mandelbrot halmaz rajzoló
  22. // Programozó Páternoszter
  23. //
  24. // Copyright (C) 2011, Bátfai Norbert, nbatfai@inf.unideb.hu, nbatfai@gmail.com
  25. //
  26. // This program is free software: you can redistribute it and/or modify
  27. // it under the terms of the GNU General Public License as published by
  28. // the Free Software Foundation, either version 3 of the License, or
  29. // (at your option) any later version.
  30. //
  31. // This program is distributed in the hope that it will be useful,
  32. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  33. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  34. // GNU General Public License for more details.
  35. //
  36. // You should have received a copy of the GNU General Public License
  37. // along with this program.  If not, see <http://www.gnu.org/licenses/>.
  38. //
  39. // Ez a program szabad szoftver; terjeszthetõ illetve módosítható a
  40. // Free Software Foundation által kiadott GNU General Public License
  41. // dokumentumában leírtak; akár a licenc 3-as, akár (tetszõleges) késõbbi
  42. // változata szerint.
  43. //
  44. // Ez a program abban a reményben kerül közreadásra, hogy hasznos lesz,
  45. // de minden egyéb GARANCIA NÉLKÜL, az ELADHATÓSÁGRA vagy VALAMELY CÉLRA
  46. // VALÓ ALKALMAZHATÓSÁGRA való származtatott garanciát is beleértve.
  47. // További részleteket a GNU General Public License tartalmaz.
  48. //
  49. // A felhasználónak a programmal együtt meg kell kapnia a GNU General
  50. // Public License egy példányát; ha mégsem kapta meg, akkor
  51. // tekintse meg a <http://www.gnu.org/licenses/> oldalon.
  52. //
  53. //
  54. // Version history:
  55. //
  56. // 0.0.1    Bár a Nokia Qt SDK éppen tartalmaz egy Mandelbrotos példát, de
  57. // ezt nem tartottam megfelelõnek elsõ Qt programként ajánlani, mert elég
  58. // bonyolult: használ kölcsönös kizárást stb. Ezért "from scratch" megírtam
  59. // egy sajátot a Javát tanítokhoz írt dallamára:
  60. // http://www.tankonyvtar.hu/informatika/javat-tanitok-2-2-080904-1
  61. //
  62.  
  63. #include <QTime>
  64. #include <QtCore/qmath.h>
  65. #include <QtGui/QApplication>
  66. #include "frakablak.h"
  67.  
  68. //várakozás (~Sleep)
  69. void delay()
  70. {
  71.     QTime dieTime= QTime::currentTime().addMSecs(10);
  72.     while( QTime::currentTime() < dieTime )
  73.     QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
  74. }
  75.  
  76. FrakAblak::FrakAblak(double a, double b, double c, double d,
  77.                      int szelesseg, int iteraciosHatar, QWidget *parent)
  78.                          : QMainWindow(parent)
  79. {
  80.     setWindowTitle("Mandelbrot halmaz");
  81.     //fix szélesség és magasság (HD 720p)
  82.     szelesseg = 1280;
  83.     int magassag = 720;
  84.     setFixedSize(QSize(100,100));
  85.     fraktal= new QImage(szelesseg, magassag, QImage::Format_RGB32);
  86.     QString str;
  87.     double p1=-7.5,p2=7.5,p3=-5,p4=5; //kezdő (szélső) koordináták megadása
  88.     double c1=.14388310362010260,c2=.6523089200791890;  //középpont - ide fog zoomolni
  89.     for (long int zoom = 1;zoom<=1200;zoom++){  //for ciklus a sorozatképek generálásához -- talán lehetne több szálat is futtatni
  90.         double zoom2 =qPow ( 1.02, zoom );  //zoomolás exponenciálisan
  91.         //a szélső koordinátákat osztja el a zoom mértékével és eltolja azt a megadott kezdőpontba
  92.         mandelbrot = new FrakSzal(c1+p1/zoom2, c1+p2/zoom2, c2+p3/zoom2, c2+p4/zoom2, szelesseg, magassag, iteraciosHatar, this);
  93.         mandelbrot->start();    //fraktál szál indítása
  94.         while(!(mandelbrot->rendered)) delay(); //várakozás amég kész nincs a fraktál
  95.         str = "/media/HDD/__FRAKTAL/fact_A"; //Fix elérési út és fájlnév
  96.         str += QString::number(zoom);
  97.         str += ".png";
  98.         fraktal->save(str); //képkocka mentése
  99.     }
  100.     //képkockák összefűzése videóvá: ffmpeg -i fact_A%d.png -r 30 -sameq test.mpg
  101.     //generálás után jeleníti meg az ablakot - csúnya :S
  102. }
  103.  
  104. FrakAblak::~FrakAblak()
  105. {
  106.     delete fraktal;
  107.     delete mandelbrot;
  108. }
  109.  
  110. void FrakAblak::paintEvent(QPaintEvent*) {
  111.     //nem kell megjeleníteni!!!
  112.  
  113.     /*QPainter qpainter(this);
  114.     qpainter.drawImage(0, 0, *fraktal);
  115.     qpainter.end();*/
  116. }
  117.  
  118. void FrakAblak::vissza(int magassag, int *sor, int meret)
  119. {
  120.     for(int i=0; i<meret; ++i) {
  121.         QRgb szin = qRgb(255-1.9*sor[i], 255-sor[i],255-1.8*sor[i]);
  122.         fraktal->setPixel(i, magassag, szin);
  123.     }
  124.     update();
  125. }
  126.  
  127. // frakszal.cpp
  128. //
  129. // Mandelbrot halmaz rajzoló
  130. // Programozó Páternoszter
  131. //
  132. // Copyright (C) 2011, Bátfai Norbert, nbatfai@inf.unideb.hu, nbatfai@gmail.com
  133. //
  134. // This program is free software: you can redistribute it and/or modify
  135. // it under the terms of the GNU General Public License as published by
  136. // the Free Software Foundation, either version 3 of the License, or
  137. // (at your option) any later version.
  138. //
  139. // This program is distributed in the hope that it will be useful,
  140. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  141. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  142. // GNU General Public License for more details.
  143. //
  144. // You should have received a copy of the GNU General Public License
  145. // along with this program.  If not, see <http://www.gnu.org/licenses/>.
  146. //
  147. // Ez a program szabad szoftver; terjeszthetõ illetve módosítható a
  148. // Free Software Foundation által kiadott GNU General Public License
  149. // dokumentumában leírtak; akár a licenc 3-as, akár (tetszõleges) késõbbi
  150. // változata szerint.
  151. //
  152. // Ez a program abban a reményben kerül közreadásra, hogy hasznos lesz,
  153. // de minden egyéb GARANCIA NÉLKÜL, az ELADHATÓSÁGRA vagy VALAMELY CÉLRA
  154. // VALÓ ALKALMAZHATÓSÁGRA való származtatott garanciát is beleértve.
  155. // További részleteket a GNU General Public License tartalmaz.
  156. //
  157. // A felhasználónak a programmal együtt meg kell kapnia a GNU General
  158. // Public License egy példányát; ha mégsem kapta meg, akkor
  159. // tekintse meg a <http://www.gnu.org/licenses/> oldalon.
  160. //
  161. //
  162. // Version history:
  163. //
  164. // 0.0.1    Bár a Nokia Qt SDK éppen tartalmaz egy Mandelbrotos példát, de
  165. // ezt nem tartottam megfelelõnek elsõ Qt programként ajánlani, mert elég
  166. // bonyolult: használ kölcsönös kizárást stb. Ezért "from scratch" megírtam
  167. // egy sajátot a Javát tanítokhoz írt dallamára:
  168. // http://www.tankonyvtar.hu/informatika/javat-tanitok-2-2-080904-1
  169. //
  170.  
  171. #include "frakszal.h"
  172.  
  173. FrakSzal::FrakSzal(double a, double b, double c, double d,
  174.                    int szelesseg, int magassag, int iteraciosHatar, FrakAblak *frakAblak)
  175. {
  176.     this->a = a;
  177.     this->b = b;
  178.     this->c = c;
  179.     this->d = d;
  180.     this->szelesseg = szelesseg;
  181.     this->iteraciosHatar = iteraciosHatar;
  182.     this->frakAblak = frakAblak;
  183.     this->magassag = magassag;
  184.     rendered = false;
  185.     egySor = new int[szelesseg];
  186. }
  187.  
  188. FrakSzal::~FrakSzal()
  189. {
  190.     delete[] egySor;
  191. }
  192.  
  193. // A szál kódját a Javát tanítokhoz írt Java kódomból vettem át
  194. // http://www.tankonyvtar.hu/informatika/javat-tanitok-2-2-080904-1
  195. // mivel itt az algoritmust is leírtam/lerajzoltam, így meghagytam
  196. // a kommenteket, hogy a hallgató könnyen hozzáolvashassa az "elméletet",
  197. // ha érdekli.
  198. void FrakSzal::run()
  199. {
  200.     rendered = false;
  201.     // A [a,b]x[c,d] tartományon milyen sûrû a
  202.     // megadott szélesség, magasság háló:
  203.     double dx = (b-a)/szelesseg;
  204.     double dy = (d-c)/magassag;
  205.     double reC, imC, reZ, imZ, ujreZ, ujimZ;
  206.     // Hány iterációt csináltunk?
  207.     int iteracio = 0;
  208.     // Végigzongorázzuk a szélesség x magasság hálót:
  209.     for(int j=0; j<magassag; ++j) {
  210.         //sor = j;
  211.         for(int k=0; k<szelesseg; ++k) {
  212.             // c = (reC, imC) a háló rácspontjainak
  213.             // megfelelõ komplex szám
  214.             reC = (a+k*dx);
  215.             //imC = 1.6*(0.5*d-j*0.5625*dy);
  216.             imC = d-j*dy;
  217.             // z_0 = 0 = (reZ, imZ)
  218.             reZ = 0;
  219.             imZ = 0;
  220.             iteracio = 0;
  221.             // z_{n+1} = z_n * z_n + c iterációk
  222.             // számítása, amíg |z_n| < 2 vagy még
  223.             // nem értük el a 255 iterációt, ha
  224.             // viszont elértük, akkor úgy vesszük,
  225.             // hogy a kiinduláci c komplex számra
  226.             // az iteráció konvergens, azaz a c a
  227.             // Mandelbrot halmaz eleme
  228.             while(reZ*reZ + imZ*imZ < 4 && iteracio < iteraciosHatar) {
  229.                 // z_{n+1} = z_n * z_n + c
  230.                 ujreZ = reZ*reZ - imZ*imZ + reC;
  231.                 ujimZ = 2*reZ*imZ + imC;
  232.                 reZ = ujreZ;
  233.                 imZ = ujimZ;
  234.  
  235.                 ++iteracio;
  236.  
  237.             }
  238.             // ha a < 4 feltétel nem teljesült és a
  239.             // iteráció < iterációsHatár sérülésével lépett ki, azaz
  240.             // feltesszük a c-rõl, hogy itt a z_{n+1} = z_n * z_n + c
  241.             // sorozat konvergens, azaz iteráció = iterációsHatár
  242.             // ekkor az iteráció %= 256 egyenlõ 255, mert az esetleges
  243.             // nagyítasok során az iteráció = valahány * 256 + 255
  244.  
  245.             iteracio %= 256;
  246.  
  247.             //a színezést viszont már majd a FrakAblak osztályban lesz
  248.             egySor[k] = iteracio;
  249.         }
  250.         // Ábrázolásra átadjuk a kiszámolt sort a FrakAblak-nak.
  251.         frakAblak->vissza(j, egySor, szelesseg);
  252.     }
  253.     rendered = true;
  254. }
  255.  
  256. //frakablak.h
  257. #ifndef FRAKABLAK_H
  258. #define FRAKABLAK_H
  259.  
  260. #include <QtGui/QMainWindow>
  261. #include <QImage>
  262. #include <QPainter>
  263. #include "frakszal.h"
  264.  
  265. class FrakSzal;
  266.  
  267. class FrakAblak : public QMainWindow
  268. {
  269.     Q_OBJECT
  270.  
  271. public:
  272.     FrakAblak(double a = -2.0, double b = .7, double c = -1.35,
  273.               double d = 1.35, int szelesseg = 600,
  274.               int iteraciosHatar = 255, QWidget *parent = 0);
  275.     ~FrakAblak();
  276.     void vissza(int magassag , int * sor, int meret) ;
  277.  
  278. protected:
  279.     void paintEvent(QPaintEvent*);
  280.  
  281. private:
  282.     QImage* fraktal;
  283.     FrakSzal* mandelbrot;
  284.  
  285. };
  286.  
  287. #endif // FRAKABLAK_H
  288.  
  289. //frakszal.h
  290. #ifndef FRAKSZAL_H
  291. #define FRAKSZAL_H
  292.  
  293. #include <QThread>
  294. #include <QImage>
  295. #include "frakablak.h"
  296.  
  297. class FrakAblak;
  298.  
  299. class FrakSzal : public QThread
  300. {
  301.     Q_OBJECT
  302.  
  303. public:
  304.     FrakSzal(double a, double b, double c, double d,
  305.              int szelesseg, int magassag, int iteraciosHatar, FrakAblak *frakAblak);
  306.     ~FrakSzal();
  307.     void run();
  308.     //renderelés elkészültének jelzése
  309.     bool rendered;
  310. protected:
  311.     // A komplex sík vizsgált tartománya [a,b]x[c,d].
  312.     double a, b, c, d;
  313.     // A komplex sík vizsgált tartományára feszített
  314.     // háló szélessége és magassága.
  315.     int szelesseg, magassag;
  316.     // Max. hány lépésig vizsgáljuk a z_{n+1} = z_n * z_n + c iterációt?
  317.     // (tk. most a nagyítási pontosság)
  318.     int iteraciosHatar;
  319.  
  320.     FrakAblak* frakAblak;
  321.     int* egySor;
  322.  
  323. };
  324.  
  325. #endif // FRAKSZAL_H
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement