HTML

Survive Developement

Itt olvashatod a Survive! nevű játék fejlesztésének állapotát, lépéseit. És mi is lesz a játék? Egy zombis-túlélős játék, ahol elsősorban a csapatmunkára építkezve kell megpróbálni életben maradni egy kihalt városban. A terep teljesen a tietek, nincsenek szabályok: éljetek túl, ahogy tudtok!


Küldj e-mailt nekünk:
gilgamesco@gmail.com

Sikolyok

Ettől tépjük a hajunkat:

Friss topikok

  • Sir Butcher: A gyors mozgású ütközés-érzékelés majd a lövésnél lesz topic :D A második esetben teljesen igaza... (2012.04.05. 16:38) Ütközésérzékelés
  • _fpeti_: Halad ez. (2012.04.04. 22:01) Gravitáció
  • Sir Butcher: Az sem rossz, az tény :D Szerencsére egyelőre annyi különbözőt kell csinálnom, hogy esélyem sincs ... (2012.02.20. 21:48) Scenery - Még több látvány
  • Sir Butcher: Na, ideírom: obj-nél megoldottam a csontokat. Melléktermékként összejöttek, extra számítás nélkül ... (2011.12.02. 11:48) Model Animálás - a probléma, és a (vélt) megoldás
  • Burwor: "A tesztvárosban sétálgatva belefutsz egy házba, aminek hiányzik egy fala. Mit csinálsz?" Zárva a... (2011.11.10. 15:00) Sziduri - a grafmotor bemutatkozik

Majdnem maximális beírt téglalap - part 2.

2012.01.24. 22:00 :: GizmoSDK

A HLint érdekes kis program. Kiszúrta például, hogy a "foldl1 (&&)" helyett írhatnék simán "and"-et is. A posztok javítva vannak.

Az előző posztban megígértem, hogy megértjük az isPointInPolygon függvényt. Nézzük.

-- Ha egy polygon pontjait az óramutató járásával ellentétes
-- irányban haladva adjuk meg, akkor annyit kell megnézni,
-- hogy az adott pont minden vonal bal oldalán van-e. Ha
-- igen, a polygonon belül van a pont, különben kívül.
-- (Kicsire nem adunk, ha rajta van, kívül van, kész.)
isPointInPolygon :: Position -> Polygon -> Bool
isPointInPolygon p ps =
  and (map (\x -> onLeft (ps !! x)
                         (ps !! ((x + 1) `mod` psn))
                         p)
                   [0..psn-1])
  where
    psn = length ps

Egy C pontról meg tudjuk állapítani, hogy egy AB vonal bal oldalán van-e (onLeft a b c). Fel tudjuk-e ezt használni ahhoz, hogy egy pontról eldönthessük, benne van-e egy polygonban? Egyértelmű, hogy ha a polygon minden oldalától balra van, és az oldalak CCW irányban vannak megadva, akkor a pont a polygonon belül van. Első lépésben döntsük el minden oldalra, hogy a pont attól jobbra, vagy balra van-e! Ehhez kelleni fog a map, ami fog egy függvényt és egy tömböt, majd a tömb minden elemére alkalmazza a függvényt, és visszatér ezzel az új tömbbel. Típusa a haskellerek kedvéért:

map :: (a -> b) -> [a] -> [b]

Ehhez ugyebár kelleni fog az onLeft, és a map. Van egy tömbünk a polygon pontjairól, sorrendben. Mindig összefogjuk az éppen aktuálisat az utána következővel, és ez lesz az a vonal, amihez hasonlítjuk a pontot. Na de ha van egy pontunk, honnan tudjuk, hogy melyik a következő pont, anélkül, hogy ismernénk a tömböt? Nos, sehogy. Épp ezért én úgy oldottam meg, hogy nem pontokra alkalmaztam a map-et, hanem indexekre. Nézzük:

boolArray polygon point =
  map (\index -> onLeft (polygon !! index)
                        (polygon !! (index + 1) point)
      [0..length polygon - 1]

a (polygon !! index) elkéri az index-edik elemet a polygon tömbből. A map utáni és a [0..] előtti rész egy úgynevezett lambda függvény, ami azt jelenti, hogy nem adunk meg neki nevet, hanem csak simán definiáljuk. a \ jel (ami a lambda lenne, csak azt nehéz m,egtalálni a billentyűzeten, úgyhogy ezt választották, mert eléggé hasonlít hozzá) után jönnek a paraméterek, majd egy nyíl után a definíció maga. A probléma viszont, hogy az utolsó elemnél az utolsó utánira is szükségünk lenne, ami viszont out-of-boundary error. De igazából ott nekünk az első elem kellene, mivel ugye a polygon önmagába tér vissza. Erre van egy ügyes kis trükk, a maradékos osztás, vagy mod. Ezt nem magyarázom el, tele van vele a gugli. Viszont ha az index + 1 részt maradékosan osztjuk a hosszal, akkor az első olyan index, ami a hosszon kívül lenne, pontosan 1 lesz. Vagyis, amire szükségünk van :D A módosított verzió:

boolArray polygon point =
  map (\index -> onLeft (polygon !! index)
                        (polygon !! ((index + 1) `mod`
                          (length polygon)) point)

      [0..length polygon - 1]

Na, most hogy van egy tömbünk Bool értékekkel, ideje lenne őket kiértékelni. Minden bool azt mutatja, hogy az adott szakasztól jobbra vagy balra van-e a pontunk. Ugyebár akkor van a polygonban, ha minden szakasztól balra van, tehát minden True. Ezt úgy lehet a legjobban megoldani, hogy && operátorral "összeéseljük" őket. Erre van kitalálva a foldl1 (foldl, foldl', foldl1, foldr, foldr1, stb...), ami megkap egy operátort, meg egy tömböt, aztán fogja az első két elemet, applikálja rájuk az operátort, majd az eredményre és a harmadik elemre is, majd ennek az eredményére és a negyedikre is stb. (Ez a foldl - az l a leftből van. A foldr jobbról megy végig a listán. Vannak esetek, amikor ez a célravezetőbb.) Nyilván az üres tömbre hibát fog adni. Pedáns olvasóknak:

foldl1 :: (a -> a -> a) -> [a] -> a

Megvan minden, ami kell. A fentebb megírt boolArrayra használva így néz ki:

result = foldl1 (&&) boolArray

Persze erre a HLint kiböki, hogy "foldl1 (&&)" helyett talán olvashatóbb lenne, ha "and"-et használnánk, így a kód:

result = and boolArray

Ezekután pár szépítgetés után el is juthatunk a fent látott isPointInPolygonhoz. Köszöntem a figyelmet.

Szólj hozzá!

Címkék: tech ház fejlesztés generálás haskell

A bejegyzés trackback címe:

https://survivedev.blog.hu/api/trackback/id/tr933630622

Kommentek:

A hozzászólások a vonatkozó jogszabályok  értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai  üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a  Felhasználási feltételekben és az adatvédelmi tájékoztatóban.

Nincsenek hozzászólások.
süti beállítások módosítása