БлогNot. 8120601 математический аттрактор в 80 строк кода :)

8120601 математический аттрактор в 80 строк кода :)

Математические аттракторы, пожалуй, ещё красивее, чем просто генерируемые двойным циклом математические картинки... При этом для их программирования и вовсе нужен один-единственный цикл! (см. функцию draw)

Соотношения для вычисления координат следующей точки в зависимости от предыдущей использованы другие, чем в этой старой программе про "салфетки", но вышло, мне кажется, не хуже, вот несколько первых попавшихся картинок, для экономии места наложенных на одно и то же полотно:

математические аттракторы
математические аттракторы

Ниже показано приложение в работе (откроется после полной загрузки страницы, нужен включённый в браузере Javascript), инструкция и исходник.

Для копирования коэффициентов a,b,c просто кликните по строчке под картинкой, где написано "a=..." и нажмите комбинацию клавиш Ctrl+C (Копировать в буфер обмена).

Потом в нужном месте, например, в комментарии к статье, нажмите Ctrl+V и выразите своё восхищение красивым аттрактором.

Я не стал делать автообновление полотна, как у квадратичного фрактала, лучше просто кликните по картинке левой кнопкой мыши и через некоторое время она перерисуется со случайными коэффициентами. Также можно выбрать свои коэффициенты из списков, картинка обновляется после каждого нового выбора в списке. Насколько это будет быстро, зависит от быстродействия Вашего компьютера, но в норме долго ждать не придётся :)

А для сохранения картинки современные браузеры прекрасно позволяют нажать на канве правую кнопку мыши и кликнуть пункт меню "Сохранить картинку как..." или "Сохранить изображение как..." (зависит от браузера).

Ну а число из заголовка - это просто 201 в третьей степени, так как в каждом из трёх списков можно выбрать по 201 значению.

Проверил пока только в текущем Firefox и IE11, работает. Исходник приведён на момент написания, его можно вставить в файл формата .html в нужной кодировке.

<div align="center">
 <canvas id="attrCanvas" width="600" height="600" onclick="drawFractal(1)"></canvas>
 <div align="center" id="abcDiv" onclick="selectAbcDiv()"></div>
 <div align="center" id="selectDiv"></div>
</div> 

<script type="text/javascript">
function selectAbcDiv() { //Выделить abcDiv по клику
 var div = document.getElementById('abcDiv');
 var range = document.createRange();
 range.selectNodeContents(div);
 var sel = window.getSelection();
 sel.removeAllRanges();
 sel.addRange(range);
}

function drawFractal (rnd) {
 var canvas = document.getElementById('attrCanvas');	
 var ctx = canvas.getContext('2d');
 var w = canvas.width, h = canvas.height;
 ctx.fillStyle = color(255,255,255);
 ctx.fillRect (0 , 0 , w, h); 

 function draw (a,b,c) {
  var depth = 500000, scale = 0.2, x = w/4, y = h/4;
  for (var v = 0 ; v < depth; v++) { 
   var x2 = x / Math.abs(x);
   var x1 = y - x2 * (Math.abs(Math.sin(x) * Math.cos(b) + c - x * Math.sin(a + b + c)))
   var y1 = a - x;
   ctx.fillStyle = color(Math.floor(v/12000),Math.floor(v/7000),Math.floor(v/12000));
   ctx.fillRect (Math.floor(x*scale+w/2), Math.floor(y*scale+h/2), 1, 1);
   x = x1; y = y1;
  }
 }

 function color (r,g,b) {
  return '#' + (r<16?'0':'') + r.toString(16) + (g<16?'0':'') + 
   g.toString(16) + (b<16?'0':'') + b.toString(16);
 }
 function rand () {
  var diap = 100; //диапазон разброса случайных коэффициентов [-diap;diap]
  return Math.floor(Math.random()*2*diap-diap);
 }

 document.getElementById('abcDiv').innerHTML = '';
 var a,b,c;
 if (rnd==1) {
  a = rand(); b = rand(); c = rand();
  document.getElementById("sel_A").value = ''+a;
  document.getElementById("sel_B").value = ''+b;
  document.getElementById("sel_C").value = ''+c;
 }
 else {
  var sel_A = document.getElementById("sel_A");
  a = parseInt(sel_A.value); 
  var sel_B = document.getElementById("sel_B");
  b = parseInt(sel_B.value); 
  var sel_C = document.getElementById("sel_C");
  c = parseInt(sel_C.value); 
 }
 draw(a,b,c);
 document.getElementById('abcDiv').innerHTML = 'a='+a+',b='+b+',c='+c;
}

window.addEventListener('load', function () {
 var s = '';
 var letr = new Array ('A','B','C');
 var selt = new Array (-98,-40,-19);
 for (var i=0; i<3; i++) {
  s += "\n"+letr[i]+'=<select size="1" id="sel_'+letr[i]+'" onchange="drawFractal(0)">';
  for (var n=-100; n<=100; n++) {
   s += "\n" + '<option value="'+n+'"'+(n==selt[i]?' selected':'')+'>'+n;
  }
  s += "\n"+'</select> ';
 }
 document.getElementById('selectDiv').innerHTML = s;
 drawFractal (0);
}, false);
</script>
<noscript><p>Для работы приложения нужен включенный Javascript</p></noscript>

13.03.2019, 15:03 [1562 просмотра]


теги: javascript картинка графика random математика

показать комментарии (4)