This is an old revision of the document!


Laboratorul 01

Bun venit la prima activitate practică a acestei materii! În fiecare săptămână, până la finalul semestrului, vom folosi un framework adaptat special pentru aceste activități practice. Framwork-ul este scris în limbajul C++ și folosește API-ul grafic OpenGL. Primul pas al acestui laborator este să realizați setup-ul framework-ului .

Pentru bibliografie suplimentară în legatură cu conceptul de vector, aplicat explicit în contextul graficii pe calculator, puteți accesa următorul articol:

  • Goldman, Ronald. (2002). On the algebraic and geometric foundations of computer graphics. ACM Trans. Graph.. 21. 52-86. 10.1145/504789.504792.

Triunghiul

Triunghiul este un poligon cu 3 colțuri și 3 laturi.

Aria unui triunghi oarecare

Pentru calcularea ariei unui triunghi oarecare, se poate folosi formula lui Heron, ce utilizează semiperimetrul triunghiului:

$$ A_{\Delta P_1 P_2 P_3} = \sqrt{s \cdot (s-a) \cdot (s-b) \cdot (s-c)} \\ s = \frac{1}{2} \cdot (a+b+c) \\ a=\lVert P_1-P_2 \rVert \\ b=\lVert P_1-P_3 \rVert \\ c=\lVert P_2-P_3 \rVert \\ $$

unde $P_1$ , $P_2$ și $P_3$ sunt punctele de la colțurile triunghiului, conform imaginii de mai jos:

Punct în interiorul unui triunghi

Pentru a verifica dacă un punct se află în interiorul unui triunghi, se pot folosi ariile triunghiului și cele ale triunghiurilor formate de punct cu perechi de vârfuri din triunghi. În imaginea de mai jos se pot vedea aceste suprafețe.

Astfel, în situația în care suma ariilor triunghiurilor interioare este egală cu aria triunghiului, punctul se află în interior.

$$ A_{\Delta P_1 P_2 P_3} = A_{\Delta P P_1 P_3} + A_{\Delta P P_1 P_2} + A_{\Delta P P_2 P_3} $$

unde $P$ este punctul pentru care se verifica faptul că se află în triunghi. Un exemplu de configurație pentru $P$ se poate vedea în imaginea de mai jos.

</hidden>

Laborator

Biblioteca glm

În framework-ul de laborator, se utilizează biblioteca glm , ce pune la dispoziție structuri de date pentru puncte și vectori, împreună cu operațiile uzuale de lucru cu aceste elemente.

Definirea unui obiect de tip vector în spațiul $\mathbb{R}^2$ se realizează după cum urmează:

glm::vec2 v = glm::vec2(4.0f, 3.0f);

Accesarea componentelor individuale ale unui vector se realizează:

float x = v.x;
float y = v.y;

Obținerea unui vector prin diferența a două puncte:

glm::vec2 p1 = glm::vec2(2, 2);
glm::vec2 p2 = glm::vec2(6, 5);
 
glm::vec2 v12 = p2 - p1;

Compunerea a 2 vectori:

glm::vec2 v1 = glm::vec2(3.0f, 1.0f);
glm::vec2 v2 = glm::vec2(2.0f, 3.0f);
 
glm::vec2 v_res = v1 + v2;

Obținerea magnitudinii unui vector:

glm::vec2 v = glm::vec2(4.0f, 3.0f);
 
float norm = glm::length(v);

Obținerea unui vector unitate pe direcția unui alt vector dat:

glm::vec2 v = glm::vec2(4.0f, 3.0f);
 
glm::vec2 vu = glm::normalize(v);

Produsul scalar a doi vectori:

glm::vec2 v1 = glm::vec2(2, 2);
glm::vec2 v2 = glm::vec2(6, 5);
 
float res = glm::dot(v1, v2);

Descrierea culorilor

Conceptul de culoare este unul complex, care ar putea necesita conținutul unui curs în sine. În domeniul graficii pe calculator, se utilizează modele matematice, denumite modele de culoare pentru a prelucra o astfel de informație. În practică, API-urile grafice, precum și API-ul OpenGL, pe care îl utilizăm în cadrul framework-ului, utilizează modelul de culoare RGB, la care ne vom rezuma și noi până la finalul semestrului.

Modelul de culoare RGB descrie culorile prin descompunerea lor în 3 culori primare, respectiv: roșu, verde și albastru. Acronimul „RGB” provine de la numele lor în limba engleză: „Red”, „Green” și „Blue”.

În cadrul laboratorului, se poate utiliza o structură de tip glm::vec3, ce conține 3 componente, analog structurii glm::vec2, la care se mai adaugă componenta z. Se utilizează această structură de date doar pentru a stoca un triplet de valori ce este interpretat sub formă de culoare în modelul RGB. API-ul grafic OpenGL interpretează valoarea fiecărei componente a tripletului între limitele 0 și 1. Mai jos sunt descrise cateva culori de baza formate din valorile tripletelor.

glm::vec3 red_color = glm::vec3(1, 0, 0);
glm::vec3 green_color = glm::vec3(0, 1, 0);
glm::vec3 blue_color = glm::vec3(0, 0, 1);
 
