OpenGL SuperBible (6th Edition) / OpenGL Супер Книга (6-ое издание): Математика для 3D-графики
| Английский оригинал | Перевод на русский | |
|---|---|---|
Сожалеем, но текст оригинала доступен только зарегистрированным пользователям. |
Поэтому мы можем переписать это уравнение следующим образом vk955 07.09.14 в 09:33 |
|
|
Легко увидеть, что при t равном нулю, P равна A, а когда t равен единице, P равен A + B – A, т.е. просто B. Такая линия показана на рисунке 4.13. vk955 07.09.14 в 09:33 |
||
|
Рисунок 4.13: Нахождение точки на линии vk955 07.09.14 в 09:33 |
||
|
Если t лежит между 0.0 и 1.0, то Р будет в конечном итоге лежать где-то между А и В. Значения t за пределами этого диапазона будет выталкивать P за концы линии. Вы должны видеть, что путем плавного изменения t, мы можем двигаться точку Р из А в В и обратно. Это называется линейной интерполяцией. Значения A и B (и, следовательно, P) может иметь любое число измерений. Например, они могут быть скалярными значениями; двумерными значениями вроде точек на графике; трехмерными значениями вроде координат в трехмерном пространстве, значениями цветов и т.д.; или величинами даже более высокой размерности вроде матриц, массивов и даже целыми изображениями. Во многих случаях, линейная интерполяция не имеет особого смысла (например, линейная интерполяция между двумя матрицами, как правило, не дает значимого результата), но углы, позиции и координаты обычно можно интерполировать безопасно. vk955 07.09.14 в 09:35 |
||
|
Линейная интерполяция - настолько распространенная операция в графике, что GLSL имеет встроенную функцию mix специально для этой цели: vk955 07.09.14 в 09:35 |
||
|
vec4 mix(vec4 A, vec4 B, float t); vk955 07.09.14 в 09:35 |
||
|
Функция mix имеет несколько версий, которые принимают векторы различной размерности или скаляры во входных параметрах А и В, а также принимают скаляры или соответствующие вектора в параметре t. vk955 07.09.14 в 09:36 |
||
|
Кривые vk955 07.09.14 в 09:39 |
||
|
Рисунок 4.14: простая кривая Безье vk955 07.09.14 в 09:39 |
||
|
Кривая, показанная на рисунке 4.14, имеет три контрольные точки A, B и C. А и С являются концевыми точками кривой, а В определяет форму кривой. Если мы соединим точки А и В одной линией, а точки В и С другой, то мы сможем произвести интерполяцию вдоль двух линий, используя простую линейную интерполяцию, чтобы найти новую пару точек D и E. Теперь, имея эти две точки, мы можем, соединив их с помощью еще одной линии, произвести вдоль нее интерполяцию и найти новые точку P. И пока мы будем изменять наш параметр интерполяции t, точка P будет двигаться по гладкой криволинейной траектории от А до D. Выразив это математически, получим vk955 07.09.14 в 09:43 |
||
|
Сделав подстановку вместо D и E и сократив формулу, мы получим следующее: vk955 07.09.14 в 09:43 |
||
|
Вы должны узнать в этой формуле квадратное уравнение с переменной t. Кривая, которую описывает данное уравнение, известна как квадратичная кривая Безье. На самом деле, в GLSL мы можем реализовать этот функционал очень легко благодаря функции mix, так как все, что мы делаем, является линейной интерполяцией результатов двух предыдущих интерполяций. vk955 07.09.14 в 09:44 |
||
|
vec4 quadratic_bezier(vec4 A, vec4 B, vec4 C, float t) vk955 07.09.14 в 09:44 |
||
|
Добавив четвертую контрольную точку, как показано на рисунке 4.15, мы можем увеличить порядок кривой на единицу и получить кубическую кривую Безье. vk955 07.09.14 в 09:44 |
||
|
Рисунок 4.15: кубическая кривая Безье vk955 07.09.14 в 09:45 |
||
|
Теперь у нас есть четыре контрольные точки A, B, C и D. Способ построения кривой аналогичен построению квадратичной кривой Безье. Мы строим первую линию от A до B, вторую от B к C, третью от С до D. Интерполирование вдоль всех из трех линий порождает три новые точки E, F и G. Используя эти три точки, мы формируем еще две линии: одну от E до F, а другую от F до G, интерполирование вдоль которых порождает точки H и I, между которыми мы можем произвести еще одну интерполяцию, чтобы найти наш конечную точку P. Таким образом, наше уравнение будет выглядеть как показано ниже. vk955 07.09.14 в 09:47 |
||
|
Если вам показалось, что уравнения выше выглядят знакомо, вы правы - наши точки E, F и G образуют квадратичную кривую Безье, которую теперь мы используем при интерполяции для нахождения нашей конечной точки P. Если бы мы должны были подставить уравнения для точек E, F и G в уравнения для точек H и I, а те, в свою очередь, подставив в уравнение для P и раскрывая скобки, мы получим кубическое уравнение (“кубическое” означает t3). Опять же, в GLSL мы можем осуществить это просто и эффективно с точки зрения линейной интерполяцией благодаря функции mix: vk955 07.09.14 в 09:50 |
||
|
vec4 cubic_bezier(vec4 A, vec4 B, vec4 C, vec4 D, float t) vk955 07.09.14 в 09:50 |
||
|
Так же, как структура уравнений для кубической кривой Безье "включает в себя" уравнения для квадратичной кривой, так и код для ее реализации будет включать в себя код для реализации кривой меньшей степени. На самом деле, мы можем наложить эти кривые друг на друга, используя код для одной, чтобы построить следующую: vk955 07.09.14 в 09:51 |
||
|
vec4 cubic_bezier(vec4 A, vec4 B, vec4 C, vec4 D, float t) vk955 07.09.14 в 09:51 |
||
|
Теперь, когда у нас есть этот пример, мы можем действовать по аналогии, чтобы строить кривые еще более высоких степеней. К примеру, кривая Безье пятой степени (с пятью контрольными точками) может быть реализована следующим образом vk955 07.09.14 в 09:52 |
||
|
vec4 quintic_bezier(vec4 A, vec4 B, vec4 C, vec4 D, vec4 E, float t) vk955 07.09.14 в 09:52 |
||
|
Это наложение теоретически может использоваться снова и снова для любого количества контрольных точек. Однако, на практике, кривые более, чем четвертой степени обычно не используются. Лучше мы используем сплайны. vk955 07.09.14 в 09:53 |
||
|
Сплайны vk955 07.09.14 в 09:56 |
||
|
Рисунок 4.16: Кубический сплайн Безье vk955 07.09.14 в 09:57 |
||
|
На рисунке 4.16, кривая определена десятью контрольными точками, от А до J, которые образуют три кубических кривых Безье. Первая определена точками A, B, C и D; вторая образована общей точкой D, а также E, F и G; третья начинается с общей G, за которой идут H, I и J. Этот тип сплайна известен как кубический сплайн Безье, потому что построен из последовательности кубических кривых Безье. Он также называется кубическим B-сплайном - термин, который может быть знаком тем, кто раньше уже читал что-то о графике. vk955 07.09.14 в 09:59 |
||
|
Таким образом, целая часть значения t определяет сегмент кривой, вдоль которого мы осуществляем интерполяцию, а дробная часть используется для интерполяции вдоль этого сегмента. Конечно, мы можем масштабировать t, как захотим. Например, если мы возьмем значение между 0.0 и 1.0 и умножим его на количество сегментов в кривой, мы сможем продолжать использовать наш исходный диапазон значений t независимо от количества контрольных точек в кривой. vk955 07.09.14 в 10:00 |
||
|
vec4 cubic_bspline_10(vec4 CP[10], float t) vk955 07.09.14 в 10:00 |
||
|
Если мы используем сплайн для определения положения или ориентации объекта, мы должны быть очень осторожны при выборе позиций контрольных точек, чтобы сохранить движение плавным. Частота изменения значения нашей интерполированной точки P (скорость) является дифференциалом уравнения кривой относительно t. Кроме того, частота изменения скорости P (ускорение) является производной второго порядка уравнения сплайна относительно t. Если ускорение не плавное, то P станет внезапно ускоряться или замедляться. vk955 07.09.14 в 10:01 |
||
|
Функция, которая имеет непрерывную первую производную называется C1-непрерывной, и аналогично кривая, которая имеет непрерывную вторую производную называется C2-непрерывной. Сегменты кривой Безье являются C1- и C2-непрерывными, но для того, чтобы убедиться, что мы сохраняем преемственность над швами (welds) сплайна, мы должны убедиться, что каждый сегмент начинается с условиями, при которых предыдущий заканчивается, а именно: в положении, направлении движения и частоте изменения. Итак, частота перемещения в определенном направлении - это просто скорость. Таким образом, вместо того, чтобы назначать произвольные контрольные точки нашему сплайну, мы можем назначить скорость в каждом weld. Если одинаковая скорость кривой в каждом weld используется для вычисления сегментов кривой по обе стороны от этого weld, то мы будем иметь сплайн-функцию, которая является одновременно и C1-, и C2-непрерывной. vk955 07.09.14 в 10:05 |
||
|
Вы все поймете, если еще раз взглянете на рисунок 4.16 - перегибов нет, кривая красиво и плавно проходит через welds (точки D и G). Теперь посмотрим на контрольные точки по обе стороны от welds. Для примера, возьмем точки С и E, которые окружают D. С и E образуют прямую линию, а D находится прямо в середине нее. На самом деле, мы можем назвать отрезок от D до E скоростью в D, или Vd. Имея положение точки D (weld) и скорости кривой Vd в D, точки С и Е могут быть рассчитаны так vk955 07.09.14 в 10:07 |
||
|
Аналогично, если Va является скоростью в A, то B может быть рассчитано так vk955 07.09.14 в 10:07 |
||
|
Таким образом, вы можете видеть, что, имея положения и скорости в welds кубического B-сплайна, мы можем обойтись без других контрольных точек, вычисляя их на лету также, как мы вычисляем каждую контрольную точку. Кубический B-сплайн, определенный подобным образом (в виде набора положений и скоростей weld), известен как кубический эрмитов сплайн (cubic Hermite spline, cspline). Это чрезвычайно полезный инструмент для получения плавной и естественной анимации. vk955 07.09.14 в 10:10 |
||
|
Заключение vk955 07.09.14 в 10:12 |
||
|
Наконец, мы показали, как использовать библиотеку vmath, которая поставляется вместе с этой книгой. Эта библиотека, написанная полностью на переносимом C++, предоставляет вам удобный инструментарий из различных математических и прочих вспомогательных функций, которые могут быть использованы вместе с OpenGL. vk955 07.09.14 в 10:13 |
||
|
Удивительно, но в этой главе мы не рассмотрели ни одной новой для нас OpenGL-функции. Да, эта глава была о математике, и вы могли даже не заметить этого, если считаете, что математика - это только формулы и расчеты. Векторы и матрицы абсолютно необходимы для того, чтобы вы смогли использовать OpenGL для отрисовки трехмерных миров и объектов. Тем не менее, важно отметить, что OpenGL не налагает никаких особых условий на использование математики, как и не содержит никакой реализации математических функций. Даже если вы используете другую математическую библиотеку, или даже написали свою собственную, она вы все равно будет построена на основе тех концепций, что были изложены в этой главе. А теперь двигаемся вперед и начинаем что-то делать! vk955 07.09.14 в 10:14 |
