Снежинка Коха - реализация на HTML+Javascript
Код ниже
Кривая Коха — фрактальная кривая, описанная в 1904 году шведским математиком Хельге фон Кохом.
Три копии кривой Коха, построенные (остриями наружу) на сторонах правильного треугольника, образуют замкнутую кривую бесконечной длины, называемую снежинкой Коха.
Эта фигура — один из первых исследованных учеными фракталов. Она получается из трех копий кривой Коха, которая впервые появилась в статье шведского математика Хельге фон Коха в 1904 году. Эта кривая была придумана как пример непрерывной линии, к которой нельзя провести касательную ни в одной точке. Линии с таким свойством были известны и раньше (Карл Вейерштрасс построил свой пример еще в 1872 году), но кривая Коха замечательна простотой своей конструкции. Не случайно его статья называется «О непрерывной кривой без касательных, которая возникает из элементарной геометрии».
Рисунок и анимация отлично показывают, как по шагам строится кривая Коха. Первая итерация — просто начальный отрезок. Потом он делится на три равные части, центральная достраивается до правильного треугольника и затем выкидывается. Получается вторая итерация — ломаная линия, состоящая из четырех отрезков. К каждому из них применяется такая же операция, и получается четвертый шаг построения. Продолжая в том же духе, можно получать всё новые и новые линии (все они будут ломаными). А то, что получится в пределе (это уже будет воображаемый объект), и называется кривой Коха.
Основные свойства кривой Коха
1. Она непрерывна, но нигде не дифференцируема. Грубо говоря, именно для этого она и была придумана — как пример такого рода математических «уродцев».
2. Имеет бесконечную длину. Пусть длина исходного отрезка равна 1. На каждом шаге построения мы заменяем каждый из составляющих линию отрезков на ломаную, которая в 4/3 раза длиннее. Значит, и длина всей ломаной на каждом шаге умножается на 4/3: длина линии с номером n равна (4/3)n–1. Поэтому предельной линии ничего не остается, кроме как быть бесконечно длинной.
3. Снежинка Коха ограничивает конечную площадь. И это при том, что ее периметр бесконечен. Это свойство может показаться парадоксальным, но оно очевидно — снежинка полностью помещается в круг, поэтому ее площадь заведомо ограничена. Площадь можно посчитать, и для этого даже не нужно особых знаний — формулы площади треугольника и суммы геометрической прогрессии проходят в школе. Для интересующихся вычисление приведено ниже мелким шрифтом.
Пусть сторона исходного правильного треугольника равна a. Тогда его площадь . Сначала сторона равна 1, а площадь: . Что происходит при увеличении итерации? Можно считать, что к уже имеющемуся многоугольнику пристраиваются маленькие равносторонние треугольнички. В первый раз их всего 3, а каждый следующий раз их в 4 раза больше чем было в предыдущий. То есть на n-м шаге будет достроено Tn = 3 · 4n–1 треугольничков. Длина стороны каждого из них составляет треть от стороны треугольника, достроенного на предыдущем шаге. Значит, она равна (1/3)n. Площади пропорциональны квадратам сторон, поэтому площадь каждого треугольничка равна . При больших значениях n это, кстати, очень мало. Суммарный вклад этих треугольничков в площадь снежинки равен Tn · Sn = 3/4 · (4/9)n · S0. Поэтому после n-го шага площадь фигуры будет равна сумме S0 + T1 · S1 + T2 · S2 + ... +Tn · Sn = . Снежинка получается после бесконечного числа шагов, что соответствует n → ∞. Получается бесконечная сумма, но это сумма убывающей геометрической прогрессии, для нее есть формула: . Площадь снежинки равна .
4. Фрактальная размерность равна log4/log3 = log34 ≈ 1,261859... . Аккуратное вычисление потребует немалых усилий и подробных разъяснений, поэтому здесь приведена, скорее, иллюстрация определения фрактальной размерности. Из формулы степенной зависимости N(δ) ~ (1/δ)D, где N — число пересекающихся квадратиков, δ — их размер, а D — размерность, получаем, что D = log1/δN. Это равенство верно с точностью до прибавления константы (одной и той же для всех δ). На рисунках изображена пятая итерация построения кривой Коха, зеленым закрашены квадратики сетки, которые с ней пересекаются. Длина исходного отрезка равна 1, поэтому на верхнем рисунке длина стороны квадратиков равна 1/9. Закрашено 12 квадратиков, log912 ≈ 1,130929... . Пока не очень похоже на 1,261859... . Смотрим дальше. На среднем рисунке квадратики в два раза меньше, их размеры 1/18, закрашено 30. log1830 ≈ 1,176733... . Уже лучше. Внизу квадратики еще вдвое меньше, закрашено уже 72 штуки. log7230 ≈ 1,193426... . Еще ближе. Дальше нужно увеличивать номер итерации и одновременно уменьшать квадратики, тогда «эмпирическое» значение размерности кривой Коха будет неуклонно приближаться к log34, а в пределе и вовсе совпадет.
Варианты
Снежинка Коха «наоборот» получается, если строить кривые Коха внутрь исходного равностороннего треугольника.
Линии Чезаро. Вместо равносторонних треугольников используются равнобедренные с углом при основании от 60° до 90°. На рисунке угол равен 88°.
Квадратный вариант. Тут достраиваются квадраты.
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<HEAD>
<TITLE>Снежинка Коха</TITLE>
<style>
canvas {
border: 1px dashed black;
}
</style>
</HEAD>
<script type="text/javascript">
var cos = 0.5,
sin = Math.sqrt(3) / 2,
deg = Math.PI / 180;
canv, ctx;
function rebro(n, len) {
ctx.save(); // Сохраняем текущую трансформацию
if (n == 0) { // Нерекурсивный случай - отрисовываем линию
ctx.lineTo(len, 0);
}
else {
ctx.scale(1 / 3, 1 / 3); // Уменьшаем масштаб в 3 раза
rebro(n-1, len); //RECUURSION на ребре
ctx.rotate(60 * deg);
rebro(n-1, len);
ctx.rotate(-120 * deg);
rebro(n-1, len);
ctx.rotate(60 * deg);
rebro(n-1, len);
}
ctx.restore(); // Восстанавливаем трансформацию
ctx.translate(len, 0); // переходим в конец ребра
}
function drawKochSnowflake(x, y, len, n) {
x = x - len / 2;
y = y + len / 2 * Math.sqrt(3)/3;
ctx.save();
ctx.beginPath();
ctx.translate(x, y);
ctx.moveTo(0, 0);
rebro(n, len); ctx.rotate(-120 * deg); //RECUUUURSION уже треугольник
rebro(n, len); ctx.rotate(-120 * deg);
rebro(n, len); ctx.closePath();
ctx.strokeStyle = "#000";
ctx.stroke();
ctx.restore();
}
function clearcanvas(){ //чистим канвас
ctx.save();
ctx.beginPath();
// Use the identity matrix while clearing the canvas
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.clearRect(0, 0, canvas1.width, canvas1.height);
// Restore the transform
ctx.restore();
}
function run() {
canv = document.getElementById('canvas1');
ctx = canv.getContext('2d');
var numberiter = document.getElementById("qty").value;
drawKochSnowflake(canv.width/2, canv.height/2, 380, numberiter);
ctx.stroke(); //отрисовка
}
</script>
<BODY>
<div align="center">
<H3>Снежинка Коха - пример</H3>
<div align="center">
<canvas height='500' width='500' id='canvas1' align="center"></canvas>
<FORM>
<br>
<INPUT TYPE=button VALUE="Сгенерить снежинку" id="btn1" onclick="run();">
<INPUT TYPE=button VALUE="Очистить" id="btn2" onclick="clearcanvas();">
</FORM>
<input id="qty" value="0" />
</div>
</BODY>
</HTML>