Autor: Alexander Wagner Matrikelnummer: 0227425 Beispielnummer: 3152 Kurzbeschreibung: Die Eckpunkte eines Dreiecks werden eingelesen; der Inkreismittelpunkt sowie der Radius des Inkreises werden ermittelt Dokumentation: (i) Variablen Was auf den ersten Blick bei dem Programm auffällt ist die schier erschlagende Anzahl an Variablen. Dies ist jedoch bei solch einerAufgabenstellung kaum zu umgehen, da irrsinnig viele Punkte und Vektoren, die alle x und y Werte haben, gespeichert werden müssen. Ich habe mich jedoch bemüht möglichst verständliche Namen zu wählen. Um Arrays die bloß aus 2 Werten bestehen zu vermeiden, habe ich statische Variable gewählt, die später nachdem die jeweiligen Methoden ausgeführt wurden den spezifischen Variablen die gerade benötigt werden zugewiesen werden. Beispiel: Die Methode zur Berechnung der Winkelsymmetralen wird ausgeführt. Die statischen Variablen WsymX und WsymY erhalten einen Wert, welcher den spezifischen Variablen WsymAx und WsymAy zugewiesen wird. Danach wird die Methode nochmal ausgeführt, WsymX und WsymY erhalten neue Werte, welche diesmal jedoch WsymBx und WsymBy zugewiesen werden. Gehen wir alle wichtigen Variablen durch: *) static: WsymX, WsymY: Der Vektor der Winkelsymmetrale xWert, yWert, IstGleich: Um eine Art Geradengleichung ins Programm implementieren zu können, werden die einzelnen Werte dieser Gleichung diesen Variablen zugewiesen. Eine Gleichung würde folgendermaßen aussehen: xWert * x + yWert * y = IstGleich !Beachte!: Das Programm interessiert sich jedoch nur für xWert, yWert, IstGleich. Das x und y kommt im Programmablauf nicht vor! SchnittpunktX, SchnittpunktY: Wie der Name schon sagt, die Koordinaten des Schnittpunktes zweier Geraden *) spezifische Variable: xA, yA, xB, yB, xC, yC: Die eingegebenen Eckpunkte des Dreiecks WsymAx, WsymAy, WsymBx, WsymBy: Die Vektoren der Winkelsymmetrale durch Punkt A bzw. durch Punkt B xWert1, yWert1, IstGleich1, xWert2, yWert2, IstGleich2: Die Werte der Geradengleichungen (siehe oben). Damit zwei Geraden gespeichert und anschließend geschnitten werden können bekommt jede einen eigenen Satz Variablen. InkreisX, InkreisY: Die Koordinaten des Inkreismittelpunktes Radius: Der Radius des Inkreises (ii) Methoden Ein Kernbestandteil des Programms sind die Methoden: *) WsymBilden: Dieser Methode werden x und y Koordinaten von drei Punkten übergeben und sie liefert den Vektor der Winkelsymmetrale durch den ersten der drei Punkte. Dieser wird gespeichert in WsymX und WsymY. Folgende Vorgangsweise: Der Einheitsvektor AB ist der Vektor AB gebrochen durch den Betrag von AB. Die Winkelsymmetrale durch A ergibt sich aus der Addition des Einheitsvektors AB und des Einheitsvektors AC. !Beachte!: Die Berechnungen werden seperat für x bzw. für den y Wert durchgeführt. *) GeradeBilden: Dieser Methode wird ein Punkt und ein Vektor übergeben, woraus eine Gerade aufgestellt wird. Dabei müssen die Koordinaten des Vektors umgedreht und einer Minus gesetzt werden. Anschließend werden die Werte der Gleichung in den jeweiligen statischen Variablen gespeichert. Die Geradengleichung mit diesen Werten hätte die Form: xWert * x + yWert * y = IstGleich !Beachte!: Das Programm interessiert sich jedoch nur für xWert, yWert, IstGleich. Das x und y kommt im Programmablauf nicht vor! *) GeradeSchneiden: Hier kommt viel Mathematik ins Spiel. Man übergibt die Werte zweier Geraden in der bekannten Form (xWert1, yWert1,...). Und hat dann 2 Geradengleichungen: Gerade1: xWert1 * x + yWert1 * y = IstGleich1 Gerade2: xWert2 * x + yWert2 * y = IstGleich2 Durch Umformen dieser 2 Gleichungen ergibt sich für die x und y Koordinaten des Schnittpunkts: SchnittpunktY = (IstGleich2*xWert1 - xWert2*IstGleich1)/(xWert2 * (-yWert1) + yWert2 * xWert1); SchnittpunktX = (IstGleich1 + (-yWert1 * SchnittpunktY) ) / xWert1; Diese Formel reicht in 90 % aller Fälle auch aus, es kann jedoch zu einer Division durch Null kommen, falls xWert1 gleich Null ist. Daher habe ich noch die 4 anderen Formeln eingebaut, die sich alle durch mathematisches Umformen ergeben. *) BetragBilden: Dieser Methode werden x und y Koordinaten zweier Punkte übergeben und sie berechnet ganz einfach anhand der BetragsFormel den Abstand zwischen den Punkten. Das Ergebnis wird auf ein float gecastet, da ansonsten ein double Wert geliefert wird. *) checkIfDreieck: Dieser Methode werden drei Punkte übergeben und sie prüft ob sich daraus ein Dreieck bilden lässt, und gibt das Ergebnis in einem boolean Wert zurück. Dazu muss folgende Bedingung gegeben sein: Die drei Punkte dürfen nicht alle auf derselben Gerade liegen. Um dies zu prüfen werden die Vektoren AB und BC gebildet und auf Parallelität überprüft (2 Vektoren sind dann parallel wenn der eine ein Vielfaches des anderen ist). Dies geschieht durch: if ( (VektorAx / VektorBx) == (VektorAy / VektorBy) ) return false; Um hier eine mögliche Division durch Null zu vermeiden habe ich noch zwei Bedingungen eingebaut: Die erste prüft ob x oder y Koordinate bei allen drei Punkten gleich ist, die zweite ob zwei Punkte genau dieselben Koordinaten haben: if ( ( (xA == xB) && (xB == xC) ) || ( (yA == yB) && (yB == yC) ) ) return false; if ( ( (xA == xB) && (yA == yB) ) || ( (xA == xC) && (yA == yC) ) || ( (xB == xC) && (yB == yC) ) ) return false; Dadurch sollten alle ungültigen Eingaben abgefangen werden. (iii) Programmablauf Gleich nach der Variablendeklaration folgt das Einlesen der Eckpunkte für das Dreieck mittels EprogIO.readFloat() . Ich verwende dabei 6 seperate try - catch Befehle aus dem Grund, dass der Datensatz vollständig eingelesen werden soll, und nicht mittendendrin während der Eingabe eine Fehlermeldung ausgegeben werden soll. Gibt der User nun als erstes eine ungültige Eingabe ein, so kann er trotzdem noch die restlichen Eingaben machen. Kam es zu einem Eingabefehler, wird "?" ausgegeben und das Programm beendet. Ist dies nicht der Fall wird noch überprüft mittels "checkIfDreieck" ob die Eingaben inhaltlich korrekt sind und gegebenenfalls "FALSCHE EINGABE" ausgegeben und das Programm beendet. War alles korrekt folgen die Berechnungen für den Inkreismittelpunkt, die aus folgenden Schritten bestehen: *) Der Vektor der ersten Winkelsymmetrale (durch Punkt A) wird mittels "WsymBilden" gebildet. *) Gerade 1 wird mit "GeradeBilden" durch den Punkt A mit dem Vektor der Winkelsymetrale gebildet. *) Der Vektor der zweiten Winkelsymmetrale (durch Punkt B) wird mittels "WsymBilden" gebildet. *) Gerade 2 wird mit "GeradeBilden" durch den Punkt B mit dem Vektor der zweiten Winkelsymetrale gebildet. *) Mit "GeradeSchneiden" werden Gerade 1 und Gerade 2 geschnitten. Der Schnittpunkt der sich ergibt entspricht dem Inkreismittelpunkt. Dann kommen die Berechnungen für den Radius des Inkreises: *) Zuerst wird die Gerade durch die Punkte A und B gebildet indem der Methode "GeradeBilden" die x und y Koordinaten des Inkreismittelpunktes und x und y Wert des Vektors AB übergeben werden (es ist also quasi eine Normale auf die Normale die gleich folgt - !Mathematik! :-P ). Für IstGleich2 multiplizieren wir x und y Koordinate mit dem Punkt A durch den die Gerade ja gehen soll. *) Dann wird eine Normale auf diese Gerade durch den Inkreismittelpunkt gebildet. Dies geschieht ganz einfach durch umdrehen des x und y Wertes der Geraden (wobei ein Wert Minus gesetzt wird). Für IstGleich1 multiplizieren wir x und y Koordinate mit dem Inkreismittelpunkt, durch den die Normale ja gehen soll. *) Normale und Gerade werden mittels "GeradeSchneiden" geschnitten, wir bekommen neue Werte für SchnittpunktX und SchnittpunktY. *) Abschließend ergibt sich der Radius als Abstand zwischen Schnittpunkt und Inkreismittelpunkt, was wir einfach mit "BetragBilden" berechnen. Bevor dann noch Inkreismittelpunkt und Radius ausgegeben werden, überprüfen wir noch ob alle dafür benötigten Variablen auch einen Wert haben. Bei zu großen Zahlen kann es vorkommen, dass eine Variable NaN ("not a number") ist. Dies wird in einer if - Anweisung abgefangen und gegebenenfalls mit "?" quittiert. Sollte alles stimmen werden x und y Koordinate des Inkreismittelpunktes sowie der Radius mit printFixed auf drei Nachkommastellen gerundet ausgegeben. Abschließend möchte ich noch anmerken dass das Programm ganz einfach durch Verändern der main - Methode erweitert bzw. verändert werden kann. Man kann den verschiedenen Methoden beliebige Werte übergeben und somit alle möglichen Berechnungen durchführen.