From 6a09cc4e8be440f5f25ebfb56970f5ffd02de79c Mon Sep 17 00:00:00 2001
From: Maximilian Reininghaus <maximilian.reininghaus@kit.edu>
Date: Tue, 31 Jul 2018 18:20:03 +0200
Subject: [PATCH] first implementation of geometry

---
 Framework/Geometry/BaseVector.h        | 21 ++++++++
 Framework/Geometry/CoordinateSystem.cc | 54 ++++++++++++++++++++
 Framework/Geometry/CoordinateSystem.h  | 71 ++++++++++++++++++++++++++
 Framework/Geometry/Point.h             | 48 +++++++++++++++++
 Framework/Geometry/QuantityVector.h    | 42 +++++++++++++++
 Framework/Geometry/Vector.h            | 61 ++++++++++++++++++++++
 Framework/Units/Units.h                |  1 -
 7 files changed, 297 insertions(+), 1 deletion(-)
 create mode 100644 Framework/Geometry/BaseVector.h
 create mode 100644 Framework/Geometry/CoordinateSystem.cc
 create mode 100644 Framework/Geometry/CoordinateSystem.h
 create mode 100644 Framework/Geometry/Point.h
 create mode 100644 Framework/Geometry/QuantityVector.h
 create mode 100644 Framework/Geometry/Vector.h
 delete mode 100644 Framework/Units/Units.h

