c-uebungen/Assignment_023/readme.md

6.0 KiB

Assignment: Vektor (stack-basiert)

📆 Fällig: ---- 📆 Musterlösung

Es ist sechs Uhr morgens, Ihr Radiowecker weckt Sie mit dem Song "I Got You Babe" von Sonny and Cher. Irgendwie erinnert Sie das an einen Film, den Sie vor längerer Zeit gesehen haben, mit Bill Murray...

Quelle: Pixabay.com

Es gibt einen lauten Knall. Sie schauen zum Himmel uns sehen dort ein Raumschiff der Kryptonier, die offensichtlich die Weltherrschaft an sich reißen wollen; woher Sie das wissen? Natürlich aus den vielen Filmen, die Sie gesehen haben: Aliens == böse. Zum Glück haben Sie noch eine kleine Rakete im Garten (woher auch immer die stammt), die Sie auf das Raumschiff abfeuern könnten. Aber wie bloß die Flugbahn berechnen? Dazu bietet sich doch die gute alte Vektorrechnung an...

Wie bitte? Die Geschichte kennen wir doch schon. Wieso schon wieder die Kryptonier? Wenn Ihnen das nicht klar ist, sollten Sie noch einmal den Film mit Bill Murray schauen.

Ziel: Ziel dieses Assignments ist es, Vektoren in C zu implementieren.

Vector: Struktur und Funktionen

Beschreibung des Programms

Implementieren Sie eine Struktur Vector und die dazugehörigen Funktionen in einer Datei vector_stack.c mit deren Hilfe man auf dreidimensionalen Vektoren die wichtigsten Operationen durchführen kann. Drei Dimensionen reichen, um die Flugbahn der Rakete zu berechnen -- also kein Grund für mehr Dimensionen!

Die Komponenten x, y und z sollen als double gespeichert werden.

Ihre Implementierung soll die folgenden Aktionen unterstützen:

  • vec_init - Befüllen des Vektors mit Daten für die drei Komponenten
  • vec_null - Setzen eines Vektors als Nullvektor (alle drei Komponenten [x,y,z] sind 0)
  • vec_add - Addieren zweier Vektoren
  • vec_sub - Subtrahieren zweier Vektoren
  • vec_mul_scalar - Multiplikation des Vektors mit einem Skalar
  • vec_mul_dot - Skalarmultiplikation zweier Vektoren
  • vec_mul_cross - Kreuzprodukt zweier Vektoren
  • vec_norm - Erzeugung des Einheitsvektors aus einem gegebenen Vektor (d.h. Vektor der Länge 1 mit derselben Richtung wie der ursprüngliche Vektor). Beachten Sie, dass vom Nullvektor kein Einheitsvektor erzeugt werden kann. In diesem Fall müssen Sie eine entsprechende Rückgabe machen, um den Fehler anzuzeigen.
  • vec_length - Berechnung des Betrages (der Länge) eines Vektors
  • vec_collinear - Test, ob zwei Vektoren kollinear (parallel oder antiparallel) sind
  • vec_equals - Test, ob zwei Vektoren gleich sind
  • vec_print - Ausgabe des Vektors auf der Console
  • vec_to_s - Umwandlung des Vektors in einen String

Keine der Funktionen verändert die übergebenen Vektoren, sondern schreibt das Ergebnis in den ebenfalls übergebenen Vektor für das Ergebnis. Siehe hierzu das Beispiel unten.

Bei einer C-Bibliothek muss man sich entscheiden, wer für die Allokation des Speichers zuständig ist. Hier entscheiden wir uns dafür, dass der Verwender der Funktionen den Speicher beschaffen muss und den Funktionen als Pointer übergeben. Das folgende Beispiel zeigt, wie Ihre Vektor-Bibliothek zu benutzen ist:

Vector v1, v2, v3;
char* result;

/* Vektoren initialisieren */
vec_init(&v1,  10.0, 20.0, 30.0);
vec_init(&v2, -20.0, 99.0, 38.0);

/* Kreuzprodukt berechnen. v1 und v2 bleiben unverändert,
   Ergebnis wird in v3 gespeichert. */
vec_mul_cross(&v3, v1, v2);

/* Ergebnis ausgeben */
result = vec_to_str(v3);
printf("Das Ergebnis ist: %s\n", result);
free(result);

Einzig die vec_to_str-Funktion beschafft Speicher für den String per malloc, den der Verwender per free wieder freigeben muss. Alle anderen Funktionen führen keine Speicherallokation durch.

Schreiben Sie eine Header-Datei vector_stack.h, welche die exportierten Funktionen als Prototypen enthält. Diese werden wir für die Tests benötigen. Kommentieren Sie die Funktionen ausreichend.

Tests

Überprüfen Sie die Funktionalität Ihrer Implementierung mit entsprechenden Unit-Tests (Datei vektor_stack_test.c) und weisen Sie mit diesen Tests nach, dass die implementierten Operationen richtig funktionieren.

Für die Unit-Tests steht Ihnen eine ganz einfache Testbibliothek über das Header-File minitest.h zur Verfügung. Die Datei vektor_stack_test.c enthält ein Beispiel für die Benutzung dieser Bibliothek. Verwenden Sie das dort benutzte Schema und fügen Sie Ihre Tests hinzu.

Verwenden Sie bitte mindestens die folgenden Testdaten/Testfälle.

Multiplikation mit einem Skalar

  • [1, -5, 3] * 6 = [ 6, -30, 18 ]
  • [ 1, -5, 3 ] * -3 = [ -3, 15, -9 ]

Skalarprodukt zweier Vektoren

  • [ 1, 2, 3 ] * [ -7, 8, 9 ] = 36
  • [ -5, 9, 7 ] * [ 10, 3, 8 ] = 33

Addition und Subtraktion

  • [ 4, 0, 8 ] + [ -1, 4, 7 ] = [ 3, 4, 15 ]
  • [ 4, 0, 8 ] - [ -1, 4, 7 ] = [ 5, -4, 1 ]
  • [ 4, 0, 8 ] + [ -1, 4, 7 ] = [ -1, 4, 7 ] + [ 4, 0, 8 ]

Kreuzprodukt

  • [ 1, 2, 3 ] x [ -7, 8, 9 ] = [ -6, -30, 22 ]
  • [ 1, 2, 8 ] x [ 4, 3, 5 ] = [ -14, 27, -5 ]

Betrag

  • |[ 1, 1, 1 ]| = sqrt(3)
  • |[ 5, 4, 3 ]| = sqrt(50)

Kollinearität

  • [ 4, 5, 7 ] und [ 16, 20, 28 ] sind kollinear
  • [ 4, 5, 7 ] und [ 16, 20, 21 ] sind nicht kollinear

Komplexere Rechnung

  • ([ -1, 5, -2 ] x [ 2, 1, 2 ]) * [ 2, 0, 5 ] = -31

Makefile

Automatisieren Sie das Kompilieren und Testen Ihrer Programme mit einem Makefile. Dieses sollte mindestens die folgenden Targets haben:

  • all - baut alle Dateien
  • clean - setzt das Projekt zurück und löscht alle Kompilationsergebnisse
  • test - führt die oben beschriebenen Tests aus

Sie benötigen natürlich weitere Targets für die Objektdateien und fertigen Executables.

Quellen