programming_tutorials/01_alapok.txt
2021-03-27 10:39:53 +01:00

278 lines
14 KiB
Plaintext

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)
| + 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.
| + 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 |
| + lenght_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 = lenght_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: 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)
| + 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 + 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 |
| + lenght_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 = lenght_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: 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 : Vector3) : bool |
| + grow(by : float) : Rect2 | -> x, y, csökkent, w,h növel by-al
| + shrink(by : float) : Rect2 | -> 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_include_borders:
if (x > (b.x + b.w))
return false;
if ((x + w) < b.x)
return false;
if (y > (b.z + b.h))
return false;
if ((y + h) < b.y)
return false;
return true;
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;
}
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) |
| + 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.
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!)