Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen der Seite angezeigt.

Link zu der Vergleichsansicht

Beide Seiten, vorherige Überarbeitung Vorherige Überarbeitung
Nächste Überarbeitung
Vorherige Überarbeitung
ef_informatik:csharp_oop [2022-03-29 11:05] – [Teil IV: Überladung von Methoden und Konstruktor] scaef_informatik:csharp_oop [2022-04-25 19:48] (aktuell) – [Teil IX: Aufgaben] sca
Zeile 75: Zeile 75:
    1. Die Genauigkeit soll auch im Nachhinein angepasst werden können, dazu muss diese aber public gemacht werden. Wir wollen aber eine Obergrenze setzen, z.B. soll für die Genauigkeit kein Wert $> 10^{-5}$ (oder was auch immer) gesetzt werden können. Dazu gehen wir wie folgt vor: Wir haben ein privates Feld `_accuracy` und eine public Eigenschaft `Accuracy`. Über dessen **getter/setter** wird der Wert von `_accuracy` gesetzt, wobei sichergestellt wird, dass ein erlaubter Wert gesetzt wird (Stichword: setter!). Siehe z.B. hier für mehr Infos dazu: https://codeasy.net/lesson/properties    1. Die Genauigkeit soll auch im Nachhinein angepasst werden können, dazu muss diese aber public gemacht werden. Wir wollen aber eine Obergrenze setzen, z.B. soll für die Genauigkeit kein Wert $> 10^{-5}$ (oder was auch immer) gesetzt werden können. Dazu gehen wir wie folgt vor: Wir haben ein privates Feld `_accuracy` und eine public Eigenschaft `Accuracy`. Über dessen **getter/setter** wird der Wert von `_accuracy` gesetzt, wobei sichergestellt wird, dass ein erlaubter Wert gesetzt wird (Stichword: setter!). Siehe z.B. hier für mehr Infos dazu: https://codeasy.net/lesson/properties
    1. In Realität benötigt man meist 2D- und 3D-Vektoren. Daher macht es Sinn, für diese Fälle weitere Überladungen des Konstruktors zu machen: `Vecor(3,-42)` und `Vector(3,-42,7)` soll dann einen entsprechenden 2D- resp. 3D-Vektor erzeugen. Die Genauigkeit wird dabei jeweils auf den Standardwert gesetzt.    1. In Realität benötigt man meist 2D- und 3D-Vektoren. Daher macht es Sinn, für diese Fälle weitere Überladungen des Konstruktors zu machen: `Vecor(3,-42)` und `Vector(3,-42,7)` soll dann einen entsprechenden 2D- resp. 3D-Vektor erzeugen. Die Genauigkeit wird dabei jeweils auf den Standardwert gesetzt.
-   + 
 ==== Teil V: Method Overriding ==== ==== Teil V: Method Overriding ====
  
Zeile 82: Zeile 83:
 `Console.Writeline` ruft jeweils die Klassenmethode `ToString()` auf. Für gewissen Datentypen wie ints wurde diese Methode bereits implementiert. Deshalb können solche Datentypen mit `Console.Writeline` angezeigt werden, obwohl sie keine Strings sind - sie werden vor der Anzeige in Strings umgewandelt. `Console.Writeline` ruft jeweils die Klassenmethode `ToString()` auf. Für gewissen Datentypen wie ints wurde diese Methode bereits implementiert. Deshalb können solche Datentypen mit `Console.Writeline` angezeigt werden, obwohl sie keine Strings sind - sie werden vor der Anzeige in Strings umgewandelt.
  
-Implementiere die Methode `ToString()` für unsere VektorklasseEin Vektor soll dann wie folgt ausgegeben werden: `[3,-42,7]`+Implementiere die Methode `ToString()` für unsere Vektorklasse
 +<code csharp> 
 +public override String ToString() 
 +
 +    // YOUR CODE HERE 
 +
 +</code> 
 +Ein Vektor soll dann wie folgt ausgegeben werden: `[3,-42,7]`
 Vergewissere dich, dass `Console.Writeline` nun für Vektoren funktioniert. Vergewissere dich, dass `Console.Writeline` nun für Vektoren funktioniert.
  
  
