Как покрасить Мандельброта? - PullRequest
0 голосов
/ 01 мая 2018

После выполнения этого очень простого урока, который дает вам весь код (http://warp.povusers.org/Mandelbrot/) Мне не повезло, когда я понял, как раскрасить контур, как на картинках.

Если в нашем примере мы сопоставляем n с цветом, так что от 0 до MaxIterations / 2-1 цвет меняется с черного на красный, а с MaxIterations / 2 до MaxIterations-1 цвет меняется с красного на белый, мы получаем следующее изображение:

void compute_mandelbrot(double left, double right, double top, double bottom, double start, double end) //improved mandelbort following a tutorial
{
    double ImageHeight = 960;
    double ImageWidth = 960;

    //double MinRe = -2.5;
    //double MaxRe = 1.25;
    //double MinIm = -1.2;
    double MinRe = left;
    double MaxRe = right;
    double MinIm = top;
    double MaxIm = MinIm + (MaxRe - MinRe)*ImageHeight / ImageWidth;
    double Re_factor = (MaxRe - MinRe) / (ImageWidth - 1);
    double Im_factor = (MaxIm - MinIm) / (ImageHeight - 1);
    //unsigned MAX_ITERATIONS = 100;

    /*int r = 0x00, g = 0x00, b = 0x00;*/


    for (unsigned y = 0; y<ImageHeight; ++y)
    {
        double c_im = MaxIm - y*Im_factor;
        for (unsigned x = 0; x<ImageWidth; ++x)
        {
            //vertex.color = sf::Color(255, 255, 255, 255);
            //r = g = b = 0;

            double c_re = MinRe + x*Re_factor;

            double Z_re = c_re, Z_im = c_im;
            bool isInside = true;
            for (unsigned n = 0; n<MAX_ITERATIONS; ++n)
            {
                //vertex.color = sf::Color(0, 0, 0, 255); //figure is black
                //vertex.color = sf::Color(255, 255, 255, 255); //figure is white
                r = g = b = 0;

                double Z_re2 = Z_re*Z_re, Z_im2 = Z_im*Z_im;
                if (Z_re2 + Z_im2 > 4)
                {

                    isInside = false;

                    auto half = MAX_ITERATIONS / 2.0;

                    if (n < half) {
                        r = n / half * 255;
                    }
                    else {
                        r = 255;
                        g = b = (n - half) / half * 255;
                    }

                    vertex.color = sf::Color(r, g, b, 255);

                    break;
                }

                Z_im = 2 * Z_re*Z_im + c_im;
                Z_re = Z_re2 - Z_im2 + c_re;


            }

            if (isInside)
            {
                //vertex.color = sf::Color(r, g, b, 255); //line pattern

                mutex.lock();
                vertex.position = sf::Vector2f(x, y);
                varray.append(vertex);
                mutex.unlock();
            } 
        }
    }



}

Не думаю, что понимаю, что я должен делать, я попробовал несколько вещей, в том числе то, что в коде, но безуспешно.

1 Ответ

0 голосов
/ 01 мая 2018

В строке isInside = false; у вас есть значение n, при котором точка выходит за пределы множества. Используйте это значение n, чтобы установить значения r, g, b для точки на основе ваших цветовых предпочтений. Если точка не исчезнет, ​​она будет черной (или чем бы вы ни инициализировали r, g и b).

сопоставить n с цветом, чтобы от 0 до MaxIterations / 2-1 цвет переходил от черного к красному, а от MaxIterations / 2 до MaxIterations-1 - от красного до белого

Это простая математика RGB, например

auto half = MaxIterations/2.0;

if( n < half ) {
  r = n / half;
}else {
  r = 1.0;
  g = b = (n - half) / half;
}

, который дает rgb в диапазоне 0-1, умножьте на 255, если вы используете целые числа для цветов

...