Cat hungry.png
Здравствуйте! Собираем деньги на перевод материалов по электронике(https://www.allaboutcircuits.com/education/). Реквизиты указаны здесь.

Processing:Примеры/Кривая Коха

Материал из Онлайн справочника
Перейти к: навигация, поиск


Перевод: Максим Кузьмин (Cubewriter)
Перевел 2686 статей для сайта.

Контакты:

Проверка/Оформление/Редактирование: Мякишев Е.А.


Ambox content.png Черновик


Описание[1]

Анимация простого фрактала – снежинки Коха. Уровни рекурсии рисуются друг за другом.

Пример

  1. KochFractal k;
  2.  
  3. void setup() {
  4.   size(640, 360);
  5.   frameRate(1);  // частота анимации – 1 кадр в секунду
  6.   k = new KochFractal();
  7. }
  8.  
  9. void draw() {
  10.   background(0);
  11.   // рисуем снежинку!
  12.   k.render();
  13.   // итерируем:
  14.   k.nextLevel();
  15.   // не делаем более 5 итераций...
  16.   if (k.getCount() > 5) {
  17.     k.restart();
  18.   }
  19. }
  20.  
  21.  
  22.  
  23.  
  24.  
  25. // Кривая Коха
  26. // Класс для управления несколькими линейными сегментами,
  27. // формирующими паттерн снежинки
  28.  
  29. class KochFractal {
  30.   PVector start;       // объект PVector для начала
  31.   PVector end;         // объект PVector для конца
  32.   ArrayList<KochLine> lines;   // объект ArrayList для хранения
  33.                                // всех линейных сегментов
  34.   int count;
  35.  
  36.   KochFractal() {
  37.     start = new PVector(0,height-20);
  38.     end = new PVector(width,height-20);
  39.     lines = new ArrayList<KochLine>();
  40.     restart();
  41.   }
  42.  
  43.   void nextLevel() {  
  44.     // для каждого линейного сегмента в ArrayList
  45.     // создаем в ArrayList еще 4 линейных сегмента:
  46.     lines = iterate(lines);
  47.     count++;
  48.   }
  49.  
  50.   void restart() {
  51.     count = 0;      // сбрасываем счетчик
  52.     lines.clear();  // очищаем ArrayList
  53.     lines.add(new KochLine(start,end));  // добавляем начальную линию
  54.                                          // (от вектора «start»
  55.                                          // до вектора «end»)
  56.   }
  57.  
  58.   int getCount() {
  59.     return count;
  60.   }
  61.  
  62.   // здесь все просто - рисуем все линии:
  63.   void render() {
  64.     for(KochLine l : lines) {
  65.       l.display();
  66.     }
  67.   }
  68.  
  69.   // А здесь начинается «МАГИЯ»!
  70.   // Шаг 1 - создаем пустой ArrayList
  71.   // Шаг 2 - для каждой линии в ArrayList...
  72.   //   - рассчитываем 4 линии на основе алгоритма Коха
  73.   //   - добавляем в ArrayList все 4 новых линейных сегмента
  74.   // Шаг 3 – возвращаем новый ArrayList,
  75.   //         и он будет хранилищем всех линий для структуры
  76.  
  77.   // делаем это снова и снова, разбивая каждую линию на 4 линии,
  78.   // и каждую из них тоже разбивая на 4 линии, и так далее...
  79.   ArrayList iterate(ArrayList<KochLine> before) {
  80.     ArrayList now = new ArrayList<KochLine>();    // создаем
  81.                                                   // пустой ArrayList
  82.     for(KochLine l : before) {
  83.       // рассчитываем 5 векторов для кривой Коха:
  84.       PVector a = l.start();                
  85.       PVector b = l.kochleft();
  86.       PVector c = l.kochmiddle();
  87.       PVector d = l.kochright();
  88.       PVector e = l.end();
  89.       // создаем линии между всеми 5 векторами и добавляем их в «now»:
  90.       now.add(new KochLine(a,b));
  91.       now.add(new KochLine(b,c));
  92.       now.add(new KochLine(c,d));
  93.       now.add(new KochLine(d,e));
  94.     }
  95.     return now;
  96.   }
  97.  
  98. }
  99.  
  100.  
  101.  
  102. // Книга «The Nature of Code» («Природа кода»)
  103. // Автор - Дэниэл Шиффман
  104. // Сайт - http://natureofcode.com
  105.  
  106. // Кривая Коха
  107. // Класс для описания одного линейного сегмента во фрактале.
  108. // Включает методы для расчета промежуточных векторов на линии
  109. // в соответствии с алгоритмом Коха.
  110.  
  111. class KochLine {
  112.  
  113.   // два объекта PVector:
  114.   // «а» - это крайний левый PVector,
  115.   // «b» - это крайний правый PVector:
  116.   PVector a;
  117.   PVector b;
  118.  
  119.   KochLine(PVector start, PVector end) {
  120.     a = start.copy();
  121.     b = end.copy();
  122.   }
  123.  
  124.   void display() {
  125.     stroke(255);
  126.     line(a.x, a.y, b.x, b.y);
  127.   }
  128.  
  129.   PVector start() {
  130.     return a.copy();
  131.   }
  132.  
  133.   PVector end() {
  134.     return b.copy();
  135.   }
  136.  
  137.   // ничего сложного, просто рассчитываем 1/3 пути:
  138.   PVector kochleft() {
  139.     PVector v = PVector.sub(b, a);
  140.     v.div(3);
  141.     v.add(a);
  142.     return v;
  143.   }    
  144.  
  145.   // чуть посложнее, для расчета этого вектора
  146.   // приходится задействовать немного тригонометрии:
  147.   PVector kochmiddle() {
  148.     PVector v = PVector.sub(b, a);
  149.     v.div(3);
  150.    
  151.     PVector p = a.copy();
  152.     p.add(v);
  153.    
  154.     v.rotate(-radians(60));
  155.     p.add(v);
  156.    
  157.     return p;
  158.   }    
  159.  
  160.   // ничего сложного – просто рассчитываем 2/3 пути:
  161.   PVector kochright() {
  162.     PVector v = PVector.sub(a, b);
  163.     v.div(3);
  164.     v.add(b);
  165.     return v;
  166.   }
  167. }

См.также

Внешние ссылки

  1. processing.org - Koch Curve by Daniel Shiffman.