Связь и интернет Архив Программирование
   
Сделать стартовойСделать закладку            
   ПОИСК  
   
Главная / Алгоритмы / Графика / Отсечение отрезка /
8  Perl
8  PHP
8  JavaScript
8  HTML
8  DHTML
8  XML
8  CSS
8  C / C++
8  Pascal и Delphi
8  Турбо Ассемблер
8  MySQL
8  CASE-технологии
8  Алгоритмы
8  Python
8  Обратная связь
8  Гостевая книга
Новости о мире


Двумерный алгоритм Лианга-Барски - Программирование от RIN.RU
Двумерный алгоритм Лианга-Барски

В 1982 г. Лианг и Барски [32] предложили алгоритмы отсечения прямоугольным окном с использованием параметрического представления для двух, трех и четырехмерного отсечения. По утверждению авторов, данный алгоритм в целом превосходит алгоритм Коэна-Сазерленда. Однако в работе [37] показывается, что это утверждение справедливо только для случая когда оба конца видимого отрезка вне окна и окно небольшое (до 50×50 при разрешении 1000×1000). Приведенное далее изложение двумерного варианта алгоритма следует, основном, работе [32].


Как уже говорилось, при 2D отсечении прямые отсекаются по 2D области, называемой окном отсечения. В частности, внутренняя часть окна отсечения может быть выражена с помощью следующих неравенств (рис. 0.2.7).



Рисунок 33


Xлев
?

x
?
Xправ
Yверх
?
y
?
Yниз
(0.2.1)




Внутренняя часть окна отсечения


Продолжим каждую из четырех границ окна до бесконечных прямых. Каждая из таких прямых делит плоскость на 2 области. Назовем "видимой частью" ту, в которой находится окно отсечения, как это показано на рис. 0.2.8. Видимой части соответствует внутренняя сторона линии границы. Невидимой части плоскости соответствует внешняя сторона линии границы.



Рисунок 34
Рис. 0.2.7: Видимая часть линии границы




Таким образом, окно отсечения может быть определено как область, которая находится на внутренней стороне всех линий границ.



Рисунок 35

Рис. 0.2.7: Пример рассчета отсечения




Отсекаемый отрезок прямой может быть преобразован в параметрическое представление следующим образом. Пусть конечные точки отрезка есть V0 и V1 с координатами (x0,y0) и (x1,y1), соответственно. Тогда параметрическое представление линии может быть задано следующим образом:


x    =   x0   +  dx  ·  t;       y    =   y0   +  dy  ·  t,
(0.2.2)




где     dx    =   x1   -  x0;       dy    =   y1   -  y0.
(0.2.3)




Или в общем виде для отрезка, заданного точками V0 и V1:


V(t)    =   V0   +  (V1   -  V0)   ·  t
(0.2.4)




Для точек V0 и V1 параметр t равен 0 и 1, соответственно. Меняя t от 0 до 1 перемещаемся по отрезку V0V1 от точки V0 к точке V1. Изменяя t в интервале от -? до +?, получаем бесконечную (далее удлиненную) прямую, ориентация которой - от точки V0 к точке V1.


Однако вернемся к формальному рассмотрению алгоритма отсечения.


Подставляя параметрическое представление, заданное уравнениями (0.2.2) и (0.2.3), в неравенства (0.2.1), получим следующие соотношения для частей удлиненной линии, которая находится в окне отсечения:


-dx·t
?
x0   -  Xлев
и
dx·t
?
Xправ   -  x0,
-dy·t
?
y0   -  Yниз
и
dy·t
?
Yверх   -  y0.
(0.2.5)




Заметим, что соотношения (0.2.5) - неравенства, описывающие внутреннюю часть окна отсечения, в то время как равенства определяют его границы.


Рассматривая неравенства (0.2.5), видим, что они имеют одинаковую форму вида:


Pi·t    ?   Qi       для   i   = 1,2,3,4.

(0.2.6)


Здесь использованы следующие обозначения:


P1
=
-dx;
Q1
=
x0
-
Xлев;
P2
=
dx;
Q2
=
Xправ
-
x0;
P3
=
-dy;
Q3
=
y0
-
Yниз;
P4

=
dy;
Q4
=
Yверх
-
y0.
(0.2.7)




