As3 – gesty i rozpoznawanie narysowanych kształtów i znaków
Aktualnie mam tę przyjemność pracować nad grą, w której trzeba rozpoznawać narysowane przez użytkownika kształty. Gdy już zakończe pracę, a gra będzie dostępna online, to pewnie naskrobę jakiś wpis. Ale pomyślałem, że być może niektórym z Was przydadzą się znalezione przeze mnie informacje na temat rozpoznawania kształtów narysowanych na ekranie.
Jest to coś podobnego do tzw. gestów, które można znaleźć np. w przeglądarce Firefox. Są dodatki, dzięki którym rysując jakiś symbol, możemy wykonywać konkretne działanie. Z tego co do tej pory znalazłem i przeczytałem wynika, że rozpoznawanie gestu sprowadza się do kilku głównych punktów:
- Zapisanie danych wprowadzonych przez użytkownika – czyli tego co narysował, w postaci kolejnych punktów na ekranie. Używając do tego zdażeń takich jak MOUSE_MOVE, MOUSE_DOWN, itd – możemy zapisać w tablicy kolejne punkty x i y, do których użytkownik dotarł myszką podczas rysowania. W ten sposób powstaje tablica, która zawiera cały narysowany kształt w postaci łatwo dostępnych współrzędnych.
- Następnie należy w jakiś sposób znormalizować wprowadzony rysunek. A zatem dobrze byłoby go sprowadzić do określonych wymiarów. Przykładowo, by zmieścił się na przestrzeni 100×100 pikseli. W ten sposób będzie łatwiej porównać go ze wzorcem, który również musi być znormalizowany do takiej własnie postaci. Dzięki temu, nie ma znaczenia w którym miejscu narysujemy nasz symbol, ani też nie jest istotne jak duży on będzie. W rezultacie i tak sprowadzamy go do zakładanej wcześniej wielkości.
- W kolejnym etapie normalizacji symbolu, należy wyliczyć równo rozmieszczone punkty wzdłuż naszego rysunku. Można to osiągnąć np. szukając punktów przecięcia między linią a okręgiem. Ustawiając kolejne okręgi wzdłuż linii obrazka, wyliczamy punkty w równej od siebie odległości.
- Mając tak znormalizowaną postać symbolu, możemy porównać odległości punktów z naszego narysowanego kształtu, do kształtów, które musimy wcześniej przygotować w bibliotece. Sumując odgległości między kolejnymi punktami (punkt z naszego symbolu w odległości od odpowiedniego punktu z symbolu z biblioteki kształtów), dla każdego kolejnego symbolu z biblioteki kształtów, otrzymujemy listę długości, z której ta najkrótsza będzie najlepiej pasującym symbolem, do tego, którego uprzednio narysowaliśmy na ekranie.
I tak mniej więcej to wygląda. Metoda ta oczywiście nie jest kompletna i przy dużej ilości gestów, które będziemy musili porównać, może być mało wydajna. Ale przecież zawsze można ją odpowiednio dopracować i optymalizować (np. tylko porównując punkt początkowy naszego symbolu do symboli z biblioteki, już możemy wykluczyć kilka z nich, jeśli odległość jest zbyt duża), do naszych konkretnych potrzeb. Dla mnie ta metoda jest wystarczająca.
A jeśli potrzebujecie bardziej dokładnych instrukcji, to polecam poniższe źródła, z których sam korzystałem (English only):
- http://gskinner.com/blog/archives/2005/03/gesture_recogni.html
- http://blog.sqrtof5.com/?p=173
- http://www.bytearray.org/?p=91
- http://www.betriebsraum.de/blog/2009/07/21/efficient-gesture-recognition-and-corner-finding-in-as3/
- http://faculty.washington.edu/wobbrock/pubs/uist-07.1.pdf