// mandel.cpp #include "colors.h" #include "mandel.h" MandelResultCell::MandelResultCell() {} MandelResultCell::MandelResultCell(size_t iter, QPointF rpos) : iter(iter), rpos(rpos) {} static inline void incrpos(QPoint &pos, const int width) { pos.setX(pos.x() + 1); if (pos.x() == width) { pos.setX(0); pos.setY(pos.y() + 1); } } 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)), center_f(qreal(-3) / 4, 0), one(1), four(4), scale(std::max(qreal(3) / size.width(), qreal(3) / size.height())) { QVector::iterator i; QPointF c(size.width() / 2., size.height() / 2.); QPoint pos; for (i = cells.begin(); i != cells.end(); incrpos(pos, size.width()), i++) { i->set_meta(this); i->set_pos(pos); } } void MandelMeta::zoom2x(QPoint pos) { QVector::iterator i; center_f = cells[img.width() * pos.y() + pos.x()].get_rpos0(); scale /= 2; 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 &cell) { img.setPixelColor( cells[num].update_result(cell.iter, cell.rpos), cell.iter < max_iter ? colors[cell.iter % colors.size()] : Qt::GlobalColor::black ); } MandelResultCell MandelMeta::iterate(const MandelCell &cell) { return cell.iterate(); } void MandelCell::reset_rpos0() { QPointF center_f = meta->get_center_f(); rpos0 = QPointF( center_f.x() + (pos.x() - meta->get_width() / 2.) * meta->get_scale(), center_f.y() + (pos.y() - meta->get_height() / 2.) * meta->get_scale() ); } MandelCell::MandelCell(MandelMeta *meta) : meta(meta), iter(0) {} MandelCell::MandelCell(const MandelCell &cell) : meta(cell.meta), pos(cell.pos), iter(cell.iter), rpos(cell.rpos), rpos0(cell.rpos0) {} QPoint MandelCell::update_result(size_t iter, const QPointF &rpos) { this->iter = iter; this->rpos = rpos; return pos; } void MandelCell::reset_iter_and_rpos() { iter = 0; rpos = QPointF(); reset_rpos0(); } void MandelCell::set_meta(MandelMeta *meta) { this->meta = meta; } void MandelCell::set_pos(QPoint pos) { this->pos = pos; reset_rpos0(); } MandelResultCell MandelCell::iterate() const { size_t iter = this->iter; QPointF rpos = this->rpos, sq; for (; iter < this->meta->get_max_iter(); iter++) { sq = QPointF(rpos.x() * rpos.x(), rpos.y() * rpos.y()); if (sq.x() + sq.y() > meta->get_four()) break; rpos = QPointF( sq.x() - sq.y() + rpos0.x(), 2 * rpos.x() * rpos.y() + rpos0.y() ); } return MandelResultCell(iter, rpos); }