Учебно рисуване с математика

Дори когато наистина искам да науча нов език за програмиране, рамка или инструмент, процесът на започване с него може да ми се стори като скучна работа. Но помага, когато наградата е висока, и помага още повече, ако можете да видите наградата бързо.

Това беше моят опит да се науча да правя фрактали в p5.js. С по-малко от 40 реда JavaScript код, вие също можете да направите свое собствено регулируемо и персонализирано фрактално дърво.

Препоръчвам да гледате и видеото на Coding Train за създаване на фрактални дървета.

Единственият ресурс, от който ще се нуждаете, за да започнете, е библиотеката p5 от уебсайта на p5. Връзката „p5.js complete“ ви дава библиотеката във файл с име p5.js, който можете да посочите в друг JavaScript файл, като го включите в главата на вашия HTML файл:

<script src='./p5.js'></script>
<script src='./index.js></script>

За да инструктираме p5 да нарисува изображение като това в горната част на тази статия, трябва да разделим частите на това, което се опитваме да изградим, и да попитаме...

Какво е фрактал?

Дори ако сме ги виждали много пъти преди, определението на Оксфорд помага да се изясни:

„Крива или геометрична фигура, всяка част от която има същия статистически характер като цялото.“

Преди да навлезем в подробностите, може вече да си представим, че каквито и команди да напишем могат да се повтарят, може би с някаква незначителна модификация или прогресивна миниатюризация, за да продължат да изобразяват все повече и повече по-малки части, които имат „същия статистически характер“ като тяхната родителска част.

Каква роля играе p5 в това?

P5 прави цялото чертане вместо нас.

Ние даваме само няколко p5 инструкции и ако ги напишем по такъв начин, че параметрите на инструкциите рекурсивно (самореферентно) да се променят, можем да накараме p5 да изпълнява голям брой операции, докато пише само няколко инструкции.

Време е да рисувате

Ако ще нарисуваме една от най-простите фрактални форми, дърво с клони върху клони върху клони, можем да започнем с рисуване на първия клон. Но първо, нека настроим нашия index.js файл:

function setup() {
    createCanvas(800, 600)
}

Можем да напишем това на първия ред. Както подсказва името, той създава нашето платно.

Следващия:

function draw() {
    background(0)
}

Setup() и draw() са първите две функции, които се появяват във всеки p5 файл.

Следващата важна функция е translate(). Инструкциите, които даваме за превод, са x и y-координати на екрана, указващи посоката и разстоянието, на което трябва да се движи виртуалната четка.

Важно е да следите позицията на четката, тъй като следващите движения се основават на движенията, направени преди. В рамките на функцията за рисуване можем да се позовем на ширината и височината на платното, за да намерим дъното по следния начин:

translate(width / 2, height)

Сега, когато сме в позиция, можем да начертаем линия с функцията line() с помощта на функцията stroke(), която определя цвета на нашата линия:

stroke(50, 50, 250)
line(0,0,0, -150)

Всичко това заедно ни дава една линия в долната част на нашето платно. Ако това, което сме начертали, е нашето първо разклонение и искаме да начертаем още разклонения, нека отделим това разклонение в неговата собствена функция и да го извикаме в нашата функция за рисуване.

Тъй като искаме да променим дължината на разклонението, функцията може да приеме аргумент с неговата дължина. Като цяло нашият код сега изглежда така:

За да начертаем следващия ред, трябва да започнем да рисуваме от края на последния ред под нов ъгъл. Ъгълът е дефиниран по отношение на pi, така че можем да добавим към нашата функция за рисуване по следния начин:

Обърнете внимание на втория път, когато превеждаме. Това ни отвежда до върха на клона. Оттам завъртаме ориентацията си на 45 градуса и рисуваме нов клон, който е 3/4 от дължината на последния.

Естественото нещо, което трябва да направим след това, е да начертаем следващия ни клон, който започва от същото място, както и последният.

Можем да преведем обратно там, но тогава, когато правим все повече и повече разклонения, ще трябва да превеждаме нагоре и надолу всяко разклонение, което ще стане много трудно за мащабиране. Ето защо следващият p5 инструмент е толкова полезен.

pop() и push()

Тези функции ни позволяват да рисуваме върху нашето платно, след което да се върнем обратно към предишната си позиция, преди да начертаем следващия елемент.

Следващият път ще завъртим противоположния ъгъл и ще начертаем същия клон в тази посока. Функцията за рисуване сега изглежда така:

Това ни дава два клона. На път сме! Но за да повторим тази функция, все пак трябва да преведем следващия клон нагоре, след това обратно надолу и обратно по следващия начин, за да начертаем още клони.

Това все още е много повтарящо се за изпълнение без силата на...

Рекурсия

Рекурсията ще ни помогне да изпълним всички наши последващи операции, без да записваме всяка една. Рекурсията е доста мощна - достатъчно мощна, че може да разбие кода ви, като се опита да работи вечно, ако не му дадете точка на прекъсване.

Избрах точка на прекъсване, когато дължината на разклонението достигне 1. Това отне на браузъра ми няколко секунди, за да стартира. Може да искате да зададете минималната дължина на 3 или 5 или по-висока в зависимост от скоростта на вашия компютър.

Чрез преместване на функциите push, pop, rotate и branch в нашата функция за разклоняване, нашият код сега изглежда така:

Което най-накрая изобразява първия ни фрактал:

Какво следва?

Ако сами сте изпълнявали този код, може би вече имате някои идеи как да експериментирате и персонализирате. Можете да промените ъгъла на въртене, дължината на клона, да добавите още клони, да промените цвета или да промените функцията много по-драстично.

Понякога може да се наложи да намалите минималната дължина, установена в оператора if, ако изобразяването отнема твърде много време.

По-долу е модифицирана версия на горния код с добавяне на плъзгач, който позволява на потребителя да променя ъгъла на живо в браузъра.

Забавлявайте се, като направите този проект ваш собствен. P5 е мощен инструмент и с малко познания за общите функционалности и поведението им вече сте добре поели.

За да стартирате този код, можете да го клонирате от моето GitHub repo.