Вычисления фрактала Mandelbrot
Затем Вы запишете код, чтобы вычислить очень известный фрактал Mandelbrot. Чтобы поддерживать многократные фракталы в будущем, Вам предоставляют исходный файл FractalGenerator.java, из которого произойдут все Ваши фрактальные генераторы. Вы также заметите, что некоторые очень полезные операции обеспечены, чтобы перевести из экранных координат в систему координат вычисляемого фрактала.
Виды фракталов, с которыми мы будем работать, вычислены в комплексной плоскости и включают очень простые математические функции, которые неоднократно выполняются с помощью итераций, пока некоторое условие не удовлетворено. Для фрактала Mandelbrot функция - цинк = цинк 12 + c, где все значения - комплексные числа, z0 = 0, и c - определенная точка во фрактале, который мы выводим на экран. Это вычисление выполнено с помощью итераций до любого |z |> 2 (в этом случае точка не находится во Множестве Мандельброта), или пока количество итераций не поражает максимальное значение, например, 2000 (в этом случае, мы предполагаем, что точка находится в наборе).
Процесс графического изображения Множества Мандельброта очень прост: мы просто выполняем итерации по каждому пикселю в нашем изображении, вычисляем количество итераций для соответствующей координаты, и затем устанавливаем пиксель в цвет на основе количества итераций, которые мы вычислили. Но, мы доберемся до этого через секунду - на данный момент, Вы просто должны реализовать вышеупомянутое вычисление.
Создайте подкласс FractalGenerator по имени Mandelbrot. Вы будете видеть, что есть только два метода, которые Вы должны обеспечить в подклассе, getInitialRange () и numIterations ().
getInitialRange (Rectangle2D.Double) метод просто позволяет фрактальному генератору определять, какая часть комплексной плоскости является самой "интересной" для определенного фрактала. Обратите внимание на то, что прямоугольный объект передан как параметр методу, и метод должен изменить поля прямоугольника, чтобы отразить надлежащий начальный диапазон для фрактала. (Вы видите пример этого в FractalGenerator.recenterAndZoomRange () метод.) Реализация Mandelbrot этого метода должна установить начальный диапазон в (-2 - 1.5i) - (1 + 1.5i). Т.е. x и значения y будут-2 и-1.5 соответственно, и ширина и высота оба будут 3.
numIterations (дважды, дважды) метод реализует итеративную функцию для фрактала Mandelbrot. Вы можете определить константу для "максимальных итераций" как это:
общедоступный статический заключительный международный MAX_ITERATIONS = 2000;
Тогда Вы можете обратиться к этому значению в Вашей реализации.
Обратите внимание на то, что у Java нет типа данных для комплексных чисел, таким образом, Вы должны будете реализовать итеративную функцию, используя отдельные двойные компоненты для действительных и мнимых частей. (Я предполагаю, что Вы могли реализовать свой собственный класс комплексного числа, но это не будет, вероятно, стоить того.) Вы должны попытаться сделать свою реализацию быстро; например, не сравнивайте |z | с 2; сравните |z|2 с 22, чтобы избежать противных и медленных вычислений квадратного корня. И не используйте Math.pow (), чтобы вычислить маленькие целочисленные полномочия; умножьте их непосредственно, иначе Ваш код будет очень медленным.
Наконец, когда Вы выполняете итерации своей функции, если Вы совершаете нападки, MAX_ITERATIONS тогда просто возвращаются-1, чтобы указать, что точка не вышла за пределами границы.
Соединим всё это
Наконец мы готовы начать отображать фракталы! Теперь Вы создадите класс FractalExplorer, который позволяет Вам исследовать различные части фрактала, создавая и показывая GUI Swing и обрабатывая события, вызванные различным взаимодействием с пользователем.
Как Вы видите от вышеупомянутых изображений пользовательского интерфейса, Фрактальный Проводник очень прост, состоять из JFrame, содержащего JImageDisplay, возражает, что выводит на экран фрактал и единственный JButton для сброса дисплея, чтобы показать весь фрактал. Вы можете достигнуть этого простого расположения, установив фрейм иметь BorderLayout, затем поместив дисплей в центр расположения и кнопку сброса в "южной" части расположения.
Ваш класс FractalExplorer должен будет отслеживать несколько важных полей для состояния программы:
Целое число "выводит на экран размер", который является просто шириной и высотой дисплея в пикселях. (Наш фрактальный дисплей будет квадратным.)
Ссылка JImageDisplay, так, чтобы мы могли обновить наш дисплей из различных методов, поскольку мы вычисляем фрактал.
Объект FractalGenerator. Мы будем использовать ссылку базового класса так, чтобы мы могли показать другие виды фракталов в будущем.
Определение объекта Rectangle2D.Double диапазона комплексной плоскости, которую мы в настоящее время выводим на экран.
Конечно, все эти поля будут частными...
У класса должен быть конструктор, который берет размер дисплея в качестве параметра, затем хранит это значение в соответствующем поле, и также инициализирует объекты фрактального генератора и диапазон. Обратите внимание на то, что конструктор не должен устанавливать компоненты Swing; они будут установлены в следующем методе.
Обеспечьте createAndShowGUI () метод, который инициализирует GUI Swing: JFrame, содержащий JImageDisplay, возражает и кнопка для сброса дисплея. Вы должны установить фрейм использовать java.awt. BorderLayout для его содержания; добавьте объект дисплея изображения в BorderLayout. ЦЕНТРАЛЬНАЯ позиция и кнопка в BorderLayout. ЮЖНАЯ позиция.
Вы должны также дать фрейму подходящий заголовок для своего приложения и установить операцию закрытия фрейма по умолчанию "выходить" (см. JFrame.setDefaultCloseOperation () метод).
Наконец, после того, как компоненты UI инициализированы и размечены, включают эту последовательность операций:
frame.pack ();
frame.setVisible (истина);
frame.setResizable (ложь);
Это правильно разметит содержание фрейма, заставит его быть видимым (окна не первоначально видимы, когда они создаются, так, чтобы Вы могли сконфигурировать их прежде, чем вывести на экран их), и затем отвергните изменение размеров окна.
Вы должны реализовать частный метод помощника, чтобы вывести на экран фрактал, например, вызванный drawFractal (). Этот метод должен циклично выполниться через каждый пиксель в дисплее (т.е. x будет колебаться от 0 до размера дисплея, как будет y), и сделайте следующее:
Вычислите количество итераций для соответствующих координат в области дисплея фрактала. Вы можете определить координаты с плавающей точкой для определенного набора пиксельных координат, используя FractalGenerator.getCoord () метод помощника; например, к получить x-координату, соответствующую пиксельной-X координате, Вы сделали бы это:
//x - пиксельная координата; xCoord - координата в пространстве фрактала
удвойте xCoord = FractalGenerator.getCoord (range.x, range.x + range.width, displaySize, x);
Если количество итераций-1 (т.е. точка не выходит, se цвет пикселя к черному цвету (rgb оценивают 0). Иначе Вы должны выбрать значение на основе количества итераций. Мы можем на самом деле использовать цветовое пространство HSV для этого: поскольку оттенок колеблется от 0 до 1, мы получаем гладкую последовательность цветов от красного до желтого, зеленого, синего, фиолетового цвета, и затем назад к красному! Вы можете использовать работу как это:
оттенок плавающий = 0.7f + (плавание) numIters / 200f;
интервал rgbColor = Цвет. HSBtoRGB (оттенок, 1f, 1f);
Конечно, если Вы придумываете некоторый другой интересный способ окрасить пиксели на основе количества итераций, не стесняйтесь использовать его!
Конечно, дисплей должен быть обновлен с цветом для каждого пикселя, таким образом, Вы будете использовать свой drawPixel () работа от ранее.
Наконец, когда Вы закончили тянуть все пиксели, Вы должны вынудить JImageDisplay быть перекрашенным, чтобы соответствовать текущее содержание его изображения. Сделайте это, вызвав перекрашивание () на компоненте. Если Вы забудете делать это, Ваш дисплей никогда не будет обновлять!
Создайте внутренний класс, чтобы обработать java.awt.event. События ActionListener от кнопки сброса. Обработчик просто должен сбросить диапазон к начальному диапазону, определенному генератором, и затем потянуть фрактал.
Как только Вы завершили этот класс, обновите свой createAndShowGUI () метод, чтобы зарегистрировать экземпляр этого обработчика на кнопке сброса.
Создайте другой внутренний класс, чтобы обработать java.awt.event. События MouseListener от дисплея. Действительно Вы только должны обработать события щелчка мышью, таким образом, Вы должны получить этот внутренний класс из класса MouseAdapter AWT, упомянутого в лекции 3 слайда. Когда этот обработчик получает событие щелчка мышью, он должен отобразить пиксельные координаты щелчка в область фрактала, который выводится на экран, и затем вызовите recenterAndZoomRange генератора () метод с координатами, по которым щелкнули, и масштаб 0.5. Таким образом, только, нажимая на расположение во фрактальном дисплее увеличит масштаб того расположения!
Конечно, не забывайте перерисовывать фрактал после того, как Вы измените область выводимого на экран фрактала.
После того, как этот класс сделан, обновите свой createAndShowGUI () метод, чтобы зарегистрировать экземпляр этого обработчика на компоненте фрактального дисплея.
Наконец, Вы должны создать статическое основное () метод для фрактального проводника так, чтобы это могло быть запущено. Основной метод будет очень прост в данный момент:
Инициализируйте новый экземпляр FractalExplorer с размером дисплея 800 (или безотносительно исков Вы, но не слишком крупные).
Вызовите createAndShowGUI () на объекте проводника.
Вызовите drawFractal () на проводнике, чтобы видеть начальное представление!
Как только Вы завершили все эти шаги, Вам необходимо путешествовать вокруг рассмотрения фрактала Mandelbrot удивительной детали. Если Вы увеличите масштаб достаточно, то Вы столкнетесь с двумя интересными проблемами:
Во-первых, Вы в конечном счете найдете, что уровень детализации в конечном счете заканчивается; это вызвано тем, что нам были бы нужны больше чем 2000 итераций, чтобы узнать, находится ли точка во Множестве Мандельброта или нет! Конечно, мы могли бы испытать желание увеличить максимальные итерации, но тогда черные области фрактала действительно замедлят нас!
Во-вторых, если Вы увеличите масштаб действительно далеко, Вы в конечном счете столкнетесь с пикселированным выводом дисплея! Это вызвано тем, что Вы сталкиваетесь с пределом того, какую двойную точность значения с плавающей точкой могут представлять.
Вы, вероятно, также заметите, что это довольно раздражающее, как весь дисплей зависает, в то время как фрактал оттягивается. Это - что-то, что мы исследуем в будущих лабораториях, а также использовании в своих интересах многократных процессоров, чтобы потянуть наши фракталы намного быстрее. Но на данный момент, как только у Вас есть свой Фрактальный завершенный Проводник (и хорошо прокомментировал), Вы можете представить свою работу csman!