Материал: 252_337

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

Алгоритм Джарвіса

Як видно з попередніх двох методів, побудова опуклої обо­ лонки починається з визначення стартової точки, що належить цій опуклій оболонці. Такими точками завжди є крайні точки: ліва, верхня, права і нижня. Залежно від обраного методу, стартовою визначається одна з них. Наступною точкою опуклої оболонки серед решти точок обов'язково буде точка з наймен­ шим кутом відхилення від стартової. Це обумовлено тим, що при повороті, наприклад, наліво від стартової точки першою точкою, яка трапиться на цьому шляху, буде точка з наймен­ шим кутом повороту відносно стартової (мал. 162).

Алгоритм, що носить назву алгоритму Джарвіса, побудова­ ний на ідеї розбиття процесу пошуку вершин опуклої оболонки на окремі кроки. На кожному з цих кроків стартовою точкою вважається точка, що приєднана до опуклої оболонки на по­ передньому кроці. Далі до опуклої оболонки приєднується така наступна точка серед решти, що залишились, яка має міні­ мальний кут відхилення від цієї поточної стартової точки.

Візуально даний метод можна уявити собі наступним чином. Зав'яжемо мотузку на най лівішому нижньому цвяху, що за­ битий у дошку. Далі закидатимемо мотузку з правого боку, щоб «упіймати» наступний цвях справа. Закріпимо мотузку на цьому цвяху і знову будемо закидати її з правої сторони, щоб «упіймати» наступний цвях. Таким чином мотузка врештірешт охопить усі цвяхи і буде зав'язана лише на тих з них, що належать опуклій оболонці.

Розглянемо покрокове виконання алгоритму Джарвіса (мал. 162). На малюнку зображено задані точки у довільному порядку. Стартовою точкою є точка рь - найлівіша нижня точ­ ка серед усіх заданих, тобто така, у якої найменше значення по

ОРв

ОРз

 

 

Ор6

Ор3

 

 

 

 

 

ОР2

 

 

 

 

 

ОРю

О

 

 

 

 

0і

Рі

 

 

 

 

 

 

 

 

 

-о-

 

 

 

 

 

Рп

о„

%

 

 

 

%

1 2

 

 

і

2

З

а)

 

б)

5

9

8

 

 

 

 

 

Мал. 162

 

 

 

282

осі абсцис та по осі ординат. Занесемо її порядковий номер у шукану послідовність номерів точок, що утворюють опуклу оболонку. Виконаємо паралельне перенесення початку коор­ динат у цю точку і серед решти точок визначимо ту, що має найменший лівий кут відносно стартової (мал. 162, а). Такою точкою у нашому прикладі буде точкаpQ . Перше ребро опуклої оболонки знайдено, воно сполучає точки р5 і р9. Допишемо по­ рядковий номер точки рд у шукану послідовність і перейдемо до наступного кроку.

На другому кроці виконання алгоритму паралельно перене­ семо початок координат у точку р9 (мал. 162, б) і визначимо точку, яка має найменший лівий кут відхилення від точки р9 у побудованій системі координат. Такою є точкаps .

Наступні кроки аналогічні попереднім і зображені на ма­ люнках 163, а, є. Слід зауважити, що для всіх точок нижнього ланцюга опуклої оболонки кут визначається у правій коорди­ натній півплощині, а для верхнього - у лівій. Ці дві частини ре­ зультуючої опуклої оболонки позначені на малюнках пунктир­ ною прямою.

На малюнку 163, є за послідовністю отриманих порядкових номерів заданих точок побудована шукана опукла оболонка.

Опишемо алгоритм Джарвіса для побудови опуклої оболонки.

1.Визначити стартову точку як таку, що має найменші коор­ динатні значення по осі абсцис і по осі ординат, записати її поряд­ ковий номер у послідовність вершин шуканої опуклої оболонки.

2.Перенести початок координат у стартову точку і серед усіх п - 1 точок визначити точку з найменшим лівим кутом відхилення від стартової в правій координатній півплощині. Якщо таких точок кілька, то серед них узяти точку з найбіль­ шим значенням по осі абсцис. Дописати порядковий номер ви­ значеної точки у послідовність вершин опуклої оболонки. На­ дати визначеній точці статус стартової.

3.Якщо стартова точка не збігається з точкою, що є крайньою справа і верхньою точкою заданої множини точок, то перейти до п. 2.

4.Перенести початок координат у стартову точку і серед усіх п - 1 точок визначити точку з найменшим лівим кутом відхилення від стартової в лівій координатній півплощині. Як­ що таких точок кілька, то серед них узяти точку з найбільшим значенням по осі абсцис. Дописати порядковий номер визначе­ ної точки у послідовність вершин опуклої оболонки. Надати визначеній точці статус стартової.

5.Якщо поточний номер стартової точки не збігається з номе­ ром першої точки, записаної у послідовність, то перейти до п. 4.

6.Завершити виконання алгоритму і вивести порядкові номери точок, що містяться у послідовності і є вершинами

283

1 2

В 4 5 б

.1 2

3

4 5 6* 7

 

1 5 9

8 4 11 з

 

 

 

 

в)

*)

5

9

8

4 11 3 6

 

 

 

 

 

 

^РҐ*Р*

 

 

1

2

3

4

5

