BigintWidget::BigintWidget(QWidget *parent)
: QWidget(parent),
fw(new QFutureWatcher<MandelResultCell>(this)),
- meta(128, QSize(1800, 900)),
+ settings(128, QSize(502, 334)),
img_label(new QLabel(this)),
img_dirty(true),
status_bar(new QStatusBar(this))
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() {
}
void BigintWidget::finished_cell(int num) {
- meta.finished_cell(num, fw->resultAt(num));
+ settings.finished_cell(num, fw->resultAt(num));
img_dirty = true;
update();
}
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);
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)"
)
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) {
}
}
-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<MandelCell>::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<MandelCell>::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) {
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)
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<MandelCell> 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<MandelCell> 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<MandelCell> 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<MandelCell> get_cells() const { return cells; }
void zoom(QPoint pos);
void finished_cell(int num, const MandelResultCell &cell);
};
class MandelCell {
- MandelMeta *meta;
+ MandelParams *params;
QPoint pos;
MpzPoint rpos0;
MandelResultCell result;
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; }