-==== Teil V: Statische Methoden ====+==== Teil VI: Statische Methoden ====
  
 Gegeben seien zwei Vektoren `v1` und `v2`. Möchten wir nun die Vektorsumme der beiden bestimmen, so haben wir zwei Möglichkeiten: `v1.Add(v2)` oder `v2.Add(v1)`. Im ersten Fall verwenden wir also die Klassenmethode `Add` des ersten Vektors und übergeben den zweiten Vektor als Argument. Schön wäre aber, wenn wir dies ohne die Klassenmethode machen könnten und einfach `Add(v1,v2)` schreiben könnten. Eine solche Methode heisst **statische Methode.** Sie ist //objektunabhängig//, gehört also //nicht// direkt zum Objekt. Wir könnten diese neue Add-Methode (`Add(v1,v2)`) deshalb in der Main-Methode deklarieren, was aber nicht sehr viel Sinn ergibt. Die Methode passt thematisch zur Vector-Klasse, da sie zwei Vektoren entgegennimmt, diese Addiert und dann wieder einen Vector zurückgibt. Deshalb liegt es auf der Hand, diese Methode als //statische// Methode in der Vector-Klasse zu definieren. Gegeben seien zwei Vektoren `v1` und `v2`. Möchten wir nun die Vektorsumme der beiden bestimmen, so haben wir zwei Möglichkeiten: `v1.Add(v2)` oder `v2.Add(v1)`. Im ersten Fall verwenden wir also die Klassenmethode `Add` des ersten Vektors und übergeben den zweiten Vektor als Argument. Schön wäre aber, wenn wir dies ohne die Klassenmethode machen könnten und einfach `Add(v1,v2)` schreiben könnten. Eine solche Methode heisst **statische Methode.** Sie ist //objektunabhängig//, gehört also //nicht// direkt zum Objekt. Wir könnten diese neue Add-Methode (`Add(v1,v2)`) deshalb in der Main-Methode deklarieren, was aber nicht sehr viel Sinn ergibt. Die Methode passt thematisch zur Vector-Klasse, da sie zwei Vektoren entgegennimmt, diese Addiert und dann wieder einen Vector zurückgibt. Deshalb liegt es auf der Hand, diese Methode als //statische// Methode in der Vector-Klasse zu definieren.
Zeile 99: Zeile 107:
  
  
-==== Teil V: Überladung von Operatoren ====+==== Teil VII: Überladung von Operatoren ====
  
 Noch praktischer wäre, wenn man einfach `v1 + v2` anstelle von `Add(v1,v2)` schreiben könnte. Dies ist möglich und heisst **Überladung von Operatoren**: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/operator-overloading Noch praktischer wäre, wenn man einfach `v1 + v2` anstelle von `Add(v1,v2)` schreiben könnte. Dies ist möglich und heisst **Überladung von Operatoren**: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/operator-overloading
Zeile 109: Zeile 117:
  
  
-==== Teil VI: Weitere Vektormethoden ====+==== Teil VIII: Weitere Vektormethoden ====
  
 Implementiere die folgenden, nützlichen Methoden für Vektoren. Implementiere die folgenden, nützlichen Methoden für Vektoren.
Zeile 118: Zeile 126:
  
  
-   1. `AngleInRad(v1,v2)` und `AngleInDeg(v1,v2)`: Bestimmt den Winkel (im Bogenmass und in Grad) zwischen den beiden Vektoren, siehe https://de.wikipedia.org/wiki/Skalarprodukt.  +   1. `AngleInRad(v1,v2)` und `AngleInDeg(v1,v2)`: Bestimmt den Winkel (im Bogenmass und in Grad) zwischen den beiden Vektoren, siehe https://de.wikipedia.org/wiki/Skalarprodukt. Achtung: Der Winkel zwischen zwei Vektoren ist nur definiert, falls //keiner// der beiden ein //Nullvektor// ist
-   2. `AreParallel(v1,v2)`, `AreAntiparallel (v1,v2)`, `AreParallelOrAntiparallel(v1,v2)`, `ArePerpendicular(v1,v2)` geben true/false zurück. Parallel heisst: zeigen in gleiche Richtung, Antiparallel heisst: zeigen in entgegengesetzte Richtung.+   2. `AreParallel(v1,v2)`, `AreAntiparallel (v1,v2)`, `AreParallelOrAntiparallel(v1,v2)`, `ArePerpendicular(v1,v2)` geben true/false zurück. Parallel heisst: zeigen in gleiche Richtung, Antiparallel heisst: zeigen in entgegengesetzte Richtung. Achtung auch wieder vor Nullvektoren!
    3. `SameLength(v1,v2)`: true/false    3. `SameLength(v1,v2)`: true/false
 +   4. Eigene Ideen
  
