Javascript: рисуем множество Жюлиа
Если мы что и знаем о множествах Жюлиа, обычно это лишь то, что "они красивые", ну, вот такие примерно:
множество Жюлиа, картинка
Ниже приложен небольшой сервис, позволяющий изобразить точки из окрестности множества примерно так, как это делается в "Вики".
Похоже чем-то на мандельбротщину, но не в Маткаде, а прямо онлайн и цветное.
Способ извлечения параметров и код - самые примитивные, после любого нового выбора из списка старая канва удаляется и заменяется новой. Ну а выбор всех настроек из списков сделан, чтобы не соблазнять юзера ничего вводить.
Большинство этих конфигураций будут "мёртвые", но вы можете попытаться найти и "живые" :) Если получится что-то красивее, чем картинка по умолчанию - отпишитесь с цифрами настроек, для этого в скрипте есть кнопка "Записать", выводящая нужную строку текста, например
Итераций: 1000, Размер канвы: 800, Коэффициенты: -0.7, 0.7, -0.8, 0.8, 0.285, 0.01
Кнопка "Сброс" возвращает настройки по умолчанию.
Приложение в работе (текущее окно/вкладка)
JuliaSet.html, файл приложения (скачать правой кнопкой мыши) (9 Кб)
Полный исходник, большая часть которого - просто форма HTML, предполагается, что файл .html будет сохранён в Юникоде (UTF-8):
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title>Julia Set</title> </head> <body> <div align="center"> <form name="juliaForm"> Итераций: <select size="1" name="maxIterations" id="maxIterations" onchange="init()"> <option value="100">100 <option value="200">200 <option value="300">300 <option value="400">400 <option value="450" selected>450 <option value="500">500 <option value="600">600 <option value="700">700 <option value="800">800 <option value="900">900 <option value="1000">1000 </select> Размер канвы: <select size="1" name="canvasSize" id="canvasSize" onchange="init()"> <option value="400">400 <option value="600" selected>600 <option value="800">800 <option value="1000">1000 </select> Коэффициенты: <select size="1" name="minX" id="minX" onchange="init()"> <option value="-1">-1 <option value="-0.9">-0.9 <option value="-0.8">-0.8 <option value="-0.7">-0.7 <option value="-0.6">-0.6 <option value="-0.5" selected>-0.5 <option value="-0.4">-0.4 <option value="-0.3">-0.3 <option value="-0.2">-0.2 <option value="-0.1">-0.1 <option value="0">0 <option value="0.1">0.1 <option value="0.2">0.2 <option value="0.3">0.3 <option value="0.4">0.4 <option value="0.5">0.5 <option value="0.6">0.6 <option value="0.7">0.7 <option value="0.8">0.8 <option value="0.9">0.9 <option value="1">1 </select> (minX), <select size="1" name="maxX" id="maxX" onchange="init()"> <option value="-1">-1 <option value="-0.9">-0.9 <option value="-0.8">-0.8 <option value="-0.7">-0.7 <option value="-0.6">-0.6 <option value="-0.5">-0.5 <option value="-0.4">-0.4 <option value="-0.3">-0.3 <option value="-0.2">-0.2 <option value="-0.1">-0.1 <option value="0">0 <option value="0.1">0.1 <option value="0.2">0.2 <option value="0.3">0.3 <option value="0.4">0.4 <option value="0.5" selected>0.5 <option value="0.6">0.6 <option value="0.7">0.7 <option value="0.8">0.8 <option value="0.9">0.9 <option value="1">1 </select> (maxX), <select size="1" name="minY" id="minY" onchange="init()"> <option value="-1">-1 <option value="-0.9">-0.9 <option value="-0.8">-0.8 <option value="-0.7">-0.7 <option value="-0.6">-0.6 <option value="-0.5" selected>-0.5 <option value="-0.4">-0.4 <option value="-0.3">-0.3 <option value="-0.2">-0.2 <option value="-0.1">-0.1 <option value="0">0 <option value="0.1">0.1 <option value="0.2">0.2 <option value="0.3">0.3 <option value="0.4">0.4 <option value="0.5">0.5 <option value="0.6">0.6 <option value="0.7">0.7 <option value="0.8">0.8 <option value="0.9">0.9 <option value="1">1 </select> (minY), <select size="1" name="maxY" id="maxY" onchange="init()"> <option value="-1">-1 <option value="-0.9">-0.9 <option value="-0.8">-0.8 <option value="-0.7">-0.7 <option value="-0.6">-0.6 <option value="-0.5">-0.5 <option value="-0.4">-0.4 <option value="-0.3">-0.3 <option value="-0.2">-0.2 <option value="-0.1">-0.1 <option value="0">0 <option value="0.1">0.1 <option value="0.2">0.2 <option value="0.3">0.3 <option value="0.4">0.4 <option value="0.5" selected>0.5 <option value="0.6">0.6 <option value="0.7">0.7 <option value="0.8">0.8 <option value="0.9">0.9 <option value="1">1 </select> (maxY), <select size="1" name="jsX" id="jsX" onchange="init()"> <option value="-1">-1 <option value="-0.9">-0.9 <option value="-0.8">-0.8 <option value="-0.7">-0.7 <option value="-0.6">-0.6 <option value="-0.5">-0.5 <option value="-0.4">-0.4 <option value="-0.3">-0.3 <option value="-0.2">-0.2 <option value="-0.1">-0.1 <option value="0">0 <option value="0.1">0.1 <option value="0.2">0.2 <option value="0.25">0.25 <option value="0.275">0.275 <option value="0.28">0.28 <option value="0.285" selected>0.285 <option value="0.29">0.29 <option value="0.295">0.295 <option value="0.3">0.3 <option value="0.4">0.4 <option value="0.5">0.5 <option value="0.6">0.6 <option value="0.7">0.7 <option value="0.8">0.8 <option value="0.9">0.9 <option value="1">1 </select> (dX), <select size="1" name="jsY" id="jsY" onchange="init()"> <option value="-1">-1 <option value="-0.9">-0.9 <option value="-0.8">-0.8 <option value="-0.7">-0.7 <option value="-0.6">-0.6 <option value="-0.5">-0.5 <option value="-0.4">-0.4 <option value="-0.3">-0.3 <option value="-0.2">-0.2 <option value="-0.1">-0.1 <option value="-0.09">-0.09 <option value="-0.08">-0.08 <option value="-0.07">-0.07 <option value="-0.06">-0.06 <option value="-0.05">-0.05 <option value="-0.04">-0.04 <option value="-0.03">-0.03 <option value="-0.02">-0.02 <option value="-0.01">-0.01 <option value="0">0 <option value="0.01" selected>0.01 <option value="0.02">0.02 <option value="0.03">0.03 <option value="0.04">0.04 <option value="0.05">0.05 <option value="0.06">0.06 <option value="0.07">0.07 <option value="0.08">0.08 <option value="0.09">0.09 <option value="0.1">0.1 <option value="0.2">0.2 <option value="0.3">0.3 <option value="0.4">0.4 <option value="0.5">0.5 <option value="0.6">0.6 <option value="0.7">0.7 <option value="0.8">0.8 <option value="0.9">0.9 <option value="1">1 </select> (dY) <input type="button" value="сброс" onclick="reloadMe()"> <input type="button" value="записать" onclick="writeMe()"> </form> <div id="juliaResults"></div> <script type="text/javascript"> var maxIterations; //количество итераций var width, height, context; //размеры канвы и контекст var minX,maxX,minY,maxY,jsX,jsY; //коэффициенты //0.01 function getMapCoeffs (x, t1, t2, s1, s2) { var f = (x - t1) / (t2 - t1); var g = f * (s2 - s1) + s1; return g; } function getColor (c) { var r, g, b, p = c / 32, l = ~~( p * 6 ), o = p * 6 - l, //~~ - это двойное побитовое "не" q = 1 - o; switch( l % 6 ) { case 0: r = 1; g = o; b = 0; break; case 1: r = q; g = 1; b = 0; break; case 2: r = 0; g = 1; b = o; break; case 3: r = 0; g = q; b = 1; break; case 4: r = o; g = 0; b = 1; break; case 5: r = 1; g = 0; b = q; break; } var c = "#" + ( "00" + ( ~~( r * 255 ) ).toString( 16 ) ).slice( -2 ) + ( "00" + ( ~~( g * 255 ) ).toString( 16 ) ).slice( -2 ) + ( "00" + ( ~~( b * 255 ) ).toString( 16 ) ).slice( -2 ); return (c); } function drawFractal() { var a, as, za, b, bs, zb, count, clr; for (var j = 0; j < height; j++) { for (var i = 0; i < width; i++ ) { a = getMapCoeffs (i, 0, width, minX, maxX); b = getMapCoeffs (j, 0, height, minY, maxY); count = 0; while (++count < maxIterations) { za = a * a; zb = b * b; if (za + zb > 4) break; as = za - zb; bs = 2 * a * b; a = as + jsX; b = bs + jsY; } if (count < maxIterations) { context.fillStyle = getColor (count); } context.fillRect (i, j, 1, 1); //рисуем точку } } } function init() { maxIterations = parseInt(document.juliaForm.maxIterations.value); if (maxIterations === 'undefined') maxIterations=450; canvasSize = parseInt(document.juliaForm.canvasSize.value); if (canvasSize === 'undefined') canvasSize=600; minX = parseFloat(document.juliaForm.minX.value); if (minX === 'undefined') minX=-0.5; maxX = parseFloat(document.juliaForm.maxX.value); if (maxX === 'undefined') maxX=0.5; minY = parseFloat(document.juliaForm.minY.value); if (minY === 'undefined') minY=-0.5; maxY = parseFloat(document.juliaForm.maxY.value); if (maxY === 'undefined') maxY=0.5; jsX = parseFloat(document.juliaForm.jsX.value); if (jsX === 'undefined') jsX=0.285; jsY = parseFloat(document.juliaForm.jsY.value); if (jsY === 'undefined') jsY=0.01; if (document.getElementById("juliaCanvas")) { document.body.removeChild (document.getElementById("juliaCanvas")); } var canvas = document.createElement("canvas"); canvas.setAttribute("id", "juliaCanvas"); width = height = canvasSize; canvas.width = width; canvas.height = height; context = canvas.getContext("2d"); context.fillStyle = "black"; context.fillRect (0, 0, width, height); document.body.appendChild( canvas ); drawFractal(); if (document.getElementById("juliaResults").innerHTML!='') writeMe(); } function reloadMe() { document.juliaForm.maxIterations.value = 450; document.juliaForm.canvasSize.value = 600; document.juliaForm.minX.value = -0.5; document.juliaForm.maxX.value = 0.5; document.juliaForm.minY.value = -0.5; document.juliaForm.maxY.value = 0.5; document.juliaForm.jsX.value = 0.285; document.juliaForm.jsY.value = 0.01; document.getElementById("juliaResults").innerHTML = ''; init(); return false; } function writeMe() { document.getElementById("juliaResults").innerHTML = 'Итераций: ' + document.juliaForm.maxIterations.value + ', ' + 'Размер канвы: ' + document.juliaForm.canvasSize.value + ', ' + 'Коэффициенты: ' + document.juliaForm.minX.value + ', ' + document.juliaForm.maxX.value + ', ' + document.juliaForm.minY.value + ', ' + document.juliaForm.maxY.value + ', ' + document.juliaForm.jsX.value + ', ' + document.juliaForm.jsY.value; } init(); </script> <noscript>Извините, требуется включённый Javascript для работы приложения!</noscript> </div></body></html>
Место для сохранения интересных конфигураций:
Итераций: 450, Размер канвы: 600, Коэффициенты: -0.9, 0.3, -0.7, 0.9, -0.6, -0.6 Итераций: 800, Размер канвы: 800, Коэффициенты: 0.2, 0.8, -0.7, -0.5, 0.25, -0.5 Итераций: 800, Размер канвы: 800, Коэффициенты: 0.2, 0.8, 0.2, 0.8, 0.28, 0.01
12.10.2017, 14:28 [4312 просмотров]