From 0b3b15aa9b2563d32a5822ae858f205fbbd5c203 Mon Sep 17 00:00:00 2001 From: mar77i Date: Thu, 11 Apr 2024 02:39:54 +0200 Subject: [PATCH] split up mandelmeta into mandelsettings and mandelparams --- bigintwidget.cpp | 21 +++++++------ bigintwidget.h | 2 +- mandel.cpp | 82 +++++++++++++++++++++++++++++++----------------- mandel.h | 40 ++++++++++++++--------- 4 files changed, 91 insertions(+), 54 deletions(-) diff --git a/bigintwidget.cpp b/bigintwidget.cpp index 399ee88..ed976c7 100644 --- a/bigintwidget.cpp +++ b/bigintwidget.cpp @@ -12,7 +12,7 @@ BigintWidget::BigintWidget(QWidget *parent) : QWidget(parent), fw(new QFutureWatcher(this)), - meta(128, QSize(1800, 900)), + settings(128, QSize(502, 334)), img_label(new QLabel(this)), img_dirty(true), status_bar(new QStatusBar(this)) @@ -31,13 +31,13 @@ BigintWidget::BigintWidget(QWidget *parent) this, &BigintWidget::finished ); - fw->setFuture(QtConcurrent::mapped(meta.get_cells(), MandelMeta::iterate)); + fw->setFuture(QtConcurrent::mapped(settings.get_cells(), MandelSettings::iterate)); setLayout(new QVBoxLayout()); layout()->addWidget(setup_menu_bar()); layout()->addWidget(scroll_area); status_bar->setSizeGripEnabled(false); layout()->addWidget(status_bar); - img_label->setMinimumSize(meta.get_size()); + img_label->setMinimumSize(settings.get_size()); } BigintWidget::~BigintWidget() { @@ -67,7 +67,7 @@ QMenuBar *BigintWidget::setup_menu_bar() { } void BigintWidget::finished_cell(int num) { - meta.finished_cell(num, fw->resultAt(num)); + settings.finished_cell(num, fw->resultAt(num)); img_dirty = true; update(); } @@ -96,7 +96,7 @@ static inline void finished_status(QStatusBar *status_bar) { void BigintWidget::paintEvent(QPaintEvent *event) { static int prev_num_threads = -1; if (img_dirty) { - img_label->setPixmap(meta.get_pixmap()); + img_label->setPixmap(settings.get_pixmap()); img_dirty = false; if (fw->isFinished()) finished_status(status_bar); @@ -110,18 +110,19 @@ void BigintWidget::paintEvent(QPaintEvent *event) { void BigintWidget::mousePressEvent(QMouseEvent *event) { if (!fw->isFinished() || event->button() != Qt::MouseButton::LeftButton) return; + QSize size(settings.get_size()); QPoint pos = img_label->mapFromParent(event->pos()); - if (pos.x() < 0 || pos.x() >= meta.get_width() - || pos.y() < 0 || pos.y() >= meta.get_height()) + if (pos.x() < 0 || pos.x() >= size.width() + || pos.y() < 0 || pos.y() >= size.height()) return; - meta.zoom(pos); - fw->setFuture(QtConcurrent::mapped(meta.get_cells(), MandelMeta::iterate)); + settings.zoom(pos); + fw->setFuture(QtConcurrent::mapped(settings.get_cells(), MandelSettings::iterate)); img_dirty = true; update(); } void BigintWidget::export_img() { - meta.save_img( + settings.save_img( QFileDialog::getSaveFileName( this, "Save image", "", "Images (*.png *.xpm *.jpg)" ) diff --git a/bigintwidget.h b/bigintwidget.h index 6952bb2..6281bd9 100644 --- a/bigintwidget.h +++ b/bigintwidget.h @@ -16,7 +16,7 @@ class BigintWidget : public QWidget { Q_OBJECT QFutureWatcher *fw; - MandelMeta meta; + MandelSettings settings; QLabel *img_label; bool img_dirty; QStatusBar *status_bar; diff --git a/mandel.cpp b/mandel.cpp index 10e6b4d..1140984 100644 --- a/mandel.cpp +++ b/mandel.cpp @@ -13,6 +13,24 @@ MandelResultCell::MandelResultCell() : iter(0) {} MandelResultCell::MandelResultCell(size_t iter, MpzPoint rpos) : iter(iter), rpos(rpos) {} +MandelParams::MandelParams( + size_t max_iter, + QSize size, + MpzPoint center_f, + mpz_class one +) +: max_iter(max_iter), + size(size), + center_f(center_f), + one(one) {} + +MandelParams::MandelParams(const MandelParams &other) +: max_iter(other.max_iter), + size(other.size), + center_f(other.center_f), + one(other.one) {} + + static inline void incrpos(QPoint &pos, const int width) { pos.setX(pos.x() + 1); if (pos.x() == width) { @@ -21,74 +39,80 @@ static inline void incrpos(QPoint &pos, const int width) { } } -static inline mpz_class get_one(const QSize size) { - int one = std::min(size.width() / 3, size.height() / 3) / 2; - one--; - one |= one >> 1; - one |= one >> 2; - one |= one >> 4; - one |= one >> 8; - one |= one >> 16; - return mpz_class(one + 1); +static inline MandelParams initial_params(size_t max_iter, const QSize size) { + mpz_class one; + MpzPoint center_f; + int ione = std::min(size.width() / 3, size.height() / 3) / 2; + ione--; + ione |= ione >> 1; + ione |= ione >> 2; + ione |= ione >> 4; + ione |= ione >> 8; + ione |= ione >> 16; + one = mpz_class(ione + 1); + center_f = MpzPoint(one * -3 / 4, 0); + return MandelParams(max_iter, size, center_f, one); } -MandelMeta::MandelMeta(size_t max_iter, const QSize size) -: max_iter(max_iter), - img(size, QImage::Format_RGB888), - cells(size.width() * size.height(), MandelCell(this)), - one(::get_one(size)) +MandelSettings::MandelSettings(size_t max_iter, const QSize size) +: current(::initial_params(max_iter, size)), img(size, QImage::Format_RGB888) { QVector::iterator i; QPointF c(size.width() / 2., size.height() / 2.); QPoint pos; - center_f = MpzPoint(one * -3 / 4, 0); + cells.resize(size.width() * size.height(), MandelCell(¤t)); for (i = cells.begin(); i != cells.end(); incrpos(pos, size.width()), i++) { i->set_pos(pos); } } -void MandelMeta::zoom(QPoint pos) { +void MandelSettings::zoom(QPoint pos) { QVector::iterator i; MpzPoint p = cells[img.width() * pos.y() + pos.x()].get_rpos0(); - center_f = MpzPoint(p.get_x() * 8, p.get_y() * 8); - one *= 8; + current = MandelParams( + current.get_max_iter(), + current.get_size(), + MpzPoint(p.get_x() * 8, p.get_y() * 8), + current.get_one() * 8 + ); img.fill(Qt::GlobalColor::black); for (i = cells.begin(); i != cells.end(); i++) i->reset_iter_and_rpos(); } -void MandelMeta::finished_cell(int num, const MandelResultCell &result) { +void MandelSettings::finished_cell(int num, const MandelResultCell &result) { size_t iter = result.get_iter(); cells[num].set_result(result); img.setPixelColor( cells[num].get_pos(), - iter < max_iter + iter < current.get_max_iter() ? colors[iter % colors.size()] : Qt::GlobalColor::black ); } -MandelResultCell MandelMeta::iterate(const MandelCell &cell) { +MandelResultCell MandelSettings::iterate(const MandelCell &cell) { return cell.iterate(); } -void MandelMeta::save_img(QString file_name) { +void MandelSettings::save_img(QString file_name) { img.save(file_name); } void MandelCell::reset_rpos0() { - MpzPoint center_f = meta->get_center_f(); + QSize size(params->get_size()); + MpzPoint center_f = params->get_center_f(); rpos0 = MpzPoint( - center_f.get_x() + (pos.x() - meta->get_width() / 2.), - center_f.get_y() + (pos.y() - meta->get_height() / 2.) + center_f.get_x() + (pos.x() - size.width() / 2.), + center_f.get_y() + (pos.y() - size.height() / 2.) ); } -MandelCell::MandelCell(MandelMeta *meta) : meta(meta) {} +MandelCell::MandelCell(MandelParams *params) : params(params) {} MandelCell::MandelCell(const MandelCell &cell) -: meta(cell.meta), pos(cell.pos), result(cell.result), +: params(cell.params), pos(cell.pos), result(cell.result), rpos0(cell.rpos0) {} void MandelCell::set_result(const MandelResultCell &result) { @@ -107,10 +131,10 @@ void MandelCell::set_pos(QPoint pos) { MandelResultCell MandelCell::iterate() const { MpzPoint rpos = this->result.rpos, sq; - mpz_class one = meta->get_one(), four = one * one * 4; + mpz_class one = params->get_one(), four = one * one * 4; mpz_class sqx, sqy; size_t iter = this->result.iter; - for (; iter < meta->get_max_iter(); iter++) { + for (; iter < params->get_max_iter(); iter++) { sqx = rpos.get_x() * rpos.get_x(); sqy = rpos.get_y() * rpos.get_y(); if (sqx + sqy > four) diff --git a/mandel.h b/mandel.h index 7876ec4..5cd8b18 100644 --- a/mandel.h +++ b/mandel.h @@ -32,26 +32,38 @@ public: const size_t get_iter() const { return iter; } }; -class MandelMeta { - /* max_iter, img size, center_f and one are parameters - * that we may want to adjust for our next calculation. - */ +class MandelParams { +private: size_t max_iter; - QImage img; - QVector cells; + QSize size; MpzPoint center_f; mpz_class one; public: - MandelMeta(size_t max_iter, QSize size); + MandelParams( + size_t max_iter, + QSize size, + MpzPoint center_f, + mpz_class one + ); + MandelParams(const MandelParams &other); + const size_t get_max_iter() const { return max_iter; } - const QPixmap get_pixmap() const { return QPixmap::fromImage(img); } - const int get_width() const { return img.width(); } - const int get_height() const { return img.height(); } - const QSize get_size() const { return img.size(); } - const QVector get_cells() const { return cells; } + const QSize get_size() const { return size; } const MpzPoint get_center_f() const { return center_f; } const mpz_class get_one() const { return one; } +}; + +class MandelSettings { + MandelParams current; + QImage img; + QVector cells; + +public: + MandelSettings(size_t max_iter, QSize size); + const QPixmap get_pixmap() const { return QPixmap::fromImage(img); } + const QSize get_size() const { return current.get_size(); } + const QVector get_cells() const { return cells; } void zoom(QPoint pos); void finished_cell(int num, const MandelResultCell &cell); @@ -60,7 +72,7 @@ public: }; class MandelCell { - MandelMeta *meta; + MandelParams *params; QPoint pos; MpzPoint rpos0; MandelResultCell result; @@ -69,7 +81,7 @@ protected: void reset_rpos0(); public: - MandelCell(MandelMeta *meta); + MandelCell(MandelParams *params); MandelCell(const MandelCell &cell); inline const QPoint get_pos() const { return pos; } inline const size_t get_iter() const { return result.iter; } -- 2.47.0