- •Классификация применения машинной графики.
- •Основные понятия машинной графики: Графическая система. Графическая станция. Графические преобразования.
- •Алгоритмы машинной графики, особенности и ограничения. Проблемы построения графических систем. Сегмент. Графические файлы и их структура. Видовое преобразование.
- •Развертка окружности. Преобразование отрезков. Развертка эллипса.
- •Двухмерные преобразования
- •Трехмерные преобразования
- •Параметрические в-сплайны.
- •Трехмерный алгоритм разрезания невыпуклых тел. Последовательное отсечение многоугольника. Алгоритм Сазерленда-Ходжмана.
- •Алгоритм построения пересечения двух выпуклых многоугольников. Алгоритм Вейлера-Айзертона пересечения произвольных многоугольников.
- •Алгоритмы удаления скрытых линий и поверхностей. Алгоритм плавающего горизонта. Алгоритм Робертса.
Параметрические в-сплайны.
Математическими сплайнами называют функции, используемые для аппроксимации кривых. Важным их свойством является простота вычислений. На практике часто используют сплайны вида полиномов третьей степени. С их помощью довольно удобно проводить кривые, которые интуитивно соответствуют человеческому субъективному понятию гладкости.
Термин B-сплайн был введён И. Шенбергом и является сокращением от словосочетания «базисный сплайн».
Кривая В-сплайн записывается в следующем виде:
,
,
где выражения
являются рекурсивными формулами.
Значения
называются узловыми, они ограничивают
отрезки значений параметра
,
внутри которых функции сопряжения
имеют ненулевые значения. Следует также
отметить, что величины
– это элементы узлового вектора,
удовлетворяющие отношению
.
То, что было в лекции
Кривая B-сплайнов должна
принадлежать к классу функций дважды
непрерывно дифференцируемых
.
Задается четырьмя точками P1-P4.
Описывается формулой
,
где
Ms =
Пусть t = 1, тогда
Пусть t = 0, тогда
Функция в точке сопряжения
сплайнов должна совпадать, поэтому
Есть еще статья, автор которой некто Трибрат. Там все как-то не совсем для меня понятно. Но если кто-то сильно жаждет то вот:
http://masters.donntu.edu.ua/2005/kita/tribrat/library/splines.htm
И вот еще чуть-чуть:
В-сплайны можно классифицировать по виду узлового вектора.
Узлы бывают двух основных типов [1, 14]: периодические, для которых
и непериодические:
Главное
отличие этих узлов состоит в следующем:
первый и третий непериодические узлы
повторяются
раз. Это приводит к тому, что В-сплайн
проходит через начальную и последнюю
задающие точки (
)
– как у кривой Безье.
В периодическом В-сплайне начальная и последняя точки влияют на форму кривой ( как и все точки), поэтому В-сплайн не проходит через них.
Непериодические кривые чаще используются в системах автоматизированного проектирования, так как большинству конструкторов привычнее работать с кривыми, проходящими через первую и последнюю точки.
Если расстояние между соседними узлами не одинаково, то такие узлы
называются неоднородными; имеют место неоднородные рациональные
В-сплайны (NURBS), у которых вершины задаются в однородных координатах.
Если расстояние между соседними узлами всегда одинаково и равно единице, то такие узлы называются однородными; также называются и В-сплайны.
>Отсечение отрезков. Алгоритм Сазерленда-Коэна. Алгоритм разбиения средней точкой. (Домрачев)
При отсечении отрезков необходимо выяснить является ли отрезок полностью видимым, частично видимым или полностью невидимым.
Простейший алгоритм:
Если одна из координат отрезка лежит вне окна, то отрезок не является полностью видимым. Иначе отрезок полностью видимый и надо его визуализировать.
Если оба конца отрезка лежат справа, сверху, слева, снизу от окна, то отрезок полностью невидим.
Отрезок частично видим или невидим, надо определить пересечения отрезка с окном.
В алгоритме С-К для определения, какой из 9 областей принадлежит конец отрезка, вводится четырехзначный битовый код. Крайний правый бит считается первым.
Если побитовое перемножение двух концов отрезка равно единице, то отрезок вне окна и его можно тривиально отбросить. Прежде всего надо найти такие отрезки и отрезки тривиально видимые. Далее необходимо передать оставшиеся отрезки в подпрограмму, которая находит пересечения отрезков. (огромные блок-схемы стр.150-151)
Алгоритм С-К
Для каждого отрезка определить, не является ли он полностью видимым или может быть тривиально отвергнут как невидимый.
Если P1 вне окна, то продолжить выполнение, иначе поменять P1 и P2 местами.
Заменить P1 на точку пересечения отрезка со стороной окна.
Алгоритм разбиения средней точкой
Для отрезков применяется такая же проверка на полную видимость и полную невидимость. Оставшиеся отрезки делятся пополам и снова проверяются. И так до тех пор, пока не будет обнаружено пересечение со стороной окна или длина не выродится в точку. Для того, чтобы не отрисовывать отрезки кусками, запоминается наиболее отстоящая от центра точка с одной строны, а потом с другой, и между ними проводится отрезок.
Этот алгоритм медленнее в программной реализации, но быстрее в аппаратной, т.к. может быть распараллелен.
Если концевая точка видима, то она будет наиболее удаленной видимой точкой. Процесс завершен, иначе продолжить.
Если отрезок тривиально невидимый, то процесс завершен.
Грубо оценить наиболее удаленную видимую точку путем деления отрезка Р1Р2 средней точкой Рм. Применить 1 и 2 к двум половинам. Если РмР2 тривиально отвергается как невидимый, то средняя точка дает верхнюю оценку для наиболее удаленной видимой точки. Продолжить процедуру с отрезком Р1Рм. Иначе - средняя точка дает оценку снизу для наиболее удаленной видимой точки. Продолжить с куском Р2Рм. Если отрезок становится настолько мал, что средняя точка совпадает с его концами, то надо оценить ее видимость и закончить процесс.
>Алгоритм отсечения отрезка выпуклым окном. Алгоритм Кируса-Бека. (Домрачев)
В случае, если окно находится под углом, то описанные выше алгоритмы не сработают.
Отсечение отрезка окном.
P(t) = P1 + (P2 - P1)t, 0 ≤ t ≤ 1 - параметрически заданный отрезок.
Для прямоугольного окна:
слева t = (xl - x1)/(x2 - x1);
справа t = (xr - x1)/(x2 - x1);
снизу t = (yb - y1)/(y2 - y1);
сверху t = (yu - y1)/(y2-y1);
Если решение лежит вне единичного диапазона, то оно отвергается. Но есть проблемы, частично видимый отрезок может дать до четырех решений. Для видимых и невидимых значения могут лежать вне интервала. Поэтому используют алгоритм К-Б.
Алгоритм К-Б.
В алгоритме КБ используется вектор нормали для определения положения точки относительно окна. Внутренняя нормаль в точке а удовлетворяет условию n*(b-f)≥0, где f - любая другая точка на границе.
P(t) = P1 + (P2 - P1)t, 0 ≤ t ≤ 1 - параметрически заданный отрезок.
n*[P(t) - f] - скалярное произведение внутренней нормали i-ой стороны на вектор, оно будет положительно, равно нулю или отрицательно, в зависимости от того, будет ли точка внутри, на границе или вне окна.
Подставляем одно в другое: n*(P1 - f) + n*(P2 - P1)*t = 0 - условие пересечения границы.
D = P2 - P1, - ориентация отрезка. w = P1 - f, - весовой множитель.
t(n * D) + w * n = 0, t = - (w * n)/(D * n).
При вырождении отрезка в точку D = 0.
Если значение t лежит вне единичного интервала, то его можно проигнорировать. Известно, что отрезок может пересечь выпуклое окно не более, чем в двух точках, но при двух значениях t, уравнение может дать большее число решений. Их следует разбить на две группы: нижнюю и верхнюю, в зависимости от того, к началу или к концу отрезка ближе точка. Нужно найти наибольшую из нижних и наименьшую из верхних точек. Если D*n>0, то точка рассматривается в качестве нижнего предела, D*n<0, - верхнего предела.
>Разбиение невыпуклых многоугольников. Трехмерный алгоритм разбиения средней точкой. Трехмерный алгоритм Кируса-Бека. (Б)
Обобщение метода поворотов и переносов окна, используемого для определения факта его выпуклости или невыпуклости, позволяет разбивать или разделять простой невыпуклый многоугольник на несколько выпуклых многоугольников. Если вершины многоугольника перечисляются против часовой стрелки, то процедура будет иметь вид:
1) переносим каждую i-ю вершину в начало координат
2) поворачиваем многоуг-к по часовой стрелке так, чтобы i+1-я вершина оказалась на положительной полуоси х
3) если знак ординаты i+2-й вершины неотрицателен, то многоуг-к выпуклый в i+1-й вершине, в противном случае многоуг-к невыпуклый, надо разбивать
Разрезаем многоуг-к вдоль положительной полуоси х: ищутся все такие стороны многоуг-ка, которые пересек-я с осью x. Получили 2 многоугольника:
1) вершины исходной фигуры, начиная с i+1-й и кончая точной пересечения, он целиком ниже оси x
2) точка пересечения и все оставшиеся вершины исходной фигуры (он может пересекать ось х)
Алгоритм рекурсивно применяется к полученным многоугольникам, пока не будут выпуклыми.
Этот алгоритм не дает минимального числа выпуклых компонент и некорректно разбивает многоугольник, стороны которого пересекаются между собой.
Когда вершина V2 совпадает с началом координат, а V3 лежит на положительной полуоси x, знак ординаты V4 будет отрицательным, значит этот многоугольник невыпуклый. Разрезание его осью х дает многоугольники V3V4V5 ниже оси х и V1V2V3V5 выше этой оси. Возобновление работы алгоритма с новыми многоуг-ми показывает, что они оба выпуклы, поэтому алгоритм прекратит работу.
Алг-м разбиения средней точкой
Дан отрезок P1(-600,-600,600)P2(100,100,-100), заданный в экранной система координат, расположенной на дальней плоскости, и отсекаемый пирамидой видимости с хп=ув=500, хн=ун=-500. Аппликаты (это как абсцисса и ордината, только для z) ближней и дальней граней таковы: zб=357.14б zд=-500. Центр проекции лежит на zцп=2500.
Вычисляем коэффициенты, которые понадобятся далее (коэффициенты эти получены из уравнения прямых на 6 плоскостях, несущих проекции граней отсекателя, пример уравнения прямой для плоскости xz, несущей проекцию правой грани отсекателя:x=(z-zцп)*xп/(zд-zцп)=z*a1+a2 :
a1=xп/(zд-zцп)
а2=-а1zцп
b1=xл/(zд-zцп)
b2=-b1zцп
с1=yв/(zд-zцп)
c2=-с1zцп
d1=унп/(zд-zцп)
d2=-d1zцп
Отрезки идентифицируем с использованием обобщения кодов концевых точек Коэна-Сазерленда.
В трехмерном случае используется 6-битовый код. Самый правый бит считается первым. В биты кода заносятся единицы с помощью обобщения двумерной процедуры, если заносим единицу:
в 1-й бит-конец ребра левее объема
в 2-й бит-конец ребра правее объема
в 3-й бит-конец ребра ниже объема
в 4-й бит-конец ребра выше объема
в 5-й бит-конец ребра ближе объема
в 6-й бит-конец ребра дальше объема:
И по коэффициентам находим этот код::
if(Px-Pzb1-b2<0)
код[6]=1 else код[6]=0
if(Px-Pza1-a2>0)
код[5]=1 else код[5]=0
if(Pу-Pzd1-b2<0)
код[6]=1 else код[4]=0
if(Pу-Pzc1-a2>0)
код[5]=1 else код[3]=0
if(Pz-zб>0)
код[6]=1 else код[2]=0
if(Pz-zд<0)
код[5]=1 else код[1]=0
Код концевой точки P1 равен (010101), а код P2 равен (000000). Поскольку оба этих кода не равны 0 одновременно, отрезок не является полностью видимым. Логическое произведение кодов концевых точек равно (000000). Поэтому отрезок не является и тривильно невидимым. Поскольку код точки P2 равен 0 (складываются все 6 разрядов числа 000000), то P2 лежит внутри отсекателя. Сл-но, P2-наиболее удаленная от P1 видимая точк а отрезка. Значит, отрезок имеет только одно пересечение с границей отсекателя. Координаты середины отрезка равны:
хс=(х2+х1)/2=-250, ус=-250, zc=250
Код этой точки равен (000000). Отрезок PcP2-полностью видимый, отрезок P1Pc-частично видимый. Алгоритм продолжает работу с отрезком P1Pc.
Фактические координаты точки пересечения равны (-357.14, -357.14, 357.14). Отличие из-за использовании целочисленной арифметики.
Трехмерный алгоритм К.-Б.
Пусть отсекающее окно – любой выпуклый многогранник, заданный уравнениями плоскостей, содержащих его грани, вида Ax+By+Cz+D=0. Так как многогранник – выпуклый, то отрезок будет пересекать его не более, чем в двух точках. Параметрическое уравнение отрезка имеет вид P(t)=P1+(P2-P1)t, где 0≤t≤1, P1 – координаты начала отрезка, P2 – координаты конца отрезка. Принцип алгоритма заключается в нахождении tн и tв – пределы точек, определяющих видимую часть отрезка. К каждой плоскости грани проводим внутреннюю нормаль n и вектор, начинающийся в любой точке f плоскости и заканчивающийся в точке пересечения отрезка и плоскости (рис.1). Их скалярное произведение должно быть равно нулю.
n [ P(t) – f] = 0
n [P1 + (P2 – P1)t – f] = 0
n [P1 – f] + n [P2 – P1] t = 0
пусть w = P1 – f D = P2 – P1
t = –
(n*w)/(n*D)
Если n*w>0, то точка P1 лежит внутри окна относительно текущей плоскости; если n*w<0, то точка P1 лежит вне окна; если n*w=0, то точка P1 лежит на границе окна.
Если D*n>0, то n*w должно быть меньше нуля, так как t≥0, следовательно найденное t – возможный нижний предел.
Если D*n<0, то n*w должно быть больше нуля и следовательно, найденное t – возможный верхний предел. Если D*n = 0, то отрезок либо вырожден в точку, либо он параллелен данной плоскости. И в том, и в другом случае проверяем: если w*n>0, то отрезок (точка) видим в окне видимости относительно данной плоскости; если w*n<0, то отрезок (точка) невидимы.
Проделав выше описанные действия для каждой плоскости, получим возможные нижние пределы, из которых выбираем максимальный, и возможные верхние пределы, из которых выбираем минимальный (рис.2).
