]> git.mar77i.info Git - bigintmandel/blob - mandel.cpp
initial commit
[bigintmandel] / mandel.cpp
1
2 // mandel.cpp
3
4 #include "colors.h"
5 #include "mandel.h"
6
7 MandelResultCell::MandelResultCell() {}
8
9 MandelResultCell::MandelResultCell(size_t iter, QPointF rpos)
10 : iter(iter), rpos(rpos) {}
11
12 static inline void incrpos(QPoint &pos, const int width) {
13 pos.setX(pos.x() + 1);
14 if (pos.x() == width) {
15 pos.setX(0);
16 pos.setY(pos.y() + 1);
17 }
18 }
19
20 MandelMeta::MandelMeta(size_t max_iter, const QSize size)
21 : max_iter(max_iter),
22 img(size, QImage::Format_RGB888),
23 cells(size.width() * size.height(), MandelCell(this)),
24 center_f(qreal(-3) / 4, 0),
25 one(1),
26 four(4),
27 scale(std::max(qreal(3) / size.width(), qreal(3) / size.height()))
28 {
29 QVector<MandelCell>::iterator i;
30 QPointF c(size.width() / 2., size.height() / 2.);
31 QPoint pos;
32
33 for (i = cells.begin(); i != cells.end(); incrpos(pos, size.width()), i++) {
34 i->set_meta(this);
35 i->set_pos(pos);
36 }
37 }
38
39 void MandelMeta::zoom2x(QPoint pos) {
40 QVector<MandelCell>::iterator i;
41 center_f = cells[img.width() * pos.y() + pos.x()].get_rpos0();
42 scale /= 2;
43 img.fill(Qt::GlobalColor::black);
44 for (i = cells.begin(); i != cells.end(); i++)
45 i->reset_iter_and_rpos();
46 }
47
48 void MandelMeta::finished_cell(int num, const MandelResultCell &cell) {
49 img.setPixelColor(
50 cells[num].update_result(cell.iter, cell.rpos),
51 cell.iter < max_iter
52 ? colors[cell.iter % colors.size()]
53 : Qt::GlobalColor::black
54 );
55 }
56
57 MandelResultCell MandelMeta::iterate(const MandelCell &cell) {
58 return cell.iterate();
59 }
60
61 void MandelCell::reset_rpos0() {
62 QPointF center_f = meta->get_center_f();
63 rpos0 = QPointF(
64 center_f.x() + (pos.x() - meta->get_width() / 2.) * meta->get_scale(),
65 center_f.y() + (pos.y() - meta->get_height() / 2.) * meta->get_scale()
66 );
67 }
68
69 MandelCell::MandelCell(MandelMeta *meta) : meta(meta), iter(0) {}
70
71 MandelCell::MandelCell(const MandelCell &cell)
72 : meta(cell.meta), pos(cell.pos), iter(cell.iter),
73 rpos(cell.rpos), rpos0(cell.rpos0) {}
74
75 QPoint MandelCell::update_result(size_t iter, const QPointF &rpos) {
76 this->iter = iter;
77 this->rpos = rpos;
78 return pos;
79 }
80
81 void MandelCell::reset_iter_and_rpos() {
82 iter = 0;
83 rpos = QPointF();
84 reset_rpos0();
85 }
86
87 void MandelCell::set_meta(MandelMeta *meta) {
88 this->meta = meta;
89 }
90
91 void MandelCell::set_pos(QPoint pos) {
92 this->pos = pos;
93 reset_rpos0();
94 }
95
96 MandelResultCell MandelCell::iterate() const {
97 size_t iter = this->iter;
98 QPointF rpos = this->rpos, sq;
99 for (; iter < this->meta->get_max_iter(); iter++) {
100 sq = QPointF(rpos.x() * rpos.x(), rpos.y() * rpos.y());
101 if (sq.x() + sq.y() > meta->get_four())
102 break;
103 rpos = QPointF(
104 sq.x() - sq.y() + rpos0.x(),
105 2 * rpos.x() * rpos.y() + rpos0.y()
106 );
107 }
108 return MandelResultCell(iter, rpos);
109 }