6

7

 

1 2

3

4 5

6

7

 

І 5

9

8

4 |11|

3 | 6 |

5)

| 5 | 9

8

4 |11

3

6

є)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Мал. 163

 

 

 

 

 

 

284

побудованої опуклої оболонки в порядку їх обходу проти го­ динникової стрілки.

Перш ніж навести фрагмент програми, що реалізує описа­ ний алгоритм, розглянемо його математичну складову.

На кожному кроці виконання алгоритму при паралельному перенесенні початку координат у поточну стартову точку не­ обхідно робити перерахунок координат тих точок, що надалі розглядаються. Перераховані координати стартової точки при перенесенні у неї початку координат набудуть значення (0; 0). Якщо позначити реальні координати поточної стартової точки (xst; yst), а досліджуваної точки (xt; yt), то перетворені координа­ ти і-ї точки будуть обчислюватися за формулами дг/ = xt - xst,

УІ'=УІ-УВГ

 

 

 

 

Для

обчислення лівого

кута

 

 

відхилення необхідно враховувати,

 

 

до якої частини опуклої оболонки

 

 

відноситься досліджувана

точка:

 

 

до нижньої чи до верхньої. У пер­

 

 

шому випадку кут визначається у

 

 

правій координатній півплощині, а

 

 

у другому - у лівій. Ця ознака ви­

 

 

пливає

з аналізу перерахованих

 

 

значень координат точок по осі абс­

 

 

цис: при паралельному перенесенні

 

 

початку координат у поточну стар­

 

 

тову точку для точок, що належать

 

 

опуклій оболонці і знаходяться у

 

 

нижній частині, значення абсцис

Мал.

164

будуть додатними, а для верхньої -

 

 

від'ємними (мал. 164).

Так само, як і для алгоритму Грехема, обчислення значення ку­ та можна звести до обчислення значення його синуса за формулою

у—у,

' =. У правій координатній півплощині протн­

у в ~ * J 2 +0/І -&*)2

гом пошуку вершин опуклої оболонки це значення буде збіль­ шуватись від - 1 до + 1. Така зміна значень відповідає алгорит­ му Джарвіса, по якому на кожному кроці шукається точка, що має найменший лівий кут відхилення від поточної стартової точки. Однак у лівій координатній півплощині точки, що є кандидатами на включення до послідовності вершин опуклої оболонки і мають від'ємні значення по осі абсцис, характерні тим, що лівий кут їх відхилення від поточної стартової точки зменшується від + 1 до - 1 . Саме цю особливість необхідно вра­ хувати, коли під час побудови опуклої оболонки буде досягну­ то найправішої верхньої точки.

285

Отже, фрагмент основної частини програми, що реалізує алго­ ритм Джарвіса для побудови опуклої оболонки, може бути таким:

x_min := maxint; y j m i n := maxint;

{Блок ініціалізації.}

x j n a x := 0; y_max := 0;

 

for І := 1 to n do

{Перегляд усіх заданих точок.}

begin

 

r e a d ( f _ i n , x [ i ] , y [ i ] ) ;

 

{Визначення найлівішої нижньої точки.}

if (х[і] < x j n i n ) or ((х[і] = x j n i n ) and (у[і]

< y_min))

then begin

 

|x_min := x[i]; y_min := y[i]; p s t := і end;

{Визначення найправішої верхньої точки.} if (х[і] > xjmax) or ((x[i] = x_max) and (y[i] < y m a x ) )

then begin

| x_max := x[i]; y_max := y[i]; p e n d := і end;

end;

 

 

 

{Запис у результуючу послідовність шуканих вершин}

k := 1; p[k] := p_st; st := [ p _ s t ] ;

{опуклої оболонки першої вершини.}

repeat

{Побудова нижньої частини ланцюга вершин опуклої оболонки.}

include(O);

 

 

 

{Ознакою завершення побудови нижньої частини ланцюга}

until p_St = p_end;

{є досягнення найправішої верхньої точки.}

 

 

{Побудова верхньої частини ланцюга вершин}

St := St - [р[1]];

 

{опуклої оболонки.}

repeat

 

 

include(1);

 

 

 

{Ознакою завершення побудови верхньої частини ланцюга}

until p s t = р[1 ];

 

{є досягнення найлівішої нижньої точки.}

Процедура include визначає вершини опуклої оболонки і за­ лежить від напряму пошуку: для нижньої частини ланцюга во­ на працює з параметром рг = 0, а для верхньої - рг = 1:

procedure include(pr: byte);

var angl, angljnin, d_k_st, d_k_i: real; begin

{Визначення частини ланцюга вершин опуклої оболонки, що будується.}

if рг= 0 then anglmin := 2 else angljnin := -2;

for і := 1 to n do

{Перегляд усіх заданих точок.}

 

{Виключення з перегляду точки, що вже включена}

if not (і in St)

{до послідовності вершин опуклої оболонки.}

then begin

{Обчислення відстані від точки pjst, яка на даний момент є кандидатом} {для включення до послідовності вершин опуклої оболонки,}

{до точки р[к], з якої ведеться спостереження.}

d_k_st := sqrt(sqr(x[p_st] - x[p[k]]) + sqr(y[p_st] - y[p[k]]));

286

Источник: https://studfile.net/preview/14502490/