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 .

Elemene de geometrie

Vectorul

Vectorul reprezintă un instrument matematic ce descrie deplasamentul unui punct de la o poziție inițială la o poziție finală.

Un astfel de exemplu se poate vedea în imaginea de mai jos, unde vectorul $\vec{V_{12}}$ descrie deplasamentul de la poziția la care se află punctul $P_1$ , la poziția la care se află punctul $P_2$ . Se poate observa faptul că simbolul grafic ce descrie un element de tip vector reprezintă numele elementului, acompaniat de o sageată ce este poziționată deasupra lui.

Termenul de vector provine din limba latină și se traduce în limba română prin “transportator”. Interpretarea aceasta are aplicabilități în domeniul medical, unde se utilizează structura “vector de propagare”. Vizual, aplicarea conceptului de vector în domeniul matematic se poate asocia cu procesul de “transportare” a unui element de la o poziție la o altă poziție într-un spațiu.

Un vector are asociate următoarele 2 proprietăți:

  • Magnitudine, respectiv lungimea distanței vectorului;
  • Direcție; acest concept se va elabora în laboratorul 3.

Un vector se definește printr-o mulțime ordonată de $n$ elemente, pe baza numărului de dimensiuni ale spațiului în care este construit. Pentru vectorul din imaginea de mai sus, descrierea este în felul următor:

$$ \vec{V_{12}} = \begin{bmatrix} 4 & 3 \end{bmatrix} $$

Analog, pentru un vector în spațiul $\mathbb{R}^3$ , el poate fi definit după cum urmează:

$$ \vec{V_{\mathbb{R}^3}} = \begin{bmatrix} 4 & 3 & 1 \end{bmatrix} $$

În situația în care considerăm conceptul de vector în alt context decât cel de descriere a unui deplasament între două puncte, el se descrie vizual printr-o sageată trasată din originea axelor de coordonate, la poziția definită de mulțimea ordonată de $n$ elemente. Pentru această reprezentare vizuală, considerăm faptul că plasăm coada săgeții în originea axelor și capul în poziția descrisă de mulțimea ordonată. Pentru vectorul de mai sus, reprezentarea vizuală este descrisă în imaginea de mai jos.

Toată discuția din acest laborator, împreună cu imaginile demonstrative și aplicațiile, se rezumă la utilizarea conceptului de vector în spațiul $\mathbb{R}^2$. Cu toate acestea, este important de menționat faptul că toate conceptele prezentate sunt valabile și pentru spațiul $\mathbb{R}^3$ și pentru orice alt spațiu $\mathbb{R}^n$. Diferența dintre utilizarea unui vector în spațiul $\mathbb{R}^2$ față de un spațiu $\mathbb{R}^n$ este dată de faptul că formula comună pentru primele 2 componente ale unui vector din spațiul $\mathbb{R}^2$ se aplică pentru restul de n-2 ale spațiului $\mathbb{R}^n$.

Definirea prin diferența a 2 puncte

Un punct reprezintă un instrument matematic ce este definit doar printr-o poziție. Vizual, putem considera că este o formă geometrică descrisă doar printr-o poziție, ce are dimensiunea 0. În practică, punctul este utilizat pentru a descrie poziții în spațiu.

Situația face că un punct se definește la fel precum un vector, printr-o mulțime ordonată de $n$ elemente, pe baza numărului de dimensiuni ale spațiului în care este descris punctul. Este important de considerat în momentul în care se lucrează cu puncte și vectori care este interpretarea fiecărui element. Altfel spus, este important să știm ce element este punct și ce element este vector. În toate formulele din acest laborator, se poate observa că vectorii sunt marcați corespunzător prin simbolul matematic specific.

$$ \vec{V_{12}} = P_2-P_1 = \begin{bmatrix} x_{P_2} - x_{P_1} & y_{P_2}-y_{P_1} \end{bmatrix} $$

Analog, vectorul în direcție opusă, vizibil în imaginea de mai jos, se obține după următoarea formulă:

