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.
Un vector are asociate următoarele 2 proprietăți:
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.
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} $$
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.
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 în 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 obținută 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.
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 :) .
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.
Datorită construcției funcției trigonometrice cosinus, $\cos\theta_1=\cos\theta_2$ .
Triunghiul este un poligon cu 3 colțuri și 3 laturi.
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:
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.
Î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);
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);
Î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 ¢er = 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);
Completați fisierul lab01.cpp
cu următoarele:
Exercise1()
astfel:RenderVector(…)
pentru desenarea unui vector. După rezolvarea acestei cerințe, ar trebui să obțineți rezultatul următor: Exercise3()
astfel:Exercise4()
pentru desenarea arcului de cerc dintre cei doi vectori. 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: 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. RenderText(…)
pentru desenarea valorii ariei. După rezolvarea acestei cerințe, ar trebui să obțineți rezultatul următor: Exercise6()
pentru desenarea punctelor din listă după următoarea regulă: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: