Как вынести переменную из класса?

261
20 апреля 2018, 15:59

Имеется следующий код (рисует множество Мандельброта):

#include <SFML/Graphics.hpp>
#include <array>
#include <vector>
#include <thread>
static constexpr int IMAGE_WIDTH = 1000;
static constexpr int IMAGE_HEIGHT = 600;
const uint8_t AMOUNT_RED = 33;
const uint8_t AMOUNT_GREEN = 78;
const uint8_t AMOUNT_BLUE = 220;
const uint8_t SHIFT = 0b00000111;
//<<<<<<Пытаюсь вынести сюда int max = 200;
class Mandelbrot {
public:
    Mandelbrot();
    void updateImage(double zoom, double offsetX, double offsetY, sf::Image& image) const; 
    static const int MAX = 200;
private:
    std::array<sf::Color, MAX+1> colors;//<<<<<здесь ошибка
    int mandelbrot(double startReal, double startImag) const;
    sf::Color getColor(int iterations) const;
    void updateImageSlice(double zoom, double offsetX, double offsetY, sf::Image& image, int minY, int maxY) const;
};
Mandelbrot::Mandelbrot() {
    for (int i=0; i <= MAX; ++i) {
        colors[i] = getColor(i);
    }
}
int Mandelbrot::mandelbrot(double startReal, double startImag) const {
    double zReal = startReal;
    double zImag = startImag;
    for (int counter = 0; counter < MAX; ++counter) {
        double r2 = zReal * zReal;
        double i2 = zImag * zImag;
        if (r2 + i2 > 4.0) {
            return counter;
        }
        zImag = 2.0 * zReal * zImag + startImag;
        zReal = r2 - i2 + startReal;
    }
    return MAX;
}
sf::Color Mandelbrot::getColor(int iterations) const {
    int magnitude = iterations/8;
    int r, g, b;
    if (iterations == MAX){
            r=0;
            g=0;
            b=0;
    }
    else{
        r = AMOUNT_RED | (SHIFT << magnitude);
        g = AMOUNT_GREEN | (SHIFT << magnitude);
        b = AMOUNT_BLUE | (SHIFT << magnitude);
    }
    return sf::Color(r, g, b);
}
void Mandelbrot::updateImageSlice(double zoom, double offsetX, double offsetY, sf::Image& image, int minY, int maxY) const
{
    double real = 0 * zoom - IMAGE_WIDTH / 2.0 * zoom + offsetX;
    double imagstart = minY * zoom - IMAGE_HEIGHT / 2.0 * zoom + offsetY;
    for (int x = 0; x < IMAGE_WIDTH; x++, real += zoom) {
        double imag = imagstart;
        for (int y = minY; y < maxY; y++, imag += zoom) {
            int value = mandelbrot(real, imag);
            image.setPixel(x, y, colors[value]);
        }
    }
}
void Mandelbrot::updateImage(double zoom, double offsetX, double offsetY, sf::Image& image) const
{
    const int STEP = IMAGE_HEIGHT/std::thread::hardware_concurrency();
    std::vector<std::thread> threads;
    for (int i = 0; i < IMAGE_HEIGHT; i += STEP) {
        threads.push_back(std::thread(&Mandelbrot::updateImageSlice, *this, zoom, offsetX, offsetY, std::ref(image), i, std::min(i+STEP, IMAGE_HEIGHT)));
    }
    for (auto &t : threads) {
        t.join();
    }
}
int main() {
    double offsetX = -0.7; // and move around
    double offsetY = 0.0;
    double zoom = 0.004; // allow the user to zoom in and out...
    Mandelbrot mb;
    sf::RenderWindow window(sf::VideoMode(IMAGE_WIDTH, IMAGE_HEIGHT), "Mandelbrot");
    window.setFramerateLimit(0);
    sf::Image image;
    image.create(IMAGE_WIDTH, IMAGE_HEIGHT, sf::Color(0, 0, 0));
    sf::Texture texture;
    sf::Sprite sprite;
    bool stateChanged = true; // track whether the image needs to be regenerated
    while (window.isOpen()) {
        sf::Event event;
        while (window.pollEvent(event)) {
            switch (event.type) {
                case sf::Event::Closed:
                    window.close();
                    break;
                case sf::Event::KeyPressed:
                    stateChanged = true; // image needs to be recreated when the user changes zoom or offset
                    switch (event.key.code) {
                        case sf::Keyboard::Escape:
                            window.close();
                            break;
                        case sf::Keyboard::Equal:
                            zoom *= 0.9;
                            //mb.MAX+=0.01;
                            break;
                        case sf::Keyboard::Dash:
                            zoom /= 0.9;
                            //mb.MAX-=0.01;
                            break;
                        case sf::Keyboard::W:
                            offsetY -= 40 * zoom;
                            break;
                        case sf::Keyboard::S:
                            offsetY += 40 * zoom;
                            break;
                        case sf::Keyboard::A:
                            offsetX -= 40 * zoom;
                            break;
                        case sf::Keyboard::D:
                            offsetX += 40 * zoom;
                            break;
                        default: 
                            stateChanged = false;
                            break;
                    }
                default:
                    break;
            }
        }
        if (stateChanged) { 
            mb.updateImage(zoom, offsetX, offsetY, image);
            texture.loadFromImage(image);
            sprite.setTexture(texture);
            stateChanged = false;
        }
        window.draw(sprite);
        window.display();
    }
}

Переменная MAX в классе Mandelbrot отвечает за максимальное количество итераций. Когда я пытаюсь вынести её из класса и убрать static и const, возникает ошибка "error: the value of 'MAX' is not usable in a constant expression" на строке, указанной в коде. (Я хочу вынести переменную, чтобы в дальнейшем изменять по нажатию клавиши). Вопрос: Из-за чего возникает ошибка и как это можно исправить?

READ ALSO
Подружить cmake и glew в личном проекте

Подружить cmake и glew в личном проекте

Написал небольшую программу на visual studio 15 c++ с использованием GLEW GLFW GLM OpenCVПо требованиям человека, которому я это делаю, я должен отдать проект...

184
Сборка небольшого проекта из GitHub

Сборка небольшого проекта из GitHub

Доброго времени сутокСобираю проект https://github

170
codecpar = NULL и audio_codec_context-&gt;channels = 0

codecpar = NULL и audio_codec_context->channels = 0

Не знаю по какой причине codecpar = NULLЕсли без codecpar делать (по аналогии с video_codec_context), то audio_codec_context->channels = 0 и данных в фрейме нет

199