Thank you very much for answering! Unfortunately, I don't think there is anything wrong with the offsets.
Here is some pseudo-code of my program:
// where the ref. orbit is stored
complex X[]
// variables
complex z, c = <coordinates of the ref. point inside the image>
// calculate ref. orbit
for (i = 0; i < MAX_ITER; i++) {
z = z * z + c;
X[i] = z;
}
// loop over the points in the image
for (y = 0; y < HEIGHT; y++) {
for (x = 0; x < WIDTH; x++) {
complex yn = 0, y0 = <coordinates of the point>
// deltas; d0 = the delta at iteration 0
complex dn = 0, d0 = y0 - X[0];
// i starts with i = 1
for (i = 1; i < MAX_ITER; i++) {
dn = 2 * dn * X[i] + dn * dn + d0
// if the delta becomes too large
if (abs(dn) > e^-5) {
// calculate back to the coordinates of y at this iteration
yn = dn + X[i + 1]
// stop this loop
break;
}
}
// continue with the calculated yn and the normal mandelbrot equation
for (; i < MAX_ITER; i++) {
yn = yn * yn + y0;
if (abs(yn) > 4) {
// the point has escaped
// <set color of pixel>
// finish
break;
}
}
}
}
And this is the code of my actual program (in C++; it requires png++):
#include <math.h>
#include <stdlib.h>
#include <algorithm>
#include <chrono>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <png++/png.hpp>
#include <sstream>
#include <string>
#include <vector>
#include <complex>
int main(int argc, char **argv)
{
// ====== BEGIN SETUP ======
// Define and calculate a few common variables
double centerX = -1.2553763440860217, centerY = 0.38131720430107524, fov = 0.02;
centerX -= 0.0016;
double left = centerX - fov, right = centerX + fov, top = centerY + fov, bottom = centerY - fov;
const int image_width = 1200, image_height = 1200;
const int MAX_ITERATIONS = 900;
png::image<png::rgb_pixel> image(image_width, image_height);
double range_horizontal = std::abs(left - right), range_vertical = std::abs(top - bottom);
double step_horizontal = range_horizontal / image_width, step_vertical = range_vertical / image_height;
// ====== END SETUP ======
// ====== BEGIN CALCULATIONS ======
// Calulate the orbit of the reference point
std::complex<double> X[MAX_ITERATIONS] = {0}; // initialise to zero
std::complex<double> c, z = 0;
// assign value to c
c.real(centerX);
c.imag(centerY);
for (int i = 0; i < MAX_ITERATIONS; i++)
{
if (z.real() * z.real() + z.imag() * z.imag() > 4)
{
printf("ERROR: The reference escaped!\n");
break;
}
z = z * z + c;
// store copy in array
X[i] = z;
}
// loop over all points in the image
for (int x = 0; x < image_width; x++) {
for (int y = 0; y < image_height; y++) {
double coord_y = y * step_vertical + bottom,
coord_x = x * step_horizontal + left,
brightness = 0;
std::complex<double> y0, d0, dn = 0, yn;
y0.real(coord_x);
y0.imag(coord_y);
d0 = y0 - X[0];
int i;
for (i = 1; i < MAX_ITERATIONS; i++) {
dn = 2.0 * dn * X[i] + dn * dn + d0;
if (dn.real() * dn.real() + dn.imag() * dn.imag() > 1e-5) {
yn = dn + X[i + 1];
break;
}
}
for (; i < MAX_ITERATIONS; i++) {
yn = yn * yn + y0;
if (yn.real() * yn.real() + yn.imag() * yn.imag() > 4) {
brightness = i;
break;
}
}
// ====== END CALCULATIONS ======
brightness *= 4;
double col_r = 0, col_g = 0.8, col_b = 1;
if (brightness > 255)
brightness = 255;
image[image_height - 1 - y][x] = png::rgb_pixel((int)brightness * col_r, (int)brightness * col_g, (int)brightness * col_b);
}
}
image.write("output.png");
return 0;
}