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 10:42] – [Teil IV: Überladung von Methoden und Konstruktor] scaef_informatik:csharp_oop [2022-04-25 19:48] (aktuell) – [Teil IX: Aufgaben] sca
Zeile 77: Zeile 77:
  
  
-==== Teil V: Statische Methoden ====+==== Teil V: Method Overriding ==== 
 + 
 +Schön wäre doch, wenn man einfach mit `Console.Writeline(v)` die Komponenten des Vektors schön ausgeben könnte. Wie du dich selbst vergewissern kannst, funktioniert dies (noch) nicht. 
 + 
 +`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 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. 
 + 
 + 
 +==== 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 90: 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 100: 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 109: 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.1648550534.txt.gz
  • Zuletzt geändert: 2022-03-29 10:42
  • von sca