Редактирование: Фрактал
Внимание! Вы не авторизовались на сайте. Ваш IP-адрес будет публично видимым, если вы будете вносить любые правки. Если вы войдёте или создадите учётную запись, правки вместо этого будут связаны с вашим именем пользователя, а также у вас появятся другие преимущества.
Правка может быть отменена. Пожалуйста, просмотрите сравнение версий, чтобы убедиться, что это именно те изменения, которые вас интересуют, и нажмите «Записать страницу», чтобы изменения вступили в силу.
Текущая версия | Ваш текст | ||
Строка 1: | Строка 1: | ||
− | Программа позволяет строить фрактальные и простые структуры при заданных начальных условиях | + | Программа позволяет строить фрактальные и простые структуры при заданных начальных условиях. |
==Начальные условия и принцип работы== | ==Начальные условия и принцип работы== | ||
В системе координат Oxy дан единичный квадрат, который отображается на экран в масштабе 1000:1 | В системе координат Oxy дан единичный квадрат, который отображается на экран в масштабе 1000:1 | ||
<br>{{#widget:Iframe |url = http://tm.spbstu.ru/htmlets/js2020/Borisenkov/fotos/coordinat2.jpg| width= 382 | height = 362}} | <br>{{#widget:Iframe |url = http://tm.spbstu.ru/htmlets/js2020/Borisenkov/fotos/coordinat2.jpg| width= 382 | height = 362}} | ||
− | <br>Программа получает | + | <br>Пользователю предлагается задать коэффициенты рекурсивной функции вычисления новых координат и координаты "x" и "y" начальной точки, количество итераций, которое произведет программа и способ вычисления новых точек. Начальная точка задается кликом левой кнопки мыши по холсту. |
+ | Программа получает на вход "x"(0<x<1) и "y"(0<y<1) и строит N точек, координаты которых вычисляются по формулам: | ||
<br> | <br> | ||
\begin{equation} | \begin{equation} | ||
\begin{cases} | \begin{cases} | ||
− | x_{k | + | x_{k} = F(a_{11}*x_{k-1} + a_{12}*y_{k-1})\\ |
− | y_{k | + | y_{k} = F(a_{21}*x_{k} + a_{22}*y_{k-1}) |
\end{cases} | \end{cases} | ||
\end{equation} | \end{equation} | ||
− | < | + | <br>где <math>F</math> - функция<i> [https://ru.wikipedia.org/wiki/Дробная_часть дробной части]</i>. |
Сразу можно сказать, что все точки, вычисленные по этим формулам, попадут в единичный квадрат (вследствие использования функции дробной части). | Сразу можно сказать, что все точки, вычисленные по этим формулам, попадут в единичный квадрат (вследствие использования функции дробной части). | ||
− | + | Эти рекуррентные формулы эквивалентны системе дифференциальных уравнений с одним отличием: функция дробной части позволяет получить фрактал с паттерном, повторяющим интегральные кривые эквивалентной системы дифференциальных уравнений. | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
==Пример работы программы== | ==Пример работы программы== | ||
− | Зададим | + | Зададим коэффициенты: |
− | <br>\begin{equation} a_{11} = 1, a_{12} = 1, a_{21} = -0.9, a_{22} = 1.\end{equation} | + | <br>\begin{equation} a_{11} = 1, a_{12} = 1, a_{21} = -0.9, a_{22} = 1.\end{equation} Если убрать функцию дробной части, точки будут заполнять эллипс: |
+ | <br>{{#widget:Iframe |url = http://tm.spbstu.ru/htmlets/js2020/Borisenkov/fotos/ell2.png| width= 181 | height = 168}} | ||
<br>Получив несколько начальных точек, программа построит такую картину при данных коэффициентах: | <br>Получив несколько начальных точек, программа построит такую картину при данных коэффициентах: | ||
<br>{{#widget:Iframe |url = http://tm.spbstu.ru/htmlets/js2020/Borisenkov/fotos/Ellips2.jpg| width= 212 | height = 209}} | <br>{{#widget:Iframe |url = http://tm.spbstu.ru/htmlets/js2020/Borisenkov/fotos/Ellips2.jpg| width= 212 | height = 209}} | ||
− | <br> | + | <br>Другие примечательные наборы начальных условий можно посмотреть, выбрав номер эксперимента |
− | == | + | ==Задание коэффициентов== |
− | + | Коэффициенты \begin{equation}a_{11},a_{12},a_{21},a_{22}\end{equation} можно задать с помощью полей ввода: | |
− | + | <br>{{#widget:Iframe |url = http://tm.spbstu.ru/htmlets/js2020/Borisenkov/fotos/koeff.png| width= 487 | height = 61}} | |
− | |||
− | |||
− | |||
− | <br>{{#widget:Iframe |url = http://tm.spbstu.ru/htmlets/js2020/Borisenkov/fotos/ | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
==Два режима работы программы== | ==Два режима работы программы== | ||
− | + | В данной программе можно переключаться между двумя режимами: | |
− | <br>1) Режим задания начальных данных (стоит по умолчанию). Кликом мыши по холсту добавляем | + | <br>1) Режим задания начальных данных (стоит по умолчанию). Кликом мыши по холсту добавляем начальную точку. |
− | <br>2) Режим "ZOOM'а". Включается нажатием на соответствующий "checkbox" | + | <br>2) Режим "ZOOM'а". Включается нажатием на соответствующий "checkbox". Позволяет подробнее рассмотреть уже полученный рисунок. |
− | <br>Чтобы программа лучше прорисовала картину в режиме "ZOOM" | + | <br>Чтобы программа лучше прорисовала картину в режиме "ZOOM" необходимо задать большее количество точек в поле задания количества итераций, используя при этом кнопку "Обновить рисунок" |
− | {{#widget:Iframe |url = http://tm.spbstu.ru/htmlets/js2020/Borisenkov/ | + | {{#widget:Iframe |url = http://tm.spbstu.ru/htmlets/js2020/Borisenkov/Fractals25_kopia17_11_20.html | width =1500 | height = 1250| border = 0}} |
+ | ==Другая версия программы== | ||
+ | <br><b>http://tm.spbstu.ru/Фрактал(2-ая_версия_программы) | ||
==Код программы== | ==Код программы== | ||
<div class="mw-collapsible mw-collapsed"> | <div class="mw-collapsible mw-collapsed"> | ||
Строка 106: | Строка 72: | ||
var y_oldmin = 0; | var y_oldmin = 0; | ||
var y_oldmax = scale; | var y_oldmax = scale; | ||
− | |||
− | |||
− | |||
− | |||
var intermid; | var intermid; | ||
var imageData = ctx.createImageData(w,h); | var imageData = ctx.createImageData(w,h); | ||
var imageData2; | var imageData2; | ||
var upd = false; | var upd = false; | ||
+ | x_minim.innerHTML = x_min.toFixed(2); | ||
+ | y_minim.innerHTML = y_min.toFixed(2); | ||
+ | x_maxim.innerHTML = x_max.toFixed(2); | ||
+ | y_maxim.innerHTML = y_max.toFixed(2); | ||
− | + | // заполняем холст непрозрачными белыми пикселями | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | // заполняем холст непрозрачными белыми пикселями | ||
for (i = 0; i<1000; i++) { | for (i = 0; i<1000; i++) { | ||
for (j = 0; j<1000; j++) { | for (j = 0; j<1000; j++) { | ||
Строка 171: | Строка 106: | ||
document.body.removeChild(link); | document.body.removeChild(link); | ||
} | } | ||
− | update.onclick = function () { clearcanv(); upd = true; | + | update.onclick = function () { clearcanv(); upd = true; control(); } |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
a11.onchange = function() { | a11.onchange = function() { | ||
a_11 = parseFloat(document.getElementById('a11').value); | a_11 = parseFloat(document.getElementById('a11').value); | ||
Строка 208: | Строка 132: | ||
if (!zoom.checked) { | if (!zoom.checked) { | ||
var rect = cnv.getBoundingClientRect(); | var rect = cnv.getBoundingClientRect(); | ||
+ | console.log((event.clientX - rect.left)/scale,(event.clientY - rect.top)/scale); | ||
if (z != 1) { | if (z != 1) { | ||
z2 = x_max - x_min; | z2 = x_max - x_min; | ||
Строка 223: | Строка 148: | ||
} else { | } else { | ||
clearcanv (); | clearcanv (); | ||
+ | some_span.innerHTML = ""; | ||
+ | z = 1; | ||
+ | z2 = 1; | ||
+ | RGB = []; | ||
+ | X = []; | ||
+ | Y = []; | ||
r = Math.floor(Math.random()*256); | r = Math.floor(Math.random()*256); | ||
g = Math.floor(Math.random()*256); | g = Math.floor(Math.random()*256); | ||
b = Math.floor(Math.random()*256); | b = Math.floor(Math.random()*256); | ||
+ | ctx.beginPath(); | ||
+ | ctx.arc(x*scale,y*scale,3,0,2*Math.PI); | ||
+ | ctx.strokeStyle = 'blue'; | ||
+ | ctx.stroke(); | ||
} | } | ||
X.push(x); | X.push(x); | ||
Строка 288: | Строка 223: | ||
} | } | ||
z = z*scale/(x_relativemax - x_relativemin); | z = z*scale/(x_relativemax - x_relativemin); | ||
− | some_span.innerHTML = "Увеличение в "+z.toFixed( | + | some_span.innerHTML = "Увеличение в "+z.toFixed(2)+" раз"; |
clearcanv (); | clearcanv (); | ||
move = false; | move = false; | ||
control(); | control(); | ||
} | } | ||
− | + | x_minim.innerHTML = x_min.toFixed(2); | |
+ | y_minim.innerHTML = y_min.toFixed(2); | ||
+ | x_maxim.innerHTML = x_max.toFixed(2); | ||
+ | y_maxim.innerHTML = y_max.toFixed(2); | ||
} | } | ||
Строка 336: | Строка 274: | ||
x = X[m]; | x = X[m]; | ||
y = Y[m]; | y = Y[m]; | ||
− | |||
r = Number(RGB[m*3]); | r = Number(RGB[m*3]); | ||
g = Number(RGB[m*3+1]); | g = Number(RGB[m*3+1]); | ||
Строка 347: | Строка 284: | ||
} | } | ||
} else { | } else { | ||
− | |||
for (j = 0;j<=N; j++){ | for (j = 0;j<=N; j++){ | ||
coord(); | coord(); | ||
Строка 354: | Строка 290: | ||
} | } | ||
ctx.putImageData(imageData,0,0); | ctx.putImageData(imageData,0,0); | ||
− | + | ||
− | |||
− | |||
} | } | ||
Строка 368: | Строка 302: | ||
z2 = 1; | z2 = 1; | ||
x_min = 0; y_min = 0; x_max = 1; y_max = 1; x_oldmin = 0; y_oldmin = 0; x_oldmax = scale; y_oldmax = scale; | x_min = 0; y_min = 0; x_max = 1; y_max = 1; x_oldmin = 0; y_oldmin = 0; x_oldmax = scale; y_oldmax = scale; | ||
− | if (N_exp == 1) { | + | if (N_exp == 1) {x = 0.31; y = 0.32; a_11 = 1; a_12 = 0.5; a_21 = -0.5; a_22 = 1; } |
− | if (N_exp == | + | if (N_exp == 2) {x = 0.46; y = 0.63; a_11 = 1; a_12 = 1; a_21 = -0.9; a_22 = 1; } |
− | if (N_exp == | + | if (N_exp == 3) {x = 1/4; y = 1/4; a_11 = 1; a_12 = 0.01; a_21 = 0.01; a_22 = -1; } |
− | if (N_exp == | + | if (N_exp == 4) {x = 1/2; y = 1/2; a_11 = 1; a_12 = 0.32; a_21 = 0.32; a_22 = -1; } |
+ | if (N_exp == 5) {x = 1/2; y = 1/2; a_11 = 0.9; a_12 = 0.1; a_21 = -0.1; a_22 = 1.2; } | ||
+ | if (N_exp == 6) {x = 1/4; y = 1/4; a_11 = Math.cos(angle); a_12 = Math.sin(angle); a_21 = -a_12; a_22 = a_11; } | ||
+ | if (N_exp == 7) {x = 1/2; y = 1/2; a_11 = 1; a_12 = 1.5; a_21 = 0.01; a_22 = -1; } | ||
+ | if (N_exp == 8) {x = 1/2; y = 1/2; a_11 = 1; a_12 = 0.1296; a_21 = -0.1296; a_22 = 1; } | ||
+ | if (N_exp == 9) {x = 1/4; y = 1/4; a_11 = -0.05; a_12 = -0.95; a_21 = 1.1; a_22 = 0.65; } | ||
if (N_exp) { | if (N_exp) { | ||
a11.value = a_11; | a11.value = a_11; | ||
− | a12.value = a_12; | + | a12.value = a_12; X.push(x); Y.push(y); |
a21.value = a_21; | a21.value = a_21; | ||
a22.value = a_22; | a22.value = a_22; | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
+ | r = Math.floor(Math.random()*256); | ||
+ | g = Math.floor(Math.random()*256); | ||
+ | b = Math.floor(Math.random()*256); | ||
+ | RGB.push(r); | ||
+ | RGB.push(g); | ||
+ | RGB.push(b); | ||
} | } | ||
num.onchange = function() { set_exp(document.getElementById('num').value); control();} | num.onchange = function() { set_exp(document.getElementById('num').value); control();} | ||
Строка 401: | Строка 336: | ||
<meta charset="UTF-8"> | <meta charset="UTF-8"> | ||
<title> Fractals </title> | <title> Fractals </title> | ||
− | <script src = ' | + | <script src = 'Fractals25_kopia17_11_20.js'> |
</script> | </script> | ||
</head> | </head> | ||
Строка 407: | Строка 342: | ||
<p align = 'left'><canvas id = 'cnv' width = 1000 height = 1000 style='border: 1px solid black;'></canvas></p> | <p align = 'left'><canvas id = 'cnv' width = 1000 height = 1000 style='border: 1px solid black;'></canvas></p> | ||
<span id=some_span></span> | <span id=some_span></span> | ||
− | <br><b>Рассматриваемая область: x_min = < | + | <br><b>Рассматриваемая область: x_min = <span id =x_minim></span> , y_min = <span id =y_minim></span>, x_max = <span id=x_maxim></span>, y_max = <span id=y_maxim></span> |
− | |||
<br><b>(*) Задайте коэффициенты:</b> | <br><b>(*) Задайте коэффициенты:</b> | ||
− |               <label><input type='text' | + |                 <label><input type='text' id='a11' value='1' ><b>A_11</b></label> |
− | + | <label><input type='text' id='a12' value='1' ><b>A_12</b></label> | |
<br><b>(*) Включить очистку холста после клика? </b> | <br><b>(*) Включить очистку холста после клика? </b> | ||
<label><input type = 'radio' name = 'clear_rect' value = 'yes'><b>Да</b></label> | <label><input type = 'radio' name = 'clear_rect' value = 'yes'><b>Да</b></label> | ||
<label><input type = 'radio' name = 'clear_rect' value = 'no' checked><b>Нет</b></label> | <label><input type = 'radio' name = 'clear_rect' value = 'no' checked><b>Нет</b></label> | ||
− |  <label><input type='text' | + |     <label><input type='text' id='a21' value='1' ><b>A_21</b></label> |
− | <label><input type='text' | + | <label><input type='text' id='a22' value='1' ><b>A_22</b></label> |
</br> | </br> | ||
    <label><b>Режим <I>ZOOM'а</I><input type = 'checkbox' id = 'zoom_check'></b></label> |     <label><b>Режим <I>ZOOM'а</I><input type = 'checkbox' id = 'zoom_check'></b></label> | ||
    <label><input type='text' id='number_it' value ='200000'><b>   Количество итераций</b></label> |     <label><input type='text' id='number_it' value ='200000'><b>   Количество итераций</b></label> | ||
<br><b> Выберите номер эксперимента:</b> | <br><b> Выберите номер эксперимента:</b> | ||
− | <input type='number' size='1' id = 'num' min='1' max=' | + | <input type='number' size='1' id = 'num' min='1' max='9' value='0' step='1'> |
<br><b> <input type='button' id='downloadimg' value='Сохранить рисунок'> | <br><b> <input type='button' id='downloadimg' value='Сохранить рисунок'> | ||
<input type = 'button' style="width:200px;height:40px" id = 'refresh' value = 'Обновить рисунок'></b></br> | <input type = 'button' style="width:200px;height:40px" id = 'refresh' value = 'Обновить рисунок'></b></br> |