Вспоминая определения внутренней и внешней стороны линии границы (см. рис. 0.2.8), замечаем, что каждое из неравенств (0.2.6) соответствует одной из граничных линий (левой, правой, нижней и верхней, соответственно) и описывает ее видимую сторону. (Например, для i=1 имеем: P1·t    ?   Q1 Ю -dx·t    ?   x0 - XлевЮ x0   +  dx·t    ?   Xлев).
Удлиним V0V1 в бесконечную прямую. Тогда каждое неравенство задает диапазон значений параметра t, для которых эта удлиненная линия находится на видимой стороне соответствующей линии границы. Более того, конкретное значение параметра t для точки пересечения есть t = Qi/Pi. Причем знак Qi показывает на какой стороне соответствующей линии границы находится точка V0. А именно, если Qi    ?   0, тогда V0 находится на видимой стороне линии границы, включая и ее. Если же Qi    <   0, тогда V0 находится на невидимой стороне.


Рассмотрим Pi в соотношениях (0.2.7). Ясно, что любое Pi может быть меньше 0, больше 0 и равно 0.

Pi    <   0




Если Pi    <   0, тогда соответствующее неравенство становится:


t    ?   Qi  /  Pi.
(0.2.8)/td>




Для пояснения на рис. 0.2.10 показано пересечение с левой и правой границами при Pi    <   0.



Рисунок 36
Рис. 0.2.8: Пересечение удлиненной линии, определяемой точками V0V1 и идущей с невидимой на видимую сторону, слевой и правой границами




Очевидно, что диапазон значений параметра t, для которых удлиненная линия находится на видимой стороне соответствующей граничной линии, имеет минимум в точке пересечения направленной удлиненной линии, заданной вектором V0V1 и идущей с невидимой на видимую сторону граничной линии (так как только на границе t равно Qi   /  Pi, а в остальной части видимой стороны больше).


Pi    >   0




Аналогично, если Pi    >   0, тогда соответствующее неравенство становится:


t    ?   Qi  /  Pi.
(0.2.9)

Для пояснения на рис. 0.2.11 показано пересечение с левой и правой границами при Pi    >   0.



Рисунок 37
Рис. 0.2.9: Пересечение удлиненной линии, определяемой точками V0V1 и идущей с видимой на невидимую сторону, с левой и правой границами




Так как значения параметра t только на границе равны Qi/Pi, а в остальной видимой части меньше Qi/Pi, то значение параметра t имеет максимум на границе.


Pi    =   0



Наконец, если Pi    =   0, тогда соответствующее неравенство превращается в:


0    ?   Qi.
(0.2.10)




Заметим, что здесь нет зависимости от t, т.е. неравенство выполняется для всех t, если Qi    ?   0 и не имеет решения при Qi   <   0. Для пояснения на
рис. 0.2.12 иллюстрируется случай Pi    =   0.



Рисунок 38

Рис. 0.2.10: Относительное расположение удлиненной линии, заданной точками V0V1 и идущей параллельно левой и правой границам




Геометрически, если Pi    =   0, то нет точек пересечения удлиненной линии, определяемой точками V0V1, с линиями границы. Более того, если Qi    <   0, то удлиненная линия находится на внешней стороне линии границы, а при Qi    ?   0 находится на внутренней стороне (включая ее). В последнем случае отрезок V0V1 может быть видим или нет в зависимости от того где находятся точки V0V1 на удлиненной линии. В предыдущем же случае нет видимого сегмента, так как удлиненная линия вне окна, т.е. это случай тривиального отбрасывания.


Все эти случаи суммированы на блок-схеме, представленной на рис. 0.2.13.



Рисунок 39
Рис. 0.2.11: Блок-схема алгоритма Лианга-Барски




Итак, рассмотрение четырех неравенств дает диапазон значений параметра t, для которого удлиненная линия находится внутри окна отсечения. Однако, отрезок V0V1 только часть удлиненной линии и он описывается значениями параметра t в диапазоне: 0    ?   t   ?   1. Таким образом, решение задачи двумерного отсечения эквивалентно решению неравенств (0.2.6) при условии 0    ?   t    ?   1. Решение этой задачи сводится к далее описанному отысканию максимумов и минимумов.


Вспомним, что для всех i таких, что Pi    <   0, условие видимости имеет вид: t    ?   Qi  /  Pi. Из условия принадлежности
точек удлиненной линии отрезку V0V1 имеем t    ?   0. Таким образом, нужно искать:


t    ?   max   (  {  Qi  /  Pi  |  Pi   <   0,  i = 1,2,3,4  }  И{0}}.
(0.2.11)




