Крива Коха
Крива́ Ко́ха — фрактальна крива, описана 1904 року шведським математиком Хельге фон Кохом[1][2].
Крива Коха цікава тим, що ніде не має дотичних, тобто ніде не диференційовна, хоча всюди неперервна.
Три копії кривої Коха, побудовані (вістрями назовні) на сторонах правильного трикутника, утворюють замкнену криву, так звану сніжинку Коха[1][3][2]. Крива Коха задається такою системою ітераційних функцій:
Побудова
Крива Коха є типовим геометричним фракталом. Процес її побудови виглядає так: беремо одиничний відрізок, поділяємо на три рівні частини і замінюємо середній інтервал рівностороннім трикутником без цього сегмента. У результаті утворюється ламана, що складається з чотирьох ланок з довжиною 1/3 довжини початкового відрізка. На наступному кроці повторюємо операцію для кожного з чотирьох отриманих ланок і так далі. Гранична крива і є кривою Коха.
<?php
set_time_limit(3);
$x = 600; // Довжина малюнку
$y = 200; // Висота малюнку
$r = 10; // Рамка
$i = 4; // Кількість ітерацій
define("PI", 3.14159265358979323846);
$img = imagecreate($x, $y);
$black = imagecolorallocate($img, 0, 0, 0);
imagefill($img, 1, 1, $black);
$color = imagecolorallocate($img, 255, 255, 255);
recursion($i, $r, $y - $r, $x - $r, $y - $r);
function recursion($i, $x1, $y1, $x2, $y2) {
global $img, $color;
if($i == 0)
imageline($img, $x1, $y1, $x2, $y2, $color);
else {
$alpha = atan2($y2 - $y1, $x2 - $x1);
$r = sqrt(($x2 - $x1) * ($x2 - $x1) + ($y2 - $y1) * ($y2 - $y1));
$xa = $x1 + $r * cos($alpha) / 3;
$ya = $y1 + $r * sin($alpha) / 3;
$xc = $xa + $r * cos($alpha - PI / 3) / 3;
$yc = $ya + $r * sin($alpha - PI / 3) / 3;
$xb = $x1 + 2 * $r * cos($alpha) / 3;
$yb = $y1 + 2 * $r * sin($alpha) / 3;
recursion($i - 1, $x1, $y1, $xa, $ya);
recursion($i - 1, $xa, $ya, $xc, $yc);
recursion($i - 1, $xc, $yc, $xb, $yb);
recursion($i - 1, $xb, $yb, $x2, $y2);
}
}
header("Content-type: image/png");
imagepng($img);
imagedestroy($img);
?>
int i = 0; // Кількість ітерацій
void setup()
{
size(600, 250); // Розміри вікна
}
void draw()
{
// замалювати все в чорний корлі
background(0);
// відобразити білим кольором номер ітерації в лівому верхньому куті
stroke(255);
text(i, 10, 20);
// намалювати Криву Коха за допомогою рекурсивних викликів
recursion(i, 0, 200, 600, 200 );
}
void recursion(int i, float x1, float y1, float x2, float y2)
{
// кінець рекурсивним викликам функції
if (i == 0)
{
// намалювати білу лінію від точки (x1, y1) до (x2, y2)
stroke(255);
line(x1, y1, x2, y2);
return;
}
float alpha = atan2(y2 - y1, x2 - x1);// кут повороту
float r = sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));// відстань між точками
// обраховує 3 точки на прямій
// C
// / \
// ----A B----
// ліва точка (ліва вершина трикутника)
float xa = x1 + r * cos(alpha) / 3;
float ya = y1 + r * sin(alpha) / 3;
// центральна точка (верхня вершина трикутника)
float xc = xa + r * cos(alpha - PI / 3) / 3;
float yc = ya + r * sin(alpha - PI / 3) / 3;
// права точка (права вершина трикутника)
float xb = x1 + 2 * r * cos(alpha) / 3;
float yb = y1 + 2 * r * sin(alpha) / 3;
// рекурсивні виклики функції для 4 отриманих ліній
recursion(i - 1, x1, y1, xa, ya);
recursion(i - 1, xa, ya, xc, yc);
recursion(i - 1, xc, yc, xb, yb);
recursion(i - 1, xb, yb, x2, y2);
}
// перехід на наступну ітерації із нажиманням клавіші мишки
void mousePressed()
{
++i;
}
// клас представляє собою одну лінію, яка вміє генерувати на собі Криву Коха
class Segment
{
// поля
PVector start; // початок лінії
PVector end; // кінець лінії
// конструктор
Segment(PVector start, PVector end)
{
this.start = start.copy();
this.end = end.copy();
}
// методи
// генеруємо Криву Коха на прямій
Segment[] generate()
{
// з одної прямою утворюється 4
Segment[] children = new Segment[4];
// 1/3 прямої
PVector v = PVector.sub(end, start);
v.div(3);
// ліва вершина трикутника
PVector ls = PVector.add(start, v);
children[0] = new Segment(start, ls);
// права вершина трикутника
PVector rs = PVector.sub(end, v);
children[3] = new Segment(rs, end);
// верхня вершина трикутника
v.rotate(-PI/3);
PVector m = PVector.add(ls, v);
children[1] = new Segment(ls, m);
children[2] = new Segment(m, rs);
// повертаємо Криву Коха для цієї лінії
return children;
}
// відображаємо лінію
void show()
{
stroke(255);
line(start.x, start.y, end.x, end.y);
}
}
// динамічний масив кривих, які будуть відображатись
ArrayList<Segment> segments;
int i;// номер ітерації
void setup()
{
size(600, 600);// розмір вікна
// ініціалізація полів
segments = new ArrayList<Segment> ();
i = 0;
// встановлюємо 3 точки, вершини трикутника
PVector leftPoint = new PVector(100, 200);
PVector rightPoint = new PVector(500, 200);
PVector bottomPoint = new PVector(300, 500);
// зєднюємо ці точки прямими
Segment s1 = new Segment(bottomPoint, leftPoint);
Segment s2 = new Segment(leftPoint, rightPoint);
Segment s3 = new Segment(rightPoint, bottomPoint);
// додаємо ці прямі до масиву
segments.add(s1);
segments.add(s2);
segments.add(s3);
}
void draw()
{
// замалювати все в чорний колір
background(0);
// відобразити білим кольором номер ітерації в лівому верхньому куті
fill(255);
text(i, 10, 20);
// відобразити усі прямі
for (Segment segment : segments)
{
segment.show();
}
}
// з нажиманням клавіші миші, обраховуємо прямі в наступній ітерації
void mousePressed()
{
// тимчасовий динамічний масив для нових прямих
ArrayList<Segment> nextGeneration = new ArrayList<Segment>(segments.size() * 4);
// для кожної прямої із минулої ітерації...
for (Segment segment: segments)
{
// ... обраховуємо Криву Коха
Segment[] child = segment.generate();
// усі прямі Кривої Коха запам'ятовуємо в тимчасовий масив
for (Segment c : child) nextGeneration.add(c);
}
// тимчасовий масив стає постійним, про масив на минулій ітерації забуваємо
segments = nextGeneration;
// збільшуємо номер ітерації
++i;
}
Властивості
- Крива Коха ніде не диференційована і не спрямна.
- Крива Коха не має самоперетинів.
- Крива Коха має проміжну (тобто не цілу) розмірність Хаусдорфа, яка дорівнює , оскільки вона складається з чотирьох рівних частин, кожна з яких подібна всій кривій з коефіцієнтом подібності 1/3.
- Довжина кривої Коха описується виразом
Узагальнення
Можливі узагальнення кривої Коха, також використовують при побудові підстановки ламаної з чотирьох рівних відрізків, але вони мають іншу геометрію. Вони мають Розмірність Хаусдорфа від 1 до 2. Зокрема, якщо замість поділу відрізка 1:1:1 використовувати золотий перетин (φ: 1: φ), то отримаємо криву, що має відношення до мозаїк Пенроуза.
Також можна побудувати криву «Хрест Коха» на сторонах квадрата, при цьому проводячи побудову «в середину» квадрата.
Також можна побудувати «Сніжинку Коха» на сторонах рівностороннього трикутника.
Див. також
Примітки
- Слюсар В. И. Фрактальные антенны.// Радиоаматор. — 2002. — № 9. — С. 54 -56., Конструктор. — 2002. — № 8. — С. 6 — 8.
- Вишневский В. М., Ляхов А. И., Портной С. Л., Шахнович И. В. Широкополосные беспроводные сети передачи информации. — М.: Техносфера. — 2005.- C. 498—569
- Слюсар, В. (2007). Фрактальные антенны. Принципиально новый тип «ломаных» антенн.. Электроника: наука, технология, бизнес. — 2007. — № 5. с. С. 78—83.
Джерела
- Вишневский В. М., Ляхов А. И., Портной С. Л., Шахнович И. В. Широкополосные беспроводные сети передачи информации. — М.: Техносфера. — 2005.- C. 498—569.