Pull to refresh

www.contextfreeart.org — программирование на службе искусства

Reading time2 min
Views1.6K
Пост тем, кто хочет немножко отвлечься от работы и поразвлекаться с умом.

Сегодня наткнулся на интересный проект: contextfree

Все помнят курс теории компиляторов с университета? contextfree — генератор изображений на основе контекстно-свободных грамматик. Терминалами выступают простые графические примитивы (CIRCLE, SQUARE, TRIANGLE и т.д.). Нетерминалы задаем мы. Правила вывода могут включать в себя так называемые преобразования (повернуть, отразить, сдвинуть, поменять цвет). На основе этой простой модели можно получать очень интересные вещи… буквально несколькими строчками кода.

Начнем с простого примера:
startshape JustASquare //Начальный символ грамматики

background { b -1 } //Здесь мы задаем фон. b -1 - означает преобразование
//По умолчанию фон белый (brightness = 1), мы изменяем brightness до 0.

rule JustASquare { // Здесь мы задаем простое правило.
SQUARE { b 1 r 45 } // Белый квадрат, повернутый на 45 градусов.
}




Давайте попробуем что-нибудь посложнее. Что-нибудь рекурсивное.
startshape Circles
background { b -1 }

rule Circles {
CIRCLE { b 1 } //Кружочек белого цвета
CIRCLE { s 0.7 } //Кружочек черного цвета поменьше (s - масштаб), чтобы получилось кольцо.
Circles { x 1 s 0.9 r 30 } //А вот и реализация рекурсии. Правило вывода включает нетерминал.
//Явного выхода из рекурсии нет, поэтому рендериться будет до тех пор
//пока это еще полезно — пока не займет один пиксель на экране.
}


Заметьте, всего несколько строк, а уже что-то красивое :)

Давайте реализуем с вами простейшее рекурсивное дерево. На нем я покажу, что правил вывода с одинаковыми левыми частями может быть несколько, тогда они выбираются случайно на основании «веса» правила.
startshape begin

background { b -1 }

rule begin {
tree { b 1 }
}

rule tree { //Это правило в одиночестве нарисует завитушку.
CIRCLE { s 1 2 }
tree { y 1 s 0.99 r 7 b -0.005}
}

rule tree 0.2 { //А это иногда заставляет завитушку виться в другую сторону. Число 0.2 - и есть "вес" правила.
tree { flip 90 }
}

rule tree 0.1 { //Это правило добавляет ветвление.
tree { r 10 }
tree { s 0.5 r -20 }
}


С кодом разобраться уже чуть сложнее, но кому интересно, просто попробуйте… И очень быстро вы разберетесь.

Ну и наконец то, что получилось у меня… не очень оригинально, но писал сам, никуда не подглядывая :)
startshape begin

background { b -1 }

rule begin {
tree { x 10 }
}

rule tree {
branch {}
}

rule branch {
CIRCLE { s 0.5 2 b .4 h 120 saturation .7}
branch { y 1 s 0.97 r 3 b -.2 }
}

rule branch 0.1 { //реализация нашего дерева
branch { flip 90 }
}

rule branch 0.3 {
branch { r 3 }
branch {s 0.5 r -30}
}

rule branch 0.01 {
branch2 {}
}

rule branch2 { //Ветвь без ответвлений
CIRCLE { s 0.5 2 b .4 h 120 saturation .7}
branch2 { y 1 s 0.99 r 3 b -.2 }
}

rule branch2 0.1 {
branch2 { flip 90 }
}

rule branch2 0.01 { //Заканчивается цветком
Rose { s 5 }
}

rule Rose { //Подобие цветка, полученное просто спиралевидным закручиванием окружностей..как в нашем втором примере
CIRCLE { b 0.5 saturation 0.7 }
CIRCLE { b 1 s 0.8 saturation 0.7}
Rose { r 45 x 0.5 s 0.95 }
}

На картинку можно кликнуть, чтобы рассмотреть поближе.


Вот такая вот интересная программа.
У нее есть очень маленькая вики.
И фронтэнд на ruby+gnome.

Вот собственно и все. Творческих вам успехов!

P.S. Подумываю написать про shoes — фреймворк для создания легких GUI для Ruby от известного маньяка _why. Возможно в статье мы реализуем простенький кроссплатформенный GUI для contextfree. А может и что-то другое. Посмотрим.
Tags:
Hubs:
Total votes 73: ↑72 and ↓1+71
Comments44

Articles