Beide Seiten, vorherige Überarbeitung Vorherige Überarbeitung Nächste Überarbeitung | Vorherige Überarbeitung |
talit:csharp_oop [2025-05-12 10:34] – [Auftrag im Detail] sca | talit:csharp_oop [2025-05-18 13:30] (aktuell) – [Auftrag im Detail] sca |
---|
1. [[https://www.youtube.com/watch?v=puf8z--uDp8|Eigenschaften (Achtung: Variablen = Felder)]] | 1. [[https://www.youtube.com/watch?v=puf8z--uDp8|Eigenschaften (Achtung: Variablen = Felder)]] |
1. [[https://www.youtube.com/watch?v=qXj4B4l92_A|Getter und Setter]]\\ \\ | 1. [[https://www.youtube.com/watch?v=qXj4B4l92_A|Getter und Setter]]\\ \\ |
1. Füge nun deiner Vector-Klasse die **Eigenschaften** "Dim" (für Dimension), "Magnitude" und "Components" hinzu. Diese sollen *im Konstruktor über ein privates Feld festgelegt* werden und über einen getter abgerufen werden. Natürlich sollen sie //nicht von aussen über einen setter verändert// werden können! Die Eigenschaft "Components" beinhaltet das Double-Array zurückgeben, welches den Vektor definiert.\\ \\ | 1. Programmiere nun den Konstruktor aus: Speichere die dem Konstruktor übergebenen Werte in einem *privaten* Feld `components`, ein Double-Array, welches die Komponenten des Vektors beinhaltet. Regle über eine Eigenschaft (get/set) `Components` den Zugriff auf `components`. Sinn könnte machen: |
| 1. Die Komponenten sind unveränderbar. |
| 1. Die Komponenten sind nur veränderbar, wenn sie die gleiche Dimension haben (benötigt `Dim` von unten).\\ \\ |
| 1. Füge nun deiner Vector-Klasse die **Eigenschaften** `Dim` (für Dimension) und `Magnitude`. Diese sollen über eine Eigenschaft (get) abgerufen werden. Natürlich sollen sie //nicht von aussen über einen setter verändert// werden können!\\ \\ |
1. Informiere dich nun über **statische und nicht-statische Methoden**, z.B. hier; [[https://www.youtube.com/watch?v=PhvjwmkVEfg|Methoden in Klassen]]\\ \\ | 1. Informiere dich nun über **statische und nicht-statische Methoden**, z.B. hier; [[https://www.youtube.com/watch?v=PhvjwmkVEfg|Methoden in Klassen]]\\ \\ |
1. Füge deiner Klasse folgende (nicht-statische) public **Methoden** hinzu: `IsZeroVector()` und `IsUnitVector()`. Diese geben den Bool true oder false zurück, jenachdem ob es sich beim Vektor um einen Nullvektor oder einen Einheitsvektor (unit vector) handelt.\\ \\ | 1. Füge deiner Klasse folgende (nicht-statische) public **Methoden** hinzu: `IsZeroVector()` und `IsUnitVector()`. Diese geben den Bool true oder false zurück, je nachdem ob es sich beim Vektor um einen Nullvektor oder einen Einheitsvektor (unit vector) handelt.\\ Achtung: Da wir mit doubles Arbeiten, können schnell Rundungsfehler entstehen. Es kann deshalb sein, dass die Länge des Vektors eigentlich $0$ wäre, der Code aber eine ganz kleine Zahl berechnet. Deshalb sollte man der Klasse eine Eigenschaft `accuracy` geben: Ist der Betrag des Werts kleiner dieser Genauigkeit, so wird der Wert als $0$betrachtet.\\ \\ |
1. Nun wollen wir mit den Vektoren **Rechnen** können. Dazu fügen wir drei **statische Methoden** mit den Namen *Add, Sub* und *ScalarProd* für die Vektoraddition, Vektorsubtraktion und das Skalarprodukt hinzu. Über `Vector.Add(v1,v2);` soll man dann die Vektorsumme zweier Vektoren berechnen können.\\ \\ | 1. Nun wollen wir mit den Vektoren **Rechnen** können. Dazu fügen wir drei **statische Methoden** mit den Namen *Add, Sub* und *ScalarProd* für die Vektoraddition, Vektorsubtraktion und das Skalarprodukt hinzu. Über `Vector.Add(v1,v2);` soll man dann die Vektorsumme zweier Vektoren berechnen können.\\ \\ |
1. Die beiden Rechenmethoden vom letzten Punkt sollen können nur Funktionieren, wenn beide Vektoren, die als Argument übergeben werden, die gleiche Dimension haben. Überprüfe dies und gib gegebenenfalls einen **Fehler** aus: `throw new System.Exception("...");`\\ \\ | 1. Die beiden Rechenmethoden vom letzten Punkt sollen können nur Funktionieren, wenn beide Vektoren, die als Argument übergeben werden, die gleiche Dimension haben. Überprüfe dies und gib gegebenenfalls einen **Fehler** aus: `throw new System.Exception("...");`\\ \\ |
1. Nun wollen wir aber nicht immer `Vector.Sub(v1,v2);` schreiben müssen, um zwei Vektoren zu Subtrahieren. Stattdessen soll das mit dem Operator `-`, also `v1-v2`, gehen. Dies geht ganz einfach mit einem **Operator Overloading**, siehe z.B. hier: [[https://www.tutorialspoint.com/csharp/csharp_operator_overloading.htm|C# - Operator Overloading]]. Füge nun jeweils ein Operator Overloading für die Operatoren + (Vektoraddition), - (Vektorsubtraktion) und * (Skalarprodukt) hinzu.\\ \\ | 1. Nun wollen wir aber nicht immer `Vector.Sub(v1,v2);` schreiben müssen, um zwei Vektoren zu Subtrahieren. Stattdessen soll das mit dem Operator `-`, also `v1-v2`, gehen. Dies geht ganz einfach mit einem **Operator Overloading**, siehe z.B. hier: [[https://www.tutorialspoint.com/csharp/csharp_operator_overloading.htm|C# - Operator Overloading]]. Füge nun jeweils ein Operator Overloading für die Operatoren + (Vektoraddition), - (Vektorsubtraktion) und * (Skalarprodukt) hinzu.\\ \\ |
| 1. Aktuell gibt der Befehl `System.Console.WriteLine(v);` für einen Vektor `v` nur "Vector" aus. Schön wäre aber, wenn man direkt die Komponenten erhalten würde: Jede Klasse in C# erbt automatisch von der Basisklasse `object`, und `object` definiert die Methode `ToString()`. Wenn man also `Console.WriteLine(anyObject)` aufrufst, wird intern `anyObject.ToString()` verwendet, ganz egal was `anyObject` für ein Objekt ist. Mit `public override string ToString()` können wir nun diese standardmässige Methode **überschreiben**.\\ \\ |
1. Über eine Eigenschaft soll von einem Vektor der zugehörige **Einheitsvektor** ausgegeben werden: `v.UnitVector`. Dieser Einheitsvektor soll *selbst wieder vom Typ Vector* sein! Um von einem Vektor den zugehörigen Einheitsvektor zu erhalten, dividiert man jede Komponente des Vektors durch die Länge des gesamten Vektors. *Tipp:* Überlege dir gut, *wo* genau der Einheitsvektor berechnet werden soll!\\ \\ | 1. Über eine Eigenschaft soll von einem Vektor der zugehörige **Einheitsvektor** ausgegeben werden: `v.UnitVector`. Dieser Einheitsvektor soll *selbst wieder vom Typ Vector* sein! Um von einem Vektor den zugehörigen Einheitsvektor zu erhalten, dividiert man jede Komponente des Vektors durch die Länge des gesamten Vektors. *Tipp:* Überlege dir gut, *wo* genau der Einheitsvektor berechnet werden soll!\\ \\ |
| 1. Es ist etwas umständlich, für neue Vektoren immer zuerst ein double-Array erstellen zu müssen. Stattdessen wollen wir die gängigsten Vektoren (sagen wir 1-4D) auch durch `Vector v = new Vector(3.2,0,4)` erzeugen. Dafür müssen wir den Konstruktor **überladen**, in dem wir 'weitere Konstruktoren' wie `public Vector(double x, double y, double z)` hinzufügen.\\ \\ |
| 1. Erweitere nun deine Klasse beliebig. Hier einige Vorschläge: |
| 1. Weiter Operationen: |
| 1. `DotProduct` |
| 1. `ScalarMultiplication` (überladen, damit `ScalarMultiplication(3,v)` und `ScalarMultiplication(v,3)` funktionieren. |
| 1. `VectorProduct` (nur für 3D Vektoren) |
| 1. Winkel zwischen zwei Vektoren: `AngleInRad` , `AngleInRad` |
| 1. Zwei Vektoren vergleichen: `ArePerpendicular`,`AreParallel`,`AreAntiParallel`,`HaveSameMagnitude`\\ \\ |
| 1. **Operatoren überladen**: Mit `v1 + v2` soll man zwei Vektoren addieren können. Der Operator `+` muss dazu überladen werden: Wird `+` auf zwei Vektoren angewendet, soll die `Add`-Methode aufgerufen werden. Gleiches für `v1 * v2` (dot product) und `s * v` resp. `v * s` (scalar multiplication).\\ \\ |
| 1. **Optional:** Falls du sehr motiviert bist, könntest du eine Klasse *Matrix* definieren, mit der man Matrizen-Rechnungen durchführen kann. Matrizen können als Verallgemeinerungen von Vektoren betrachtet werden. |
| |
**Neue Features:** | <nodisp 2> |
| |
1. Ein bestehender Vektor soll überschrieben werden können, aber nur, wenn er die //gleiche Dimension// wie der bestehende hat. Dazu soll man einfach `v.Components` neu setzen können. Dies geschieht im //setter// der Components-Eigenschaft. | ++++Weiteres| |
| |
===== Zusatzaufgaben ===== | |
| |
1. Für 3er Vektoren soll nun auch das **Vektorprodukt** berechnet werden können. [[https://de.wikipedia.org/wiki/Kreuzprodukt#Komponentenweise_Berechnung|Wikipedia Vektorprodukt]]\\ \\ | |
1. Füge nun auch die Skalarmultiplikation hinzu. Dort wird ein Vektor mit einer reellen Zahl gestreckt oder gestaucht. Der Operator `*` soll so überladen werden, dass `v1*v2` das Skalarprodukt ergibt und (s sei eine Zahl, kein Vektor) `v*s` oder `s*v` die Skalarmultiplikation.\\ \\ | |
1. Erweitere deine Klasse mit weiteren sinnvollen Methoden usw.\\ \\ | |
1. Falls du sehr motiviert bist, könntest du eine Klasse *Matrix* definieren, mit der man Matrizen-Rechnungen durchführen kann. | |
| |
===== 2D-Drawing ===== | ===== 2D-Drawing ===== |
* Scene untersucht für alle möglichen Paare von Körpern, ob sie sich berühren und führt die Kollision aus. | * Scene untersucht für alle möglichen Paare von Körpern, ob sie sich berühren und führt die Kollision aus. |
| |
| ++++ |
| |
| </nodisp> |