Conventii

Uneori cind gindesti un sistem descoperi ca poti face sau reprezenta ceva in mai multe feluri echivalente, si atunci trebuie sa recurgi la o conventie. Bizonul prost ajuns intr-o fundatura d-asta va judeca situatia cu mintea lui si va alege bazindu-se pe ce i se pare lui oportun la momentul ala, ignorind preferintele altora de pina la el.

De obicei cind e nevoie de o conventie, alternativele au merite egale. Nu conteaza ce alegi. Nu e mai bine sa mergi cu masina pe dreapta drumului decit pe stinga lui. E tot aia, deci prima data alegerea se poate face arbitrar. Ceea ce conteaza e sa respecte toata lumea conventia aia si sa nu se trezeasca un bou ca a gasit el nu stiu ce avantaje daca face altfel decit restul lumii, iar alti boi sa se ia dupa el, ducind la schisme, probleme de interoperabilitate si in general haos.

Un teritoriu destul de fertil pentru boi neconventionali este programarea 3D, asa ca ma voi opri asupra a doua cazuri in care s-a gasit un mintos sa faca pe specialu’ si sa nenoroceasca o groaza de oameni care au venit dupa el. Primul e legat de reprezentarea vectorilor.

Cind trebuie sa inmultesti vectori cu matrici ai doua optiuni: ori consideri vectorul ca fiind o linie, si faci v’ = vM, ori consideri vectorul ca fiind o coloana, si faci v’ = Mv. In toate cartile de mate se foloseste a doua varianta, asa ca s-au gasit unii sa remarce ca nu e bine si sa faca invers. Rezultatul e ca DirectX si o groaza de alte chestii sint in momentul de fata in dezacord direct cu matematica, asa ca daca incerci sa treci de la una la alta, te ia rapid cu dureri de cap. Ca sa fie si mai misto, multi oameni confunda “column major” si “row major” cu “column vector” si “row vector”, ducind la un haos complet in terminologie. Cind dai prima data peste un sistem cu propria biblioteca de algebra liniara, esti intr-o mare ceata si sint sanse ca documentatia sa nu te scoata, pentru ca unii au simtit nevoia sa-si puna mintea la contributie cind nu era cazul. In unele manifestari de prostie deosebita, cum e 3D Studio Max, biblioteca de mate chiar are doi operatori de inmultit vectori cu matrici, astfel incit sa poti sa scrii si v*M, si M*v, si sa se intimple acelasi lucru.

Din punct de vedere matematic se poate argumenta ca e mai bine sa folosesti vectori coloane, pentru ca sa nu ajungi la spital cind ai nevoie sa derivezi functii. Chris Hecker da un exemplu aici. Pe rebelii carora le datoram dezastrul asta i-au preocupat insa alte lucruri. Un argument des intilnit este ca daca iti place pe invers, poti implementa mai eficient inmultirile intre vectori si matrici pe procesoare SIMD care n-au operatiuni orizontale (produs scalar, in speta). Cu vectori coloana poti inmulti vectorul cu o linie a matricei intr-o singura instructiune, dar dupa aia trebuie sa despachetezi numerele rezultate si sa le aduni intre ele pe rind. In 3D cu coordonate omogene, asta ar veni vreo 4 inmultiri, 8 adunari, 8 shuffle-uri si 4 store-uri (cel putin in SSE). Cu vectori linie, poti inmulti fiecare linie a matricei cu o componenta a vectorului in 2 instructiuni (un shuffle si un mul), dupa care acumulezi rezultatele si ajungi la vectorul transformat, deci ai 4 inmultiri, 4 shuffle-uri, 3 adunari si 1 store (plus mai putine dependinte deci pipelining mult mai bun). S-ar parea ca miracolul graficii 3D realtime a fost facut posibil prin scuiparea matematicii intre ochi, dar nu-i chiar asa.

Daca chiar ai nevoie sa optimizezi inmultirile dintre matrici si vectori, poti sa-ti tii matricile transpuse in memorie, sau “column major”, adica in a[0] – a[3] e prima coloana a matricei, nu prima linie. Layout-ul in memorie nu impune notatia. Poti scrie frumos v’ = Mv peste tot si sa ai un operator care se foloseste asa, dar sa-ti tii matricile column major si sa beneficiezi de viteza superluminica a tehnologiilor SIMD. Totusi, s-ar putea sa n-ai un bottleneck in inmultirea matricilor cu vectorii (mai ales daca traiesti in prezent), sau sa ai un procesor SIMD cu instructiuni orizontale, sau ambele. In particular, GPU-urile au o instructiune de produs scalar, deci daca folosesti vectori coloana, o transformare in GPU se face in 4 instructiuni si atit. D-aia aplicatiile care folosesc matricile din DirectX le tot transpun inainte sa le trimita la shadere. Noroc ca ar putea merge foarte repede inmultirile pe CPU, asta daca s-ar face vreo inmultire acolo.

A doua conventie despre care fiecare pionier al graficii 3D a simtit nevoia sa-si dea cu parerea este aranjarea axelor de coordonate. Daca pui un elev de clasa a 8-a sa-ti deseneze axele de coordonate in spatiu, primesti inapoi ori o privire timpa, ori asta:

Nu e greu. X la dreapta, Y in sus, Z inspre tine. Asa a invatat toata lumea la scoala, nu e nevoie de opinii suplimentare. Nu e mai bine daca il pui pe Z in sus, sau pe X la stinga. Se aude si acolo in spate la 3D Studio Max, in pula mea? Atunci cind treci din 3D in 2D – cum ar veni, atunci cind proiectezi – vrei sa ramii cu X la dreapta si Y in sus. Nu vrei ca axele cu care ramii sa se cheme X si Z. Oamenii normali stau in picioare si privesc inainte. D-aia daca nu esti pe medicamente, Z e adincimea.

La Max n-au lucrat niciodata oameni normali, ci doar labari care nu stiu nimic despre programare. In general, chiar daca un soft e foarte prost, se va gasi cineva care sa incerce sa domoleasca discutiile aprinse cu cuvintele magice “da, dar…”. La Max nu e asa. Orice programator care s-a atins vreodata de SDK-ul lui il uraste cu pasiune. Nimeni nu incearca sa-i gaseasca scuze. In Max, Z este inaltimea. Ca sa ajungi la o asemenea idee ca programator, trebuie sa fii obisnuit sa stai mult pe burta si sa privesti lumea de sus, adica fix pozitia in care-i sta cel mai bine unui muist care crede ca e cool sa descrii atributele nodurilor trimitind sute de parametri la un constructor variadic. Puletul care a facut asta a vrut si el, ca toata lumea, sa ramina cu X si Y cind trece in 2D, dar el se uita de sus, nu din fata, crezindu-se probabil arhitect (d-ala care proiecteaza cladiri, nu d-ala care crede ca design pattern-urile sint chestii interesante si utile). Si din cauza lui si a altora ca el, importatul geometriei dintr-o aplicatie in alta e putin mai greu decit ar trebui sa fie, ca de ce sa avem si noi o viata mai usoara si sa ne concentram pe lucrurile importante, cind putem sa pierdem vremea schimbind axe prin vertecsi si coloane prin matrici. Important e sa fie un jegos fericit ca si-a construit o lume dupa chipul si asemanarea lui, nu dupa cum faceau toti prostii de pina la el.

PS: A da, si e “bitangenta”, nu “binormala”, ca suprafetele n-au doua normale.

Tags: , , , , , , , ,

6 Responses to “Conventii”

  1. BloodRain Says:

    Nu stiu daca chiar orice elev de a 8-a ar desena asa axele. Eu am invatat in liceu sa le fac asa(x pe post de depth, y spre dreapta si z in sus) : http://ro.wikipedia.org/wiki/Fi%C8%99ier:Rectangular_coordinates.svg

    La facultate (Poli bucuresti automatica si calculatoare) am uitat conventia si am desenat ca in poza ta. Seminarista m-a pus sa sterg si sa fac ca in poza mea si m-a intrebat unde am invatat eu sa fac axele asa. Am incercat eu sa explic ca iei 2 dimensiuni, le lasi asa cum erau si mai adaugi o axa, nu le modifici iar pe toate. Oricum problema era la fel…

  2. Mihnea Says:

    Astia cu Y la dreapta si Z in sus sint si mai retardati. N-am mai vazut asa ceva pina acum, dar observ ca pe wikipedia e plin de desene d-astea pagine.

  3. Tudor Says:

    E doar o conventie – un matematician sau arhitect care se gandeste la coordonatele in plan xy, e mai normal sa le deseneze intr-un plan orizontal, si z sa reprezinte cea de a treia dimensiune, adica inaltimea.
    Matematicienii “de moda veche” cel mai adesea se gandesc la planul orizontal pe care e pusa o hartie pe o masa, sau la o harta plana asezata pe pamant.

    Pentru un programator, e mai normal sa vada planul dat de xy ca fiind planul monitorului (asezat vertical de obicei), si z “adancimea”..

  4. Cristi Says:

    http://web.mit.edu/8.02t/www/materials/modules/ReviewB.pdf
    http://www.geom.uiuc.edu/docs/reference/CRC-formulas/node39.html
    http://www.math.montana.edu/frankw/ccp/multiworld/multipleIVP/spherical/learn.htm

  5. RRR Says:

    De când mă ştiu, peste tot prin şcoală am fost învăţat să fac axele aşa: http://pastebin.com/gRKGWxyf .
    Mi s-a părut ciudat când, în opengl, a trebuit să trec la XOY în planul monitorului si OZ spre mine.

  6. Mihnea Says:

    Eu l-am invatat la scoala p-ala cu Y in sus, nu mi-am imaginat ca exista disensiuni si la nivelul clasei a 8-a. Ala are meritele lui in 3D in general, asta desenat de tine are meritele lui in arhitectura, ala al lu’ D3D are si el alt set de merite in 3D, dar toate sint chichite pina la urma. Pe mine nu ma framinta care-i mai bun, ma oftica ca se folosesc toate permutarile posibile in loc sa fie una si gata.

Leave a Reply

Optionally add an image (JPEG only)