Аналогично, для всех i таких что Pi    >   0, условие видимости
- t    ?   Qi  /  Pi и, следовательно, ? 1.


t    ?   min   (  {  Qi  /  Pi  |  Pi   >   0,  i = 1,2,3,4  }  И{1}}.
(0.2.12)




Наконец, для всех i, таких что Pi    =   0 следует проверить знак Qi. Если Qi    <   0, то это случай тривиального отбрасывания, задача отсечения решена и дальнейшие вычисления не нужны. Если же Qi    ?   0, то информации, даваемой неравенством, недостаточно и это неравенство игнорируется.


Правая часть неравенств (0.2.11) и (0.2.12) - значения параметра t, соответствующие началу и концу видимого сегмента, соответственно. Обозначим эти значения как t0 и t1:


t0
?
max ({Qi/Pi | Pi < 0,
i = 1,2,3,4}
И{0}},
t1
?
min ({Qi/Pi | Pi > 0,
i = 1,2,3,4}
И{1}}.
(0.2.13)




Если сегмент отрезка V0V1 видим, то ему соответствует интервал параметра:


t0    ?   t    ?   t1.
(0.2.14)




Следовательно, необходимое условие видимости сегмента:


t0    ?   t1
(0.2.15)




Но это недостаточное условие, так как оно игнорирует случай тривиального отбрасывания при Pi    =   0, если Qi    <   0. Тем не менее это достаточное условие для отбрасывания, т.е. если t0    >   t1, то отрезок должен быть отброшен. Алгоритм проверяет,
если Pi    =   0     c    Qi    <   0, или t0 > t1 и в этом случае отрезок немедленно отбрасывается без дальнейших вычислений.


В алгоритме t0 и t1 инициализируются в 0 и 1, соответственно. Затем последовательно рассматривается каждое отношение Qi/Pi.


Если Pi    <   0, то отношение вначале сравнивается с t1 и, если оно больше t1, то это случай отбрасывания. В противном случае оно сравнивается с t0 и, если оно больше, то t0 должно быть заменено на новое значение.


Если Pi > 0, то отношение вначале сравнивается с t0 и, если оно меньше t0, то это случай отбрасывания. В противном случае оно сравнивается с t1 и, если оно меньше, то t1 должно быть заменено на новое значение.


Наконец, если Pi    =   0   и  Qi < 0, то это случай отбрасывания.


На последнем этапе алгоритма, если отрезок еще не отброшен, то t0 и t1 используются для вычисления соответствующих точек. Однако, если t0 = 0, то конечная точка равна V0 и не требуется вычислений. Аналогично, если t1 = 1, то конечная точка - V1 и вычисления также не нужны.


Геометрический смысл этого процесса состоит в том, что отрезок удлиняется для определения где эта удлиненная линия пересекает каждую линию границы. Более детально, каждая конечная точка заданного отрезка V0V1 используется как начальное значение для конечных точек отсеченного отрезка C0C1. Затем вычисляются точки пересечения
удлиненной линии с каждой линией границы (эти вычисления соответствуют вызову процедуры LB_tclip в программе). Если для данной линии границы направление, определяемое V0V1, идет с невидимой на видимую сторону линии границы, то эта точка пересечения вначале сравнивается с С1. Если точка находится далее вдоль линии, тогда C1 (и таким образом, С0С1) должна быть на невидимой стороне линии, поэтому отрезок должен быть отброшен. В противном случае точка пересечения сравнивается с С0; если точка далее вдоль линии, тогда С0 перемещается вперед к этой точке.


С другой стороны, если направление с видимой на невидимую сторону, тогда точка пересечения вначале сравнивается с С0. Если С0 далее вдоль линии, чем точка пересечения, тогда C0 (и, следовательно C0C1) находится на невидимой стороне линии границы, т.е. отрезок должен быть отброшен. В противном случае точка пересечения сравнивается с С1 и, если С1 далее вдоль линии, тогда С1 перемещается назад к точке пересечения.


Наконец, если удлиненная линия параллельна граничной линии и она на невидимой стороне, то отрезок отбрасывается. В конце алгоритма, если отрезок не отброшен, тогда C0 и С1 используются как конечные точки видимой части отрезка.


В Приложении 7 приведена C-подпрограмма V_LBclip, реализующая описанный выше алгоритм.



 8  Комментарии к статье  8 8  Обсудить в чате

 
  
  
    Copyright ©  RIN 2003 - 2004      * Обратная связь
www.vremena-goda.ru/banquet/ . Купить программу розница на 1с