glm::vec3 yellow_color = glm::vec3(1, 1, 0);
glm::vec3 cyan_color = glm::vec3(0, 1, 1);

Aprofundarea modelelor de culoare depășește conținutul acestui curs. Pentru a obține mai multe informații despre acest subiect, puteți consulta următoarele cărți:

  • Levkowitz, Haim, ed. Color theory and modeling for computer graphics, visualization, and multimedia applications. Boston, MA: Springer US, 1997.
  • Fairchild, Mark D. Color appearance models. John Wiley & Sons, 2013.

Metode utilitare

În cadrul acestui laborator, sunt oferite metode specifice pentru desenarea mai multor tipuri de primitive grafice. Semnăturile acestor metode sunt scrise mai jos. Consultați fișierul primitives_rendering_scene.h pentru o descriere mai detaliată a fiecărui parametru al metodelor.

void RenderVector(const glm::vec2 &v, const glm::vec3 &color, const std::string& label = std::string (), const glm::vec2 &p = glm::vec2(0.0f));
void RenderPoint(const glm::vec2 &p, const glm::vec3 &color, const std::string &label = std::string());
void RenderArc(float start_angle, float angle, const glm::vec3 &color, float radius = 3.0f, const glm::vec2 &center = glm::vec2(0.0f));
void RenderTriangle(const glm::vec2 &p1, const glm::vec2 &p2, const glm::vec2 &p3, const glm::vec3 &color);
void RenderText(const glm::vec2 &p, const std::string &text, float size, const glm::vec3 &color);

Cerințe laborator

În cadrul acestui laborator, veți avea de rezolvat 6 cerințe distincte. Pentru a schimba între panourile specifice cerințelor, apăsați tastele 1, 2, 3, 4, 5 și 6 de la tastatură.

Completați fisierul lab01.cpp cu următoarele:

  1. 0.05p - Completați metoda Exercise1() astfel:
    1. Desenați vectorui rezultant în urma compunerii vectorilor $\vec{V_1}$ și $\vec{V_2}$ .
    2. Desenați vectorul $\vec{V_2}$ în continuarea lui $\vec{V_1}$ și vectorul $\vec{V_1}$ în continuarea lui $\vec{V_2}$ , conform procesului de compunere a doi vectori, descris mai sus.
      Utilizați metoda RenderVector(…) pentru desenarea unui vector. După rezolvarea acestei cerințe, ar trebui să obțineți rezultatul următor:
  2. 0.05p - Completați metoda Exercise2() pentru desenarea următorilor vectori rezultanți în urma diferenței dintre două puncte: $\{\vec{V_{21}}, \vec{V_{43}}, \vec{V_{56}}, \vec{V_{87}}\}$ .
    După rezolvarea acestei cerințe, ar trebui să obțineti rezultatul următor:
  3. 0.05p - Completați metoda Exercise3() astfel:
    1. Desenați vectorii unitate aflați pe direcția celor 5 vectori prezenți în cadrul cerinței.
    2. Nu utilizați etichete pentru desenarea vectorilor unitate.
      După rezolvare, ar trebui să obțineți rezultatul următor:
  4. 0.05p - Completați metoda Exercise4() pentru desenarea arcului de cerc dintre cei doi vectori.
    Utilizați metoda RenderArc(…) pentru desenarea arcului de cerc, împreună cu produsul scalar și acos(radians) pentru calcularea unghiului dintre cei 2 vectori. După rezolvarea acestei cerințe, ar trebui să obțineți rezultatul următor:
  5. 0.05p - Completați metoda Exercise5() pentru desenarea valorii ariei fiecăruia dintre cele 3 triunghiuri. Textul trebuie afișat la poziția centrului de greutate al fiecărui triunghi.
    Utilizați formula lui Heron pentru calcularea ariei. Folosiți metoda RenderText(…) pentru desenarea valorii ariei. După rezolvarea acestei cerințe, ar trebui să obțineți rezultatul următor:
  6. 0.05p - Completați metoda Exercise6() pentru desenarea punctelor din listă după următoarea regulă:
    1. Punctele ce se află în interiorul triunghiului se desenează în culoarea verde;
    2. Punctele ce se află în afara triunghiului se desenează în culoarea roșie.
      Deoarece ariile sunt calculate cu tipuri de date în virgulă mobilă, nu se poate folosi direct comparația de egalitate și trebuie să ne asumăm un anumit nivel de eroare în calcule. Astfel, în cod, comparația va fi în felul următor:
      const float EPSILON = 0.01f;
       
      bool inside_triangle = abs(area_v1v2v3 - (area_pv1v3 + area_pv1v2 + area_pv2v3)) < EPSILON;


      După rezolvarea acestei cerințe, ar trebui să obțineți rezultatul următor:

Bonus: În cadrul exercițiului 4, desenați cu o culoare diferită arcul de cerc pentru unghiul mare dintre cei doi vectori. După rezolvarea acestei cerințe, ar trebui să obțineți rezultatul următor:

ipg/laboratoare/01.1790785507.txt.gz · Last modified: 2026/09/30 19:25 by andrei.lambru
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0