VYSOKÉ UČENÍ TECHNICKÉ V BRNĚ FAKULTA ELEKTROTECHNIKY A KOMUNIKAČNÍCH TECHNOLOGIÍ ÚSTAV AUTOMATIZACE A MĚŘICÍ TECHNIKY MRBT M8. VIDITELNOST OBJEKTŮ AUTOŘI PRÁCE Bc. JAKUB BERÁNEK Bc. MARTIN MAŠTERA VEDOUCÍ PROJEKTU Ing. Aleš Jelínek BRNO 2014
Zadání M8. Viditelnost objektů Vytvořte program, ve kterém bude možné navrhnout jednoduchou 2D mapu s vyznačenými překážkami. Uživatel bude dále moci určit libovolný validní (mimo překážku) bod pozorování. Proveďte rešerši a navrhněte algoritmus, který určí, které překážky lze z dané pozice vidět a které jsou skryty. Dbejte na efektivitu algoritmu a v diskuzi zhodnoťte jeho výkonnostní možnosti při velké mapě s mnoha překážkami.
Řešení viditelnosti ve 3D v praxi Řešit viditelnost ve scéně umí většina grafických programů. Cílem je určit ty objekty, resp. Jejich části, které jsou viditelné z určitého místa. Tyto algoritmy jsou vždy svázány s určitou reprezentací objektu ve scéně. Podle toho, v jakém tvaru jsou výstupní data, rozdělujeme algoritmy do dvou skupin: 1. Vektorové algoritmy jejich výstupem je soubor geometrických prvků, např. úseček, které představují viditelné části zobrazovaných objektů. Používá se především v technických aplikacích. Bez změny viditelnosti lze plynule úsečky zvětšovat. Nevýhodou je, že při numerické chybě je špatně celá úsečka, což výrazně mění celý pohled. 2. Rastrové algoritmy pracují pouze v rastru. Výsledek je obraz, jehož jednotlivé pixely obsahují barvu odpovídajících viditelných ploch. Nevýhodou je pevný rozměr obrázku. Většina metod patří do této skupiny. Mezi rastrové algoritmy patří z-buffer, malířův algoritmus či algoritmus plovoucího horizontu. Paměť hloubky (Z-buffer) Tato metoda patří k nejznámějším a nejefektivnějším. Základem je použití paměti hloubky z-bufferu. Ta tvoří dvojrozměrné pole, jehož rozměry odpovídají velikosti obrazu. Každá položka paměti hloubky obsahuje souřadnici z toho bodu, který leží nejblíže pozorovateli a jehož průmět leží v odpovídajícím pixelu v rastru. Na obrázku1 vidíme scénu a odpovídající z- buffer. Čím blíže je předmět k pozorovateli, tím světlejší má odstín. Výhody metody Obrázek 1: Z-buffer Není třeba třídit Umí správně vykreslit nestandardní situace (např. průseky)
Rychlost, jednoduchost výpočtu Nevýhody metody Větší paměťová náročnost Některé pixely se vícekrát překreslují Algoritmus Pro každý pixel ukládáme jeho barvu a vzdálenost od pozorovatele (z-buffer). V inicializační části nastavíme barvu pro všechny pixely na barvu pozadí, paměť hloubky vyplníme hodnotou minus nekonečno. 1. Každou plochu rozlož na pixely a pro každý její pixel [x i,y i ] stanov hloubku z i 2. Má-li z i větší hodnotu než položka [x i,y i ] v z-bufferu pak: a. Obarvi pixel [x i,y i ] v obrazové paměti barvou této plochy b. Položku [x i,y i ] v z-bufferu aktualizuj hodnotou z i Obrázek 2: Princip fungování algoritmu z-buffer Malířův algoritmus (Painter s algorithm) Princip tohoto algoritmu spočívá v tom, že je jednotlivým útvarům, prvkům, je přidělena priorita kresby dle vzdálenosti od průmětny. Čím je prvek dále, tím má vyšší prioritu kresby. Je tedy kreslen nejdříve. Vlastní kresba potom probíhá tak, že jsou jednotlivé útvary překreslovány. Jde o techniku, kterou používají malíři. Ke zvýraznění "prostorovosti" kreslí nejprve pozadí obrazu a postupně na toto pozadí nanášejí další vrstvy a tím zlepšují prostorovost obrazu. Jistou modifikací tohoto způsobu je tzv. obrácený malířův algoritmus. Jeho princip spočívá v postupu, kdy kreslíme objekty odpředu dozadu tak, že kreslíme nejbližší části a z ostatních kreslíme postupně dle vzdálenosti jen ty, které neleží v již dříve kreslené části. Předpokladem obou způsobů je, že scéna je modelována hraniční reprezentací s rovinnými pláty, které se neprotínají.
Obrázek 3: Princip malířova algoritmu Algoritmus Nejprve nalezneme pro každou plochu její nejmenší z-ovou souřadnici a podle ní plochy uspořádáme. První plocha v seznamu je označena jako aktivní a je podrobena několika testům překrývání s ostatními plochami, a pokud lze po těchto testech rozhodnout, že leží za všemi ostatními, je vykreslena a vyřazena ze seznamu. V opačném případě dojde v seznamu k výměně aktivní plochy s plochou, u které dopadly všechny testy negativně. Malířův algoritmus není vhodný pro všechny případy. Některé pozice (protínání) zobrazovaných objektů mohou vést ke špatnému zobrazení. Pokud se objekty navzájem překrývají, může to vést až k zacyklení algoritmu. Takový případ nastane například při situaci na obrázku 4. Obrázek 4: Problémový případ pro Malířův algoritmus Setřiď objekty podle hloubky. Vstup: Plošky, které se neprotínají for všechny objekty v určeném pořadí do{ for každý pixel [x][y] pokrytý objektem do { Obarvi pixel [x][y] barvou objektu. } }
GUI rozhraní Jednoduché GUI rozhraní slouží jako nástroj pro uživatele, který chce náš program používat. Po spuštění aplikace se uživateli zobrazí okno, které je rozděleno do tří částí, a to: Ovládací část zde si uživatel vybírá velikost mapy, zda chce Přidávat nebo Smazat objekty, anebo přidat Pozorovatele. Informační část zde se vypisuje čas délky výpočtu algoritmu určení viditelnosti a chybové hlášky Vizuální část zde se přidávají samotné objekty i pozorovatel a současně se zde zobrazují výsledky, tedy viditelné a neviditelné objekty Obrázek 5: GUI rozhraní po přidání objektů Přidávání objektu ve vizuální části stlačením levého tlačítka myši se zadá výchozí bod a se stále stlačeným tlačítkem a posunem myši na libovolnou stranu se zvětšuje či zmenšuje zadávaný objekt. Při spokojenosti s tvarem a velikostí objektu stačí pustit levé tlačítko myši, které bylo doposud stále stlačené a objekt se vytvoří. Vytvářet lze pouze objekty ve tvaru čtverce a obdélníku libovolných velikostí a poměrů stran.
Přidání pozorovatele stačí pouze zaškrtnout a poté kliknout do vizuální části na místo, kde chceme pozorovatele umístit. Po jeho přidání se provede výpočet algoritmu a zobrazí se výsledky. Výsledky Při přidání pozorovatele se tedy spustí algoritmus. Objekty, které jsou neviditelné z místa pozorovatele, zůstanou nevybarvené. Objekty, které jsou alespoň z části viditelné, se vybarví do červena. Zelená barva částečného obrysu, se na hranách těchto viditelných červených objektů vykreslí pouze tam, kde je opravdu z místa pozorovatele vidět. Nakonec se v informační části (logu) vypíše čas, který byl potřeba pro výpočet.
Naše řešení pro určení viditelnosti ve 2D: Postup algoritmu: Při vytváření objektu se stlačením a puštěním tlačítka myši se vždy zadá počáteční a koncový bod např. A a D. Zbylé dva body, tedy B a C se dopočítají a všechny body se vloží do vytvořeného prvku objekt. Dále se pak zavolá funkce vykresli(), která vykreslí zadané prvky na obrazovku. Při zadání pozorovatele se zavolá funkce invisible(), ve které se nastaví u všech prvků, že nejsou vidět a také se u nich vymažou souřadnice, podle kterých se vykreslují hrany. Dále se pro každý objekt určí, v jakém kvadrantu se pozorovatel od objektu nachází a dopočítají se úhly a nejkratší vzdáleností od pozorovatele k objektu. Toho se docílí pomocí cosinusovi věty a prací s funkcí tangens. Např. pokud se pozorovatel nachází kdekoliv v kvadrantu č.1, tak se dopočítají úhly k bodu C a k bodu B. Taktéž se dopočítá nejkratší vzdálenost od pozorovatele k objektu a to je tedy v tomto případě vzdálenost k bodu A. Pokud se pozorovatel nachází v kvadrantu č.5, vypíše se chybová hláška, protože se pozorovatel nesmí nacházet uvnitř objektu. Všechny tyto prvky se skládají do listu objektů, kde se řadí podle minimální vzdálenosti od nejmenší po největší. Do dalšího listu se řadí objekty podle úhlů. Po vypočítání všech úhlů u objektů se spustí funkce vyhodnocení_úhlu(). V této funkci se ze seřazeného listu úhlů určí, zda je daný prvek viditelný či nikoliv a to tak, že se tento list prochází od začátku a kontroluje se s druhým listem, do kterého přidávám úhly, které se nepřekrývají se žádným úhlem v tomto listě, a edituji úhly, které se částečně nebo úplně překrývají. Tento druhý list se v každém kroku kontroluje, zda se data v něm uložená data nepřekrývají. Pokud ano, tak se upraví, aby se rovnala. Dále pak ve funkci vytváříme list úhlů z objektů, které jsme určili jako viditelné. Při tom se nastaví parametr visible na hodnotu true a vloží se do dalšího listu viditelných objektů. Na tento list voláme funkci hrana(), která tento list projde a zjistí z něj úhly, ze kterých se díky funkci vid_hrana() vypočítají body viditelných hran. Nakonec se zavolá
samotné vykreslení a funkce algoritmu končí. Po tomto výpočtu se do log okna vypíše celkový čas trvání operace.
Benchmark Testování rychlosti výpočtu probíhal ze sta hodnot, pro každý výsledek a to tak, že se nejvyšší a nejnižší hodnota vyškrtla a ze zbylých 98 se spočítal aritmetický průměr. Jak je vidět z výsledků, tak velikost mapy i počet vzorků má na výsledný čas vliv. S počtem vzorků exponenciálně stoupá i časová náročnost algoritmu. Velikost mapy pouze přidává aditivní odchylku se zvětšováním mapy. Tabulka 1: Výsledky benchmarků Počet vzorků Malá mapa Střední mapa Velká mapa 1 0,0003633 0,001394 0,0032184 10 0,0009323 0,0022649 0,0039186 50 0,0034051 0,0048993 0,0065321 100 0,0102456 0,012485 0,015248 0,01800000 0,01600000 0,01400000 0,01200000 čas [s] 0,01000000 0,00800000 0,00600000 Malá mapa Střední mapa Velká mapa 0,00400000 0,00200000 0,00000000 1 10 50 100 Graf 1: Časová závislost na velikosti mapy a počtu prvků počet vzorků [ks]
Závěr: V tomto projektu jsme vytvořili aplikaci, která umožňuje vložit různé objekty a také pozorovatele. Po vložení pozorovatele se spustí algoritmus pro výpočet viditelnosti, který vybarví červeně viditelné (i jen částečně viditelné) objekty z místa pozorovatele a dále pak vykreslí zeleně přesně viditelné hrany objektů. Algoritmus jsme vymysleli vlastní, ale v konečné fázi vypadá úplně jinak, než jsme si představovali na začátku, jelikož jsme netušili, kolik problémů nás čeká při psaní tohoto algoritmu. Při malém počtu objektů se výpočty a vykreslení provádí správně, ale při větším počtu objektů ještě nastávají situace ve výpočtech, které způsobují špatné určení viditelné hrany, někdy dokonce i určení, zda je daný objekt viditelný či nikoliv.
Zdroje: [1] Řešení viditelnosti. [online]. [cit. 2014-05-01]. Dostupné z: http://mathonline.fme.vutbr.cz/pg/flash/teoriegrafika/pocgrafika5.pdf [2] Viditelnost. [online]. [cit. 2014-05-01]. Dostupné z: http://www.elearn.vsb.cz/archivcd/fei/zpg/00/8.pdf