$$ \vec{V_{21}} = P_1-P_2 = \begin{bmatrix} x_{P_1} - x_{P_2} & y_{P_1}-y_{P_2} \end{bmatrix} $$

În situația în care doriți să obțineți vectorul de deplasare de la punctul $P_1$ la punctul $P_2$ , în direcția spre $P_2$ , se calculeaza vectorul de diferență $\vec{V_{12}}=P_2-P_1$ . Cu alte cuvinte, punctul spre care doriți să obțineți vectorul rezultant este cel din care scădeți punctul de la care pleacă vectorul.

Adunarea unui punct cu un vector

Analog operației descrise mai sus, putem considera operația inversă, în care adunăm un punct cu un vector. Rezultatul se poate observa în imaginea de mai jos și se poate descrie cu următoarea formulă:

$$ P_{res} = P + \vec{V} = (x_{P}+x_{\vec{V}}, y_{P}+y_{\vec{V}}) $$

Se poate observa și din formulă faptul că în urma adunării unui punct cu un vector, se obține un punct. Este important de menționat faptul că interpretarea ce oferă cele mai multe aplicabilități este cea în care rezultatul este un punct. Schimbarea interpretării rezultatului descrie procesul de compunere a 2 vectori, prezentat mai jos, dar această schimbare nu este consistentă matematic, deoarece interpretarea unuia dintre elementele adunării este un punct.

O observație importantă este faptul că operația de adunare a unui punct cu un vector este comutativă. Prin interschimbarea interpretării celor două elemente din adunare, se obține un punct cu aceleași coordonate.

Compunerea a 2 vectori

Procesul de compunere a 2 vectori produce un alt vector, conform formulei de mai jos:

$$ \vec{V_{res}} = \vec{V_1} + \vec{V_2} = \begin{bmatrix} x_{\vec{V_1}} + x_{\vec{V_2}} & y_{\vec{V_1}}+y_{\vec{V_2}} \end{bmatrix} $$

Procesul de compunere a 2 vectori se poate reprezenta grafic prin plasarea celui de-al doilea vector in continuarea primului. Mai exact, se poate plasa coada săgeții celui de-al doilea vector în capătul sageții primului vector. Dupa acest pas, săgeata obtinuta prin trasarea ei de la coada primului vector la capătul celui de-al doilea este reprezentarea vizuală a vectorului rezultant. Acesta din urmă se află pe direcția bisectoarei unghiului dintre cei doi vectori. Procesul descris se poate observa în imaginea de mai jos.

Procesul de compunere de vectori are aplicabilitate în geometrie prin faptul că descrie o operație cu care se pot prelucra direcții. Un exemplu de aplicabilitate este compunerea unei direcții de deplasare a unui obiect cu o alta dată de direcția de accelerație a obiectului, ce este diferită de cea de deplasare. Prin procesul de compunere a celor două directii, se obține direcția de deplasare la cadrul curent.

Vectorul unitate

Un vector unitate este un vector ce are lungimea 1.

Un astfel de vector are aplicabilități în programarea jocurilor video pentru realizarea animațiilor continue și în grafica pe calculator pentru simularea efectului de iluminare. Majoritatea situațiilor de utilizare necesită obținerea unui vector unitate $\vec{V_u}$ , ce are aceeași direcție cu un alt vector $\vec{V}$ dat. Pentru a obține acest vector $\vec{V_u}$ , se poate folosi formula de mai jos.

$$ \vec{V_u} = \frac{\vec{V}}{\lVert \vec{V} \rVert} = \begin{bmatrix} \frac{x_{\vec{V}}}{\lVert \vec{V} \rVert} & \frac{y_{\vec{V}}}{\lVert \vec{V} \rVert} \end{bmatrix} $$

unde $\lVert \vec{V} \rVert$ este norma sau lungimea vectorului $\vec{V}$ , ce se calculează după următoarea formulă:

$$ \lVert \vec{V} \rVert = \sqrt{{x_{\vec{V}}}^2+{y_{\vec{V}}}^2} $$

