Освой Processing играючи
/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000
Чтобы создавать красивые программы, нужно уметь рисовать фигуры. Начнём с основ. Сначала немного о системе координат. Нулевая точка окна в Processing находится в левом верхнем углу. Функция size() устанавливает размеры окна вашего скетча. Первый параметр присваивает значение встроенной переменной width (ширина), второй - встроенной переменной height (высота).
Для простых примеров мы пока временно не будем использовать функцию draw(), а весь код будем писать в функции setup().
Для рисования точки используется функция point(). Здесь также нужно указать два параметра - координаты точки.
Создадим окно размером 480 на 120 и поместим точку в центре (разделим размеры окна пополам).
void setup() {
size(480, 120);
point(240, 60);
}
Точка очень маленькая, разглядеть её сложно. Но вы постарайтесь. Зря что-ли старались.
Если вы хотите нарисовать точку в нижнем правом углу, то можете совершить ошибку, написав код.
point(480, 120);
На самом деле, нужно использовать координаты (479, 119), т.е. отнять единицу от размеров окна.
Чтобы нарисовать линию, нужно вызвать функцию line() c четырьмя параметрами - координаты начальной и конечной точки. А программа сама нарисует линию между ними. Разделим окно программы пополам. Удалим код для рисования точки, а вместо неё напечатаем другой код.
line(0, 60, 480, 60);
Получим следующую картинку.
Подумайте, как нарисовать вертикальную линию. А по диагонали?
А что если нарисовать много параллельных линий по вертикали и горизонтали через одинаковые промежутки? Тогда получим сетку. Чтобы не повторять один и тот же код много раз, создадим отдельную функцию для рисования сетки, а в ней применим два цикла. Код получится намного короче.
void setup()
{
size(500, 300);
}
void draw()
{
drawGrid();
}
void drawGrid()
{
stroke( 225 );
for ( int i = 0; i < 64; i++ ) {
line(i * 10, 0, i * 10, height );
}
for ( int i = 0;
i < 48;
i++ ) {
line( 0, i * 10, width, i * 10 );
}
}
А мы идём дальше и попробуем нарисовать треугольник. Для этого существует функция triangle() с шестью параметрами - координаты вершин треугольника. Наугад выбираем различные числа. Получился треугольник. Захотелось нарисовать рядом близнеца. Как это сделать? Чтобы сдвинуть второй треугольник вправо, прибавляем к параметрам, которые относятся к координате X, некоторое значение. Это будет смещением. Проверяем.
void setup()
{
size(480, 120);
triangle(10, 10, 100, 20, 40, 90);
// Сдвигаем второй треугольник вправо на 90 пикселей
triangle(10 + 90, 10, 100 + 90, 20, 40 + 90, 90);
}
void draw(){ }
Для многоугольников с четырьмя точками нужно уже восемь параметров. А функция называется quad().
void setup()
{
size(480, 120);
quad(20, 10, 30, 40, 90, 25, 20, 90);
}
void draw(){}
Мы могли бы с помощью этой функции нарисовать и прямоугольник. Но писать восемь параметров слишком утомительно. К счастью, Processing немного понимает в геометрии. Если указать только координату первой точки, а потом ширину и высоту, то дальше программа сама всё рассчитает и нарисует. Функция называется rect(). Проверим.
void setup()
{
size(480, 120);
rect(10, 10, 230, 100);
}
void draw(){}
Как нарисовать квадрат, вы сами догадаетесь.
Функция ellipse() нам уже знакома по первому уроку. Для рисования эллипса нужно указать центр, ширину и высоту. Стоит отметить, что можно указывать и отрицательные значения координат. Тогда может получиться, что в окне вы увидите только часть фигуры. Например, часть эллипса.
void setup()
{
size(480, 120);
ellipse(280, -100, 400, 400);
}
void draw(){}
Также можно нарисовать дугу (сектор) с помощью функции arc(). Опять указываем центр, а также ширину и высоту. И вдобавок указываем начальный и конечный угол в радианах. Но с радианами работать не очень удобно. Что будет если указать значения 0 и 2? Для величин 180, 45, 90 и 360 градусов можно использовать готовые константы в радианах: PI, QUARTER_PI, HALF_PI, TWO_PI. Попробуем несколько вариантов.
void setup() {
size(480, 120);
arc(50, 60, 170, 80, 0, 2);
arc(150, 60, 170, 80, 0, HALF_PI);
arc(350, 60, 170, 80, 0, PI + HALF_PI);
}
Если вам известно значение в градусах, то можете его перевести в радианы с помощью функции radians().
arc(90, 60, 80, 80, 0, radians(90));
Если вы рисуете много фигур, которые накладываются друг на друга, то сверху будет та фигура, чей код в вашей программе будет последним.
У фигур можно управлять толщиной линии и режимом сглаживания. По умолчанию, толщина линий составляет один пиксель. С помощью функции strokeWeight() вы можете изменить данное поведение. Толщину следует устанавливать до вывода фигуры. Если рисуете несколько фигур, то у каждой надо устанавливать толщину линий отдельно. Иначе у фигуры будет толщина, заданная для предыдущей фигуры.
strokeWeight(3);
ellipse(175, 60, 90, 90);
Функция strokeJoin() определяет вид соединения линий (углы), а функция strokeCap() - начальную и конечную точки линий.
strokeJoin(ROUND); // скруглить
strokeJoin(BEVEL); // сделать откос
strokeCap(SQUARE); // концы линий - квадратные
strokeCap(ROUND); // скруглить концы линий
За сглаживание отвечает функция smooth(). Существует парная ей функция noSmooth(), отключающая сглаживание.
Для цветов используются функции background(), fill(), stroke(), у которых нужно указать цвет в пределах от 0 (чёрный) до 255 (белый). Промежуточные величины будут оттенками серого. Можно отключить обводку (функция noStroke()) или сделать фигуру прозрачной функцией noFill():
void setup() {
size(480, 120);
smooth();
fill(153);
ellipse(130, 80, 150, 150);
noFill();
ellipse(228, -16, 200, 200);
noStroke();
ellipse(268, 118, 200, 200);
}
Также можно указывать цвет. В этом случае используются три параметра:
background(0, 26, 51); // темно-синий цвет
fill(255, 0, 0); // красный
Первая функция закрасит окно, вторая - фигуру, которая будет рисоваться после этой функции.
Можно использовать цветовую палитру через меню Tools | Color Selector.
Если добавить четвёртый параметр, то можно управлять прозрачностью.
Также можно нарисовать сложную фигуру, например, стрелку. Начните создание фигуры с функции beginShape(). Функция vertex() используется для определения x и y-координат фигуры. Функция endShape() ставится в конце описания фигуры и сигнализирует об окончании создания фигуры.
void setup() {
size(480, 120);
smooth();
beginShape();
vertex(180, 82);
vertex(207, 36);
vertex(214, 63);
vertex(407, 11);
vertex(412, 30);
vertex(219, 82);
vertex(226, 109);
endShape();
}
Когда вы запустите пример, вы увидите, что первая и последняя точки не соединены. Чтобы сделать это, добавьте слово CLOSE как параметр функции endShape():
endShape(CLOSE);
Преимущество использования функции vertex() для создания фигур заключается в возможности построения фигур со сложной структурой. Одна программа на Processing может нарисовать тысячи линий для отображения на экране самых невероятных фигур.
Нарисуем звезду. Для неё создадим отдельную функцию star().
void setup()
{
size( 400, 400 );
smooth();
frameRate(1);
}
void draw() {
translate(200, 200);
star(5, 90, 190);
}
void star( int numSpikes, float innerRadius, float outerRadius )
{
int numVertices = numSpikes * 2;
float angleStep = TWO_PI / numVertices;
beginShape();
for ( int i = 0; i < numVertices; i++ ) {
float x, y;
if ( i % 2 == 0 ) {
x = cos( angleStep * i ) * outerRadius;
y = sin( angleStep * i ) * outerRadius;
} else {
x = cos( angleStep * i ) * innerRadius;
y = sin( angleStep * i ) * innerRadius;
}
vertex( x, y );
}
endShape(CLOSE);
}
Функция звезды имеет три параметра: одно целое число для количества лучей и два параметра для внутреннего и внешнего радиуса звезды.
Добавим функцию для рисования цветка.
void flower( int numLeafs, float innerRadius, float outerRadius )
{
float angleStep = TWO_PI / numLeafs;
beginShape();
float startX = cos( 0 ) * innerRadius;
float startY = sin( 0 ) * outerRadius;
vertex( startX, startY );
for ( int i = 0; i < numLeafs; i++ ) {
float cx1 = cos( angleStep * i ) * outerRadius;
float cy1 = sin( angleStep * i ) * outerRadius;
float x2 = cos( angleStep * (i + 1) ) * innerRadius;
float y2 = sin( angleStep * (i + 1) ) * innerRadius;
float cx2 = cos( angleStep * (i + 1) ) * outerRadius;
float cy2 = sin( angleStep * (i + 1) ) * outerRadius;
bezierVertex( cx1, cy1, cx2, cy2, x2, y2 );
}
endShape( CLOSE );
}
Вызовем вместо звезды.
void draw() {
translate(200, 200);
flower(5, 90, 190);
}
А теперь нарисуем звёзды и цветы вместе.
void draw() {
background( 0 );
noStroke();
for ( int i = 0; i < 75; i++ ) {
int numPoints = floor( random( 4, 8 ) );
float innerRadius = random( 20, 40 );
float outerRadius = random( 50, 100 );
pushMatrix();
translate( random( width ), random( height ) );
if ( random( 100 ) < 50 ) {
fill( 255, 255, 0, 64 );
star( numPoints, innerRadius, outerRadius );
} else {
fill( 255, 0, 0, 64 );
flower( numPoints, innerRadius, outerRadius );
}
popMatrix();
}
}
Мы получим анимацию из множества фигур. На скриншоте один из кадров.
На главную страницу Processing