diff --git a/Framework/Geometry/BaseVector.h b/Framework/Geometry/BaseVector.h
new file mode 100644
index 000000000..d0086c436
--- /dev/null
+++ b/Framework/Geometry/BaseVector.h
@@ -0,0 +1,21 @@
+#ifndef BASEVECTOR_H_
+#define BASEVECTOR_H_
+
+#include "QuantityVector.h"
+#include "CoordinateSystem.h"
+
+template <typename dim>
+class BaseVector
+{
+protected:
+    QuantityVector<dim> qVector;
+    CoordinateSystem const* cs;
+    
+public:
+    BaseVector(CoordinateSystem const& pCS, QuantityVector<dim> pQVector) :
+        qVector(pQVector), cs(&pCS)
+    {
+    }
+};
+
+#endif
diff --git a/Framework/Geometry/CoordinateSystem.cc b/Framework/Geometry/CoordinateSystem.cc
new file mode 100644
index 000000000..81a195ce4
--- /dev/null
+++ b/Framework/Geometry/CoordinateSystem.cc
@@ -0,0 +1,54 @@
+#include "CoordinateSystem.h"
+
+EigenTransform CoordinateSystem::getTransformation(CoordinateSystem const& c1, CoordinateSystem const& c2)
+{
+    CoordinateSystem const* a{&c1};
+    CoordinateSystem const* b{&c2};
+    CoordinateSystem const* commonBase{nullptr};
+    
+    while (a != b && b != nullptr)
+    {
+        a = &c1;
+        
+        while (a != b && a != nullptr)
+        {
+            a = a->getReference();
+        }
+        
+        if (a == b)
+            break;
+        
+        b = b->getReference();
+    }
+    
+    if (a == b && a != nullptr)
+    {
+        commonBase = a;
+        
+    }
+    else
+    {
+        throw std::string("no connection between coordinate systems found!");
+    }
+    
+    
+    EigenTransform t = EigenTransform::Identity();
+    
+    auto* p = &c1;
+    
+    while (p != commonBase)
+    {
+        t = p->getTransform() * t;
+        p = p->getReference();
+    }
+    
+    p = &c2;
+    
+    while (p != commonBase)
+    {
+        t = p->getTransform().inverse(Eigen::TransformTraits::Isometry) * t;
+        p = p->getReference();
+    }
+    
+    return t;
+}
diff --git a/Framework/Geometry/CoordinateSystem.h b/Framework/Geometry/CoordinateSystem.h
new file mode 100644
index 000000000..ab525b27a
--- /dev/null
+++ b/Framework/Geometry/CoordinateSystem.h
@@ -0,0 +1,71 @@
+#ifndef COORDINATESYSTEM_H_
+#define COORDINATESYSTEM_H_
+
+#include "QuantityVector.h"
+#include <Eigen/Dense>
+#include <phys/units/quantity.hpp>
+
+typedef Eigen::Transform<double, 3, Eigen::Affine> EigenTransform;
+typedef Eigen::Translation<double, 3> EigenTranslation;
+
+class CoordinateSystem
+{
+    CoordinateSystem const* reference = nullptr;
+    EigenTransform transf;
+    
+    CoordinateSystem(CoordinateSystem const& reference, EigenTransform const& transf) :
+        reference(&reference),
+        transf(transf)
+    {
+        
+    }
+    
+public:
+    static EigenTransform getTransformation(CoordinateSystem const& c1, CoordinateSystem const& c2);
+
+    CoordinateSystem() : // for creating the root CS
+        transf(EigenTransform::Identity())
+    {
+        
+    }
+    
+    auto& operator=(const CoordinateSystem& pCS)
+    {
+        reference = pCS.reference;
+        transf = pCS.transf;
+        return *this;
+    }    
+    
+    auto translate(QuantityVector<phys::units::length_d> vector) const
+    {
+        EigenTransform const translation{EigenTranslation(vector.eVector)};
+        
+        return CoordinateSystem(*this, translation);
+    }
+    
+    auto rotate(QuantityVector<phys::units::length_d> axis, double angle) const
+    {
+        EigenTransform const rotation{Eigen::AngleAxisd(M_PI / 6, axis.eVector.normalized())};
+        
+        return CoordinateSystem(*this, rotation);
+    }
+    
+    auto translateAndRotate(QuantityVector<phys::units::length_d> translation, QuantityVector<phys::units::length_d> axis, double angle)
+    {
+        EigenTransform const transf{Eigen::AngleAxisd(M_PI / 6, axis.eVector.normalized()) * EigenTranslation(translation.eVector)};
+        
+        return CoordinateSystem(*this, transf);
+    }
+    
+    auto const* getReference() const
+    {
+        return reference;
+    }
+    
+    auto const& getTransform() const
+    {
+        return transf;
+    }    
+};
+
+#endif
diff --git a/Framework/Geometry/Point.h b/Framework/Geometry/Point.h
new file mode 100644
index 000000000..633279e4c
--- /dev/null
+++ b/Framework/Geometry/Point.h
@@ -0,0 +1,48 @@
+#ifndef POINT_H_
+#define POINT_H_
+
+#include "BaseVector.h"
+#include "QuantityVector.h"
+#include <phys/units/quantity.hpp>
+
+class Point : public BaseVector<phys::units::length_d>
+{
+    using Length = phys::units::quantity<phys::units::length_d, double>;
+    
+    
+public:
+    Point(CoordinateSystem const& pCS, QuantityVector<phys::units::length_d> pQVector) :
+        BaseVector<phys::units::length_d>(pCS, pQVector)
+    {
+    }
+
+    Point(CoordinateSystem const& cs, Length x, Length y, Length z) :
+        BaseVector<phys::units::length_d>(cs, {x, y, z})
+    {
+    }
+    
+    auto getCoordinates() const
+    {
+        return BaseVector<phys::units::length_d>::qVector;
+    }
+    
+    auto getCoordinates(CoordinateSystem const& pCS) const
+    {
+        if (&pCS == BaseVector<phys::units::length_d>::cs)
+        {
+            return BaseVector<phys::units::length_d>::qVector;
+        }
+        else
+        {
+            return QuantityVector<phys::units::length_d>(CoordinateSystem::getTransformation(*BaseVector<phys::units::length_d>::cs, pCS) * BaseVector<phys::units::length_d>::qVector.eVector);
+        }
+    }
+    
+    void rebase(CoordinateSystem const& pCS)
+    {
+        BaseVector<phys::units::length_d>::qVector = getCoordinates(pCS);
+        BaseVector<phys::units::length_d>::cs = &pCS;
+    }
+};
+
+#endif
diff --git a/Framework/Geometry/QuantityVector.h b/Framework/Geometry/QuantityVector.h
new file mode 100644
index 000000000..647303791
--- /dev/null
+++ b/Framework/Geometry/QuantityVector.h
@@ -0,0 +1,42 @@
+#ifndef QUANTITYVECTOR_H_
+#define QUANTITYVECTOR_H_
+
+#include <phys/units/quantity.hpp>
+#include <phys/units/io.hpp>
+#include <Eigen/Dense>
+#include <iostream>
+
+template <typename dim>
+class QuantityVector
+{
+protected:
+    using Quantity = phys::units::quantity<dim, double>;
+    
+public:
+    Eigen::Vector3d eVector;
+
+    QuantityVector(Quantity a, Quantity b, Quantity c) :
+        eVector{a.magnitude(), b.magnitude(), c.magnitude()}
+    {
+    }
+    
+    QuantityVector(Eigen::Vector3d pBareVector) :
+        eVector(pBareVector)
+    {
+    }
+    
+    Quantity operator[](size_t index) const
+    {
+        return Quantity(phys::units::detail::magnitude_tag, eVector[index]);
+    }
+};
+
+template <typename dim>
+auto& operator<<(std::ostream& os, QuantityVector<dim> qv)
+{
+    os << '(' << qv.eVector(0) << ' ' << qv.eVector(1) << ' ' << qv.eVector(2)
+       << ") " << phys::units::to_unit_symbol(phys::units::quantity<dim, double>());
+    return os;
+}
+
+#endif
diff --git a/Framework/Geometry/Vector.h b/Framework/Geometry/Vector.h
new file mode 100644
index 000000000..bf8ab9d40
--- /dev/null
+++ b/Framework/Geometry/Vector.h
@@ -0,0 +1,61 @@
+#ifndef VECTOR_H_
+#define VECTOR_H_
+
+#include "BaseVector.h"
+#include "QuantityVector.h"
+#include <phys/units/quantity.hpp>
+
+template <typename dim>
+class Vector : public BaseVector<dim>
+{
+    using Quantity = phys::units::quantity<dim, double>;
+    
+    Vector(CoordinateSystem const& pCS, QuantityVector<dim> pQVector) :
+        BaseVector<Quantity>(pCS, pQVector)
+    {
+    }
+        
+    
+public:
+    Vector(CoordinateSystem const& cs, Quantity x, Quantity y, Quantity z) :
+        BaseVector<dim>(cs, QuantityVector<dim>(x, y, z))
+    {
+    }
+    
+    auto getComponents() const
+    {
+        return BaseVector<dim>::qVector;
+    }
+    
+    auto getComponents(CoordinateSystem const& pCS) const
+    {
+        if (&pCS == BaseVector<dim>::cs)
+        {
+            return BaseVector<dim>::qVector;
+        }
+        else
+        {
+            return QuantityVector<dim>(CoordinateSystem::getTransformation(*BaseVector<dim>::cs, pCS).linear() * BaseVector<dim>::qVector.eVector);
+        }
+    }
+    
+    void rebase(CoordinateSystem const& pCS)
+    {
+        BaseVector<dim>::qVector = getComponents(pCS);        
+        BaseVector<dim>::cs = &pCS;
+    }
+    
+    auto norm() const
+    {
+        return Quantity(BaseVector<dim>::qVector.eVector.norm());
+    }
+    
+    //~ template <typename dim2>
+    //~ auto operator*(Vector<dim2> const& pVec)
+    //~ {
+        //~ auto constexpr resulting_dim = dimension 
+        //~ return Vector<
+    //~ }
+};
+
+#endif
diff --git a/Framework/Units/Units.h b/Framework/Units/Units.h
deleted file mode 100644
index 8b1378917..000000000
--- a/Framework/Units/Units.h
+++ /dev/null
@@ -1 +0,0 @@
-
-- 
GitLab