Obținerea vectorului $\vec{V_u}$ poartă denumirea de normalizare a vectorului $\vec{V}$ , deoarece se împarte fiecare componentă la norma lui :) .

Produsul scalar a doi vectori

Această operație produce la finalul ei un scalar. Definiția algebrică a acestui produs este următoarea:

$$ \vec{V_1}\cdot\vec{V_2} = x_{\vec{V_1}}x_{\vec{V_2}} + y_{\vec{V_1}}y_{\vec{V_2}} $$

O interpretare importantă a produsului scalar este în context geometric. Formula de mai sus este echivalentă cu următoarea:

$$ \vec{V_1}\cdot\vec{V_2} = \lVert \vec{V_1} \rVert \lVert \vec{V_2} \rVert \cos{\theta} $$

unde $\theta$ este unghiul dintre cei doi vectori, conform imaginii de mai jos.

Este important de observat faptul că în urma construcției a doi vectori, se pot forma 2 unghiuri între cei doi:

  • $\theta_1<=180^\circ$ ;
  • $\theta_2=360^\circ-\theta_1>=180^\circ$ .

Datorită construcției funcției trigonometrice cosinus, $\cos\theta_1=\cos\theta_2$ .

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$ si $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.

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 = position.x;
float y = position.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 magnitude = 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

TBA

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 - Completati metoda Exercise1() astfel:
    1. Desenati vectorui rezultant in urma compunerii vectorilor $\vec{V_1}$ si $\vec{V_2}$ .
    2. Desenati vectorul $\vec{V_2}$ in continuarea lui $\vec{V_1}$ si vectorul $\vec{V_1}$ in continuarea lui $\vec{V_2}$ , conform procesului de compunere a doi vectori, descris mai sus.
      Utilizati metoda RenderVector(…) pentru desenarea unui vector. Dupa rezolvarea acestei cerinte, ar trebui sa obtineti rezultatul urmator:
  2. 0.05p - Completati metoda Exercise2() pentru desenarea urmatorilor vectori rezultanti in urma diferentei dintre doua puncte: $\{\vec{V_{21}}, \vec{V_{43}}, \vec{V_{56}}, \vec{V_{87}}\}$ .
    Dupa rezolvarea acestei cerinte, ar trebui sa obtineti rezultatul urmator:
  3. 0.05p - Completati metoda Exercise3() astfel:
    1. Desenati vectorii unitate aflati pe directia celor 5 vectori prezenti in cadrul cerintei.
    2. Nu utilizati etichete pentru desenarea vectorilor unitate.
      Dupa rezolvare, ar trebui sa obtineti rezultatul urmator:
  4. 0.05p - Completati metoda Exercise4() pentru desenarea arcului de cerc dintre cei doi vectori.
    Utilizati metoda RenderArc(…) pentru desenarea arcului de cerc, impreuna cu produsul scalar si acos(radians) pentru calcularea unghiului dintre cei 2 vectori. Dupa rezolvarea acestei cerinte, ar trebui sa obtineti rezultatul urmator:
  5. 0.05p - Completati metoda Exercise5() pentru desenarea valorii ariei fiecaruia dintre cele 3 triunghiuri. Textul trebuie afisat la pozitia centrului de greutate al fiecarui triunghi.
    Utilizati formula lui Heron pentru calcularea ariei. Folositi metoda RenderText(…) pentru desenarea valorii ariei. Dupa rezolvarea acestei cerinte, ar trebui sa obtineti rezultatul urmator:
  6. 0.05p - Completati metoda Exercise6() pentru desenarea punctelor din lista dupa urmatoarea regula:
    1. Punctele ce se afla in interiorul triunghiului se deseneaza in culoarea verde;
    2. Punctele ce se afla in afara triunghiului se deseneaza in culoarea rosie.
      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;


      Dupa rezolvarea acestei cerinte, ar trebui sa obtineti rezultatul urmator:

ppbg/laboratoare/01.1727190975.txt.gz · Last modified: 2024/09/24 18:16 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