mirror of
https://github.com/Relintai/programming_tutorials.git
synced 2025-04-23 21:53:28 +02:00
296 lines
15 KiB
Plaintext
Executable File
296 lines
15 KiB
Plaintext
Executable File
rev 1:
|
|
rev 2: abs() képlet hozzáadva.
|
|
rev 3: Hozzáadtam vector és float-os közötti szorzás operátorokat mindkét vektorhoz.
|
|
rev 4: Vector length képlet hozzáadva.
|
|
rev 5: Vector dot() képletben hiányzott egy .y
|
|
rev 6: lenght_squared -> length_squared.
|
|
rev 7: Rect2 is_equal_approx paraméter típus kijavítva.
|
|
rev 8: Rect2 grow, shrink visszatérési érték javítva (Már nincs).
|
|
rev 9: intersects_include_borders typo javítva.
|
|
rev 10: IntVectorba pop_back metódus hozzáadva.
|
|
|
|
1. Implementáld az alábbi 2ds matematikai vektor osztályt:
|
|
|
|
------------------------------------------------|
|
|
| class Vector2 |
|
|
|-----------------------------------------------|
|
|
| + x : float | -> Nincs getter, és szetter, mert azok lassítanának. (Függvényhívásnak van minimális erőforrás igénye)
|
|
| + y : float | -> Ilyen matematikai osztályoknál, érdemes ilyeneket kioptimalizálni. PLussz leírni is sok. getx(), setx() etc.
|
|
| + abs() : Vector2 | -> visszaadja egy új vektorba ennek a vektornak az abszolút értékét. (x, y abszolút értékét veszi)
|
|
| | Abszolút érték képlet: ha egy a < 0 ret -a, else ret a;
|
|
| + angle() float | -> atan2(x, y)
|
|
| + angle_to(b : Vector2) : float | -> atan2(cross(b), dot(b));
|
|
| + cross(b : Vector2) : float | -> Cross product -> x * b.y - y * b.x;
|
|
| + clamped(len : float) : Vector2 | -> normalized() * len
|
|
| + direction_to(b : Vector2) : Vector2 | -> Visszaad egy normalizált vektort ami ebből b be mutat. (A képlet: (b - a).normalized()) (operator-)
|
|
| + distance_to_squared(b : Vector2) : float | -> (x - b.x) * (x - b.x) + (y - b.y) * (y - b.y);
|
|
| + distance_to(b : Vector2) : float | -> sqrt((x - b.x) * (x - b.x) + (y - b.y) * (y - b.y));
|
|
| + dot(b : Vector2) : float | -> dot product -> Ha a 2 vektor 90 fokosz szöget zár be, akkor 0.
|
|
| | Pozitív, ha a 2 vektor által bezárt szög kisebb mint 90 fok, negatív, ha nagyobb.
|
|
| | képlet: x * b.x + y * b.y.
|
|
| + is_equal_approx(b : Vector2) : bool | -> nagyjából egyenlőek-e a vektorok. A max különbség legyen 0.00001 (Epszilon).
|
|
| + length() : float | -> sqrt(x * x + y * y)
|
|
| + length_squared() : float | -> A hossz a gyökvonás nélkül. (A gyökvonás relatíve lassú, és ha csak össze kell
|
|
| | hasonlítani hosszakat, akkor elég így)
|
|
| + lerp(b : Vector2, t : float) : Vector2 | -> Linear interpolate -> a jelenlegi vektor és b közötti átmenetvektort adja vissza t paraméter felhasználásával.
|
|
| | A t 0 és 1 közötti. Képlet: newx = x + (t * (b.x - x)); és newy = y + (t * (b.y - y));
|
|
| + normalized() : Vector2 | -> A vektor normalizálva. Normalizált vektor = a hossza 1.
|
|
| | float l = length_squared(); ha nem 0, gyököt kell vonni belőle, és le kell osztani x, y-t is vele
|
|
| + normalize() | -> Maga a vektor normalizálódik.
|
|
| + add(b: Vector2) | -> x += b.x, y += b.y
|
|
| + sub(b: Vector2) | -> x -= b.x, y -= b.y
|
|
| + operator+=(b: Vector2) | etc
|
|
| + operator-=(b: Vector2) |
|
|
| + operator+(a: Vector2, b: Vector2) : Vector2 |
|
|
| + operator-(a: Vector2, b: Vector2) : Vector2 |
|
|
| + operator*=(b: float) | -> x és y-t is megszorozzuk b-vel.
|
|
| + operator*(Vector2 a, float b) : Vector2 | -> x és y-t is megszorozzuk b-vel.
|
|
| + operator==(b: Vector2, b: Vector2) : bool |
|
|
| + operator!=(b: Vector2, b: Vector2) : bool |
|
|
| + Vector2() |
|
|
| + Vector2(b : Vector2) |
|
|
| + Vector2(x : float, y : float) |
|
|
------------------------------------------------|
|
|
|
|
2. Implementáld az alábbi 3ds matematikai vektor osztályt.
|
|
|
|
------------------------------------------------|
|
|
| class Vector3 |
|
|
|-----------------------------------------------|
|
|
| + x : float | -> Nincs getter, és szetter, mert azok lassítanának. (Függvényhívásnak van minimális erőforrás igénye)
|
|
| + y : float | -> Ilyen matematikai osztályoknál, érdemes ilyeneket kioptimalizálni. PLussz leírni is sok. getx(), setx() etc.
|
|
| + z : float |
|
|
| + abs() : Vector3 | -> visszaadja egy új vektorba ennek a vektornak az abszolút értékét. (x, y, y abszolút értékét veszi)
|
|
| | Abszolút érték képlet: ha egy a < 0 ret -a, else ret a;
|
|
| + angle_to(b : Vector3) : float | -> atan2(cross(b).length(), dot(b));
|
|
| + cross(b : Vector3) : Vector3 | -> Cross product -> x = (y * b.z) - (z * b.y), y = (z * b.x) - (x * b.z), z = (x * b.y) - (y * b.x)
|
|
| + clamped(len : float) : Vector3 | -> normalized() * len
|
|
| + direction_to(b : Vector3) : Vector3 | -> Visszaad egy normalizált vektort ami ebből b be mutat. (A képlet: (b - a).normalized())
|
|
| + distance_to_squared(b : Vector3) : float | -> return (b - *this).length_squared(); -> *this -> dereferencia operátor -> a this alapba mutató
|
|
| + distance_to(b : Vector3) : float | -> return (b - *this).length();
|
|
| + dot(b : Vector3) : float | -> dot product -> Ha a 2 vektor 90 fokosz szöget zár be, akkor 0.
|
|
| | Pozitív, ha a 2 vektor által bezárt szög kisebb mint 90 fok, negatív, ha nagyobb.
|
|
| | képlet: x * b.x + y * b.y + z * b.z.
|
|
| + is_equal_approx(b : Vector3) : bool | -> nagyjából egyenlőek-e a vektorok. A max különbség legyen 0.00001 (Epszilon).
|
|
| + length() : float | -> sqrt(x * x + y * y + z * z)
|
|
| + length_squared() : float | -> A hossz a gyökvonás nélkül. (A gyökvonás relatíve lassú, és ha csak össze kell
|
|
| | hasonlítani hosszakat, akkor elég így)
|
|
| + lerp(b : Vector3, t : float) : Vector3 | -> Linear interpolate -> a jelenlegi vektor és b közötti átmenetvektort adja vissza t paraméter felhasználásával.
|
|
| | A t 0 és 1 közötti. Képlet: newx = x + (t * (b.x - x)); és newy = y + (t * (b.y - y));
|
|
| | newy = z + (t * (b.z - z));
|
|
| + normalized() : Vector3 | -> A vektor normalizálva. Normalizált vektor = a hossza 1.
|
|
| | float l = length_squared(); ha nem 0, gyököt kell vonni belőle, és le kell osztani x, y, z-t is vele
|
|
| + normalize() | -> A vektor normalizálódik.
|
|
| + add(b: Vector3) | -> x += b.x, y += b.y, z += b.z
|
|
| + sub(b: Vector3) | -> x -= b.x, y -= b.y, z -= b.z
|
|
| + operator+=(b: Vector3) | etc.
|
|
| + operator-=(b: Vector3) |
|
|
| + operator+(a: Vector3, b: Vector3) : Vector3 |
|
|
| + operator-(a: Vector3, b: Vector3) : Vector3 |
|
|
| + operator*=(b: float) | -> x,y és z-t is megszorozzuk b-vel.
|
|
| + operator*(Vector2 a, float b) : Vector2 | -> x,y és z-t is megszorozzuk b-vel.
|
|
| + operator==(b: Vector3, b: Vector2) : bool |
|
|
| + operator!=(b: Vector3, b: Vector2) : bool |
|
|
| + Vector3() |
|
|
| + Vector3(b : Vector3) |
|
|
| + Vector3(x : float, y : float, z : float) |
|
|
------------------------------------------------|
|
|
|
|
|
|
3. Implementáld az alábbi matematikai négyzet osztályt.
|
|
|
|
------------------------------------------------------|
|
|
| class Rect2 |
|
|
|-----------------------------------------------------|
|
|
| + x : float |
|
|
| + y : float |
|
|
| + w : float |
|
|
| + h : float |
|
|
| + get_area() : float | -> Terület (w * h)
|
|
| + intersects(b : Rect2) : bool | -> Lejjebb
|
|
| + intersects_include_borders(b : Rect2) : bool | -> Lejjebb
|
|
| + encloses(b : Rect2) : bool | -> Lejjebb
|
|
| + has_no_area() : bool |
|
|
| + has_point(x : float, y : float) : bool |
|
|
| + is_equal_approx(b : Rect2) : bool |
|
|
| + grow(by : float) | -> x, y, csökkent, w,h növel by-al
|
|
| + shrink(by : float) | -> x, y, növel, w,h csökkent by-al
|
|
| + operator+=(b: Rect2) |
|
|
| + operator-=(b: Rect2) |
|
|
| + operator+(a: Rect2, b: Rect2) : Rect2 |
|
|
| + operator-(a: Rect2, b: Rect2) : Rect2 |
|
|
| + operator==(b: Rect2) : bool |
|
|
| + operator!=(b: Rect2) : bool |
|
|
| + Rect2() |
|
|
| + Rect2(b : Rect2) |
|
|
| + Rect2(x : float, y : float) |
|
|
| + Rect2(x : float, y : float, w : float, h : float) |
|
|
------------------------------------------------------|
|
|
|
|
intersects:
|
|
if (x >= (b.x + b.w))
|
|
return false;
|
|
|
|
if ((x + w) <= b.x)
|
|
return false;
|
|
|
|
if (y >= (b.y + b.h))
|
|
return false;
|
|
|
|
if ((y + h) <= b.y)
|
|
return false;
|
|
|
|
return true;
|
|
|
|
intersects_include_borders:
|
|
if (x > (b.x + b.w))
|
|
return false;
|
|
|
|
if ((x + w) < b.x)
|
|
return false;
|
|
|
|
if (y > (b.y + b.h))
|
|
return false;
|
|
|
|
if ((y + h) < b.y)
|
|
return false;
|
|
|
|
return true;
|
|
|
|
Encloses:
|
|
|
|
return (b.x >= x) && (b.y >= y) &&
|
|
((b.x + b.w) <= (x + w)) &&
|
|
((b.y + b.h) <= (y + h));
|
|
|
|
|
|
4. Implementáld az alábbi int-eket tároló vektor osztályt:
|
|
|
|
------------------------------------------------------|
|
|
| class IntVector |
|
|
|-----------------------------------------------------|
|
|
| + push_back(element : int) |
|
|
| + pop_back() | -> utolsó elem törlése
|
|
| + remove(index : int) |
|
|
| + erase(element : int) |
|
|
| + clear() |
|
|
| + empty() : bool |
|
|
| + get(index : int) : int |
|
|
| + get(index : int) : const &int, (const) | -> 5. feladatban már hasznos optimalizáció lesz,
|
|
| | amúgy igazából nincs értelme const referenciaként visszaadni intet
|
|
| + set(index : int, value : int) |
|
|
| + size() : int |
|
|
| + capacity() : int |
|
|
| + ensure_capacity(capacity : int) |
|
|
| + resize(size : int) |
|
|
| + append_array(other : IntVector) |
|
|
| + find(val : int) : int | -> Megkeresi az adott értéket, és visszaadja az indexét, illetve ha nem található -1 et
|
|
| + dataw() : int* | -> Visszaadja az adatokat tároló tömböt -> ki lehet optimalizálni vele függvényhívásokat, amikor fontos.
|
|
| + data() : const int*, (const) | -> Visszaadja az adatokat tároló tömböt, de ez konstans verzió.
|
|
| + operator[](index: int) : const &int, (const) | -> 5. feladatban már hasznos optimalizáció
|
|
| + operator[](index: int) : &int | -> Ha esetleg összeakad az eggyel fejlebb lévővel, akkor hagyjátok ki az egyiket, majd később kipróbálom én is
|
|
| + IntVector() |
|
|
| + IntVector(prealloc : int) |
|
|
| + IntVector(prealloc : int, grow_by : int) |
|
|
|-----------------------------------------------------|
|
|
| - _data : int* | -> Maga a tároló tömb
|
|
| - _actual_size : int | -> ekkora a tömb
|
|
| - _size : int | -> size() ezt adja vissza / ennyi elem van eltárolva a vektorban
|
|
| - _grow_by : int | -> Ha növelni kell a _data tömböt, akkor ennyivel legyen megnövelve
|
|
------------------------------------------------------|
|
|
|
|
5. A 4. feladatban elékszített IntVektor osztályból csinálj egy templatekkel általánosított Vector osztályt.
|
|
|
|
Fontos! A templatelt tagfüggvényeket implementációját vector.h-ba kell rakni! Vagy bele az osztályba, vagy a vector.h aljára!
|
|
Enélkül undefined reference hibákat fog dobmi a fordító!
|
|
|
|
Eddíg pl:
|
|
|
|
class IntVector {
|
|
|
|
int get(int index);
|
|
set(int index, int val);
|
|
|
|
void push_back(int val);
|
|
|
|
//etc...
|
|
|
|
IntVector();
|
|
|
|
private:
|
|
int *_data;
|
|
};
|
|
|
|
int main() {
|
|
IntVector a;
|
|
|
|
a.push_back(1);
|
|
a.push_back(2);
|
|
a.push_back(3);
|
|
a.push_back(4);
|
|
|
|
cout << a.get(1);
|
|
|
|
a.set(1, 4);
|
|
|
|
cout << a.get(1);
|
|
|
|
//etc...
|
|
|
|
return 0;
|
|
}
|
|
|
|
Most:
|
|
|
|
template <class T>
|
|
class Vector {
|
|
|
|
T get(int index);
|
|
set(int index, T val);
|
|
|
|
//etc...
|
|
|
|
Vector();
|
|
|
|
private:
|
|
T *_data;
|
|
};
|
|
|
|
int main() {
|
|
Vector<int> a; //Mindenhol ahol T-van, ki lessz replacelve int-re a compiler által!
|
|
|
|
a.push_back(1);
|
|
a.push_back(2);
|
|
a.push_back(3);
|
|
a.push_back(4);
|
|
|
|
cout << a.get(1);
|
|
|
|
a.set(1, 4);
|
|
|
|
cout << a.get(1);
|
|
|
|
//etc...
|
|
|
|
//de így már lehet:
|
|
Vector<float> b;
|
|
Vector<string> c;
|
|
|
|
//...
|
|
|
|
return 0;
|
|
}
|
|
|
|
7. Valamelyik vektor osztályból készíts egy saját String osztályt. (Vector<char> -al ekvivalens), de készítsd el
|
|
template nélkül, illetve adj hozzá általad hasznosnak ítélt függvényeket.
|
|
néhány ötlet: to_float(), to_double(), to_int(), trim(), replace(), find(val : String), begins_with(str : String) : bool, ends_with(),
|
|
sub_str(int from, int num = -1), c_str(), operator==, operator!=, operator=, operator+=, operator+, remove(str : String), etc.
|
|
|
|
8. Az előző feladatokban sok helyen meg lehet jelölni paramétereket konstansként, illetve pl. konstans referenciává lehet alakítani őket.
|
|
Menj végig az előző osztályokon, és mindenhol, ahol van értelme, ezeket add hozzá.
|
|
(int-eket/float okat csak konstanssá érdemes átrakni, referenciává tenni őket nincs értelme!)
|
|
(Érdemes másolatot csinálni, vagy pl. egy git commitban eltárolni az eredetieket, és csak úgy szerkesztgetni őket!)
|
|
|
|
|
|
|