Компьютерная графика Преобразования на плоскости 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 Преобразования на плоскости • • • Геометрические преобразования на плоскости необходимы для трансформации и визуализации нашей модели. Основные аффинные преобразования: перенос, вращение и масштабирование Матрицы преобразований: Преобразования на плоскости • • Несколько преобразований могут быть скомбинированы в одно, чтобы определить более сложное преобразование. Например, вращение вокруг заданной точки (xc, yc): Преобразования на плоскости • • • • • • • В processing каждый графический примитив может быть преобразован через матрицу, ещё называемую матрицей моделирования (model/view) Определив эту матрицу, мы сможем перейти от системы координат нашей модели к системе координат окна, или сделать любое другое сложное преобразование. В самом начале матрица моделирования — это просто единичная матрица, никак не влияющая на графические примитивы Эти матрицы можно определить при помощи функций rotate(angle), translate(tx, ty) и scale(sx, sy) Их смысл — сделать матрицу моделирования равной произведению предыдущего значения этой матрицы и матрицы, определённой функцией (перенос, вращение или масштабирование). rotate(PI) =>M = M • rotate(PI) На практике это означает, что порядок, в котором мы пишем эти Функции — обратный тому, в котором они будут применены, то есть порядок применения будет снизу вверх. Преобразования на плоскости • Пример: // Вращение вокруг заданной точки int xc, yc; size(300, 300); // Давайте вращать вокруг середины окна xc = width / 2; yc = height / 2; // Мы должны определить матрицы в обратном // порядке относительно того, как они будут // влиять на нашу модель translate(xc, yc); rotate(PI / 4.0); translate(-xc, -yc); // Сейчас мы нарисуем эллипс с центром // в (xc, yc), с горизонтальным диаметром // 100 и вертикальным диаметром 200. // В результате получится эллипс, повёрнутый на // 45 градусов вокруг своего центра. ellipse(xc, yc, 100, 200); Практика 4-1 • Измените код практики 2-1 (тригонометрические функции) так, чтобы система координат менялась с [0,2*PI] на [0, width] и от [-1, +1] до [height, 0], через определение подходящих матриц моделирования. • Измените код практики 3-1 чтобы показать изображение в его максимальном пропорциональном размере в пределах окна, через определение подходящих матриц моделирования Преобразования на плоскости Другие функции, связанные с матрицей моделирования: resetMatrix() Сбрасывает матрицу моделирования, делая её единичной матрицей • pushMatrix() popMatrix() В processing есть вещь, известная как стек матриц Когда вызвана pushMatrix() , текущая матрица моделирования кладётся в этот стек (не теряя свои значения) Когда вызвана popMatrix(), текущая матрица моделирования является вершиной стека. Она берётся из стека. В цепочке преобразований (серии вызовов translate(), scale() или rotate()) pushMatrix() может быть вызвана на любом промежуточном шаге, к которому мы хотим вернуться через popMatrix() Вызовов функции pushMatrix() должно быть столько же, сколько popMatrix() • • • • • Преобразования на плоскости // Пример использования // pushMatrix() и popMatrix() size(300, 300); noFill(); background(0); stroke(255); // Первый переход в новую систему // координат: // Перемещаем (0,0) в центр окна translate(width / 2, height / 2); // В этой системе координат // рисуем эллипс в середине окна ellipse(0, 0, 100, 200); // Сохраняем первую систему // координат pushMatrix(); // Вторая система координат: // Дополнительно к предыдущим изменениям, // мы применяем вращение: rotate(PI / 4.0); // Рисуем тот же самый эллипс, // но сейчас на него будут влиять // два предыдущих // преобразования ellipse(0, 0, 100, 200); // Возвращаемся к первой // системе координат popMatrix(); // Рисуем снова. // Теперь только фигуру // после первого переноса rectMode(CENTER); rect(0, 0, 100, 200);