Текущая версия |
Ваш текст |
Строка 1: |
Строка 1: |
− | Программа позволяет строить фрактальные и простые структуры при заданных начальных условиях c помощью дробно-линейного <i><b>[https://ru.wikipedia.org/wiki/Отображение_Пуанкаре отображения Пуанкаре]</b></i>. | + | Программа позволяет строить фрактальные и простые структуры при заданных начальных условиях: координат "x" и "y" исходной точки, от которой будут высчитываться координаты остальных, и коэффициентах, участвующих в расчетах. Или же расчет новых точек можно задать с помощью задания угла поворота исходной |
− | ==Начальные условия и принцип работы==
| + | {{#widget:Iframe |url = http://tm.spbstu.ru/htmlets/js2020/Borisenkov/1_zad.html | width =1500 | height = 1200| border = 0}} |
− | В системе координат Oxy дан единичный квадрат, который отображается на экран в масштабе 1000:1
| |
− | <br>{{#widget:Iframe |url = http://tm.spbstu.ru/htmlets/js2020/Borisenkov/fotos/coordinat2.jpg| width= 382 | height = 362}}
| |
− | <br>Программа получает начальную точку с координатами "x"(0<x<1) и "y"(0<y<1) и строит N точек, координаты которых вычисляются по формулам:
| |
− | <br>
| |
− | \begin{equation}
| |
− | \begin{cases}
| |
− | x_{k+1} = F(a_{11}x_{k} + a_{12}y_{k})\\
| |
− | y_{k+1} = F(a_{21}x_{k+1} + a_{22}y_{k})
| |
− | \end{cases}
| |
− | \end{equation}
| |
− | <div align = "left">где <math> a_{11}, a_{12}, a_{21}, a_{22} </math> - константы, <math>F</math> - функция<i> [https://ru.wikipedia.org/wiki/Дробная_часть дробной части]</i>.</div>
| |
− | Сразу можно сказать, что все точки, вычисленные по этим формулам, попадут в единичный квадрат (вследствие использования функции дробной части).
| |
− | ==Направление исследований==
| |
− | Если убрать функцию <math>F</math>, то формулы будут эквиваленты системе дифференциальных уравнений, описывающих отображение точек плоскости на себя с течением времени ([https://ru.wikipedia.org/wiki/Отображение_Пуанкаре отображение Пуанкаре]). То есть, мы получим динамическую систему с дискретным временем.
| |
− | \begin{cases}
| |
− | \frac{dx}{dt} = b_{11}x + b_{12}y\\
| |
− | \frac{dy}{dt} = b_{21}x + b_{22}y
| |
− | \end{cases}
| |
− | <div align = "left">где <math> b_{11}, b_{12}, b_{21}, b_{22} </math> - константы.</div>
| |
− | <div align = "center"><br>{{#widget:Iframe |url = http://tm.spbstu.ru/htmlets/js2020/Borisenkov/fotos/interpritate.png| width= 364 | height = 377}}</div>
| |
− | <br>Используя функцию <math>F</math>, программа строит <i><b>регулярные</b></i> и <i><b>нерегулярные</b></i> области:
| |
− | <br>1. <i><b>Регулярной</b></i> будем называть область, состоящую из малого количества отдельных элементов (например: два больших эллипса).
| |
− | <br>2. <i><b>Нерегулярной</b></i> будем называть область, состоящую из большого количества малых элементов (например: множество малых эллипсов в промежутках между регулярными областями).
| |
− | <br>Ниже изображен процесс вычисления точек и их отображения в случае нерегулярной и регулярной области при одних и тех же коэффициентах (эксперимент 1):
| |
− | \begin{equation} a_{11} = 1, a_{12} = 1, a_{21} = -0.9, a_{22} = 1.\end{equation}
| |
− | <br>1. Анимация №1
| |
− | <br><math> x_{0} = 0.613, y_{0} = 0.582</math>
| |
− | <br>{{#widget:Iframe |url = http://tm.spbstu.ru/htmlets/js2020/Borisenkov/fotos/reg_obl-1.gif| width= 454 | height = 369}}
| |
− | {{#widget:Iframe |url = http://tm.spbstu.ru/htmlets/js2020/Borisenkov/fotos/edinich-1.png| width= 387 | height = 218}}
| |
− | <br>Результат: регулярная область фрактала.
| |
− | <br>2. Анимация №2
| |
− | <br><math>x_{0} = 0.46, y_{0} = 0.63</math>
| |
− | <br>{{#widget:Iframe |url = http://tm.spbstu.ru/htmlets/js2020/Borisenkov/fotos/nereg_obl2.gif| width= 450 | height = 369}}
| |
− | <br>Результат: нерегулярная область фрактала.
| |
− | <font color = "blue"><br><i>Синим</i></font> цветом обозначены точки, вычисленные по рекуррентным формулам <u>без</u> использования функции <math>F</math>.
| |
− | <font color = "red"><br><i>Красным</i></font> цветом обозначены точки, вычисленные по рекуррентным формулам <u>с</u> использованием функции <math>F</math> (формулы даны выше). Программа вычисляет и отображает лишь эти точки.
| |
− | | |
− | <br><b><i>Вывод 1</i></b>: в зависимости от выбора начальной точки мы получаем дополняющие друг друга области одного фрактала, соответствующего заданным коэффициентам. Интерес состоит в том, чтобы выделять нерегулярные(большие) области фрактала, отсеивая регулярные так, чтобы не зависеть от "ZOOM'а".
| |
− | <br><b><i>Примечание</i></b>. Один из алгоритмов отыскания нерегулярных областей осуществлен в данной программе: <b>http://tm.spbstu.ru/Фрактал(2-ая_версия_программы)</b>.
| |
− | | |
− | <br><b><i>Вывод 2</i></b>: паттерн получаемого фрактала подобен кривой второго порядка, которую образуют точки, вычисленные по рекуррентным формулам без использования функции дробной части <math>F</math>. Зная как связаны коэффициенты рекуррентных формул с коэффициентами соответствующей системы дифференциальных уравнений, можно узнать тип особой точки и вид паттерна фрактала (эллипс, гипербола, спираль..).
| |
− | ==Пример работы программы==
| |
− | Зададим такие же коэффициенты, как в примерах выше (эксперимент №1 в списке программы):
| |
− | <br>\begin{equation} a_{11} = 1, a_{12} = 1, a_{21} = -0.9, a_{22} = 1.\end{equation}
| |
− | <br>Получив несколько начальных точек, программа построит такую картину при данных коэффициентах:
| |
− | <br>{{#widget:Iframe |url = http://tm.spbstu.ru/htmlets/js2020/Borisenkov/fotos/Ellips2.jpg| width= 212 | height = 209}}
| |
− | <br>Для просмотра других примечательных наборов начальных условий следует выбрать номер эксперимента в списке программы.
| |
− | ==Инструментарий программы==
| |
− | Для дальнейшего использования результатов программы в докладах/исследованиях/научных работах и повторного воспроизведения интересных результатов, программа отображает начальные значения "x" и "y", введенные пользователем последним кликом по холсту, рядом с информацией о рассматриваемой области:
| |
− | <br>{{#widget:Iframe |url = http://tm.spbstu.ru/htmlets/js2020/Borisenkov/fotos/obla.png| width= 805 | height = 29}}
| |
− | <br><div align ="left">Коэффициенты <math>a_{11},a_{12},a_{21},a_{22}</math> задаются с помощью полей ввода:</div>
| |
− | <br>{{#widget:Iframe |url = http://tm.spbstu.ru/htmlets/js2020/Borisenkov/fotos/koeffs.png| width= 197 | height = 45}}
| |
− | <br>Начальные точки задаются с помощью клика по холсту или с помощью полей ввода:
| |
− | <br>{{#widget:Iframe |url = http://tm.spbstu.ru/htmlets/js2020/Borisenkov/fotos/n.y2.png| width= 660 | height = 25}}
| |
− | <br>Количество расчетов по рекуррентным формулам для каждой начальной точки:
| |
− | <br>{{#widget:Iframe |url = http://tm.spbstu.ru/htmlets/js2020/Borisenkov/fotos/iters.png| width= 346 | height = 25}}
| |
− | <br>Чтобы посмотреть заложенные в программу примечательные наборы начальных данных, следует выбрать номер эксперимента:
| |
− | <br>{{#widget:Iframe |url = http://tm.spbstu.ru/htmlets/js2020/Borisenkov/fotos/expire.png| width= 299 | height = 25}}
| |
− | <br>Чтобы скачать полученный рисунок, обновить рисунок с учетом изменения количества итераций, или отчистить холст, следует воспользоваться следующими кнопками:
| |
− | <br>{{#widget:Iframe |url = http://tm.spbstu.ru/htmlets/js2020/Borisenkov/fotos/buttons.png| width= 472 | height = 43}}
| |
− | ==Два режима работы программы==
| |
− | Данная программа предусматривает два режима работы:
| |
− | <br>1) Режим задания начальных данных (стоит по умолчанию). Кликом мыши по холсту добавляем начальные данные.
| |
− | <br>2) Режим "ZOOM'а". Включается нажатием на соответствующий "checkbox", или с помощью численного задания области рассмотрения. Позволяет подробнее рассмотреть полученный рисунок.
| |
− | <br>Чтобы программа лучше прорисовала картину в режиме "ZOOM", необходимо задать большее количество точек в поле задания количества итераций, используя при этом кнопку "Обновить рисунок"
| |
− | {{#widget:Iframe |url = http://tm.spbstu.ru/htmlets/js2020/Borisenkov/Fractals25_kopia1_03_21.html | width =1500 | height = 1250| border = 0}} | |
| | | |
| ==Код программы== | | ==Код программы== |
| <div class="mw-collapsible mw-collapsed"> | | <div class="mw-collapsible mw-collapsed"> |
− | '''Код программы на языке JavaScript (разработчик Богдан Борисенков):''' <div class="mw-collapsible-content"> | + | '''Код программы на языке JavaScript:''' <div class="mw-collapsible-content"> |
| <syntaxhighlight lang="javascript" line start="1" enclose="div"> | | <syntaxhighlight lang="javascript" line start="1" enclose="div"> |
| window.addEventListener('load',main,false); | | window.addEventListener('load',main,false); |
Строка 78: |
Строка 12: |
| var h = cnv.height; | | var h = cnv.height; |
| var w = cnv.width; | | var w = cnv.width; |
− | var scale = 1000; | + | var scale = 1/w; |
− | var a_11; var a_12; var a_21; var a_22; | + | var a_11;var a_12;var a_21; var a_22; |
| var numb1; var numb2; var decim; | | var numb1; var numb2; var decim; |
| + | var on = false; |
| var interv; | | var interv; |
− | var clear;
| |
− | var butt = document.getElementById('downloadimg');
| |
− | var update = document.getElementById('refresh');
| |
− | X = []; // массив начальных иксов
| |
− | Y = []; // массив начальных игриков
| |
− | var move = false;
| |
− | var numberof;
| |
− | var z = 1;
| |
− | var RGB = [];
| |
− | var z2 = 1;
| |
− | var iterations = document.getElementById('number_it');
| |
− | // начальные условия
| |
| a_11 = 1; | | a_11 = 1; |
| a_12 = 1; | | a_12 = 1; |
| a_21 = 1; | | a_21 = 1; |
| a_22 = 1; | | a_22 = 1; |
− | var N = 200000; | + | var degrees = 0; |
− | var x_min = 0; var y_min = 0;
| + | var sposob; |
− | var x_max = 1; var y_max = 1;
| + | var clear; |
− | var x_move; var y_move;
| + | var butt = document.getElementById("addButton"); |
− | var x_oldmin = 0;
| |
− | var x_oldmax = scale;
| |
− | var y_oldmin = 0;
| |
− | var y_oldmax = scale;
| |
− | var x_relativemin = 0;
| |
− | var x_relativemax = scale;
| |
− | var y_relativemin = 0;
| |
− | var y_relativemax = scale; | |
− | var intermid; | |
− | var imageData = ctx.createImageData(w,h); | |
− | var imageData2;
| |
− | var upd = false;
| |
| | | |
− | x_minim.onchange = function () { | + | butt.onclick = function () { |
− | x_min = parseFloat(document.getElementById('x_minim').value);
| + | ctx.strokeStyle = "rgb("+ |
− | z = 1/(x_max - x_min);
| + | Math.floor(Math.random()*256)+","+ |
− | z2 = 1;
| + | Math.floor(Math.random()*256)+","+ |
− | y_max = y_min + x_max - x_min;
| + | Math.floor(Math.random()*256)+")"; |
− | x_relativemin = 0;
| |
− | x_relativemax = scale;
| |
− | y_relativemin = 0;
| |
− | y_relativemax = scale;
| |
− | }
| |
− | x_maxim.onchange = function () {
| |
− | x_max = parseFloat(document.getElementById('x_maxim').value);
| |
− | z = 1/(x_max - x_min);
| |
− | z2 = 1;
| |
− | y_max = y_min + x_max - x_min;
| |
− | x_relativemin = 0;
| |
− | x_relativemax = scale;
| |
− | y_relativemin = 0;
| |
− | y_relativemax = scale;
| |
− | }
| |
− | y_minim.onchange = function () {
| |
− | y_min = parseFloat(document.getElementById('y_minim').value);
| |
− | z = 1/(x_max - x_min);
| |
− | z2 = 1;
| |
− | y_max = y_min + x_max - x_min;
| |
− | x_relativemin = 0;
| |
− | x_relativemax = scale;
| |
− | y_relativemin = 0;
| |
− | y_relativemax = scale;
| |
− | }
| |
− |
| |
− | // заполняем холст непрозрачными белыми пикселями для ускорения последующего рисования
| |
− | for (i = 0; i<1000; i++) {
| |
− | for (j = 0; j<1000; j++) {
| |
− | index = parseInt((i*w + j)*4);
| |
− | imageData.data[index+0] = 255;
| |
− | imageData.data[index+1] = 255;
| |
− | imageData.data[index+2] = 255;
| |
− | imageData.data[index+3] = 255;
| |
− | }
| |
− | }
| |
− | ctx.putImageData(imageData,0,0);
| |
− | | |
− | iterations.onchange = function () {
| |
− | N = document.getElementById('number_it').value;
| |
| } | | } |
| | | |
− | butt.onclick = function () {
| + | a11.onchange = function () { |
− | var dataURL = cnv.toDataURL("image/jpeg");
| |
− | var link = document.createElement("a");
| |
− | document.body.appendChild(link);
| |
− | link.href = dataURL;
| |
− | link.download = "my-image-name.jpg";
| |
− | link.click();
| |
− | document.body.removeChild(link);
| |
− | }
| |
− | update.onclick = function () { clearcanv(); upd = true;
| |
− | if ((document.getElementById('x_o') != 0 )||(document.getElementById('y_o') != 0)){
| |
− | 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);
| |
− | X.push(document.getElementById('x_o').value); Y.push(document.getElementById('y_o').value);
| |
− | }
| |
− | control();
| |
− | }
| |
− | a11.onchange = function() { | |
| a_11 = parseFloat(document.getElementById('a11').value); | | a_11 = parseFloat(document.getElementById('a11').value); |
− | document.getElementById('num').value = 0; | + | clearInterval(interv); |
− | angle = 0; | + | on = false; |
| } | | } |
| a12.onchange = function() { | | a12.onchange = function() { |
| a_12 = parseFloat(document.getElementById('a12').value); | | a_12 = parseFloat(document.getElementById('a12').value); |
− | document.getElementById('num').value = 0; | + | clearInterval(interv); |
− | angle = 0; | + | on = false; |
| } | | } |
− | a21.onchange = function() { | + | a21.onchange = function () { |
| a_21 = parseFloat(document.getElementById('a21').value); | | a_21 = parseFloat(document.getElementById('a21').value); |
− | document.getElementById('num').value = 0; | + | clearInterval(interv); |
− | angle = 0; | + | on = false; |
| } | | } |
− | a22.onchange = function() { | + | a22.onchange = function () { |
| a_22 = parseFloat(document.getElementById('a22').value); | | a_22 = parseFloat(document.getElementById('a22').value); |
− | document.getElementById('num').value = 0; | + | clearInterval(interv); |
− | angle = 0; | + | on = false; |
| } | | } |
− | | + | |
− | cnv.onmousedown = function() { | + | degree.onchange = function() { |
− | var zoom = document.getElementById('zoom_check'); | + | degrees = parseFloat(document.getElementById('degree').value); |
− | if (!zoom.checked) { | + | clearInterval(interv); |
| + | on = false; |
| + | } |
| + | |
| + | cnv.onmousedown = function () { |
| var rect = cnv.getBoundingClientRect(); | | var rect = cnv.getBoundingClientRect(); |
− | if (z != 1) { | + | x = (event.clientX - rect.left); |
− | z2 = x_max - x_min;
| + | y = (event.clientY - rect.top); |
− | x = x_min + (event.clientX - rect.left)*z2/scale;
| + | clear = document.getElementsByName('clear'); |
− | y = y_min + (event.clientY - rect.top)*z2/scale;
| + | if (clear[0].checked == true) { |
| + | ctx.clearRect(0,0,w,h); |
| + | ctx.beginPath(); |
| + | ctx.arc(x,y,3,0,2*Math.PI); |
| + | ctx.fillStyle = 'blue'; |
| + | ctx.fill(); |
| } else { | | } else { |
− | x = (event.clientX - rect.left)/scale; | + | ctx.strokeStyle = "rgb("+ |
− | y = (event.clientY - rect.top)/scale; | + | Math.floor(Math.random()*256)+","+ |
| + | Math.floor(Math.random()*256)+","+ |
| + | Math.floor(Math.random()*256)+")"; |
| + | } |
| + | if (on == false) { |
| + | interv = setInterval(control,0.000001); |
| + | on = true; |
| + | } |
| + | if (degrees != 0) { |
| + | sposob = document.getElementsByName('sposob'); |
| + | if (sposob[0].checked == true) { |
| + | a_11 = Math.cos(degrees); |
| + | a_22 = a_11; |
| + | a_12 = Math.sin(degrees); |
| + | a_21 = -a_12; |
| } | | } |
− | clear = document.getElementsByName('clear_rect');
| + | if (sposob[1].checked == true) { |
− | if (clear[1].checked == true) { | + | a_11 = Math.cos(degrees*2*Math.PI/360); |
− | r = Math.floor(Math.random()*256); | + | a_12 = Math.sin(degrees*2*Math.PI/360); |
− | g = Math.floor(Math.random()*256); | + | a_21 = -(a_12/a_11); |
− | b = Math.floor(Math.random()*256);
| + | a_22 = a_11 - a_21*a_12; |
− | } else {
| |
− | clearcanv ();
| |
− | r = Math.floor(Math.random()*256);
| |
− | g = Math.floor(Math.random()*256);
| |
− | b = Math.floor(Math.random()*256);
| |
| } | | } |
− | X.push(x);
| |
− | Y.push(y);
| |
− | RGB.push(r);
| |
− | RGB.push(g);
| |
− | RGB.push(b);
| |
− | control();
| |
− | } else {
| |
− | var rect = cnv.getBoundingClientRect();
| |
− | z2 = x_max - x_min;
| |
− | x_oldmin = x_min*scale;
| |
− | y_oldmin = y_min*scale;
| |
− | x_oldmax = x_max*scale;
| |
− | y_oldmax = y_max*scale;
| |
− | x_min = (event.clientX - rect.left)*z2 + x_oldmin;
| |
− | y_min = (event.clientY - rect.top)*z2 + y_oldmin;
| |
− | x_relativemin = event.clientX - rect.left;
| |
− | y_relativemin = event.clientY - rect.top;
| |
− | ctx.beginPath();
| |
− | ctx.rect(event.clientX - rect.left,event.clientY - rect.top,1,1);
| |
− | ctx.fillStyle = 'blue';
| |
− | ctx.fill();
| |
− | move = true;
| |
− | imageData2 = ctx.getImageData(0,0,w,h);
| |
| } | | } |
| | | |
− | }
| |
− |
| |
− | cnv.onmousemove = function () {
| |
− | if (move) {
| |
− | ctx.putImageData(imageData2,0,0);
| |
− | var rect = cnv.getBoundingClientRect();
| |
− | y_move = (event.clientY - rect.top);
| |
− | x_move = (y_move-y_relativemin) + x_relativemin;
| |
− | ctx.beginPath();
| |
− | ctx.rect(x_relativemin,y_relativemin,x_move-x_relativemin,y_move-y_relativemin);
| |
− | ctx.stroke();
| |
− | }
| |
| } | | } |
| | | |
− | cnv.onmouseup = function () { | + | function Func (numb) { |
− | zoom = document.getElementById('zoom_check');
| + | if (numb>=0) { |
− | if (zoom.checked) { | + | decim = parseFloat(numb) - parseInt(numb); |
− | x_relativemax = x_move; | + | return (decim); |
− | y_relativemax = y_move;
| + | } else { |
− | y_max = y_move*z2 + y_oldmin;
| + | decim = parseFloat(numb) - (parseInt(numb) - 1); |
− | x_max = x_move*z2 + x_oldmin;
| + | return (decim); |
− | x_min = x_min/scale;
| |
− | y_min = y_min/scale;
| |
− | x_max = x_max/scale;
| |
− | y_max = y_max/scale;
| |
− | if (x_min > x_max) {
| |
− | intermid = x_min;
| |
− | x_min = x_max;
| |
− | x_max = intermid;
| |
− | }
| |
− | if (y_min > y_max) {
| |
− | intermid = y_min;
| |
− | y_min = y_max;
| |
− | y_max = intermid;
| |
− | }
| |
− | z = z*scale/(x_relativemax - x_relativemin);
| |
− | some_span.innerHTML = "Увеличение в "+z.toFixed(1)+" раз";
| |
− | clearcanv ();
| |
− | move = false;
| |
− | control();
| |
| } | | } |
− |
| |
| } | | } |
− |
| |
− | function Func (numb) {
| |
− | decim = parseFloat(numb) - Math.floor(numb);
| |
− | return(decim);
| |
− | }
| |
− |
| |
| function coord() { | | function coord() { |
− | numb1 = a_11*x+a_12*y; | + | x = (x)*scale; |
− | x = Func(numb1); | + | y = (y)*scale; |
− | numb2 = a_21*x+a_22*y;
| + | sposob = document.getElementsByName('sposob'); |
− | y = Func(numb2);
| + | if (sposob[0].checked == true) { |
| + | numb1 = a_11*x+a_12*y; |
| + | numb2 = a_21*x+a_22*y; |
| + | x = Func(numb1); |
| + | y = Func(numb2); |
| + | } |
| + | if (sposob[1].checked == true) { |
| + | numb1 = a_11*x+a_12*y; |
| + | x = Func(numb1); |
| + | numb2 = a_21*x+a_22*y; |
| + | y = Func(numb2); |
| + | } |
| + | y = y/scale; |
| + | x = x/scale; |
| } | | } |
− |
| |
| function draw() { | | function draw() { |
− | if ((x>=x_min)&&(x<=x_max)&&(y>=y_min)&&(y<=y_max)) { | + | ctx.beginPath(); |
− | index = (Math.floor((y-y_min)*z*scale)*w + Math.floor((x-x_min)*z*scale))*4;
| + | ctx.rect(x,y,1,1); |
− | imageData.data[index+0] = r;
| + | ctx.stroke(); |
− | imageData.data[index+1] = g;
| |
− | imageData.data[index+2] = b;
| |
− | }
| |
− | }
| |
− | // функция отчистки канваса
| |
− | function clearcanv () {
| |
− | for (i = 0; i<1000; i++) {
| |
− | for (j = 0; j<1000; j++) {
| |
− | index = parseInt((i*w + j)*4);
| |
− | imageData.data[index+0] = 255;
| |
− | imageData.data[index+1] = 255;
| |
− | imageData.data[index+2] = 255;
| |
− | }
| |
− | }
| |
− | ctx.putImageData(imageData,0,0); | |
| } | | } |
| | | |
| function control () { | | function control () { |
− | zoom = document.getElementById('zoom_check'); | + | coord(); |
− | if ((zoom.checked)||(upd == true)) {
| + | draw(); |
− | numberof = X.length;
| |
− | for (m = 0; m<numberof; m++) {
| |
− | x = X[m];
| |
− | y = Y[m];
| |
− | x_s.innerHTML = x; y_s.innerHTML = y;
| |
− | r = Number(RGB[m*3]);
| |
− | g = Number(RGB[m*3+1]);
| |
− | b = Number(RGB[m*3+2]);
| |
− | for (j = 0;j<=N; j++){
| |
− | coord();
| |
− | draw();
| |
− | }
| |
− | upd = false;
| |
− | }
| |
− | } else { | |
− | x_s.innerHTML = x; y_s.innerHTML = y;
| |
− | for (j = 0;j<=N; j++){
| |
− | coord();
| |
− | draw();
| |
− | }
| |
− | }
| |
− | ctx.putImageData(imageData,0,0);
| |
− | document.getElementById('x_minim').value = x_min;
| |
− | document.getElementById('y_minim').value = y_min;
| |
− | document.getElementById('x_maxim').value = x_max;
| |
| } | | } |
− | | + | |
− | function set_exp(N_exp) { | |
− | var k = Number(N_exp);
| |
− | clearcanv ();
| |
− | X = [];
| |
− | Y = [];
| |
− | RGB = [];
| |
− | z = 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;
| |
− | if (N_exp == 1) {X.push(0.46); Y.push(0.63); X.push(0.613); Y.push(0.582); a_11 = 1; a_12 = 1; a_21 = -0.9; a_22 = 1; }
| |
− | if (N_exp == 2) {X.push(0.31); Y.push(0.32); a_11 = 1; a_12 = 0.5; a_21 = -0.5; a_22 = 1; }
| |
− | if (N_exp == 3) {X.push(0.69); Y.push(0.23); a_11 = 1; a_12 = 0.1296; a_21 = -0.1296; a_22 = 1; }
| |
− | if (N_exp == 4) {X.push(0.15); Y.push(0.63); a_11 = -0.9899924966004454; a_12 = 0.1411200080598672; a_21 = -0.1411200080598672; a_22 = -0.9899924966004454; }
| |
− | if (N_exp) {
| |
− |
| |
− | a11.value = a_11;
| |
− | a12.value = a_12;
| |
− | a21.value = a_21;
| |
− | a22.value = a_22;
| |
− | upd = true;
| |
− | }
| |
− | numberof = X.length;
| |
− | for (m=0; m<numberof; m++) {
| |
− | 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();}
| |
| } | | } |
| </syntaxhighlight> | | </syntaxhighlight> |
Строка 401: |
Строка 148: |
| <meta charset="UTF-8"> | | <meta charset="UTF-8"> |
| <title> Fractals </title> | | <title> Fractals </title> |
− | <script src = 'Fractals25_kopia24_01_21.js'> | + | <script src = '1_zad.js'> |
| </script> | | </script> |
| </head> | | </head> |
| <body> | | <body> |
− | <p align = 'left'><canvas id = 'cnv' width = 1000 height = 1000 style='border: 1px solid black;'></canvas></p> | + | <p align = 'center'><canvas id = 'cnv' width = 1000 height = 1000 style='border: 1px solid black;'></canvas></p> |
− | <span id=some_span></span> | + | <label><input type='text' id='degree' value ='0'><b>Угол поворота</b></label> |
− | <br><b>Рассматриваемая область: x_min = <input type = 'text' id = 'x_minim' style = "width:70px;height:10px" value ='0'>, x_max = <input type = 'text' style = "width:70px;height:10px" id = 'x_maxim' value ='1'>, y_min = <input type = 'text' style = "width:70px;height:10px" id = 'y_minim' value = '0'> x_0 = <span id='x_s'></span>, y_0 = <span id='y_s'></span>
| + | <br><b> Включить очистку холста после клика? </b> |
− | <br><b>Задайте начальную точку численно (затем: Обновить рисунок): x_0 = <input type = 'text' id = 'x_o' style = "width:70px;height:10px" value = '0'>, y_0 = <input type = 'text' id = 'y_o' style = "width:70px;height:10px" value = '0'>
| + | <label><input type = 'radio' name = 'clear' value = 'yes'><b>Да</b></label> |
− | <br><b>(*) Задайте коэффициенты:</b>
| + | <label><input type = 'radio' name = 'clear' value = 'no' checked><b>Нет</b></label> |
− |               <label><input type='text' style = "width:50px;height:15px" id='a11' value='1' ><b>A_11</b></label>
| + | <b> <input type="button" id="addButton" value="Сменить цвет рисовки"> |
− |  <label><input type='text' style = "width:50px;height:15px" id='a12' value='1' ><b>A_12</b></label>
| |
− | <br><b>(*) Включить очистку холста после клика? </b> | |
− | <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='text' style = "width:50px;height:15px" id='a21' value='1' ><b>A_21</b></label>
| |
− | <label><input type='text' style = "width:50px;height:15px" id='a22' value='1' ><b>A_22</b></label>
| |
| </br> | | </br> |
− |     <label><b>Режим <I>ZOOM'а</I><input type = 'checkbox' id = 'zoom_check'></b></label>
| + | <br> |
− |     <label><input type='text' id='number_it' value ='200000'><b>   Количество итераций</b></label>
| + | <b>Способ вычисления новых точек: (оба способа вычисляют по заданному углу в <I> радианах</I>)</b> |
− | <br><b> Выберите номер эксперимента:</b>
| + | <input type = 'radio' name='sposob' value = 'star' checked> <b>1-ый</b> |
− | <input type='number' size='1' id = 'num' min='1' max='4' value='0' step='1'> | + | <input type = 'radio' name='sposob' value = 'nov'><b> 2-ой</b> |
− | <br><b> <input type='button' id='downloadimg' value='Сохранить рисунок'> | + | </br> |
− | <input type = 'button' style="width:200px;height:40px" id = 'refresh' value = 'Обновить рисунок'></b></br> | + | <b>Или задайте коэффициенты самостоятельно (в графе угла должен стоять "0"):</b> |
| + | <br><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> |
| + | <label><input type='text' id='a21' value='1' ><b>A_21</b></label> |
| + | <label><input type='text' id='a22' value='1' ><b>A_22</b></label> |
| + | </br> |
| + | |
| </body> | | </body> |
| </html> | | </html> |
| </syntaxhighlight> | | </syntaxhighlight> |
| </div> | | </div> |