add smooth coloring, precision updating(needs work)
This commit is contained in:
parent
32c36e65c1
commit
874a8f21f8
@ -18,22 +18,25 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "mandelbrot.h"
|
#include "mandelbrot.h"
|
||||||
|
#include "mpreal.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
using namespace mpfr;
|
using namespace mpfr;
|
||||||
|
|
||||||
Mandelbrotc::Mandelbrotc(Vec2mp const &f, Vec2mp const &t, Vec2i const &s, uint32_t mi)
|
Mandelbrotc::Mandelbrotc(Vec2mp const &f, Vec2mp const &t, Vec2i const &s, uint32_t mi)
|
||||||
: f(f), t(t), s(s), max_iter(mi)
|
: f(f), t(t), s(s), max_iter(mi)
|
||||||
{
|
{
|
||||||
|
mpreal::set_default_prec(digits2bits(100));
|
||||||
this->threads = std::vector<std::thread>();
|
this->threads = std::vector<std::thread>();
|
||||||
//this->screen = std::vector<std::vector<uint8_t>>();
|
this->screen = new double*[s.x];
|
||||||
this->screen = new uint8_t*[s.x];
|
|
||||||
for(int i = 0; i < s.x; ++i)
|
for(int i = 0; i < s.x; ++i)
|
||||||
this->screen[i] = new uint8_t[s.y];
|
this->screen[i] = new double[s.y];
|
||||||
|
|
||||||
this->done = false;
|
this->done = false;
|
||||||
|
this->diff = mpreal(0.0001);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mandelbrotc::start_threads(bool first)
|
void Mandelbrotc::start_threads(bool first)
|
||||||
@ -70,14 +73,16 @@ void Mandelbrotc::calc(const uint8_t tid)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this->updatePrec();
|
||||||
|
|
||||||
//std::cout << "thread " << tid << " done" << std::endl;
|
//std::cout << "thread " << tid << " done" << std::endl;
|
||||||
if (tid == thread_count-1)
|
if (tid == thread_count-1)
|
||||||
this->done = true;
|
this->done = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Mandelbrotc::mandelbrot(const Vec2mp &n)
|
double Mandelbrotc::mandelbrot(const Vec2mp &n)
|
||||||
{
|
{
|
||||||
uint32_t iter = 0;
|
double iter = 0.0;
|
||||||
|
|
||||||
// BigFloat x = BigFloat(n.x.precision);
|
// BigFloat x = BigFloat(n.x.precision);
|
||||||
// x.setValue(0.0);
|
// x.setValue(0.0);
|
||||||
@ -88,15 +93,65 @@ uint32_t Mandelbrotc::mandelbrot(const Vec2mp &n)
|
|||||||
mpreal y = mpreal(0.0);
|
mpreal y = mpreal(0.0);
|
||||||
mpreal x2 = mpreal(0.0);
|
mpreal x2 = mpreal(0.0);
|
||||||
mpreal y2 = mpreal(0.0);
|
mpreal y2 = mpreal(0.0);
|
||||||
|
mpreal xtemp = mpreal(0.0);
|
||||||
|
|
||||||
while (x2 + y2 <= 4 && iter < max_iter) {
|
// while (x2 + y2 <= (1 << 16) && iter < max_iter) {
|
||||||
y = 2.0 * x * y + n.y;
|
// y = 2.0 * x * y + n.y;
|
||||||
x = x2 - y2 + n.x;
|
// x = x2 - y2 + n.x;
|
||||||
x2 = x * x;
|
// x2 = x * x;
|
||||||
y2 = y * y;
|
// y2 = y * y;
|
||||||
|
|
||||||
|
// iter++;
|
||||||
|
// }
|
||||||
|
|
||||||
|
while (x*x + y*y <= (1 << 16) && iter < max_iter) {
|
||||||
|
xtemp = x*x - y*y + n.x;
|
||||||
|
y = 2*x*y + n.y;
|
||||||
|
x = xtemp;
|
||||||
|
|
||||||
iter++;
|
iter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return iter;//+ 1 - log(log2(abs((int)x2)));
|
if (iter == max_iter)
|
||||||
|
return max_iter;
|
||||||
|
|
||||||
|
double log_zn = (mpfr::log(x*x + y*y) / 2).toDouble();
|
||||||
|
double nu = log(log_zn / log(2)) / log(2);
|
||||||
|
|
||||||
|
iter = iter + 1 - nu;
|
||||||
|
|
||||||
|
return iter;
|
||||||
|
//return iter + 1 - log(log2(x2.toDouble()+y2.toDouble()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mandelbrotc::updatePrec()
|
||||||
|
{
|
||||||
|
//std::cout << "before updatePrec: " << this->f.x.get_prec() << std::endl;
|
||||||
|
mpfr_prec_t bprec = this->f.x.get_prec();
|
||||||
|
mpfr_prec_t aprec;
|
||||||
|
|
||||||
|
std::cout << "before updatePrec def: " << mpfr::bits2digits(
|
||||||
|
bprec) << std::endl;
|
||||||
|
|
||||||
|
if (mpfr::abs(mpfr::abs(this->f.x) - mpfr::abs(this->t.x)) < diff ||
|
||||||
|
(mpfr::abs(this->f.x) - mpfr::abs(this->t.y)) < diff) {
|
||||||
|
|
||||||
|
aprec = mpfr::digits2bits(mpfr::bits2digits(bprec)+5);
|
||||||
|
|
||||||
|
std::cout << "true" << std::endl;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->f.x.set_prec(aprec);
|
||||||
|
this->f.y.set_prec(aprec);
|
||||||
|
this->t.x.set_prec(aprec);
|
||||||
|
this->t.y.set_prec(aprec);
|
||||||
|
|
||||||
|
//std::cout << "after updatePrec: " << this->f.x.get_prec() << std::endl;
|
||||||
|
std::cout << "after updatePrec def: " << mpfr::bits2digits(
|
||||||
|
this->f.x.get_prec()) << std::endl;
|
||||||
|
|
||||||
|
diff = mpfr::abs(mpfr::abs(this->f.x) - mpfr::abs(this->t.x));
|
||||||
}
|
}
|
||||||
|
@ -32,16 +32,18 @@ class Mandelbrotc {
|
|||||||
public:
|
public:
|
||||||
Vec2mp f, t;
|
Vec2mp f, t;
|
||||||
uint8_t thread_count;
|
uint8_t thread_count;
|
||||||
|
mpfr::mpreal diff;
|
||||||
std::vector<std::thread> threads;
|
std::vector<std::thread> threads;
|
||||||
Vec2i s;
|
Vec2i s;
|
||||||
//std::vector<std::vector<uint8_t>> screen;
|
//std::vector<std::vector<uint8_t>> screen;
|
||||||
uint8_t **screen;
|
double **screen;
|
||||||
bool done;
|
bool done;
|
||||||
uint32_t max_iter;
|
uint32_t max_iter;
|
||||||
|
|
||||||
Mandelbrotc(Vec2mp const &f, Vec2mp const &t, Vec2i const &s, uint32_t mi);
|
Mandelbrotc(Vec2mp const &f, Vec2mp const &t, Vec2i const &s, uint32_t mi);
|
||||||
void start_threads(bool first);
|
void start_threads(bool first);
|
||||||
void stop_threads();
|
void stop_threads();
|
||||||
uint32_t mandelbrot(const Vec2mp &n);
|
double mandelbrot(const Vec2mp &n);
|
||||||
void calc(const uint8_t tid);
|
void calc(const uint8_t tid);
|
||||||
|
void updatePrec();
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user