После примерно полутора часов мне удалось получить случайно сформированные треугольники различных цветов.

Случайные треугольники
В рамках урока нас просили не останавливаться, пока не получится то, чем мы будем действительно довольны – играть с формой, размером и цветом.
Во время долгой поездки я мысленно прокручивал в голове всякие идеи, и решил сделать так, чтобы все эти треугольники были связаны друг с другом и не дублировались. Перед началом проекта мы обсуждали данную концепцию, но пришли к выводу: это слишком сложно сделать, учитывая, что мы всего лишь 3 часа изучаем p5.js. Я посмотрел библиотеки, которые реализовывали эту концепцию, но решил создать свое собственное решение для практики. Во время поездок мне сложно рисовать, но как только я смог остановиться, я набросал это:

Набросок, который я сделал после долгой поездки, о том, как я мог бы подойти к выполнению этой концепции
Что если вместо случайных координат для создания треугольников я мог бы:
- настроить сетку на канвас (плоскость)
- случайным образом расположить точки в этой сетке
- сохранить координаты в массиве
- затем систематически пройти через эти точки и начать использовать их для создания новых треугольников
В моей голове все выглядело так, будто избавление от рандома при формировании треугольника может сработать.
А теперь давайте посмотрим, как далеко я продвинулся в этом направлении, прежде чем понял, насколько глупо было думать, что это сработает.
Создание сетки.
Для того, чтобы я мог видеть отображение своих идей, я поместил сетку на канвас (поверхность):
function setup() { createCanvas( windowWidth, windowHeight ) colorMode( HSB ) noLoop() noStroke() } function draw() { background( 20, 20, 20) // Setup a grid so i can figure out the uppper and lower bounds // of where the points should go var columns = 5 var rows = 5 var columnWidth = windowWidth / columns var columnHeight = windowHeight / rows fill( 30, 30, 30) stroke( 90, 90, 90 ) rect( 0, 0, columnWidth, columnHeight ) // Create a row for ( i = 0; i < rows; i++ ){ // Create a column for ( j = 0; j < columns; j++ ){ rect( j * columnWidth, i * columnHeight, columnWidth, columnHeight ) } } }
И в итоге получается вот так. Для начала неплохо.

Сетка базовых линий
Генерация случайных точек.
Для того, чтобы сформировать случайные точки внутри каждой сетки, используя верхнюю и нижнюю границы, которые основаны на ширине и высоте столбца, я собираюсь создавать небольшие кружки. Просто, чтобы визуализировать то, где создаются точки.
Просто внутри цикла столбцов я написал:
for ( j = 0; j < columns + 1 ; j++ ){ rect( j * columnWidth, i * columnHeight, columnWidth, columnHeight ) //create my point var pointPositionX = random( j * columnWidth - columnWidth, j * columnWidth ) var pointPositionY = random( i * columnHeight - columnHeight, i * columnHeight ) circle( pointPositionX, pointPositionY, 10 ) }
и получил какие-то точки:

Визуализация координат
Сохранение координат в массивах.
Чтобы вернуться назад и сформировать треугольники, мне надо где-то хранить все эти координаты.
for ( i = 0; i < rows + 1; i++ ){ var columnData = [] // Create a column for ( j = 0; j < columns + 1 ; j++ ){ rect( j * columnWidth, i * columnHeight, columnWidth, columnHeight ) //create my point var pointPositionX = random( j * columnWidth - columnWidth, j * columnWidth ) var pointPositionY = random( i * columnHeight - columnHeight, i * columnHeight ) columnData.push( [pointPositionX, pointPositionY] ) console.log( columnData ) //circle( pointPositionX, pointPositionY, 10 ) } allCoordinates.push( columnData ) console.log( allCoordinates ) }
С тех пор, как я писал на JavaScript, прошло уже несколько лет, но он, кажется, все еще получается у меня легко. Вот то, что я вывел на консоль. Думаю, что у меня получилось сделать это близко к задуманному… за исключением отрицательных чисел.

Те цифры, которые почти кажутся правильными
Первый треугольник.
Да, те отрицательные числа были ошибкой. Иногда математика мне кажется странной – зачем я должен был бы вычитать из 0? Кто знает. Полагаю, мне казалось, что i и j были 1? Короче, я исправил это.
Я также не имею понятия, зачем мне понадобились два массива. Мне следовало просто сохранить все координаты в массив allCoordinates[].
Поэтому, как только все это было сделано, я захотел убедиться, что эти первые точки были сохранены так, как я хотел, и что из них можно сделать треугольник.
Вот как закончился этот код:
var allCoordinates = []; // Create a row for ( i = 0; i < rows + 1; i++ ){ // Create a column for ( j = 0; j < columns + 1 ; j++ ){ rect( j * columnWidth, i * columnHeight, columnWidth, columnHeight ) //create my point var pointPositionX = random( j * columnWidth + columnWidth, j * columnWidth ) var pointPositionY = random( i * columnHeight + columnHeight, i * columnHeight ) allCoordinates.push( [pointPositionX, pointPositionY] ) circle( pointPositionX, pointPositionY, 10 ) console.log(allCoordinates) } } // Create the first triangle fill( 90, 90, 90 ) var currentPoint = 0 var firstPointX = allCoordinates[0][0] var firstPointY = allCoordinates[0][1] var secondPointX = allCoordinates[1][0] var secondPointY = allCoordinates[1][1] var thirdPointX = allCoordinates[6][0] var thirdPointY = allCoordinates[6][1] triangle( firstPointX, firstPointY, secondPointX, secondPointY, thirdPointX, thirdPointY )
И результат:

Эй, первый треугольник находится в нужном месте!
Отлично! А теперь я должен сделать из этого цикл и пройти через каждую из них.
После 2 часов зависания моего браузера…
Я потратил достаточно времени, работая над тем, как прогнать каждую точку через массив и создать 2 треугольника для каждой точки. Я запутывался и перетасовывал все очень много раз, учитывая также то, что мне надо было знать, где что находится: в первой или последней строке, а может в последнем столбце – все было очень странно.
Наконец-то я добрался до того момента, где меня устраивал результат, и я знал, что, если бы я просто потратил еще один час на работу, я мог бы получить практически идеальный результат, но я был готов двигаться дальше и не заниматься перфекционизмом. Я не буду показывать промежуточный код, только визуальные результаты:

Да, есть недостающие треугольники, я просто не мог заставить себя исправить их прямо сейчас
Вернемся к художественной стороне всего этого дела.
Прежде чем насладиться тем, что я получил в конечном итоге, мне пришлось пройти несколько итераций, исправляя количество столбцов и строк, занимаясь креативным кадрированием и выбором цветов. Я становился все ближе к итоговому результату.

Все ближе к результату, который мне нравится
Окончательная визуализация и какой-то довольно неряшливый код.
В конце концов, рендер начал выдавать результаты все лучше и лучше, достаточно хорошие, чтобы я мог остановиться на данный момент.
Это окончательная визуализация:

Финальная визуализация, которую я сделал до того, как назвать ее, завершилась. Думаю, мне нравится!
И сам код на p5.js. Он не дочищен, но отражает процесс творческих мук. Наслаждайтесь!
function setup() { var canvas = createCanvas( 1600, 1600 ) canvas.parent("canvasArea"); colorMode( HSB ) noLoop() noStroke() } function draw() { background( 197, 31, 65 ) // Setup a grid so i can figure out the uppper and lower bounds // of where the points should go var columns = 20 var rows = 20 var columnWidth = 1600 / columns var columnHeight = 1600 / rows // Show the grid fill( 18, 11, 18 ) //stroke( 90, 90, 90 ) //rect( 0, 0, columnWidth, columnHeight ) var allCoordinates = []; // Create a row for ( i = 0; i < rows; i++ ){ // Create a column for ( j = 0; j < columns ; j++ ){ rect( j * columnWidth, i * columnHeight, columnWidth, columnHeight ) //create my point var pointPositionX = random( j * columnWidth + columnWidth, j * columnWidth ) var pointPositionY = random( i * columnHeight + columnHeight, i * columnHeight ) allCoordinates.push( [pointPositionX, pointPositionY] ) circle( pointPositionX, pointPositionY, 10 ) } } var whichRow = 1 var l = 1 while ( l < allCoordinates.length ){ //firstTriangle if (whichRow == 1 || whichRow == rows){ //don't do anything on the first and last row (thse need just one triangle) } else{ if ( (l + 1) % rows == 0 || l == 0){ console.log("it's the last item, do nothing") } else{ //Triangle 1 var colorChoices = [ [45, 15, 75], [22, 42, 95], [5, 55, 75], [0, 61, 95] ] var randomColorChoice = Math.floor(random(0,4)) fill( colorChoices[randomColorChoice][0], colorChoices[randomColorChoice][1], Math.floor(random(50,100)) ) //stroke( 200, 90, 90 ) var currentPoint = l var nextPoint = l + 1 var bottomPoint = l + rows var firstPointX = allCoordinates[currentPoint][0] var firstPointY = allCoordinates[currentPoint][1] var secondPointX = allCoordinates[nextPoint][0] var secondPointY = allCoordinates[nextPoint][1] var thirdPointX = allCoordinates[bottomPoint][0] var thirdPointY = allCoordinates[bottomPoint][1] triangle(firstPointX, firstPointY, secondPointX, secondPointY, thirdPointX, thirdPointY) //Triangle 2 randomColorChoice = Math.floor(random(0,4)) fill( colorChoices[randomColorChoice][0], colorChoices[randomColorChoice][1], Math.floor(random(50,100)) ) //stroke( 200, 90, 90 ) var currentPoint = l var nextPoint = l - rows var bottomPoint = l + 1 var firstPointX = allCoordinates[currentPoint][0] var firstPointY = allCoordinates[currentPoint][1] var secondPointX = allCoordinates[nextPoint][0] var secondPointY = allCoordinates[nextPoint][1] var thirdPointX = allCoordinates[bottomPoint][0] var thirdPointY = allCoordinates[bottomPoint][1] triangle( firstPointX, firstPointY, secondPointX, secondPointY, thirdPointX, thirdPointY ) } } l++ if ( l % rows == 0 ){ whichRow++ } } }
Если вы хотите попробовать еще что-то или начать с более простых проектов:
- Создание эффекта быстрого полета сквозь космос (или падающего снега) за 10 минут на p5.js
- Как воссоздать эффект муарового узора в библиотеке p5.js для новичка (быстрый гайд)
- Наложение 2d-текстуры на 3d-объект с использованием p5.js (часть 1 — создание паттерна)
- Наложение 2d-текстуры на 3d-объект с использованием p5.js (часть 2 — наложение паттерна на куб)
ссылка на оригинал статьи https://habr.com/ru/post/506268/
Добавить комментарий