Da wir im Laufe dieser Veranstaltung einige Mathematische Formeln verstehen müssen, werden wir eine neue Translation Unit einführen: cgmath.o

Sie kennen den Drill: Erstellen Sie die beiden benötigten Dateien und passen Sie Ihr Makefile entsprechend an.

Anmerkung: Einige der Funktionen die wir hier implementieren, unterstützt die OpenGL API auch selbst. Für andere Funktionen würde es sich anbieten auf eine speziell dafür entworfene und auf Geschwindigkeit optimierte Mathe Bibliothek zurückzugreifen. Trotzdem werden wir alle Funktionen die wir für diese Veranstaltung brauchen, selber implementieren. Unser Ziel ist dabei nicht, besonders effizient zu programmieren sondern besonders lesbar. So sind wir am Ende des Semesters in der Lage, genau zu verstehen was unser Programm tut und können die einzelnen Schritte auch von Hand nachrechnen.

Inhalt

Im Laufe des Semesters werden wir diese Bibliothek Schrittweise jeweils um die Funktionen erweitern die wir benötigen.

In diesem Kapitel beginnen wir mit der Implementierung von Rotations- und Translationsmatritzen

Fügen Sie folgendes in ihre cgmath.h ein:

#ifndef CGMATH
#define CGMATH
typedef struct {
    float m11;
    float m12;
    float m13;
    float m14;
    float m21;
    float m22;
    float m23;
    float m24;
    float m31;
    float m32;
    float m33;
    float m34;
    float m41;
    float m42;
    float m43;
    float m44;
} matrix;
#endif

matrix matrixTranslate(float x, float y, float z);
matrix matrixRotateX(float a);
matrix matrixRotateY(float a);
matrix matrixRotateZ(float a);

float deg2rad(float deg);

Hier sehen wir direkt zwei neue Elemente die wir bisher nicht kennengelernt haben. Einerseits definieren wir hier einen neuen Datentyp matrix. Das struct kennen sie bereits aus Java. Unter C funktioniert es ähnlich, allerdings benötigt man hier zusätzlich das typedef statement, damit man die Matrix auch unter ihrem Namen verwenden kann. Falls das neu für Sie ist, lesen Sie sich in die Thematik ein. Wir werden das später noch häufiger sehen.

Außerdem wird hier eine Präprozessor Direktive angewandt. #ifndef ist ein if-Statement welches während des Kompilierens ausgewertet wird, nicht zur Laufzeit. Dies ist nötig, weil wir unsere Mathe Bibliothek an mehreren Stellen einbinden wollen, die Typendefinition aber nur einmal stattfinden soll. Das Konstrukt aus #ifndef, #define und #endif sorgt also dafür, dass alles dazwischen nur genau einmal stattfindet. Lesen Sie auch hier nach, wenn dieses Thema für Sie neu ist. In der Prüfung am Ende des Semesters sollten Sie das auf jeden Fall verstanden haben.

Ansonsten sehen wir bekanntes. Hier definieren wir zwei Funktionen mit denen wir eine Rotationsmatrix erzeugen können, eine Funktion um eine Translationsmatrix zu erzeugen und eine deg2rad Funktion, die einen Wert vom Gradmaß ins Bogenmaß umwandelt. (Klicken Sie die Links für weitergehende Infos)

Hier die Implementierung:

#include <math.h>
#include "cgmath.h"

matrix matrixTranslate(float x, float y, float z)
{
    matrix m = {};
    m.m11 = 1;  m.m21 = 0;  m.m31 = 0;  m.m41 = x;
    m.m12 = 0;  m.m22 = 1;  m.m32 = 0;  m.m42 = y;
    m.m13 = 0;  m.m23 = 0;  m.m33 = 1;  m.m43 = z;
    m.m14 = 0;  m.m24 = 0;  m.m34 = 0;  m.m44 = 1;
    return m;
}

matrix matrixRotateX(float a)
{
    matrix m = {};
    m.m11 = 1;  m.m21 =      0;  m.m31 =       0;  m.m41 = 0;
    m.m12 = 0;  m.m22 = cos(a);  m.m32 = -sin(a);  m.m42 = 0;
    m.m13 = 0;  m.m23 = sin(a);  m.m33 =  cos(a);  m.m43 = 0;
    m.m14 = 0;  m.m24 =      0;  m.m34 =       0;  m.m44 = 1;
    return m;
}

matrix matrixRotateY(float a)
{
    matrix m = {};
    m.m11 =  cos(a);  m.m21 = 0;  m.m31 = sin(a);  m.m41 = 0;
    m.m12 =       0;  m.m22 = 1;  m.m32 =      0;  m.m42 = 0;
    m.m13 = -sin(a);  m.m23 = 0;  m.m33 = cos(a);  m.m43 = 0;
    m.m14 =       0;  m.m24 = 0;  m.m34 =      0;  m.m44 = 1;
    return m;
}

float deg2rad(float deg)
{
    return deg * 3.14f / 180.0f;
}

Selbststudium & Erweiterungen

Untersuchen Sie den Code und lesen Sie die passenden, verlinkten Artikel. Auch Ihre Unterlagen aus den passenden Mathematikvorlesungen kann sich jetzt wieder als Hilfreich herausstellen.

Implementieren Sie die noch fehlende Rotation um die Z-Achse:

matrix matrixRotateZ(float a) { ... }