Processing:Примеры/Кривая Коха
Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску
Содержание | Среда разработки Processing | Справочник языка Processing | Библиотеки | Примеры | Режимы программирования |
Перевод: Максим Кузьмин
Проверка/Оформление/Редактирование: Мякишев Е.А.
Описание[1]
Анимация простого фрактала – снежинки Коха. Уровни рекурсии рисуются друг за другом.
Пример
KochFractal k;
void setup() {
size(640, 360);
frameRate(1); // частота анимации – 1 кадр в секунду
k = new KochFractal();
}
void draw() {
background(0);
// рисуем снежинку!
k.render();
// итерируем:
k.nextLevel();
// не делаем более 5 итераций...
if (k.getCount() > 5) {
k.restart();
}
}
// Кривая Коха
// Класс для управления несколькими линейными сегментами,
// формирующими паттерн снежинки
class KochFractal {
PVector start; // объект PVector для начала
PVector end; // объект PVector для конца
ArrayList<KochLine> lines; // объект ArrayList для хранения
// всех линейных сегментов
int count;
KochFractal() {
start = new PVector(0,height-20);
end = new PVector(width,height-20);
lines = new ArrayList<KochLine>();
restart();
}
void nextLevel() {
// для каждого линейного сегмента в ArrayList
// создаем в ArrayList еще 4 линейных сегмента:
lines = iterate(lines);
count++;
}
void restart() {
count = 0; // сбрасываем счетчик
lines.clear(); // очищаем ArrayList
lines.add(new KochLine(start,end)); // добавляем начальную линию
// (от вектора «start»
// до вектора «end»)
}
int getCount() {
return count;
}
// здесь все просто - рисуем все линии:
void render() {
for(KochLine l : lines) {
l.display();
}
}
// А здесь начинается «МАГИЯ»!
// Шаг 1 - создаем пустой ArrayList
// Шаг 2 - для каждой линии в ArrayList...
// - рассчитываем 4 линии на основе алгоритма Коха
// - добавляем в ArrayList все 4 новых линейных сегмента
// Шаг 3 – возвращаем новый ArrayList,
// и он будет хранилищем всех линий для структуры
// делаем это снова и снова, разбивая каждую линию на 4 линии,
// и каждую из них тоже разбивая на 4 линии, и так далее...
ArrayList iterate(ArrayList<KochLine> before) {
ArrayList now = new ArrayList<KochLine>(); // создаем
// пустой ArrayList
for(KochLine l : before) {
// рассчитываем 5 векторов для кривой Коха:
PVector a = l.start();
PVector b = l.kochleft();
PVector c = l.kochmiddle();
PVector d = l.kochright();
PVector e = l.end();
// создаем линии между всеми 5 векторами и добавляем их в «now»:
now.add(new KochLine(a,b));
now.add(new KochLine(b,c));
now.add(new KochLine(c,d));
now.add(new KochLine(d,e));
}
return now;
}
}
// Книга «The Nature of Code» («Природа кода»)
// Автор - Дэниэл Шиффман
// Сайт - http://natureofcode.com
// Кривая Коха
// Класс для описания одного линейного сегмента во фрактале.
// Включает методы для расчета промежуточных векторов на линии
// в соответствии с алгоритмом Коха.
class KochLine {
// два объекта PVector:
// «а» - это крайний левый PVector,
// «b» - это крайний правый PVector:
PVector a;
PVector b;
KochLine(PVector start, PVector end) {
a = start.copy();
b = end.copy();
}
void display() {
stroke(255);
line(a.x, a.y, b.x, b.y);
}
PVector start() {
return a.copy();
}
PVector end() {
return b.copy();
}
// ничего сложного, просто рассчитываем 1/3 пути:
PVector kochleft() {
PVector v = PVector.sub(b, a);
v.div(3);
v.add(a);
return v;
}
// чуть посложнее, для расчета этого вектора
// приходится задействовать немного тригонометрии:
PVector kochmiddle() {
PVector v = PVector.sub(b, a);
v.div(3);
PVector p = a.copy();
p.add(v);
v.rotate(-radians(60));
p.add(v);
return p;
}
// ничего сложного – просто рассчитываем 2/3 пути:
PVector kochright() {
PVector v = PVector.sub(a, b);
v.div(3);
v.add(b);
return v;
}
}
См.также
Внешние ссылки
Примеры на Processing | |
---|---|
Основы |
|
Продвинутые графические эффекты |
|
Примеры из сторонних библиотек |