O introducere delicată în problema corpului convex
Corpurile convexe tind să fie utile în multe domenii diferite, uneori chiar neașteptat. În acest articol, voi explica Ideea de bază a coifurilor convexe 2d și modul de utilizare a scanării graham pentru a le găsi. Deci, dacă știți deja despre scanarea graham, atunci acest articol nu este pentru dumneavoastră, dar dacă nu, acest lucru ar trebui să vă familiarizeze cu unele dintre conceptele relevante.
Cocoșul convex al unui set de puncte este definit ca fiind cel mai mic poligon convex, care cuprinde toate punctele din set. Convex înseamnă că poligonul nu are nici un colț îndoit spre interior.
Arginile roșii de pe poligonul din dreapta delimitează colțul în care forma este concavă, opusul celei convexe.
Un mod util de a ne gândi la coca convexă este analogia cu elasticul. Să presupunem că punctele din set sunt cuie, care ies dintr-o suprafață plană. Imaginați-vă acum, ce s-ar întâmpla dacă ați lua o bandă de cauciuc și ați întinde-o în jurul cuielor. Încercând să se contracte înapoi la lungimea sa inițială, elasticul ar înconjura cuiele, atingându-le pe cele care ies cel mai departe de centru.
Pentru a reprezenta coca convexă rezultată în cod, de obicei stocăm lista punctelor care susțin această bandă elastică, adică lista punctelor de pe coca convexă.
Rețineți că mai trebuie să definim ce ar trebui să se întâmple dacă trei puncte se află pe aceeași dreaptă. Dacă vă imaginați că elasticul are un punct în care atinge unul dintre cuie, dar nu se îndoaie deloc acolo, înseamnă că acel cui de acolo se află pe o linie dreaptă între alte două cuie. În funcție de problemă, am putea considera că acest cui de-a lungul liniei drepte face parte din ieșire, deoarece atinge elasticul. Pe de altă parte, am putea spune, de asemenea, că acest cui nu ar trebui să facă parte din ieșire, deoarece forma elasticului nu se schimbă atunci când îl îndepărtăm. Această decizie depinde de problema la care lucrați în acel moment și, cel mai bine, dacă aveți o intrare în care niciunul dintre cele trei puncte nu este coliniar (acesta este adesea cazul în sarcinile ușoare pentru concursurile de programare), atunci puteți chiar să ignorați complet această problemă.
Căutarea coca convexă
Urmărind un set de puncte, intuiția umană ne permite să ne dăm seama rapid care puncte sunt susceptibile să atingă coca convexă și care dintre ele vor fi mai aproape de centru și, prin urmare, departe de coca convexă. Dar transpunerea acestei intuiții în cod necesită un pic de muncă.
Pentru a găsi coca convexă a unui set de puncte, putem folosi un algoritm numit Graham Scan, care este considerat a fi unul dintre primii algoritmi de geometrie computațională. Folosind acest algoritm, putem găsi subansamblul de puncte care se află pe coca convexă, împreună cu ordinea în care aceste puncte sunt întâlnite atunci când ne deplasăm în jurul coca convexă.
Algoritmul începe cu găsirea unui punct, despre care știm cu siguranță că se află pe coca convexă. Punctul cu cea mai mică coordonată y, de exemplu, poate fi considerat o alegere sigură. Dacă există mai multe puncte la aceeași coordonată y, îl luăm pe cel care are cea mai mare coordonată x (acest lucru funcționează și cu alte puncte de colț, de exemplu, mai întâi cel mai mic x, apoi cel mai mic y).
În continuare, sortăm celelalte puncte în funcție de unghiul la care se află, văzut din punctul de plecare. Dacă se întâmplă ca două puncte să se afle la același unghi, punctul care este mai aproape de punctul de plecare ar trebui să apară mai devreme în sortare.
Acum, ideea algoritmului este de a se plimba în jurul acestui tablou sortat, determinând pentru fiecare punct, dacă acesta se află sau nu pe coca convexă. Aceasta înseamnă că, pentru fiecare triplu de puncte pe care îl întâlnim, decidem dacă acestea formează un colț convex sau concav. Dacă colțul este concav, atunci știm că punctul din mijloc din acest triplet nu se poate afla pe coca convexă.
(Rețineți că termenii de colț concav și convex trebuie folosiți în raport cu întregul poligon, doar un colț de unul singur nu poate fi convex sau concav, deoarece nu ar exista o direcție de referință.)
Memorizăm punctele care se află pe coca convexă pe o stivă, în acest fel putem adăuga puncte dacă ajungem la ele pe drumul nostru în jurul punctelor sortate și le putem elimina dacă descoperim că formează un colț concav.
(Strict vorbind, trebuie să accesăm primele două puncte din stivă, de aceea folosim în schimb un std::vector
, dar ne gândim la ea ca la un fel de stivă, pentru că întotdeauna suntem preocupați doar de primele două elemente.)
Întorcându-ne în jurul tabloului de puncte sortate, adăugăm punctul la stivă, iar dacă mai târziu descoperim că punctul nu aparține coca convexă, îl eliminăm.
Leave a Reply