/// @file   main.cpp
/// @author Jens Gruschel
/// @date   2016-07-14
/// verbesserter Point-Typ

#include <iostream>

using std::cout;
using std::endl;

/// dreidimensionaler Punkt
struct Point
{
    Point();
    Point(const double x, const double y, const double z);
    double x;
    double y;
    double z;
};

/// Default-Konstruktor
Point::Point() :
    x(0.0), y(0.0), z(0.0)
{}

/// Konstruktor
Point::Point(const double x, const double y, const double z) :
    x(x), y(y), z(z)
{}

/// Addition zweier Punkte bzw. Vektoren
Point operator+(const Point& first, const Point& second)
{
    return Point(first.x + second.x,
                 first.y + second.y,
                 first.z + second.z);
}

/// Multiplikation einer Zahl mit einem Vektor
Point operator*(const double factor, const Point& p)
{
    return Point(factor * p.x,
                 factor * p.y,
                 factor * p.z);
}

/// Multiplikation eines Vektors mit einer Zahl
Point operator*(const Point& p, const double factor)
{
    return Point(factor * p.x,
                 factor * p.y,
                 factor * p.z);
}

/// Skalarprodukt zweier Vektoren
double operator*(const Point& a, const Point& b)
{
    return a.x * b.x + a.y * b.y + a.z * b.z;
}

/// Kreuzprodukt zweier Vektoren
Point cross(const Point& a, const Point& b)
{
    return Point(a.y * b.z - a.z * b.y,
                 a.z * b.x - a.x * b.z,
                 a.x * b.y - a.y * b.x);
}

/// Punktkoordinaten auf Konsole ausgeben
void print(const Point& p)
{
    cout << "x: " << p.x << endl;
    cout << "y: " << p.y << endl;
    cout << "z: " << p.z << endl;
}

int main()
{
    // Punkt definieren
    Point p(1.0, 2.0, 3.0);

    // Multiplikation durchfuehren
    Point q = 0.2 * p;

    // Ergebnis ausgeben
    print(p);
    print(q);

    // Skalarprodukt und Kreuzprodukt berechnen
    cout << "Skalarprodukt: " << p * q << endl;
    print(cross(p, Point(2.0, 3.0, 1.0)));

    return 0;
}