-==== Teil VII: Aufgaben ====+==== Teil IX: Aufgaben ====
  
 Öffne dein Dossier oder deine Aufgabenblätter aus dem Matheunterricht zum Thema Vektoren. Löse einige Aufgaben mithilfe deiner Vector-Klasse. Öffne dein Dossier oder deine Aufgabenblätter aus dem Matheunterricht zum Thema Vektoren. Löse einige Aufgaben mithilfe deiner Vector-Klasse.
  
  
 +<nodisp 2>
 +++++Lösung|
 +<code csharp>
 +using System;
 +namespace VectorMath
 +{
 +    public class Vector
 +    {
 +        public double[] Components;
 +        private double _accuracyDefault = 1e-15;
 +        private double _accuracyMax = 1e-1;
 +        private double _accuracy;
 +
 +        // PROPERTIES
 +        public double Accuracy
 +        {
 +            get
 +            {
 +                return _accuracy;
 +            }
 +            set
 +            {
 +                if (value <= _accuracyMax)
 +                {
 +                    _accuracy = value;
 +                }
 +                else
 +                {
 +                    _accuracy = _accuracyDefault;
 +                }
 +            }
 +        }
 +
 +        public int Dimension
 +        {
 +            get
 +            {
 +                return Components.Length;
 +            }
 +        }
 +
 +        public double Magnitude
 +        {
 +            get
 +            {
 +                double magn = 0;
 +                foreach (var c in Components)
 +                {
 +                    magn += c * c;
 +                }
 +                return Math.Sqrt(magn);
 +            }
 +        }
 +
 +        public Vector UnitVector
 +        {
 +            get
 +            {
 +                double[] A = new double[Dimension];
 +                for (int i = 0; i < A.Length; i++)
 +                {
 +                    A[i] = Components[i] / Magnitude;
 +                }
 +                return new Vector(A);
 +            }
 +        }
 +
 +        public bool IsZeroVector
 +        {
 +            get
 +            {
 +                if (Magnitude < Accuracy)
 +                {
 +                    return true;
 +                }
 +                return false;
 +            }
 +        }
 +
 +        public bool IsUnitVector
 +        {
 +            get
 +            {
 +                double a = Math.Abs(Magnitude - 1);
 +                if (Math.Abs(Magnitude - 1) < Accuracy)
 +                {
 +                    return true;
 +                }
 +                return false;
 +            }
 +        }
 +
 +        // CONSTRUCTOR
 +        public Vector(double[] _components)
 +        {
 +            Components = _components;
 +            Accuracy = _accuracyDefault;
 +        }
 +
 +        public Vector(double[] _components, double _acc)
 +        {
 +            Components = _components;
 +            Accuracy = _acc;
 +        }
 +
 +        public Vector(double x, double y)
 +        {
 +            Components = new double[] { x, y };
 +            Accuracy = _accuracyDefault;
 +        }
 +
 +        public Vector(double x, double y, double z)
 +        {
 +            Components = new double[] { x, y, z };
 +            Accuracy = _accuracyDefault;
 +        }
 +
 +        // CLASS METHODS
 +
 +        public override String ToString()
 +        {
 +            // can now print vector with Console.Writeline
 +            string l = "[";
 +            for (int i = 0; i < Dimension - 1; i++)
 +            {
 +                l += Components[i].ToString() + ",";
 +
 +            }
 +            l += Components[Dimension - 1] + "]";
 +            return l;
 +        }
 +
 +        public Vector Add(Vector V)
 +        {
 +            checkIfSameDimension(V);
 +            double[] A = new double[Dimension];
 +            for (int i = 0; i < A.Length; i++)
 +            {
 +                A[i] = Components[i] + V.Components[i];
 +            }
 +            return new Vector(A);
 +        }
 +
 +        public Vector Sub(Vector V)
 +        {
 +            checkIfSameDimension(V);
 +            double[] A = new double[Dimension];
 +            for (int i = 0; i < A.Length; i++)
 +            {
 +                A[i] = Components[i] - V.Components[i];
 +            }
 +            return new Vector(A);
 +        }
 +
 +        public double DotProduct(Vector V)
 +        {
 +            checkIfSameDimension(V);
 +            double d = 0;
 +            for (int i = 0; i < Dimension; i++)
 +            {
 +                d += Components[i] * V.Components[i];
 +            }
 +            return d;
 +        }
 +
 +        public Vector ScalarMultiplication(double s)
 +        {
 +            double[] A = new double[Dimension];
 +            for (int i = 0; i < A.Length; i++)
 +            {
 +                A[i] = s * Components[i];
 +            }
 +            return new Vector(A);
 +        }
 +
 +        public double AngleInRad(Vector v)
 +        {
 +            if (IsZeroVector)
 +            {
 +                raiseZeroVectorError();
 +            }
 +            else if (v.IsZeroVector)
 +            {
 +                v.raiseZeroVectorError();
 +            }
 +
 +            return Math.Acos(DotProduct(this, v) / (this.Magnitude * v.Magnitude));
 +        }
 +
 +        public double AngleInDeg(Vector v)
 +        {
 +            return AngleInRad(v) * 180 / Math.PI;
 +        }
 +
 +        public bool AreParallel(Vector v)
 +        {
 +            if (Math.Abs(AngleInRad(v)) < Accuracy) { return true; }
 +            else { return false; }
 +        }
 +
 +        public bool AreAntiparallel(Vector v)
 +        {
 +            if (Math.Abs(AngleInRad(v) - Math.PI) < Accuracy) { return true; }
 +            else { return false; }
 +        }
 +
 +        public bool AreParallelOrAntiparallel(Vector v)
 +        {
 +            if (AreParallel(v) || AreAntiparallel(v)) { return true; }
 +            else { return false; }
 +        }
 +
 +        public bool ArePerpendicular(Vector v)
 +        {
 +            if (Math.Abs(AngleInRad(v) - Math.PI / 2) < Accuracy) { return true; }
 +            else { return false; }
 +        }
 +
 +        public bool HaveSameMagnitude(Vector v)
 +        {
 +            if (Math.Abs(Magnitude - v.Magnitude) < Accuracy) { return true; }
 +            else { return false; }
 +        }
 +
 +        private void checkIfSameDimension(Vector V)
 +        {
 +            if (V.Dimension != Dimension)
 +            {
 +                throw new Exception("Wrong dimension ERROR!");
 +            }
 +        }
 +
 +        private void raiseZeroVectorError()
 +        {
 +
 +            throw new Exception("Zero Vector Exception!");
 +
 +        }
 +
 +        // STATIC METHODS
 +        public static Vector ZeroVector(int n)
 +        {
 +            double[] a = new double[n];
 +            for (int i = 0; i < n; i++)
 +            {
 +                a[i] = 0;
 +            }
 +            return new Vector(a);
 +        }
 +
 +        public static Vector Add(Vector v1, Vector v2)
 +        {
 +            return v1.Add(v2);
 +        }
 +
 +        public static Vector Sub(Vector v1, Vector v2)
 +        {
 +            return v1.Sub(v2);
 +        }
 +
 +        public static double DotProduct(Vector v1, Vector v2)
 +        {
 +            return v1.DotProduct(v2);
 +        }
 +
 +        public static Vector ScalarMultiplication(double s, Vector v)
 +        {
 +            return v.ScalarMultiplication(s);
 +        }
 +
 +        public static Vector ScalarMultiplication(Vector v, double s)
 +        {
 +            return v.ScalarMultiplication(s);
 +        }
 +
 +        public static Vector ScalarProduct(Vector v1, Vector v2)
 +        {
 +            if (v1.Dimension != 3 && v2.Dimension != 3)
 +            {
 +                throw new Exception("Wrong dimension ERROR!");
 +            }
 +            double[] a = new double[3];
 +            a[0] = v1.Components[1] * v2.Components[2] - v1.Components[2] * v2.Components[1];
 +            a[1] = v1.Components[2] * v2.Components[0] - v1.Components[0] * v2.Components[2];
 +            a[2] = v1.Components[0] * v2.Components[1] - v1.Components[1] * v2.Components[0];
 +            return new Vector(a);
 +        }
 +
 +        public static double AngleInRad(Vector v1, Vector v2)
 +        {
 +            return v1.AngleInRad(v2);
 +        }
 +
 +        public static double AngleInDeg(Vector v1, Vector v2)
 +        {
 +            return v1.AngleInDeg(v2);
 +        }
 +
 +        // OPERATOR OVERLOADING 
 +        public static Vector operator +(Vector v) => v;
 +        public static Vector operator -(Vector v) => ZeroVector(v.Dimension) - v;
 +
 +        public static Vector operator +(Vector v1, Vector v2) => Add(v1, v2);
 +        public static Vector operator -(Vector v1, Vector v2) => Sub(v1, v2);
 +        public static double operator *(Vector v1, Vector v2) => DotProduct(v1, v2);
 +        public static Vector operator *(Vector v, double s) => ScalarMultiplication(s, v);
 +        public static Vector operator *(double s, Vector v) => ScalarMultiplication(s, v);
  
 +    }
 +}
 +</code>
 +++++
 +</nodisp>
  • ef_informatik/csharp_oop.1648551906.txt.gz
  • Zuletzt geändert: 2022-03-29 11:05
  • von sca