Created
February 27, 2016 11:43
-
-
Save ViktorSimko/27f8ee36d52ac16e1c97 to your computer and use it in GitHub Desktop.
Biomorph Qt using signals and slots
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// frakablak.cpp | |
// | |
// Mandelbrot halmaz nagyító | |
// Programozó Páternoszter | |
// | |
// Copyright (C) 2011, Bátfai Norbert, nbatfai@inf.unideb.hu, nbatfai@gmail.com | |
// | |
// 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/>. | |
// | |
// Ez a program szabad szoftver; terjeszthetõ illetve módosítható a | |
// Free Software Foundation által kiadott GNU General Public License | |
// dokumentumában leírtak; akár a licenc 3-as, akár (tetszõleges) késõbbi | |
// változata szerint. | |
// | |
// Ez a program abban a reményben kerül közreadásra, hogy hasznos lesz, | |
// de minden egyéb GARANCIA NÉLKÜL, az ELADHATÓSÁGRA vagy VALAMELY CÉLRA | |
// VALÓ ALKALMAZHATÓSÁGRA való származtatott garanciát is beleértve. | |
// További részleteket a GNU General Public License tartalmaz. | |
// | |
// A felhasználónak a programmal együtt meg kell kapnia a GNU General | |
// Public License egy példányát; ha mégsem kapta meg, akkor | |
// tekintse meg a <http://www.gnu.org/licenses/> oldalon. | |
// | |
// | |
// Version history: | |
// | |
// 0.0.1 Bár a Nokia Qt SDK éppen tartalmaz egy Mandelbrotos példát, de | |
// ezt nem tartottam megfelelõnek elsõ Qt programként ajánlani, mert elég | |
// bonyolult: használ kölcsönös kizárást stb. Ezért "from scratch" megírtam | |
// egy sajátot a Javát tanítokhoz írt dallamára: | |
// http://www.tankonyvtar.hu/informatika/javat-tanitok-2-2-080904-1 | |
// | |
#include "frakablak.h" | |
FrakAblak::FrakAblak(double a, double b, double c, double d, | |
int szelesseg, int iteraciosHatar, QWidget *parent) | |
: QMainWindow(parent) | |
{ | |
setWindowTitle("Biomorfok"); | |
szamitasFut = true; | |
x = y = mx = my = 0; | |
this->a = a; | |
this->b = b; | |
this->c = c; | |
this->d = d; | |
this->szelesseg = szelesseg; | |
this->iteraciosHatar = iteraciosHatar; | |
magassag = (int)(szelesseg * ((d-c)/(b-a))); | |
setFixedSize(QSize(szelesseg, magassag)); | |
fraktal= new QImage(szelesseg, magassag, QImage::Format_RGB32); | |
savec = 0; | |
mandelbrot = new FrakSzal(a, b, c, d, szelesseg, magassag, iteraciosHatar, this); | |
mandelbrot->start(); | |
} | |
FrakAblak::~FrakAblak() | |
{ | |
delete fraktal; | |
delete mandelbrot; | |
} | |
void FrakAblak::paintEvent(QPaintEvent*) { | |
QPainter qpainter(this); | |
qpainter.drawImage(0, 0, *fraktal); | |
if(!szamitasFut) { | |
qpainter.setPen(QPen(Qt::white, 1)); | |
qpainter.drawRect(x, y, mx, my); | |
} | |
qpainter.end(); | |
} | |
void FrakAblak::mousePressEvent(QMouseEvent* event) { | |
// A nagyítandó kijelölt területet bal felsõ sarka: | |
x = event->x(); | |
y = event->y(); | |
mx = 0; | |
my = 0; | |
update(); | |
} | |
void FrakAblak::mouseMoveEvent(QMouseEvent* event) { | |
// A nagyítandó kijelölt terület szélessége és magassága: | |
mx = event->x() - x; | |
my = mx; // négyzet alakú | |
update(); | |
} | |
void FrakAblak::mouseReleaseEvent(QMouseEvent* event) { | |
if(szamitasFut) | |
return; | |
szamitasFut = true; | |
double dx = (b-a)/szelesseg; | |
double dy = (d-c)/magassag; | |
double a = this->a+x*dx; | |
double b = this->a+x*dx+mx*dx; | |
double c = this->d-y*dy-my*dy; | |
double d = this->d-y*dy; | |
this->a = a; | |
this->b = b; | |
this->c = c; | |
this->d = d; | |
delete mandelbrot; | |
mandelbrot = new FrakSzal(a, b, c, d, szelesseg, magassag, iteraciosHatar, this); | |
mandelbrot->start(); | |
update(); | |
} | |
void FrakAblak::keyPressEvent(QKeyEvent *event) | |
{ | |
if (event->key() == Qt::Key_N) | |
{ | |
if(szamitasFut) | |
return; | |
iteraciosHatar *= 2; | |
szamitasFut = true; | |
delete mandelbrot; | |
mandelbrot = new FrakSzal(a, b, c, d, szelesseg, magassag, iteraciosHatar, this); | |
mandelbrot->start(); | |
} | |
else if (event->key() == Qt::Key_S) | |
{ | |
fraktal->save("mandel_"+QString::number(savec++)+".png"); | |
} | |
} | |
void FrakAblak::setRow(int magassag, int *sor, int meret) | |
{ | |
for(int i=0; i<meret; ++i) { | |
QRgb szin = qRgb(255-(sor[i]/16)%256, (sor[i]%256), (sor[i]%32)); | |
fraktal->setPixel(i, magassag, szin); | |
} | |
update(); | |
} | |
void FrakAblak::setImage(void) | |
{ | |
szamitasFut = false; | |
x = y = mx = my = 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef FRAKABLAK_H | |
#define FRAKABLAK_H | |
#include <QMainWindow> | |
#include <QImage> | |
#include <QPainter> | |
#include <QMouseEvent> | |
#include <QKeyEvent> | |
#include "frakszal.h" | |
class FrakSzal; | |
class FrakAblak : public QMainWindow | |
{ | |
Q_OBJECT | |
public: | |
FrakAblak(double a = -2.0, double b = .7, double c = -1.35, | |
double d = 1.35, int szelesseg = 600, | |
int iteraciosHatar = 255, QWidget *parent = 0); | |
~FrakAblak(); | |
// A komplex sík vizsgált tartománya [a,b]x[c,d]. | |
double a, b, c, d; | |
// A komplex sík vizsgált tartományára feszített | |
// háló szélessége és magassága. | |
int szelesseg, magassag; | |
// Max. hány lépésig vizsgáljuk a z_{n+1} = z_n * z_n + c iterációt? | |
// (tk. most a nagyítási pontosság) | |
int iteraciosHatar; | |
protected: | |
void paintEvent(QPaintEvent*); | |
void mousePressEvent(QMouseEvent*); | |
void mouseMoveEvent(QMouseEvent*); | |
void mouseReleaseEvent(QMouseEvent*); | |
void keyPressEvent(QKeyEvent*); | |
private: | |
QImage* fraktal; | |
FrakSzal* mandelbrot; | |
bool szamitasFut; | |
// A nagyítandó kijelölt területet bal felsõ sarka. | |
int x, y; | |
// A nagyítandó kijelölt terület szélessége és magassága. | |
int mx, my; | |
int savec; | |
public slots: | |
void setRow(int magassag , int * sor, int meret); | |
void setImage(); | |
}; | |
#endif // FRAKABLAK_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// frakszal.cpp | |
// | |
// Mandelbrot halmaz rajzoló | |
// Programozó Páternoszter | |
// | |
// Copyright (C) 2011, Bátfai Norbert, nbatfai@inf.unideb.hu, nbatfai@gmail.com | |
// | |
// 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/>. | |
// | |
// Ez a program szabad szoftver; terjeszthetõ illetve módosítható a | |
// Free Software Foundation által kiadott GNU General Public License | |
// dokumentumában leírtak; akár a licenc 3-as, akár (tetszõleges) késõbbi | |
// változata szerint. | |
// | |
// Ez a program abban a reményben kerül közreadásra, hogy hasznos lesz, | |
// de minden egyéb GARANCIA NÉLKÜL, az ELADHATÓSÁGRA vagy VALAMELY CÉLRA | |
// VALÓ ALKALMAZHATÓSÁGRA való származtatott garanciát is beleértve. | |
// További részleteket a GNU General Public License tartalmaz. | |
// | |
// A felhasználónak a programmal együtt meg kell kapnia a GNU General | |
// Public License egy példányát; ha mégsem kapta meg, akkor | |
// tekintse meg a <http://www.gnu.org/licenses/> oldalon. | |
// | |
// | |
// Version history: | |
// | |
// 0.0.1 Bár a Nokia Qt SDK éppen tartalmaz egy Mandelbrotos példát, de | |
// ezt nem tartottam megfelelõnek elsõ Qt programként ajánlani, mert elég | |
// bonyolult: használ kölcsönös kizárást stb. Ezért "from scratch" megírtam | |
// egy sajátot a Javát tanítokhoz írt dallamára: | |
// http://www.tankonyvtar.hu/informatika/javat-tanitok-2-2-080904-1 | |
// | |
#include "frakszal.h" | |
FrakSzal::FrakSzal(double a, double b, double c, double d, | |
int szelesseg, int magassag, int iteraciosHatar, FrakAblak *frakAblak) | |
{ | |
this->a = a; | |
this->b = b; | |
this->c = c; | |
this->d = d; | |
this->szelesseg = szelesseg; | |
this->iteraciosHatar = iteraciosHatar; | |
this->frakAblak = frakAblak; | |
this->magassag = magassag; | |
egySor = new int[szelesseg]; | |
connect(this, SIGNAL(rowReady(int, int *, int)), | |
frakAblak, SLOT(setRow(int, int *, int))); | |
connect(this, SIGNAL(imageReady()), | |
frakAblak, SLOT(setImage())); | |
} | |
FrakSzal::~FrakSzal() | |
{ | |
disconnect(this, SIGNAL(rowReady(int, int *, int)), | |
frakAblak, SLOT(setRow(int, int *, int))); | |
disconnect(this, SIGNAL(imageReady()), | |
frakAblak, SLOT(setImage())); | |
delete[] egySor; | |
} | |
// A szál kódját a Javát tanítokhoz írt Java kódomból vettem át | |
// http://www.tankonyvtar.hu/informatika/javat-tanitok-2-2-080904-1 | |
// mivel itt az algoritmust is leírtam/lerajzoltam, így meghagytam | |
// a kommenteket, hogy a hallgató könnyen hozzáolvashassa az "elméletet", | |
// ha érdekli. | |
void FrakSzal::run() | |
{ | |
// A [a,b]x[c,d] tartományon milyen sûrû a | |
// megadott szélesség, magasság háló: | |
double dx = (b-a)/szelesseg; | |
double dy = (d-c)/magassag; | |
double reC, imC, reZ, imZ, ujreZ, ujimZ; | |
// Hány iterációt csináltunk? | |
int iteracio = 0; | |
// Végigzongorázzuk a szélesség x magasság hálót: | |
for(int j=0; j<magassag; ++j) { | |
//sor = j; | |
for(int k=0; k<szelesseg; ++k) { | |
// c = (reC, imC) a háló rácspontjainak | |
// megfelelõ komplex szám | |
reC = a+k*dx; | |
imC = d-j*dy; | |
// z_0 = 0 = (reZ, imZ) | |
std::complex<double> c(reC, imC); | |
reZ = 0; | |
imZ = 0; | |
std::complex<double> z_n(reZ, imZ); | |
iteracio = 0; | |
// z_{n+1} = z_n * z_n + c iterációk | |
// számítása, amíg |z_n| < 2 vagy még | |
// nem értük el a 255 iterációt, ha | |
// viszont elértük, akkor úgy vesszük, | |
// hogy a kiinduláci c komplex számra | |
// az iteráció konvergens, azaz a c a | |
// Mandelbrot halmaz eleme | |
/* | |
while(reZ*reZ + imZ*imZ < 4 && iteracio < iteraciosHatar) { | |
// z_{n+1} = z_n * z_n + c | |
ujreZ = reZ*reZ+ std::atan(reZ*reZ - imZ*imZ) + std::sqrt(reC); | |
ujimZ = 2*reZ*imZ+std::atan(2*reZ*imZ) + imC; | |
reZ = ujreZ; | |
imZ = ujimZ; | |
++iteracio; | |
} | |
*/ | |
while( std::abs(z_n) < 4 && iteracio < iteraciosHatar) { | |
z_n = std::cos(z_n*z_n)*std::pow(z_n, 5) + c*c; | |
++iteracio; | |
} | |
// ha a < 4 feltétel nem teljesült és a | |
// iteráció < iterációsHatár sérülésével lépett ki, azaz | |
// feltesszük a c-rõl, hogy itt a z_{n+1} = z_n * z_n + c | |
// sorozat konvergens, azaz iteráció = iterációsHatár | |
// ekkor az iteráció %= 256 egyenlõ 255, mert az esetleges | |
// nagyítasok során az iteráció = valahány * 256 + 255 | |
//iteracio /= 2; | |
//double oo = iteracio / iteraciosHatar; | |
//iteracio = oo*255; | |
//a színezést viszont már majd a FrakAblak osztályban lesz | |
egySor[k] = iteracio; | |
} | |
// Ábrázolásra átadjuk a kiszámolt sort a FrakAblak-nak. | |
emit rowReady(j, egySor, szelesseg); | |
} | |
emit imageReady(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef FRAKSZAL_H | |
#define FRAKSZAL_H | |
#include <QThread> | |
#include <cmath> | |
#include <complex> | |
#include "frakablak.h" | |
class FrakAblak; | |
class FrakSzal : public QThread | |
{ | |
Q_OBJECT | |
public: | |
FrakSzal(double a, double b, double c, double d, | |
int szelesseg, int magassag, int iteraciosHatar, FrakAblak *frakAblak); | |
~FrakSzal(); | |
void run(); | |
protected: | |
// A komplex sík vizsgált tartománya [a,b]x[c,d]. | |
double a, b, c, d; | |
// A komplex sík vizsgált tartományára feszített | |
// háló szélessége és magassága. | |
int szelesseg, magassag; | |
// Max. hány lépésig vizsgáljuk a z_{n+1} = z_n * z_n + c iterációt? | |
// (tk. most a nagyítási pontosság) | |
int iteraciosHatar; | |
// Kinek számolok? | |
FrakAblak* frakAblak; | |
// Soronként küldöm is neki vissza a kiszámoltakat. | |
int* egySor; | |
signals: | |
void rowReady(int magassag, int *sor, int meret); | |
void imageReady(); | |
}; | |
#endif // FRAKSZAL_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// main.cpp | |
// | |
// Mandelbrot halmaz rajzoló | |
// Programozó Páternoszter | |
// | |
// Copyright (C) 2011, Bátfai Norbert, nbatfai@inf.unideb.hu, nbatfai@gmail.com | |
// | |
// 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. | |
// | |
// Bár a Nokia Qt SDK éppen tartalmaz egy Mandelbrotos példát, de | |
// ezt nem tartottam megfelelõnek elsõ Qt programként ajánlani, mert elég | |
// bonyolult: használ kölcsönös kizárást stb. Ezért "from scratch" megírtam | |
// egy sajátot a Javát tanítokhoz írt dallamára: | |
// http://www.tankonyvtar.hu/informatika/javat-tanitok-2-2-080904-1 | |
// | |
#include <QApplication> | |
#include "frakablak.h" | |
int main(int argc, char *argv[]) | |
{ | |
QApplication a(argc, argv); | |
// További adatokat olvashatsz le innen: | |
// http://www.tankonyvtar.hu/informatika/javat-tanitok-2-3-080904 | |
FrakAblak w1; | |
w1.show(); | |
/* | |
FrakAblak w1, | |
w2(-.08292191725019529, -.082921917244591272, | |
-.9662079988595939, -.9662079988551173, 600, 3000), | |
w3(-.08292191724880625, -.0829219172470933, | |
-.9662079988581493, -.9662079988563615, 600, 4000), | |
w4(.14388310361318304, .14388310362702217, | |
.6523089200729396, .6523089200854384, 600, 38655); | |
w1.show(); | |
w2.show(); | |
w3.show(); | |
w4.show(); | |
*/ | |
return a.exec(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment