Zde můžete vidět rozdíly mezi vybranou verzí a aktuální verzí dané stránky.
| Následující verze | Předchozí verze | ||
| pitel:izg:lab06 [03. 07. 2012, 11.53:35] – upraveno mimo DokuWiki 127.0.0.1 | pitel:izg:lab06 [30. 12. 2022, 13.43:01] (aktuální) – upraveno mimo DokuWiki 127.0.0.1 | ||
|---|---|---|---|
| Řádek 1: | Řádek 1: | ||
| + | ====== 3D transformace ====== | ||
| + | [[http:// | ||
| + | <file cpp student.cpp> | ||
| + | /////////////////////////////////////////////////////////////////////////////// | ||
| + | // Soubor studentskych funkci | ||
| + | /////////////////////////////////////////////////////////////////////////////// | ||
| + | |||
| + | #include " | ||
| + | |||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | |||
| + | |||
| + | /////////////////////////////////////////////////////////////////////////////// | ||
| + | // name spaces | ||
| + | |||
| + | using namespace std; | ||
| + | |||
| + | /////////////////////////////////////////////////////////////////////////////// | ||
| + | // prace s transformacni matici | ||
| + | /////////////////////////////////////////////////////////////////////////////// | ||
| + | |||
| + | class Matrix | ||
| + | { | ||
| + | double data[16]; | ||
| + | |||
| + | public: | ||
| + | // inicializuje matici na jednotkovou | ||
| + | Matrix() { LoadIdentity(); | ||
| + | | ||
| + | // pristup k " | ||
| + | double *operator [] (int row) { return (data + row*4); } | ||
| + | |||
| + | // nastavi matici na jednotkovou | ||
| + | void LoadIdentity() | ||
| + | { | ||
| + | for (int i = 0; i < 4; i++) | ||
| + | for (int j = 0; j < 4; j++) | ||
| + | data[i*4 + j] = (i == j) ? 1.0 : 0.0; | ||
| + | } | ||
| + | |||
| + | // kdyby si to nekdo chtel vypsat, aby zkontroloval, | ||
| + | void Print() | ||
| + | { | ||
| + | cout << " | ||
| + | for (int i = 0; i < 4; i++) { | ||
| + | for (int j = 0; j < 4; j++) { | ||
| + | cout << ios_base:: | ||
| + | } | ||
| + | cout << endl; | ||
| + | } | ||
| + | } | ||
| + | }; | ||
| + | |||
| + | /////////////////////////////////////////////////////////////////////////////// | ||
| + | // aktivni matice | ||
| + | |||
| + | Matrix transf; | ||
| + | |||
| + | /////////////////////////////////////////////////////////////////////////////// | ||
| + | // operace nad aktivni matici | ||
| + | |||
| + | // nastavi transformaci na zadanou matici | ||
| + | void trSetMatrix(const Matrix &m) | ||
| + | { | ||
| + | transf = m; | ||
| + | } | ||
| + | |||
| + | // vraci aktualni transformaci | ||
| + | const Matrix & | ||
| + | { | ||
| + | return transf; | ||
| + | } | ||
| + | |||
| + | // resetuje transformacni matici na jednotkovou | ||
| + | void trLoadIdentity() | ||
| + | { | ||
| + | transf.LoadIdentity(); | ||
| + | } | ||
| + | |||
| + | // skladani transformaci (aktualni transformaci vynasobi zadanou matice) | ||
| + | void trMultMatrix(Matrix &m) | ||
| + | { | ||
| + | Matrix newtransf; | ||
| + | for (int i = 0; i < 4; i++) { | ||
| + | for (int j = 0; j < 4; j++) { | ||
| + | newtransf[i][j] = 0; | ||
| + | for (int x = 0; x < 4; x++) { | ||
| + | newtransf[i][j] += m[i][x] * transf[x][j]; | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | trSetMatrix(newtransf); | ||
| + | } | ||
| + | |||
| + | /////////////////////////////////////////////////////////////////////////////// | ||
| + | // funkce, ktere provadeji ruzne druhy transformace | ||
| + | |||
| + | // vynasobi hlavni matici translacni matici (ktera objekt posouva o zadane vzdalenosti) | ||
| + | void trTranslate(double dx, double dy, double dz) | ||
| + | { | ||
| + | Matrix m; | ||
| + | |||
| + | m[3][0] = dx; | ||
| + | m[3][1] = dy; | ||
| + | m[3][2] = dz; | ||
| + | |||
| + | trMultMatrix(m); | ||
| + | } | ||
| + | |||
| + | // vynasobi hlavni matici rotacni matici kolem osy Y | ||
| + | void trRotateY(double angle) | ||
| + | { | ||
| + | Matrix m; | ||
| + | |||
| + | // aby se goniometricke funkce nepocitaly dvakrat, kdyz to staci jednou... | ||
| + | double sina = sin(angle); | ||
| + | double cosa = cos(angle); | ||
| + | |||
| + | m[0][0] = cosa; | ||
| + | m[0][2] = sina; | ||
| + | m[2][0] = -sina; | ||
| + | m[2][2] = cosa; | ||
| + | |||
| + | trMultMatrix(m); | ||
| + | } | ||
| + | |||
| + | // vynasobi hlavni matici rotacni matici kolem osy X | ||
| + | void trRotateX(double angle) | ||
| + | { | ||
| + | Matrix m; | ||
| + | | ||
| + | // aby se goniometricke funkce nepocitaly dvakrat, kdyz to staci jednou... | ||
| + | double sina = sin(angle); | ||
| + | double cosa = cos(angle); | ||
| + | | ||
| + | m[1][1] = cosa; | ||
| + | m[1][2] = sina; | ||
| + | m[2][1] = -sina; | ||
| + | m[2][2] = cosa; | ||
| + | |||
| + | trMultMatrix(m); | ||
| + | } | ||
| + | |||
| + | // vynasobi hlavni matici projekcni matici, ktera zaridi PERSPEKTIVNI promitani | ||
| + | void trProjectionPerspective(double d) | ||
| + | { | ||
| + | Matrix m; | ||
| + | |||
| + | m[2][2] = 0.0; | ||
| + | m[2][3] = 1.0 / d; | ||
| + | |||
| + | trMultMatrix(m); | ||
| + | } | ||
| + | |||
| + | |||
| + | /////////////////////////////////////////////////////////////////////////////// | ||
| + | // funkce k vykresleni promitnute usecky, apod. | ||
| + | /////////////////////////////////////////////////////////////////////////////// | ||
| + | |||
| + | // promitne bod ve 3D | ||
| + | // x,y,z souradnice ve 3D | ||
| + | // u,v souradnice na obrazovce promitnute matici transf | ||
| + | void ProjectVertex(int &u, int &v, double x, double y, double z) | ||
| + | { | ||
| + | // vynasobeni vektoru (x,y,z,1) transformacni matici - vyjde vektor (xx, | ||
| + | double xx = x*transf[0][0] + y*transf[1][0] + z*transf[2][0] + 1*transf[3][0]; | ||
| + | double yy = x*transf[0][1] + y*transf[1][1] + z*transf[2][1] + 1*transf[3][1]; | ||
| + | double ww = x*transf[0][3] + y*transf[1][3] + z*transf[2][3] + 1*transf[3][3]; | ||
| + | |||
| + | // homogenni souradnice | ||
| + | xx /= ww; | ||
| + | yy /= ww; | ||
| + | | ||
| + | // vypocteni promitnutych souradnic - meritko odvozeno od frame_h v obou osach... | ||
| + | u = int(xx + frame_w/2); | ||
| + | v = int(yy + frame_h/2); | ||
| + | } | ||
| + | |||
| + | // vykresli usecku zadanou ve 3D po promitnuti transformaci | ||
| + | // x1, | ||
| + | // x2, | ||
| + | void ProjectLine(double x1, double y1, double z1, | ||
| + | | ||
| + | const S_RGBA &color) | ||
| + | { | ||
| + | // cara se promitne tak, ze se promitnou jeji krajni body | ||
| + | int u1, | ||
| + | ProjectVertex(u1, | ||
| + | ProjectVertex(u2, | ||
| + | DrawLine(u1, | ||
| + | } | ||
| + | |||
| + | // vykresli trojuhelnik zadany ve 3D po promitnuti transformaci | ||
| + | // x1, | ||
| + | // x2, | ||
| + | // x3, | ||
| + | void ProjectTriangle(double x1, double y1, double z1, | ||
| + | | ||
| + | | ||
| + | const S_RGBA &color) | ||
| + | { | ||
| + | // promitnou vrcholy trojuhelniku | ||
| + | int u1, v1, u2, v2, u3, v3; | ||
| + | ProjectVertex(u1, | ||
| + | ProjectVertex(u2, | ||
| + | ProjectVertex(u3, | ||
| + | |||
| + | // testujeme odvracene/ | ||
| + | if (back_face_culling) | ||
| + | { | ||
| + | // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
| + | // MISTO PRO STUDENTSKOU PRACI | ||
| + | // - zjistete zda je trojuhelnik odvraceny nebo privraceny | ||
| + | // - pokud neni viditelny (= odvraceny), tak nic nekreslete | ||
| + | // - test je nutne prevratit pokud promenna invert_culling = -1 | ||
| + | // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
| + | int vect11 = u2 - u1; | ||
| + | int vect12 = v2 - v1; | ||
| + | int vect21 = u3 - u1; | ||
| + | int vect22 = v3 - v1; | ||
| + | int normal = (vect11 * vect22 - vect12 * vect21) * invert_culling; | ||
| + | if (normal > 0) { | ||
| + | return; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | // vykresleni (pouze viditelne viditelne trojuhelniky) | ||
| + | DrawLine(u1, | ||
| + | DrawLine(u2, | ||
| + | DrawLine(u3, | ||
| + | } | ||
| + | |||
| + | |||
| + | /////////////////////////////////////////////////////////////////////////////// | ||
| + | // funkce DrawObject | ||
| + | // - vykresli objekt transformovany aktivni transformacni matici | ||
| + | |||
| + | void DrawObject(const S_RGBA &color) | ||
| + | { | ||
| + | // postupne vykresleni vsech trojuhelniku | ||
| + | T_Triangles:: | ||
| + | for( T_Triangles:: | ||
| + | { | ||
| + | int v0 = it-> | ||
| + | ProjectTriangle(vertices[v0].x, | ||
| + | vertices[v1].x, | ||
| + | vertices[v2].x, | ||
| + | color); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | |||
| + | /////////////////////////////////////////////////////////////////////////////// | ||
| + | // funkce DrawScene() volana z main.cpp | ||
| + | // - vykresli celou scenu vcetne dvou vlozenych objektu | ||
| + | |||
| + | void DrawScene() | ||
| + | { | ||
| + | // vymazani frame bufferu | ||
| + | ClearBuffer(); | ||
| + | |||
| + | // vycistit hlavni matici - do definovaneho stavu | ||
| + | trLoadIdentity(); | ||
| + | |||
| + | // nastavit projekcni matici | ||
| + | trProjectionPerspective(CAMERA_DIST); | ||
| + | |||
| + | // posuv cele sceny | ||
| + | trTranslate(0.0, | ||
| + | |||
| + | // natoceni cele sceny - jen ve dvou smerech - mys je jen 2D... :( | ||
| + | trRotateX(scene_rot_x * 0.01); | ||
| + | trRotateY(scene_rot_y * 0.01); | ||
| + | |||
| + | Matrix backuptransf = transf; | ||
| + | |||
| + | // vykresleni " | ||
| + | ProjectLine(0, | ||
| + | ProjectLine(0, | ||
| + | ProjectLine(0, | ||
| + | ProjectLine(0, | ||
| + | |||
| + | // vykresli objekt cervene | ||
| + | // pridame k nastaveni sceny umisteni a natoceni objektu | ||
| + | trTranslate(obj_move_x * 0.015, obj_move_y * 0.015, 0.0); | ||
| + | trRotateX(obj_rot_x * 0.01); | ||
| + | trRotateY(obj_rot_y * 0.01); | ||
| + | |||
| + | // a s tim co vznikne promitneme nas objekt | ||
| + | invert_culling = 1; | ||
| + | DrawObject(COLOR_RED); | ||
| + | |||
| + | // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
| + | // MISTO PRO STUDENTSKOU PRACI | ||
| + | // - vykresleni objektu soumerneho podle modre roviny | ||
| + | // - volejte DrawObject() | ||
| + | // - pouzijte barvu COLOR_RED2 | ||
| + | // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
| + | Matrix mirror; | ||
| + | invert_culling = -1; | ||
| + | transf = backuptransf; | ||
| + | mirror[0][0] = -1; | ||
| + | trMultMatrix(mirror); | ||
| + | trTranslate(obj_move_x * 0.015, obj_move_y * 0.015, 0.0); | ||
| + | trRotateX(obj_rot_x * 0.01); | ||
| + | trRotateY(obj_rot_y * 0.01); | ||
| + | DrawObject(COLOR_RED2); | ||
| + | } | ||
| + | </ | ||