Основные 2D

advertisement
Компьютерная графика
Основные 2D-примитивы
Jordi Linares i Pellicer
Escola Politècnica Superior d’Alcoi
Dep. de Sistemes Informàtics i Computació
jlinares@dsic.upv.es
http://www.dsic.upv.es/~jlinares
Режимы визуализации
•
•
•
•
•
В processing есть несколько режимов визуализации:
JAVA2D, P2D, P3D и OPENGL
Есть и другие возможности в специальных библиотеках
(например, метод трассировки лучей)
Режим визуализации определяется третьим аргументом
функции size(). Режим по умолчанию, если ничего не
указано, JAVA2D.
Режимы JAVA2D и P2D поддерживают двухмерное
представление. P2D более производителен (аппаратное
ускорение), но в нём пока ещё не реализованы все
функции из JAVA2D.
Мы будем использовать режим по умолчанию, JAVA2D,
так как в нём есть все 2D-функции
Система координат в 2D
окна определяется в функции
• Размер
size(), обычно это одно из первых
действий, происходящих в
функции setup()
• Точка(0,0)лежит слева вверху,
положительное направление оси
x — слева направо, оси y —
сверху вниз
Основные 2D-примитивы в
processing
• Точки
• Линии
• Эллипсы / Окружности / Дуги
• Прямоугольники
• Треугольники
• Четырёхугольники
• Кривые (Безье и Кэтмул-Рома)
• Объекты (свободные формы)
Цвет и настройки
В processing многие функции вызывают изменение состояния =>
они устанавливают параметры, которые будут оставаться
активными, пока мы их не поменяем. Пример: stroke() =>
меняет цвет кисти до тех пор, пока новый цвет не будет задан
•
Цвет кисти можно менять функцией stroke()
stroke(255) => RGB(255, 255, 255), один цвет означает параметр
внутри 256-значной серой шкалы (grayscale)
stroke(128, 0, 128) => Любой цвет в RGB
Толщина кисти указывается функцией strokeWeight()
strokeWeight(5) => Толщина в 5 пикселей
Цвет заполнения 2D-фигуры указывается функцией fill()
fill(128) => RGB(128, 128, 128)
fill(200, 120, 90) => RGB(200, 120, 90)
•
•
•
•
•
•
•
Цвет и настройки
background()
окно и заполняет указанным цветом
• Стирает
Примеры:
background(0)
•
background(128, 100, 128)
noFill()
•
2D-фигуры не будут заполнены
noStroke()
•
2D-фигуры не будут иметь внешней границы
(особенно полезно для замкнутых фигур, но
влияет на все виды фигур, даже на линии)
Точки
point(x, y)
Рисует точку в координатах (x, y)
Цвет задаётся stroke(), а толщина (размер) - функцией
strokeWeight()
•
•
set(x, y, color)
Рисует точку в координатах (x, y) с определённым цветом
Не учитывает stroke() или strokeWeight()
Пример:
set(50, 50, color(128, 120, 255))
•
•
•
•
Другие применения set (в следующих уроках будет подробнее)
Функция set может переместить изображение в (x, y)
set может быть применена к изображению
•
•
Линии
line(x1, y1, x2, y2)
Рисует линию между точками (x1, y1) и (x2, y2)
С помощью функции stroke мы можем определить их свойства
Пример:
•
•
•
size(100, 100);
background(0);
stroke(255);
strokeWeight(5);
line(0, 0, 99, 99);
size(200, 200);
background(0);
for (int i=0; i<100; i++) {
stroke(random(255), random(255), random(255));
strokeWeight(random(10));
line(0, 0, random(200), random(200));
}
Линии
•
Окончание линии
ROUND (скруглённое), PROJECT (линия удлиняется
в зависимости от толщины кисти), SQUARE (квадратное)
Пример:
•
•
size(100, 100);
background(0);
stroke(255);
strokeWeight(10);
strokeCap(ROUND);
line(50,50,150,50);
strokeCap(PROJECT);
line(50,75,150,75);
strokeCap(SQUARE);
line(50,100,150,100);
Эллипсы и окружности
ellipse(x, y, width, height)
Рисует эллипс в точке с координатами (x, y) с указанными
шириной и высотой
•
ellipseMode()
Меняет интерпретацию параметров эллипса
ellipseMode(CENTER) => (x, y) - центр эллипса (режим
по умолчанию).
ellipseMode(RADIUS) => как в предыдущем случае, но
ширина и высота — радиусы, а не диаметры
ellipseMode(CORNER) => (x, y) определяет верхний левый угол
ограничивающего эллипс прямоугольника (bounding box).
ellipseMode(CORNERS) => четыре параметра определяют
координаты противоположных углов ограничивающего
прямоугольника
•
•
•
•
•
Эллипсы и окружности
•
Пример:
size(200, 200);
background(0);
stroke(255, 0, 0);
strokeWeight(5);
fill(0, 255, 0);
// (x, y) и диаметры
ellipse(100, 100, 100, 50);
// 2 противоположных угла
ellipseMode(CORNERS);
ellipse(0, 0, 50, 50);
Дуги
arc(x, y, width, height, start, end)
Рисует дугу как сектор эллипса с координатами (x, y) и с
указанными шириной и высотой. Этот фрагмент или сектор
определяется углами, заданными как start и end
(в радианах по умолчанию) по часовой стрелке
Их параметры тоже интерпретируются подобно ellipseMode()
В processing заполнение фигур происходит по умолчанию, даже
для незамкнутых фигур. Функция noFill() должна быть вызвана
явно, если заполнение нежелательно
Пример:
•
•
•
•
size(200, 200);
background(0);
stroke(255, 0, 0);
strokeWeight(5);
fill(0, 255, 0);
// (x, y) и диаметры
arc(100, 100, 100, 100, 0, PI / 2.0);
// Не заполнять
noFill();
arc(100, 100, 100, 100, PI, 3 * PI / 2.0);
Прямоугольники
rect(x, y, width, height)
Рисует прямоугольник
•
rectMode()
Меняет интерпретацию параметров прямоугольника
Параметры те же, что и у эллипса: CENTER , RADIUS,
CORNER и CORNERS
Режим по умолчанию - CORNER (x и y — координаты левого
угла)
•
•
•
Треугольники и
четырёхугольники
triangle(x1, y1, x2, y2, x3, y3)
Рисует треугольник по трём вершинам
•
quad(x1, y1, x2, y2, x3, y3, x4, y4)
Рисует четырёхугольник. Первая точка - (x1, y1), остальные 3
вершины определены по часовой или против часовой стрелки
(любым из вариантов)
•
size(200, 400);
background(0);
stroke(255, 0, 0);
strokeWeight(5);
fill(0, 255, 0);
// (100,25) - (25,175) - (175,175)
triangle(100,25,25,175,175,175);
// По часовой
// (38,231) - (186,220) - (169,363) - (30,376)
quad(38, 231, 186, 220, 169, 363, 30, 376);
Практика 2-1
Представление тригонометрических функций
•
•
•
•
•
Нарисуйте функции синуса и косинуса, значения от 0 до 2*pi радиан
(0,0) в декартовых координатах находится в x=0 и y=height/2 в
координатах окна (слева с краю, с середины)
Путь от 0 до 2*pi должен занять большую часть окна
Запрограммируйте функцию, которая рисует синус, другую для
косинуса.
Входные параметры — цвет, толщина кисти и ширина и высота окна
На заднем плане нарисуйте координатную декартову ось.
Кривые Безье
bezier(x1, y1, cx1, cy2, cx2, cy2, x2, y2)
•
•
•
Кубические кривые (имеют точку перегиба)
Называются в честь инженера и математика Пьера Безье
Определяются через 4 точки:
Первая и последняя — начальная и конечная
точка кривой
Центральные точки — контрольные точки, и они
«притягивают» кривую, изменяя её, но не заставляя
проходить через них
•
•
Кривые Безье
void setup()
{
size(400, 400);
background(0);
// Рисуем две кривые Безье
drawBezier(100,140,50,40,350,40,300,140);
drawBezier(50,290,150,190,200,390,350,290);
}
void drawBezier(int x1, int y1,
int cx1, int cy1,
int cx2, int cy2,
int x2, int y2)
{
noFill();
stroke(255);
// Сама кривая Безье
bezier(x1, y1, // Начальная точка
cx1, cy1, // Контрольная точка 1
cx2, cy2, // Контрольная точка 2
x2, y2); // Конечная точка
// Нарисуем контрольные точки, чтобы
// лучше понять их влияние
strokeWeight(3);
stroke(255,0,0);
point(x1, y1); point(x2, y2);
point(cx1, cy1); point(cx2, cy2);
strokeWeight(1);
line(x1, y1, cx1, cy1);
line(x2, y2, cx2, cy2);
}
Кривые Кэтмулл-Рома
•
•
•
•
curve(cx1, cy1, x1, y1, x2, y2, cx2, cx2)
Их ввели Эдвин Катмулл и Рафи Ром
Полезно, чтобы сделать кривую, интерполируемую
множеством точек и очень полезно для компьютерной
графики - например, для анимации с ключевыми кадрами
(keyframe animation)
curve рисует кривую от (x1, y1) до (x2, y2). Первая
контрольная точка определяет кривизну в (x1, y1).
Последняя контрольная точка определяет кривизну в
(x2, y2).
Особенно интересны внутри «фигур» - свободных форм,
где могут быть определены коллекции вершин.
Кривые Кэтмулл-Рома
size(175, 125);
background(0);
noFill();
stroke(255);
curve(25, 25, // Контрольная точка 1
125, 25, // (x1, y1)
125, 75, // (x2, y1)
25, 75); // Контрольная точка 2
// Нарисуем все точки, чтобы лучше понять, как
// это всё работает.
strokeWeight(3);
stroke(255, 0, 0);
point(125, 25); point(125, 75);
point(25, 25); point(25, 75);
strokeWeight(1);
line(25, 25, 125, 25);
line(125, 75, 25, 75);
Фигуры
•
•
•
•
•
В processing можно рисовать свободные и сложные
формы простым перечислением их вершин
Основной примитив - vertex(x, y) , который
определяет одну из вершин фигуры
Чтобы начать фигуру, нужно вызвать beginShape().
Потом через vertex() определяются вершины.
Фигуру можно завершить вызовом endShape() .
Потрясающая гибкость: между вызовами beginShape()
и endShape()может быть любой код (вызовы функций,
циклы и пр.) для управления заданием вершин.
Однако, не любая функция может быть использована
между beginShape() и endShape() . Это касается
rotate(), scale() и translate(), об этом будет
дальше отдельно.
Фигуры
•
•
•
Когда beginShape() вызывается без аргументов, она позволяет
определять полилинии.
Если параметр CLOSE определён внутри endShape() , полилиния
автоматически замкнётся: последняя вершина соединится с первой
Пример:
size(200, 200);
background(0);
// Фигуры также могут быть охарактеризованы
// с помощью функций fill и stroke.
// По умолчанию фигуры заполнены, и,
// чтобы это отключить, используется noFill().
noFill();
stroke(255);
// Полилиния
beginShape();
// Теперь мы можем определить вершины ...
vertex(25, 25);
vertex(175, 25);
vertex(175, 175);
vertex(25, 175);
// Конец фигуры
endShape();
Фигуры
•
С параметром CLOSE фигура будет замкнута:
// Полилиния
beginShape();
// Теперь мы можем задать вершины ...
vertex(25, 25);
vertex(175, 25);
vertex(175, 175);
vertex(25, 175);
// Конец фигуры
endShape(CLOSE);
Фигуры
•
Можно передать аргумент в функцию beginShape()
и задать другую интерпретацию вершин:
•
•
•
•
•
•
•
POINTS. Вершины рисуются как множество точек
LINES. Вершины, по парам, задают линии
TRIANGLES. Вершины, группами по 3, задают
треугольники.
TRIANGLE_STRIP. Лента треугольников.
TRIANGLE_FAN. Веер треугольников.
QUADS. Вершины, группами по четыре, задают
четырёхугольники.
QUAD_STRIP. Лента четырёхугольников.
Фигуры
// Точки
beginShape(POINTS);
// Теперь мы определяем вершины ...
vertex(25, 25);
vertex(175, 25);
vertex(175, 175);
vertex(25, 175);
// Конец фигуры
endShape();
// Линии
beginShape(LINES);
// Теперь мы определяем вершины ...
vertex(25, 25);
vertex(175, 25);
vertex(175, 175);
vertex(25, 175);
// Конец фигуры
endShape();
Фигуры
// Треугольники
beginShape(TRIANGLES);
// Теперь мы определяем вершины ...
vertex(25, 25);
vertex(50, 175);
vertex(125, 40);
vertex(125, 150);
vertex(120, 60);
vertex(180, 190);
// Конец фигуры
endShape();
// Четырёхугольники
beginShape(QUADS);
// Теперь мы определяем вершины ...
vertex(25, 25);
vertex(50, 175);
vertex(125, 150);
vertex(115, 40);
vertex(130,
vertex(190,
vertex(195,
vertex(140,
60);
70);
150);
190);
// Конец фигуры
endShape();
Фигуры
TRIANGLE_STRIP
QUAD_STRIP
TRIANGLE_FAN
(Последняя точка должна повторяться)
Фигуры
•
•
•
•
Кроме определения вершин с помощью vertex()
в processing есть функции curveVertex()и
bezierVertex(), рисующие кривые вместо прямых
линий
Эти функции работают только с непараметрической
версией beginShape()
С этими функциями можно создать цепочку кубических
кривых Безье или Кэтмулл-Рома: bezierVertex()
или curveVertex()
Их можно комбинировать с функцией vertex() и
последовательно создавать сложные функции
Фигуры
curveVertex(x, y)
•
•
•
•
Функция curveVertex() задаёт кривую Кэтмул-Рома,
которая может интерполировать любое множество точек
Первая и последняя точки, заданные curveVertex() ,
расцениваются как контрольные, и определяют начальную
и конечную кривизну цепочки кривых.
Внутренние точки будут входить в интерполяцию
множеством кубических кривых
Должны быть заданы как минимум 4 вершины через
функцию curveVertex(), внутри beginShape() и
endShape()
Фигуры
size(400, 400);
background(0);
noFill();
stroke(255);
// Полилиния
beginShape();
// Теперь мы определяем вершины ...
curveVertex(0, 0);
for (int i = 0; i < 20; i++)
{
int x = (int)random(400), y = (int)random(400);
curveVertex(x, y); // Точка кривой
rect(x-2, y-2, 4, 4); // Мы рисуем их, чтобы было проще воспринимать
}
curveVertex(width-1, height-1);
// Конец фигуры
endShape();
Фигуры
bezierVertex(cx1, cy1, cx2, cy2, x, y)
•
•
•
•
В цепочке кривых Безье первая точка кривой должна
быть определена с помощью функции vertex()
Каждый вызов bezierVertex() после первой вершины
определит две новые контрольные точки и опорную точку
Опорная точка будет начальной точкой в случае новых
вызовов bezierVertex()
Последняя точка кривой Безье будет первой точкой у
следующей. Чтобы обеспечить гладкость (непрерывность)
в месте соединения, эти точки должны лежать на одной:
последняя контрольная точка первой кривой, первая
контрольная точка второй кривой и конечная
и начальная точки кривых (на самом деле — одна и та же)
Фигуры
size(300, 200);
background(0);
noFill();
stroke(255);
// Полилиния
beginShape();
vertex(10,100); // Первая точка кривой
bezierVertex(70, 140, 160, 140, 150, 100);
bezierVertex(140, 60, 210, 60, 290, 100);
// // Конец фигуры
endShape();
// Рисуем точки, чтобы результат
// был лучше виден
strokeWeight(5);
// Точки кривой
stroke(255);
point(10, 100); point(150, 100); point(290, 100);
// Контрольные точки
stroke(255, 0, 0);
point(70, 140); point(160, 140);
point(140, 60); point(210, 60);
// Контрольные точки по линии...
strokeWeight(1);
line(160, 140, 140, 60);
Фигуры
// Создание сложных фигур
// путём комбинирования линейных и
// кривых функций.
size(400, 300);
background(0);
stroke(255);
noFill();
// Полилиния
beginShape();
vertex(10, 10);
vertex(150, 10);
bezierVertex(175, 200, 225, 200, 250, 10);
vertex(390, 10);
vertex(390, 290);
vertex(10, 290);
vertex(10, 10);
endShape();
Практика 2-2
код Практики 1-1 с
• Перепишите
использованием фигур,
чтобы нарисовать n-сторонний
многоугольник
Практика 2-3
•
•
•
•
•
•
•
В целях статистики необходимо строить круговую диаграмму
значений в процентах
Элементы лежат в массиве, и их сумма равна 100%
Пример:
float[] values = {25.0, 45.0, 5.0, 15.0, 10.0};
Напишите функцию, получающую этот массив
на входе и отображающую эту информацию
в виде круговой диаграммы
Функция на входе также получает центр и
радиус диаграммы
Функция может узнать число элементов
массива из атрибута length
Выберите случайный цвет для каждого сектора
Практика 2-4
•
•
•
Напишите функцию, аналогичную функции из Практики 2-3,
но теперь рисующую двухмерную столбчатую диаграмму.
Возьмите максимально большой размер экрана и нарисуйте
координатные оси
Ширина столбца будет функцией от
общего числа величин и ширины окна;
высота столбца — функцией значения
соответствующей ему величины и
максимального значения среди всех
величин, учитывая, что высота
столбца с максимальной величиной
должна быть равна высоте окна.
Download