Hogyan ellenőrizzük, hogy egy sokszög konvex?

Sokszögekkel számos területen találkozhatunk a számítógépes grafikától és a geometriai algoritmusoktól kezdve egészen a matematikai optimalizálásig (konvex optimalizáció). Ezekben az alkalmazásokban gyakran felmerül, hogy egy adott pontsorozat konvex vagy konkáv sokszöget határoz-e meg.

Elsőre a kérdés nem is tűnik bonyolultnak: ránézésre, vizuálisan az emberi szem általában könnyen megállapítja, hogy egy sokszög konvex vagy konkáv. Ha azonban ezt számítógéppel kell ellenőrizni, a feladat korántsem magától értetődő. A programnak ugyanis kizárólag a csúcspontok koordinátáiból kell következtetnie a sokszög alakjára, ezért matematikai szabályokra van szükség, amelyek egyértelműen meghatározzák, mikor tekintünk egy sokszöget konvexnek. Az erre vonatkozó, geometriából ismert definíciókat láthatjuk a következő ábrán.

E meghatározások azonban nem alkalmasak arra, hogy egy csúcspontjaival megadott sokszögről algoritmikusan, programmal eldöntsük, hogy konvex-e. Az 1) esetben ugyanis végtelen sok egyenes metszéspontját kellene vizsgálnunk. A 2) esetben bár a csúcsoknál lévő szögek nagysága kiszámítható lenne, de nehézséget jelent annak eldöntése, hogy a kapott szög a belső szög, vagy a 180°-nál nagyobb, úgynevezett homorúszög.

Megfigyelhetjük azonban, hogy ha egy konvex sokszög csúcsait azonos irányban járjuk be, az oldalak mindig ugyanabba az irányba – vagyis mind balra, vagy mind jobbra – fordulnak. Ez a tulajdonság a konkáv sokszögekre már nem igaz. Ha tehát van módszerünk annak megállapítására, hogy egy oldalt követő csúcspont az adott oldal egyenesének bal vagy jobb oldalára esik, és ezt a vizsgálatot sorban minden oldalra elvégezzük, akkor a sokszög konvexitása egyértelműen meghatározható.

A következő ábrákon bemutatott módszerek eltérő megközelítést alkalmaznak, de ugyanarra a feltételre vezetnek. Az első az egyenes egyenletéből indul ki, míg a második az oldalvektorok vektoriális szorzatait  (keresztszorzatait) használja, és a kapott vektorok merőleges komponenseinek (z-komponenseinek) előjeleit vizsgálja.

Mivel a szakirodalomban általában az utóbbi módszert alkalmazzák, a konvexitás ellenőrzésére szolgáló is_convex() nevű függvényben is ezt valósítjuk meg. A függvény definíciója a segédfüggvényekkel együtt alább látható. A működési logika megértését a részletes kommentek segítik.

Ahogy említettük, az ember vizuálisan könnyen meg tudja állapítani, hogy egy sokszög konvex-e. A teszteléshez ezért egy egyszerű GUI alkalmazást készítünk. Ennek felületén bal egérgomb kattintással jelölhetünk ki pontokat, amelyek a sokszög csúcsai lesznek. Ha egy pontot el akarunk távolítani, azt a pont feletti jobb egérgomb kattintással tehetjük meg.

Miután megadtuk a csúcspontokat, a Ctrl + bal egérgomb lenyomásával létrehozhatjuk a sokszöget: a pontok az elhelyezés sorrendjében egyenes szakaszokkal összekapcsolódnak. Ezt követően a program ellenőrzi a konvexitást, és az eredményt egy felirat formájában megjeleníti.

Új teszt esetén a Töröl gomb segítségével eltávolíthatjuk a jelenlegi sokszöget, és új pontokat jelölhetünk ki.

A tesztalkalmazás kódja az alábbi:

Két eredményképet a következő ábrán láthatunk.

Ebben a bejegyzésben számos helyen használtunk iterálható objektumokat, iterátorokat és generátorokat, valamint az itertools modul iterátorait. Ezekről részleteiben, példákkal magyarázva a Python tudásépítés lépésről lépésre című e-könyvben a „Kérem a következőt! – iterálható objektumok”, a „Kifogyhatatlan sorozatlövők – generátorfüggvények” fejezetekben, valamint a „Készétel fogyasztás – a szabványos könyvtár moduljainak használata” fejezeten belül a „Speciális iterátorok” című alfejezetben lehet olvasni. GUI alkalmazás fejlesztéséhez szükséges ismereteket pedig a „Grafikus felhasználói felület készítése” című fejezetből lehet elsajátítani.

Érdekel a Python tudásépítés lépésről lépésre az alapoktól az első asztali alkalmazásig című e-könyv.