% \iffalse meta-comment
% !TEX program = pdfLaTeX
%<*internal>
\iffalse
%</internal>
%<*readme>
----------------------------------------------------------------
glmatrix v1.0.0 --- This package provides macros for linear algebra calculations with scalars, vectors, and matrices. Its structure is based on the JavaScript library glmatrix.js, and it similarly provides several convenience functions often used in computer graphics contexts, like creating a translation matrix.
E-mail: rwarnking@gmail.com

Released under BSD 3-Clause License

BSD 3-Clause License
    
    Copyright (c) 2026, Rene Warnking
    
    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions are met:
    
    1. Redistributions of source code must retain the above copyright notice, this
       list of conditions and the following disclaimer.
    
    2. Redistributions in binary form must reproduce the above copyright notice,
       this list of conditions and the following disclaimer in the documentation
       and/or other materials provided with the distribution.
    
    3. Neither the name of the copyright holder nor the names of its
       contributors may be used to endorse or promote products derived from
       this software without specific prior written permission.
    
    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

----------------------------------------------------------------

This package provides macros for linear algebra calculations with scalars, vectors, and matrices. Its structure is based on the JavaScript library glmatrix.js, and it similarly provides several convenience functions often used in computer graphics contexts, like creating a translation matrix.
%</readme>

%<*internal>
\fi
\def\nameofplainTeX{plain}
\ifx\fmtname\nameofplainTeX\else
  \expandafter\begingroup
\fi
%</internal>
%<*install>
\input docstrip.tex % chktex 27
\keepsilent
\askforoverwritefalse
\preamble
---------------------------------------------------------------
glmatrix v1.0.0 --- This package provides macros for linear algebra calculations with scalars, vectors, and matrices. Its structure is based on the JavaScript library glmatrix.js, and it similarly provides several convenience functions often used in computer graphics contexts, like creating a translation matrix.
Maintained by Rene Warnking
E-mail: rwarnking@gmail.com

Released under BSD 3-Clause License

BSD 3-Clause License
    
    Copyright (c) 2026, Rene Warnking
    
    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions are met:
    
    1. Redistributions of source code must retain the above copyright notice, this
       list of conditions and the following disclaimer.
    
    2. Redistributions in binary form must reproduce the above copyright notice,
       this list of conditions and the following disclaimer in the documentation
       and/or other materials provided with the distribution.
    
    3. Neither the name of the copyright holder nor the names of its
       contributors may be used to endorse or promote products derived from
       this software without specific prior written permission.
    
    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

---------------------------------------------------------------
\endpreamble
\postamble
Copyright (C) 2026/04/03 by
  Rene Warnking <rwarnking@gmail.com>

Released under BSD 3-Clause License

BSD 3-Clause License
    
    Copyright (c) 2026, Rene Warnking
    
    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions are met:
    
    1. Redistributions of source code must retain the above copyright notice, this
       list of conditions and the following disclaimer.
    
    2. Redistributions in binary form must reproduce the above copyright notice,
       this list of conditions and the following disclaimer in the documentation
       and/or other materials provided with the distribution.
    
    3. Neither the name of the copyright holder nor the names of its
       contributors may be used to endorse or promote products derived from
       this software without specific prior written permission.
    
    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


This work is maintained by
  Rene Warnking.

This work consists of the file  glmatrix.dtx
          and the derived files glmatrix.pdf,
                                glmatrix.sty and
                                glmatrix.ins.

\endpostamble
\usedir{tex/latex/glmatrix}
\generate{
  \file{glmatrix.sty}{\from{glmatrix.dtx}{package}}
}
%</install>
%<install>\endbatchfile
%<*internal>
\usedir{source/latex/glmatrix}
\generate{
  \file{glmatrix.ins}{\from{glmatrix.dtx}{install}}
}
\nopreamble\nopostamble
\usedir{doc/latex/glmatrix}
\generate{
  \file{README.txt}{\from{glmatrix.dtx}{readme}}
}
\ifx\fmtname\nameofplainTeX
  \expandafter\endbatchfile
\else
  \expandafter\endgroup
\fi
%</internal>

%<*package>
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{glmatrix}[2026/04/03 v1.0.0 Macros for linear algebra calculations common in computer graphics]

\RequirePackage{xinttools}
\RequirePackage{xintfrac}
\RequirePackage{fp}

\newcommand{\R}{\ensuremath{\textrm{I\!R}}}
\newcommand{\trans}[1]{\ensuremath{{#1}\mkern-1mu^{\mathsf{T}}}}
\newcommand{\norm}[1]{\ensuremath{\left\Vert #1 \right\Vert}}

%</package>

%<*driver>
\documentclass{ltxdoc}
\usepackage{xcolor}
\definecolor{uos-red}{cmyk}{0.2, 1, 0.65, 0.25}

\usepackage{etoc}
\setcounter{tocdepth}{2} % show only sections and subsections
\usepackage{hyperref}
\hypersetup{
  linkcolor=uos-red,
}
\usepackage{tabularx}
\usepackage{ltablex}
\usepackage{makecell}

\usepackage{amsmath}

\usepackage{tcolorbox}

\usepackage{listings}

\tcbset{
  mydocbox/.style={
    sharp corners,
    boxrule=0.8pt,
    left=6pt,
    right=6pt,
    top=6pt,
    bottom=6pt,
    % breakable
  }
}

% Red box
\newtcolorbox{descriptionbox}{
  mydocbox,
  colback=gray!15,
  colframe=gray!75!black,
  title=Description,
  fonttitle=\bfseries
}

% Red box
\newtcolorbox{warningbox}{
  mydocbox,
  colback=red!15,
  colframe=red!75!black,
  title=Warning,
  fonttitle=\bfseries
}

% Blue box
\newtcolorbox{equationbox}{
  mydocbox,
  colback=blue!10,
  colframe=blue!70!black,
  title=Equation,
  fonttitle=\bfseries
}

% Yellow box
\newtcolorbox{examplebox}{
  mydocbox,
  colback=yellow!20,
  colframe=yellow!60!black,
  title=Example,
  fonttitle=\bfseries
}

\lstdefinelanguage{latex}
{
	sensitive=true,
	alsoletter={\\},
	morekeywords=[1]{
        \\newVec, \\addVec, \\newMat, \\newDiagMat, \\mulMat, \\transformVec, \\printMat, \\printVec, \\begin, \\end, \\left, \\right
	},
	morekeywords=[2]{
    align
	},
	morekeywords=[3]{
    \\myMatA, \\myMatB, \\myVecV, \\myVecW, \\mulMatResult, \\addVecResult, \\transformVecResult
	},
}

% [LaTeX]TeX
\lstdefinestyle{latexStyle}{
    language=latex,
	tabsize=2,
	basicstyle=\footnotesize\ttfamily,
    upquote=true,
    % frame=leftline,
	columns=fixed,
	showstringspaces=false,
	extendedchars=true,
	breaklines=true,
    aboveskip=1em,
    belowskip=0.1em,
	showtabs=false,
	showspaces=false,
    showstringspaces=false,
    numberstyle=\color[rgb]{0.5,0.5,0.5},
	identifierstyle=\ttfamily,
	commentstyle=\color[rgb]{.3, .53, .42},
    comment=[l]\%,
    %\color{syntaxComment},
	keywordstyle=[1]\color[rgb]{.13, .13, 1},
	keywordstyle=[2]\color[rgb]{.19, .52, .58},
	keywordstyle=[3]\color[rgb]{.51, .25, .73},
	keywordstyle=[4]\color[rgb]{0.4,0.4,0.4},
	stringstyle=\color[rgb]{0.639,0.082,0.082},
}

% \usepackage{etoolbox}
% \appto{DescribeMacro}{\color{blue}}

% \usepackage[a4paper, left=2.5cm, right=2.5cm, top=2cm, bottom=2cm]{geometry}

\setlength{\parindent}{0pt}

\usepackage{fancyhdr}

% TODO make this modular
\pagestyle{fancy}
\fancyhf{}
\fancyhead[C]{%
    \hyperref[subsec:scalar]{Scalar} |
    \hyperref[subsec:vector]{Vector} |
    \hyperref[subsec:matrix]{Matrix}
}
\renewcommand{\headrulewidth}{0.4pt}

\makeatletter
\newcommand{\setlabel}[2]{%
  \phantomsection
  \def\@currentlabel{\unexpanded{#1}}\label{#2}%
}
\makeatother
\EnableCrossrefs
\CodelineIndex
\RecordChanges
\begin{document}
    \title{The \textsf{glmatrix} Package}
    \author{Rene Warnking}
    \date{Version 1.0.0\\2026/04/03}
    \maketitle

    \tableofcontents

    \section{Introduction}
    
    The \texttt{glmatrix} package provides a small set of macros that allow you to
    do basic vector and matrix arithmetics in \LaTeX. It is inspired by the javascript
    library with the same name (https://glmatrix.net/) and provides the same functions and more.
    Using this package, you can easily do vector calculations like dot and cross
    product as well as more complex calculations, like vector matrix multiplication.
    
    The package is specifically targeting use cases in computer graphics.
    Consequently, it provides macros for vector transformations using matrices and
    the creation of commonly used matrices in computer graphics, like the lookAt matrix.
    In combination, these macros allow you to do many calculations that regularly occurr in computer graphics.
    
    \clearpage

    \section{Example}
    
    Given the following equation:
    \[A B (\vec{v} + \vec{w})\ \vert\ v, w \in \R^3, A, B \in \R^{3\times3}\]
    
    The code below recreates the equation with exemplary values and directly calculates the results.
    Then, the results are used to print a step-by-step solution with the chosen values.\\
    Note:
    \begin{itemize}
    \setlength\itemsep{0em}
    \item While creating a new vector or matrix is done by providing its name as a simple string, accessing its content after creation is done as a command (with backslash)
    \item This package mainly provides macros for mathematical calculations. These macros assign the calculated result automatically to a variable using the optional parameter (for example \textbackslash addVec). If you wish to specify the name of the variable yourself, you may pass a string for the optional argument.
    \end{itemize}
    
    \lstset{style=latexStyle}
    \begin{lstlisting}[gobble=4]
    % Initialize two vectors and add them together
    \newVec{myVecV}{1,2,3}
    \newVec{myVecW}{7,8,9}
    \addVec[addVecResult]{\myVecV}{\myVecW}
    
    % Initialize two matrices and multiply them with each other
    \newMat{myMatA}{{{0.5,2,3}{4,5,6}{7,8,9}}}
    \newDiagMat{myMatB}{2, 3, 4}
    \mulMat[mulMatResult]{\myMatA}{\myMatB}
    
    % Transform the result vector with the created matrix
    \transformVec{\mulMatResult}{\addVecResult}
    
    % Print a step-by-step solution
    \begin{align}
        \printMat{\myMatA} \printMat{\myMatB}
        \left(\printVec{\myVecV} + \printVec{\myVecW}\right)
        =
        \printMat{\mulMatResult}
        \printVec{\addVecResult}
        =
        \printVec{\transformVecResult}
    \end{align}
    \end{lstlisting}
    \vspace{5mm}
    
    When compiling the above \LaTeX{} code, the following output is created.
    \begin{align*}
        \begin{pmatrix}0.5&2&3\\4&5&6\\7&8&9\end{pmatrix}
        \begin{pmatrix}2&0&0\\0&3&0\\0&0&4\end{pmatrix}
        \left(
            \begin{pmatrix}1\\2\\3\end{pmatrix} +
            \begin{pmatrix}7\\8\\9\end{pmatrix}
        \right)
        = \begin{pmatrix}1&6&12\\8&15&24\\14&24&36\end{pmatrix}
        \begin{pmatrix}8\\10\\12\end{pmatrix}
        = \begin{pmatrix}212\\502\\784\end{pmatrix}
    \end{align*}
    
    All three classes provide various macros to print the content of a variable for all kinds of use cases.
    For example, you can print a vector inside a line of text using the \textbackslash printVecT, which prints a transposed version of the vector's contents.
    
    \clearpage
    \DocInput{glmatrix.dtx}
    \clearpage
    \section{License}
    Released under BSD 3-Clause License

    BSD 3-Clause License
    
    Copyright (c) 2026, Rene Warnking
    
    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions are met:
    
    1. Redistributions of source code must retain the above copyright notice, this
       list of conditions and the following disclaimer.
    
    2. Redistributions in binary form must reproduce the above copyright notice,
       this list of conditions and the following disclaimer in the documentation
       and/or other materials provided with the distribution.
    
    3. Neither the name of the copyright holder nor the names of its
       contributors may be used to endorse or promote products derived from
       this software without specific prior written permission.
    
    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

\end{document}
%</driver>
% \fi

% \section{Macro Documentation}
% \subsection{matrix}
% \label{subsec:matrix}
% \begin{center}
% \begin{tabularx}{\textwidth}{l p{8cm}} \hline
% \textbf{Command} & \textbf{Arguments} \\ \hline
% \ref{macro:newMat} & \makecell[t{p{8cm}}]{\marg{out}, \marg{scalars}} \\
% \ref{macro:newMatFromRow} & \makecell[t{p{8cm}}]{\marg{out}, \marg{row}} \\
% \ref{macro:newMatFromRowVecs} & \makecell[t{p{8cm}}]{\marg{out}, \marg{rows}} \\
% \ref{macro:newMatFromColVecs} & \makecell[t{p{8cm}}]{\marg{out}, \marg{columns}} \\
% \ref{macro:newEmptyMat} & \makecell[t{p{8cm}}]{\marg{out}} \\
% \ref{macro:newDiagMat} & \makecell[t{p{8cm}}]{\marg{out}, \marg{scalars}} \\
% \ref{macro:appendRowToMat} & \makecell[t{p{8cm}}]{\marg{out}, \marg{matrix}, \marg{vector r}} \\
% \ref{macro:newTransMat} & \makecell[t{p{8cm}}]{\marg{out}, \marg{vector t}} \\
% \ref{macro:newScaleMat} & \makecell[t{p{8cm}}]{\marg{out}, \marg{vector s}} \\
% \ref{macro:newRotMatTwoD} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{scalar}\\Default Argument: rotMatResult} \\
% \ref{macro:newRotMat} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector}, \marg{scalar}\\Default Argument: rotMatResult} \\
% \ref{macro:newLookAtMat} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{right}, \marg{up}, \marg{dir}, \marg{pos}\\Default Argument: lookAtMatResult} \\
% \ref{macro:newProjMat} & \makecell[t{p{8cm}}]{\marg{out}} \\
% \ref{macro:newProjMatGen} & \makecell[t{p{8cm}}]{\marg{out}} \\
% \ref{macro:newFrustumMat} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{fovx}, \marg{fovy}, \marg{near}, \marg{far}\\Default Argument: frustMatResult} \\
% \ref{macro:printMat} & \makecell[t{p{8cm}}]{\oarg{fraction}, \marg{matrix}\\Default Argument: 0} \\
% \ref{macro:printMatDiag} & \makecell[t{p{8cm}}]{\oarg{fraction}, \marg{matrix}\\Default Argument: 0} \\
% \ref{macro:getMatHeight} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{matrix}\\Default Argument: matHeightResult} \\
% \ref{macro:getMatWidth} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{matrix}\\Default Argument: matWidthResult} \\
% \ref{macro:transposeMat} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{matrix}\\Default Argument: transposeMatResult} \\
% \ref{macro:addMat} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{matrix}, \marg{matrices}\\Default Argument: addMatResult} \\
% \ref{macro:subMat} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{matrix}, \marg{matrices}\\Default Argument: subMatResult} \\
% \ref{macro:mulMatScalar} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{matrix}, \marg{scalar}\\Default Argument: mulMatScalarResult} \\
% \ref{macro:mulMatVec} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{matrix}, \marg{vector}\\Default Argument: mulMatVecResult} \\
% \ref{macro:mulMat} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{matrix M}, \marg{matrix N}\\Default Argument: mulMatResult} \\
% \ref{macro:getMatTranslation} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{matrix}\\Default Argument: matTranslationResult} \\
% \ref{macro:detMat} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{matrix}\\Default Argument: detMatResult} \\
% \end{tabularx}
% \end{center}

% \setlabel{\textbackslash newMat}{macro:newMat}
% \DescribeMacro{newMat}
% \marg{out}\marg{scalars}\\[1mm]
% \marg{out}: var name to save the result (matrix) to\\
% \marg{scalars}: matrix values that are assigned to out
% \begin{descriptionbox}
% Create a new matrix from the given values.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \mathbf{M} \in \R^{m\times n} = \begin{bmatrix} s_{11} & \dots & s_{1n}\\ \vdots & \ddots & \vdots\\ s_{m1} & \dots & s_{mn}\end{bmatrix}\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newMat\{myNewMatrix\}\{\{\{0.5,2,3\}\{4,5,6\}\{7,8,9\}\}\}\\
%   \textbackslash myNewMatrix \(\mapsto{} \begin{pmatrix}0.5&2&3\\4&5&6\\7&8&9\end{pmatrix}\)\\
%   \textbackslash newMat\{myNewMatrix\}\{\{\{0.5,2,3\}\}\}\\
%   \textbackslash myNewMatrix \(\mapsto{} \begin{pmatrix}0.5&2&3\end{pmatrix}\)\\
%   \textbackslash newMat\{myNewMatrix\}\{\{\{0.5\}\{4\}\{7\}\}\}\\
%   \textbackslash myNewMatrix \(\mapsto{} \begin{pmatrix}0.5\\4\\7\end{pmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash newMatFromRow}{macro:newMatFromRow}
% \DescribeMacro{newMatFromRow}
% \marg{out}\marg{row}\\[1mm]
% \marg{out}: var name to save the result (matrix) to\\
% \marg{row}: matrix row that is assigned to out
% \begin{descriptionbox}
% Create a new matrix from the given row.
% \end{descriptionbox}

% \setlabel{\textbackslash newMatFromRowVecs}{macro:newMatFromRowVecs}
% \DescribeMacro{newMatFromRowVecs}
% \marg{out}\marg{rows}\\[1mm]
% \marg{out}: var name to save the result (matrix) to\\
% \marg{rows}: the rows that are used to construct the matrix
% \begin{descriptionbox}
% Create a new matrix from the given row vectors.
% \end{descriptionbox}
% \begin{examplebox}
%   \textbackslash newVec\{myRowVecA\}\{1, 0, 0\}\\
%   \textbackslash newVec\{myRowVecB\}\{0, 2, 0\}\\
%   \textbackslash newVec\{myRowVecC\}\{0, 0, 3\}\\
%   \textbackslash newMatFromRowVecs\{myNewMatrix\}\{\textbackslash myRowVecA, \textbackslash myRowVecB, \textbackslash myRowVecC\}\\
%   \textbackslash myNewMatrix \(\mapsto{} \begin{pmatrix}1&0&0\\0&2&0\\0&0&3\end{pmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash newMatFromColVecs}{macro:newMatFromColVecs}
% \DescribeMacro{newMatFromColVecs}
% \marg{out}\marg{columns}\\[1mm]
% \marg{out}: var name to save the result (matrix) to\\
% \marg{columns}: the columns that are used to construct the matrix
% \begin{descriptionbox}
% Create a new matrix from the given column vectors.
% \end{descriptionbox}

% \setlabel{\textbackslash newEmptyMat}{macro:newEmptyMat}
% \DescribeMacro{newEmptyMat}
% \marg{out}\\[1mm]
% \marg{out}: var name to save the result (matrix) to
% \begin{descriptionbox}
% Create a new empty matrix.
% Obacht: It is not necessary to call this to create a new matrix before using any of the arithmetic commands.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \mathbf{M} = \emptyset\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newEmptyMat\{myNewMatrix\}\\
%   \textbackslash myNewMatrix \(\mapsto{} \emptyset\)
% \end{examplebox}

% \setlabel{\textbackslash newDiagMat}{macro:newDiagMat}
% \DescribeMacro{newDiagMat}
% \marg{out}\marg{scalars}\\[1mm]
% \marg{out}: var name to save the result (matrix) to\\
% \marg{scalars}: the values that define the diagonal of the matrix
% \begin{descriptionbox}
% Create a new diagonal matrix from the given vector.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \mathbf{M} \in \R^{3\times 3} = \begin{bmatrix} s_1 & 0 & 0\\ 0 & s_2 & 0\\ 0 & 0 & s_3\end{bmatrix}\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newDiagMat\{myNewMatrix\}\{0.5,2,3\}\\
%   \textbackslash myNewMatrix \(\mapsto{} \begin{pmatrix}0.5&0&0\\0&2&0\\0&0&3\end{pmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash appendRowToMat}{macro:appendRowToMat}
% \DescribeMacro{appendRowToMat}
% \marg{out}\marg{matrix}\marg{vector r}\\[1mm]
% \marg{out}: var name to save the result (matrix) to\\
% \marg{matrix}: the matrix to append the vector to\\
% \marg{vector r}: the row vector that should be appended to the matrix
% \begin{descriptionbox}
% Append the given row to the given matrix.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \begin{bmatrix}\mathbf{M} \\\mathbf{r}\end{bmatrix} \in \R^{m+1\times n}\ \vert\ \mathbf{M} \in \R^{m\times n}, \mathbf{r} \in \R^{1\times n}\)
% \end{equationbox}

% \setlabel{\textbackslash newTransMat}{macro:newTransMat}
% \DescribeMacro{newTransMat}
% \marg{out}\marg{vector t}\\[1mm]
% \marg{out}: var name to save the result (matrix) to\\
% \marg{vector t}: the translation vector to construct the matrix from
% \begin{descriptionbox}
% Create translation matrix from the given vector.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \mathbf{T} \in \R^{4\times 4} = \begin{bmatrix}1 & 0 & 0 & \mathbf{t}_x \\0 & 1 & 0 & \mathbf{t}_y \\0 & 0 & 1 & \mathbf{t}_z \\0 & 0 & 0 & 1\end{bmatrix}\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newVec\{vecTest\}\{5, 2, 3\}\\
%   \textbackslash newTransMat\{myNewMatrix\}\{\textbackslash vecTest\}\\
%   \textbackslash myNewMatrix \(\mapsto{} \begin{pmatrix}1&0&0&5\\0&1&0&2\\0&0&1&3\\0&0&0&1\end{pmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash newScaleMat}{macro:newScaleMat}
% \DescribeMacro{newScaleMat}
% \marg{out}\marg{vector s}\\[1mm]
% \marg{out}: var name to save the result (matrix) to\\
% \marg{vector s}: the scaling vector to construct the matrix from
% \begin{descriptionbox}
% Create scaling matrix from the given vector.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \mathbf{S} \in \R^{4\times 4} = \begin{bmatrix}\mathbf{s}_x & 0 & 0 & 0 \\0 & \mathbf{s}_y & 0 & 0 \\0 & 0 & \mathbf{s}_z & 0 \\0 & 0 & 0 & 1\end{bmatrix}\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newVec\{vecTest\}\{5, 2, 3\}\\
%   \textbackslash newScaleMat\{myNewMatrix\}\{\textbackslash vecTest\}\\
%   \textbackslash myNewMatrix \(\mapsto{} \begin{pmatrix}5&0&0&0\\0&2&0&0\\0&0&3&0\\0&0&0&1\end{pmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash newRotMatTwoD}{macro:newRotMatTwoD}
% \DescribeMacro{newRotMatTwoD}
% \oarg{out}\marg{scalar}\\[1mm]
% \oarg{out}: var name to save the result (matrix) to, default: rotMatResult\\
% \marg{scalar}: the rotation value
% \begin{descriptionbox}
% Create rotation matrix from the given scalar (2D).
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \mathbf{R} \in \R^{3\times 3}\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newScalarPi\{scalarTest\}\{0.5\}\\
%   \textbackslash newRotMatTwoD[myNewMatrix]\{\textbackslash scalarTest\}\\
%   \textbackslash myNewMatrix \(\mapsto{} \begin{pmatrix}0&-1&0\\1&0&0\\0&0&1\end{pmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash newRotMat}{macro:newRotMat}
% \DescribeMacro{newRotMat}
% \oarg{out}\marg{vector}\marg{scalar}\\[1mm]
% \oarg{out}: var name to save the result (matrix) to, default: rotMatResult\\
% \marg{vector}: the axis to rotate around\\
% \marg{scalar}: the angle in degree to rotate with (counterclockwise)
% \begin{descriptionbox}
% Create a rotation matrix using the rodrigues’ matrix
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \mathbf{R} \in \R^{3\times 3}\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newVec\{rotationAxis\}\{1,1,1\}\\
%   \textbackslash newScalarPi\{scalarTest\}\{0.5\}\\
%   \textbackslash newRotMat[myNewMatrix]\{\textbackslash rotationAxis\}\{\textbackslash scalarTest\}\\
%   \textbackslash myNewMatrix \(\mapsto{} \begin{pmatrix}0&0&1\\1&0&0\\0&1&0\end{pmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash newLookAtMat}{macro:newLookAtMat}
% \DescribeMacro{newLookAtMat}
% \oarg{out}\marg{right}\marg{up}\marg{dir}\marg{pos}\\[1mm]
% \oarg{out}: var name to save the result (matrix) to, default: lookAtMatResult\\
% \marg{right}: the right vector\\
% \marg{up}: the up vector\\
% \marg{dir}: the direction vector\\
% \marg{pos}: the camera position vector
% \begin{descriptionbox}
% Create a new lookAt matrix.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \mathbf{L} \in \R^{4\times 4} = \begin{bmatrix}\mathbf{r}_x & \mathbf{r}_y & \mathbf{r}_z & -\mathbf{r} \cdot \mathbf{p} \\\mathbf{u}_x & \mathbf{u}_y & \mathbf{u}_z & -\mathbf{u} \cdot \mathbf{p} \\-\mathbf{d}_x & -\mathbf{d}_y & -\mathbf{d}_z & \mathbf{d} \cdot \mathbf{p} \\0 & 0 & 0 & 1\end{bmatrix}\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newVec\{right\}\{5, 2, 3\}\\
%   \textbackslash newVec\{up\}\{0.5, 1.75, 2\}\\
%   \textbackslash newVec\{dir\}\{0.5, 2, -3\}\\
%   \textbackslash newVec\{pos\}\{5, 2, 3\}\\
%   \textbackslash newLookAtMat[myNewMatrix]\{\textbackslash right\}\{\textbackslash up\}\{\textbackslash dir\}\{\textbackslash pos\}\\
%   \textbackslash myNewMatrix \(\mapsto{} \begin{pmatrix}5&2&3&-38\\0.5&1.75&2&-12\\-0.5&-2&3&-2.5\\0&0&0&1\end{pmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash newProjMat}{macro:newProjMat}
% \DescribeMacro{newProjMat}
% \marg{out}\\[1mm]
% \marg{out}: var name to save the result (matrix) to
% \begin{descriptionbox}
% Create a new default projection matrix.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \mathbf{P} \in \R^{4\times 4}\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newProjMat\{\textbackslash myNewMatrix\}\\
%   \textbackslash myNewMatrix \(\mapsto{} \begin{pmatrix}1&0&0&0\\0&1&0&0\\0&0&1&0\\0&0&-1&0\end{pmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash newProjMatGen}{macro:newProjMatGen}
% \DescribeMacro{newProjMatGen}
% \marg{out}\\[1mm]
% \marg{out}: var name to save the result (matrix) to
% \begin{descriptionbox}
% Create a new projection matrix from normal and distance from origin.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \mathbf{P} \in \R^{4\times 4}\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newScalar\{myDelta\}\{5\}\\
%   \textbackslash newVec\{myNormal\}\{1,1,0\}\\
%   \textbackslash newProjMatGen\{\textbackslash myNewMatrix\}\{\textbackslash myNormal\}\{\textbackslash myDelta\}\\
%   \textbackslash myNewMatrix \(\mapsto{} \begin{pmatrix}1&0&0&0\\0&1&0&0\\0&0&1&0\\0.2&0.2&0.2&0\end{pmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash newFrustumMat}{macro:newFrustumMat}
% \DescribeMacro{newFrustumMat}
% \oarg{out}\marg{fovx}\marg{fovy}\marg{near}\marg{far}\\[1mm]
% \oarg{out}: var name to save the result (matrix) to, default: frustMatResult\\
% \marg{fovx}: the fovx scalar\\
% \marg{fovy}: the fovy scalar\\
% \marg{near}: the position of the near plane (scalar)\\
% \marg{far}: the psition of the far lane (scalar)
% \begin{descriptionbox}
% Create a new frustum matrix.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \mathbf{F} \in \R^{4\times 4}\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newScalar\{fovx\}\{90\}\\
%   \textbackslash newScalar\{fovy\}\{90\}\\
%   \textbackslash newScalar\{near\}\{1\}\\
%   \textbackslash newScalar\{far\}\{6\}\\
%   \textbackslash newFrustumMat[myNewMatrix]\{\textbackslash fovx\}\{\textbackslash fovy\}\{\textbackslash near\}\{\textbackslash far\}\\
%   \textbackslash myNewMatrix \(\mapsto{} \begin{pmatrix}0.6174&0&0&0\\0&06174&0&0\\0&0&-1.4&-2.4\\0&0&-1&0\end{pmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash printMat}{macro:printMat}
% \DescribeMacro{printMat}
% \oarg{fraction}\marg{matrix}\\[1mm]
% \oarg{fraction}: whether or not the value should be printed as a fraction (val=1), default: 0\\
% \marg{matrix}: the matrix that should be printed
% \begin{descriptionbox}
% Print the values of this matrix variable.
% \end{descriptionbox}
% \begin{equationbox}
%   \(\begin{bmatrix} a_{11} & \dots & a_{1n}\\ \vdots & \ddots & \vdots\\ a_{m1} & \dots & a_{mn}\end{bmatrix}\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newMat\{myNewMatrix\}\{\{\{\(a_{11},\dots,a_{1n}\)\}\{\(a_{21},\dots,a_{2n}\)\}\{\(a_{m1},\dots,a_{mn}\)\}\}\}\\
%   \textbackslash printMat\{\textbackslash myNewMatrix\} \(\mapsto{} \begin{bmatrix} a_{11} & \dots & a_{1n}\\ \vdots & \ddots & \vdots\\ a_{m1} & \dots & a_{mn}\end{bmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash printMatDiag}{macro:printMatDiag}
% \DescribeMacro{printMatDiag}
% \oarg{fraction}\marg{matrix}\\[1mm]
% \oarg{fraction}: whether or not the value should be printed as a fraction (val=1), default: 0\\
% \marg{matrix}: the matrix that should be printed
% \begin{descriptionbox}
% Print only the diagonal values of this matrix variable.
% \end{descriptionbox}
% \begin{examplebox}
%   \textbackslash newMat\{myNewMatrix\}\{\{\{\(a_{11},\dots,a_{1n}\)\}\{\(a_{21},\dots,a_{2n}\)\}\{\(a_{m1},\dots,a_{mn}\)\}\}\}\\
%   \textbackslash printMatDiag\{\textbackslash myNewMatrix\} \(\mapsto{} \text{diag}(a_{11}, a_{22}, a_{mm})\)
% \end{examplebox}

% \setlabel{\textbackslash getMatHeight}{macro:getMatHeight}
% \DescribeMacro{getMatHeight}
% \oarg{out}\marg{matrix}\\[1mm]
% \oarg{out}: var name to save the result (scalar) to, default: matHeightResult\\
% \marg{matrix}: the matrix from which to get the height
% \begin{descriptionbox}
% Get the height of the given matrix.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = rows(\mathbf{M})\ \vert\ \mathbf{M} \in \R^{m\times n}\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newMat\{myNewMatrix\}\{\{\{\(a_{11},\dots,a_{1n}\)\}\{\(a_{21},\dots,a_{2n}\)\}\{\(a_{m1},\dots,a_{mn}\)\}\}\}\\
%   \textbackslash getMatHeight\{myNewMatrix\}\\
%   \textbackslash matHeightResult \(\mapsto{} m\)
% \end{examplebox}

% \setlabel{\textbackslash getMatWidth}{macro:getMatWidth}
% \DescribeMacro{getMatWidth}
% \oarg{out}\marg{matrix}\\[1mm]
% \oarg{out}: var name to save the result (scalar) to, default: matWidthResult\\
% \marg{matrix}: the matrix from which to get the width
% \begin{descriptionbox}
% Get the width of the given matrix.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = cols(\mathbf{M})\ \vert\ \mathbf{M} \in \R^{m\times n}\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newMat\{myNewMatrix\}\{\{\{\(a_{11},\dots,a_{1n}\)\}\{\(a_{21},\dots,a_{2n}\)\}\{\(a_{m1},\dots,a_{mn}\)\}\}\}\\
%   \textbackslash getMatWidth\{myNewMatrix\}\\
%   \textbackslash matWidthResult \(\mapsto{} n\)
% \end{examplebox}

% \setlabel{\textbackslash transposeMat}{macro:transposeMat}
% \DescribeMacro{transposeMat}
% \oarg{out}\marg{matrix}\\[1mm]
% \oarg{out}: var name to save the result (matrix) to, default: transposeMatResult\\
% \marg{matrix}: the matrix to transpose
% \begin{descriptionbox}
% Transpose a given Matrix. The parameter can also be a vector,
% but the result will be a matrix.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \trans{\mathbf{M}}\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newMat\{myNewMatrix\}\{\{\{0.5,2,3\}\{4,5,6\}\{7,8,9\}\}\}\\
%   \textbackslash transposeMat\{\textbackslash myNewMatrix\} \(\mapsto{} \begin{bmatrix}0.5&4&7\\2&5&8\\3&6&9\end{bmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash addMat}{macro:addMat}
% \DescribeMacro{addMat}
% \oarg{out}\marg{matrix}\marg{matrices}\\[1mm]
% \oarg{out}: var name to save the result (matrix) to, default: addMatResult\\
% \marg{matrix}: the matrix to add to\\
% \marg{matrices}: the matrizes to add
% \begin{descriptionbox}
% Add two or more matrices.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \mathbf{X} = \mathbf{M} + \mathbf{B}\ \vert\ \mathbf{M}, \mathbf{M}, \mathbf{B} \in \R^{m\times n}\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newMat\{myNewMatrixA\}\{\{\{0.5,2,3\}\{4,5,6\}\{7,8,9\}\}\}\\
%   \textbackslash newMat\{myNewMatrixB\}\{\{\{0.5,2,3\}\{4,5,6\}\{7,8,9\}\}\}\\
%   \textbackslash addMat\{\textbackslash myNewMatrixA\}\{\textbackslash myNewMatrixB\}\\
%   \textbackslash addMatResult \(\mapsto{} \begin{bmatrix}1&4&6\\8&10&12\\14&16&18\end{bmatrix}\)\\
%   \textbackslash addMat[resultName]\{\textbackslash myNewMatrixA\}\{\textbackslash myNewMatrixB\}\\
%   \textbackslash resultName \(\mapsto{} \begin{bmatrix}1&4&6\\8&10&12\\14&16&18\end{bmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash subMat}{macro:subMat}
% \DescribeMacro{subMat}
% \oarg{out}\marg{matrix}\marg{matrices}\\[1mm]
% \oarg{out}: var name to save the result (matrix) to, default: subMatResult\\
% \marg{matrix}: the matrix to subtract from\\
% \marg{matrices}: the matrizes to subtract
% \begin{descriptionbox}
% Subtract two or more matrices.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \mathbf{X} = \mathbf{M} - \mathbf{B}\ \vert\ \mathbf{X}, \mathbf{M}, \mathbf{B} \in \R^{m\times n}\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newMat\{myNewMatrixA\}\{\{\{0.5,2,3\}\{4,5,6\}\{7,8,9\}\}\}\\
%   \textbackslash newMat\{myNewMatrixB\}\{\{\{0.25,1,2\}\{3,2,1\}\{3,3,3\}\}\}\\
%   \textbackslash subMat[subMatResult]\{\textbackslash myNewMatrixA\}\{\textbackslash myNewMatrixB\}\\
%   \textbackslash subMatResult \(\mapsto{} \begin{bmatrix}0.25&1&1\\1&3&4\\4&5&6\end{bmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash mulMatScalar}{macro:mulMatScalar}
% \DescribeMacro{mulMatScalar}
% \oarg{out}\marg{matrix}\marg{scalar}\\[1mm]
% \oarg{out}: var name to save the result (matrix) to, default: mulMatScalarResult\\
% \marg{matrix}: the matrix to multiply\\
% \marg{scalar}: the scalar to multiply with
% \begin{descriptionbox}
% Multiply the given matrix with a scalar.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \mathbf{X} = \mathbf{M} * s\ \vert\ \mathbf{X}, \mathbf{M} \in \R^{m\times n}, s \in \R\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newMat\{myNewMatrix\}\{\{\{0.5,2,3\}\{4,5,6\}\{7,8,9\}\}\}\\
%   \textbackslash newScalar\{myNewScalar\}\{2\}\\
%   \textbackslash mulMatScalar\{\textbackslash myNewMatrix\}\{\textbackslash myNewScalar\}\\
%   \textbackslash mulMatScalarResult \(\mapsto{} \begin{bmatrix}1&4&6\\8&10&12\\14&16&18\end{bmatrix}\)\\
%   \textbackslash mulMatScalar[resultName]\{\textbackslash myNewMatrix\}\{\textbackslash myNewScalar\}\\
%   \textbackslash resultName \(\mapsto{} \begin{bmatrix}1&4&6\\8&10&12\\14&16&18\end{bmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash mulMatVec}{macro:mulMatVec}
% \DescribeMacro{mulMatVec}
% \oarg{out}\marg{matrix}\marg{vector}\\[1mm]
% \oarg{out}: var name to save the result (vector) to, default: mulMatVecResult\\
% \marg{matrix}: the matrix to transform the vetor with\\
% \marg{vector}: the vector to transform
% \begin{descriptionbox}
% Multiply the given matrix with a vector (for transformation).
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \mathbf{M} \cdot \mathbf{v}\ \vert\ \mathbf{M} \in \R^{m\times n}, \mathbf{v} \in \R^n\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newVec\{myNewVec\}\{0.5, 1, 2\}\\
%   \textbackslash newMat\{myNewMatrix\}\{\{\{0.5, 1, 2\}\{4, 5, 6\}\{7, 8, 9\}\}\}\\
%   \textbackslash mulMatVec\{\textbackslash myNewMatrix\}\{\textbackslash myNewVec\}\\
%   \textbackslash mulMatVecResult \(\mapsto{} \begin{pmatrix} 5.25\\ 19\\ 29.5\end{pmatrix}\)\\
%   \textbackslash mulMatVec[resultName]\{\textbackslash myNewMatrix\}\{\textbackslash myNewVec\}\\
%   \textbackslash resultName \(\mapsto{} \begin{pmatrix} 5.25\\ 19\\ 29.5\end{pmatrix}\)
% \end{examplebox}
% \begin{warningbox}
%   When matrix and vector have a dimension mismatch
% \end{warningbox}

% \setlabel{\textbackslash mulMat}{macro:mulMat}
% \DescribeMacro{mulMat}
% \oarg{out}\marg{matrix M}\marg{matrix N}\\[1mm]
% \oarg{out}: var name to save the result (matrix) to, default: mulMatResult\\
% \marg{matrix M}: the matrix to multiply\\
% \marg{matrix N}: the matrix to multiply with
% \begin{descriptionbox}
% Multiply the given matrix with another matrix.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \mathbf{X} = \mathbf{M} \mathbf{N}\ \vert\ \mathbf{M} \in \R^{m\times n}, \mathbf{N} \in \R^{n\times p}, \mathbf{X} \in \R^{m\times p}\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newMat\{myNewMatrixA\}\{\{\{0.5,2,3\}\{4,5,6\}\{7,8,9\}\}\}\\
%   \textbackslash newMat\{myNewMatrixB\}\{\{\{0.25,1,2\}\{3,2,1\}\{3,3,3\}\}\}\\
%   \textbackslash mulMat[mulMatResult]\{\textbackslash myNewMatrixA\}\{\textbackslash myNewMatrixB\}\\
%   \textbackslash mulMatResult \(\mapsto{} \begin{bmatrix}15.125&13.5&12\\34&32&31\\52.75&50&49\end{bmatrix}\)
% \end{examplebox}
% \begin{warningbox}
%   When the matrizes have a dimension mismatch
% \end{warningbox}

% \setlabel{\textbackslash getMatTranslation}{macro:getMatTranslation}
% \DescribeMacro{getMatTranslation}
% \oarg{out}\marg{matrix}\\[1mm]
% \oarg{out}: var name to save the result (vector) to, default: matTranslationResult\\
% \marg{matrix}: the matrix to extract the translation from
% \begin{descriptionbox}
% Get the translation component from the given matrix.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \mathbf{v} = trans(\mathbf{M})\ \vert\ \mathbf{M} \in \R^{m\times n}, \mathbf{v} \in \R^{m-1}\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newMat\{myNewMatrix\}\{\{\{0.5,2,3\}\{4,5,6\}\{7,8,9\}\}\}\\
%   \textbackslash getMatTranslation[matTranslationResult]\{\textbackslash myNewMatrix\}\\
%   \textbackslash matTranslationResult \(\mapsto{} \begin{pmatrix}3\\6\\\end{pmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash detMat}{macro:detMat}
% \DescribeMacro{detMat}
% \oarg{out}\marg{matrix}\\[1mm]
% \oarg{out}: var name to save the result (scalar) to, default: detMatResult\\
% \marg{matrix}: the matrix to calculate the determinate for
% \begin{descriptionbox}
% Get the determinate of the given matrix.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = det(\mathbf{M})\ \vert\ \mathbf{M} \in \R^{m\times n}\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newMat\{myNewMatrix\}\{\{\{0.5,2,3\}\{4,5,6\}\{7,8,9\}\}\}\\
%   \textbackslash detMat[detMatResult]\{\textbackslash myNewMatrix\}\\
%   \textbackslash detMatResult \(\mapsto{} 1.5\)
% \end{examplebox}
% \subsection{scalar}
% \label{subsec:scalar}
% \begin{center}
% \begin{tabularx}{\textwidth}{l p{8cm}} \hline
% \textbf{Command} & \textbf{Arguments} \\ \hline
% \ref{macro:newScalar} & \makecell[t{p{8cm}}]{\marg{out}, \marg{scalar}} \\
% \ref{macro:newScalarPi} & \makecell[t{p{8cm}}]{\marg{out}, \marg{scalar}} \\
% \ref{macro:newScalarFraction} & \makecell[t{p{8cm}}]{\marg{out}, \marg{scalar n}, \marg{scalar d}} \\
% \ref{macro:randomScalar} & \makecell[t{p{8cm}}]{\marg{out}, \marg{lower bound}, \marg{upper bound}} \\
% \ref{macro:copyScalar} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{scalar}\\Default Argument: scalarCopyResult} \\
% \ref{macro:setScalar} & \makecell[t{p{8cm}}]{\marg{out}, \marg{scalar}} \\
% \ref{macro:zeroScalar} & \makecell[t{p{8cm}}]{\marg{out}} \\
% \ref{macro:printScalar} & \makecell[t{p{8cm}}]{\oarg{fraction}, \marg{scalar}\\Default Argument: 0} \\
% \ref{macro:printScalarAsPi} & \makecell[t{p{8cm}}]{\oarg{fraction}, \marg{scalar}\\Default Argument: 0} \\
% \ref{macro:printPiScalarInDegree} & \makecell[t{p{8cm}}]{\oarg{fraction}, \marg{scalar}\\Default Argument: 0} \\
% \ref{macro:printScalarRounded} & \makecell[t{p{8cm}}]{\oarg{digits}, \marg{scalar}\\Default Argument: 4} \\
% \ref{macro:roundScalar} & \makecell[t{p{8cm}}]{\oarg{digits}, \marg{scalar}\\Default Argument: 4} \\
% \ref{macro:ceilScalar} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{scalar}\\Default Argument: scalarCeilResult} \\
% \ref{macro:floorScalar} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{scalar}\\Default Argument: scalarFloorResult} \\
% \ref{macro:clipScalar} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{scalar}\\Default Argument: clipScalarResult} \\
% \ref{macro:radianToDegree} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{scalar}\\Default Argument: radianToDegreeResult} \\
% \ref{macro:toRadian} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{scalar}\\Default Argument: degreeToRadianResult} \\
% \ref{macro:addScalar} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{scalar s}, \marg{scalar t}\\Default Argument: scalarAddResult} \\
% \ref{macro:subScalar} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{scalar s}, \marg{scalar t}\\Default Argument: scalarSubResult} \\
% \ref{macro:mulScalar} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{scalar s}, \marg{scalar t}\\Default Argument: scalarMulResult} \\
% \ref{macro:divScalar} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{scalar s}, \marg{scalar t}\\Default Argument: scalarDivResult} \\
% \ref{macro:powScalar} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{scalar s}, \marg{scalar t}\\Default Argument: scalarPowResult} \\
% \ref{macro:negateScalar} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{scalar}\\Default Argument: scalarNegateResult} \\
% \ref{macro:arccosScalar} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{scalar}\\Default Argument: scalarArccosResult} \\
% \ref{macro:mulAndAddScalar} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{scalar s}, \marg{scalar t}, \marg{scalar u}\\Default Argument: scalarMulAndAddResult} \\
% \ref{macro:lerpScalar} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{scalar i}, \marg{scalar j}, \marg{scalar t}\\Default Argument: lerpScalarResult} \\
% \ref{macro:minScalar} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{scalar s}, \marg{scalar t}\\Default Argument: minScalarResult} \\
% \ref{macro:maxScalar} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{scalar s}, \marg{scalar t}\\Default Argument: maxScalarResult} \\
% \ref{macro:betweenScalar} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{scalar}, \marg{lower bound}, \marg{upper bound}\\Default Argument: betweenScalarResult} \\
% \ref{macro:forEachScalar} & \makecell[t{p{8cm}}]{\marg{input}, \marg{macro}, \marg{args}} \\
% \end{tabularx}
% \end{center}

% \setlabel{\textbackslash newScalar}{macro:newScalar}
% \DescribeMacro{newScalar}
% \marg{out}\marg{scalar}\\[1mm]
% \marg{out}: var name to save the result (scalar) to\\
% \marg{scalar}: scalar value that is assigned to out
% \begin{descriptionbox}
% Create a new scalar and assign the given value.
% \end{descriptionbox}
% \begin{examplebox}
%   \textbackslash newScalar\{myNewScalar\}\{3\}\\
%   \textbackslash myNewScalar \(\mapsto{}\) 3
% \end{examplebox}

% \setlabel{\textbackslash newScalarPi}{macro:newScalarPi}
% \DescribeMacro{newScalarPi}
% \marg{out}\marg{scalar}\\[1mm]
% \marg{out}: var name to save the result (scalar) to\\
% \marg{scalar}: scalar value that is multiplied with pi and assigned to out
% \begin{descriptionbox}
% Create a new scalar and assign the given value as a multiple of pi.
% \end{descriptionbox}
% \begin{examplebox}
%   \textbackslash newScalarPi\{myNewScalar\}\{3\}\\
%   \textbackslash myNewScalar \(\mapsto{}\) 9.42
% \end{examplebox}

% \setlabel{\textbackslash newScalarFraction}{macro:newScalarFraction}
% \DescribeMacro{newScalarFraction}
% \marg{out}\marg{scalar n}\marg{scalar d}\\[1mm]
% \marg{out}: var name to save the result (scalar) to\\
% \marg{scalar n}: nominator\\
% \marg{scalar d}: denominator
% \begin{descriptionbox}
% Create a scalar from a given fraction
% \end{descriptionbox}
% \begin{examplebox}
%   \textbackslash newScalarFraction\{myScalarFraction\}\{3\}\{10\}\\
%   \textbackslash myScalarFraction \(\mapsto{}\frac{3}{10}\)
% \end{examplebox}

% \setlabel{\textbackslash randomScalar}{macro:randomScalar}
% \DescribeMacro{randomScalar}
% \marg{out}\marg{lower bound}\marg{upper bound}\\[1mm]
% \marg{out}: var name to save the result (scalar) to\\
% \marg{lower bound}: scalar that limits the possible values at the bottom\\
% \marg{upper bound}: scalar that limits the possible values at the top
% \begin{descriptionbox}
% Create a new scalar variable with a random value between lower and
% upper bound. The value is obtained by creating a random value between 0 and 1
% and then interpolating between lower and upper bound.
% \end{descriptionbox}
% \begin{examplebox}
%   \textbackslash randomScalar\{myRandomScalar\}\{3\}\{10\}\\
%   \textbackslash myRandomScalar \(\mapsto{}\) 5
% \end{examplebox}

% \setlabel{\textbackslash copyScalar}{macro:copyScalar}
% \DescribeMacro{copyScalar}
% \oarg{out}\marg{scalar}\\[1mm]
% \oarg{out}: var name to save the result (scalar) to, default: scalarCopyResult\\
% \marg{scalar}: scalar which value is assigned to out
% \begin{descriptionbox}
% Copy the value of one scalar variable to another.
% \end{descriptionbox}
% \begin{examplebox}
%   \textbackslash newScalar\{myNewScalar\}\{3\}\\
%   \textbackslash copyScalar\{myCopyScalar\}\{\textbackslash myNewScalar\}\\
%   \textbackslash myCopyScalar \(\mapsto{}\) 3
% \end{examplebox}

% \setlabel{\textbackslash setScalar}{macro:setScalar}
% \DescribeMacro{setScalar}
% \marg{out}\marg{scalar}\\[1mm]
% \marg{out}: var name to save the result (scalar) to\\
% \marg{scalar}: scalar value that is assigned to out
% \begin{descriptionbox}
% Set the value of a given scalar.
% \end{descriptionbox}
% \begin{examplebox}
%   \textbackslash newScalar\{myNewScalar\}\{3\}\\
%   \textbackslash setScalar\{myNewScalar\}\{4\}\\
%   \textbackslash myNewScalar \(\mapsto{}\) 4
% \end{examplebox}

% \setlabel{\textbackslash zeroScalar}{macro:zeroScalar}
% \DescribeMacro{zeroScalar}
% \marg{out}\\[1mm]
% \marg{out}: var name to save the result (scalar) to
% \begin{descriptionbox}
% Set or create a scalar with value 0.
% \end{descriptionbox}
% \begin{examplebox}
%   \textbackslash zeroScalar\{myZeroScalar\}\\
%   \textbackslash myZeroScalar \(\mapsto{}\) 0
% \end{examplebox}

% \setlabel{\textbackslash printScalar}{macro:printScalar}
% \DescribeMacro{printScalar}
% \oarg{fraction}\marg{scalar}\\[1mm]
% \oarg{fraction}: whether or not the value should be printed as a fraction (val=1), default: 0\\
% \marg{scalar}: the scalar that should be printed
% \begin{descriptionbox}
% Print the value of the given scalar.
% \end{descriptionbox}
% \begin{examplebox}
%   \textbackslash newScalar\{myNewScalar\}\{0.5\}\\
%   \textbackslash printScalar[1]\{\textbackslash myNewScalar\} \(\mapsto{} \frac{1}{2}\)
% \end{examplebox}

% \setlabel{\textbackslash printScalarAsPi}{macro:printScalarAsPi}
% \DescribeMacro{printScalarAsPi}
% \oarg{fraction}\marg{scalar}\\[1mm]
% \oarg{fraction}: whether or not the value should be printed as a fraction (val=1), default: 0\\
% \marg{scalar}: the scalar that should be printed
% \begin{descriptionbox}
% Print the value of the given scalar as a multiple of Pi.
% \end{descriptionbox}
% \begin{equationbox}
%   \(\left\{\frac{s}{\pi}\right\}\pi\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newScalarPi\{myNewScalar\}\{0.5\}\\
%   \textbackslash printScalarAsPi[1]\{\textbackslash myNewScalar\} \(\mapsto{} \frac{1}{2} \pi\)
% \end{examplebox}

% \setlabel{\textbackslash printPiScalarInDegree}{macro:printPiScalarInDegree}
% \DescribeMacro{printPiScalarInDegree}
% \oarg{fraction}\marg{scalar}\\[1mm]
% \oarg{fraction}: whether or not the value should be printed as a fraction (val=1), default: 0\\
% \marg{scalar}: the value that schould be printed
% \begin{descriptionbox}
% Print the value of the given scalar in degree.
% This macro does do a conversion and therefore expects the input to be in radian.
% A degree sign is automatically added.
% \end{descriptionbox}
% \begin{equationbox}
%   \(\left\{\frac{s*180}{\pi}\right\}^\circ\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newScalarPi\{myNewScalar\}\{0.5\}\\
%   \textbackslash printPiScalarInDegree[1]\{\textbackslash myNewScalar\} \(\mapsto{} 90^\circ\)
% \end{examplebox}

% \setlabel{\textbackslash printScalarRounded}{macro:printScalarRounded}
% \DescribeMacro{printScalarRounded}
% \oarg{digits}\marg{scalar}\\[1mm]
% \oarg{digits}: number of digits after comma, default: 4\\
% \marg{scalar}: the value that schould be printed
% \begin{descriptionbox}
% Print the rounded value of the given scalar.
% \end{descriptionbox}
% \begin{examplebox}
%   \textbackslash newScalar\{myNewScalar\}\{0.5\}\\
%   \textbackslash printScalarRounded\{\textbackslash myNewScalar\} \(\mapsto{} 1\)
% \end{examplebox}

% \setlabel{\textbackslash roundScalar}{macro:roundScalar}
% \DescribeMacro{roundScalar}
% \oarg{digits}\marg{scalar}\\[1mm]
% \oarg{digits}: number of digits after comma, default: 4\\
% \marg{scalar}: the value that schould be rounded
% \begin{descriptionbox}
% Round the value ot the given scalar and save it.
% \end{descriptionbox}
% \begin{examplebox}
%   \textbackslash newScalar\{myNewScalar\}\{0.5\}\\
%   \textbackslash roundScalar\{\textbackslash myNewScalar\}\\
%   \textbackslash myNewScalar \(\mapsto{} 1\)
% \end{examplebox}

% \setlabel{\textbackslash ceilScalar}{macro:ceilScalar}
% \DescribeMacro{ceilScalar}
% \oarg{out}\marg{scalar}\\[1mm]
% \oarg{out}: var name to save the result (scalar) to, default: scalarCeilResult\\
% \marg{scalar}: the scalar that schould be ceiled
% \begin{descriptionbox}
% Ceil the value of the given scalar.
% \end{descriptionbox}
% \begin{examplebox}
%   \textbackslash newScalar\{myNewScalar\}\{0.5\}\\
%   \textbackslash ceilScalar\{\textbackslash myNewScalar\}\\
%   \textbackslash myNewScalar \(\mapsto{} 1\)
% \end{examplebox}

% \setlabel{\textbackslash floorScalar}{macro:floorScalar}
% \DescribeMacro{floorScalar}
% \oarg{out}\marg{scalar}\\[1mm]
% \oarg{out}: var name to save the result (scalar) to, default: scalarFloorResult\\
% \marg{scalar}: the scalar that schould be floored
% \begin{descriptionbox}
% Floor the value of the given scalar.
% \end{descriptionbox}
% \begin{examplebox}
%   \textbackslash newScalar\{myNewScalar\}\{0.5\}\\
%   \textbackslash floorScalar\{\textbackslash myNewScalar\}\\
%   \textbackslash myNewScalar \(\mapsto{} 0\)
% \end{examplebox}

% \setlabel{\textbackslash clipScalar}{macro:clipScalar}
% \DescribeMacro{clipScalar}
% \oarg{out}\marg{scalar}\\[1mm]
% \oarg{out}: var name to save the result (scalar) to, default: clipScalarResult\\
% \marg{scalar}: the scalar from which the zeros should be removed
% \begin{descriptionbox}
% Remove all trailing zeros from the value of the given scalar.
% \end{descriptionbox}
% \begin{examplebox}
%   \textbackslash newScalar\{myNewScalar\}\{5.0000\}\\
%   \textbackslash clipScalar\{\textbackslash myNewScalar\}\\
%   \textbackslash myNewScalar \(\mapsto{} 5\)
% \end{examplebox}

% \setlabel{\textbackslash radianToDegree}{macro:radianToDegree}
% \DescribeMacro{radianToDegree}
% \oarg{out}\marg{scalar}\\[1mm]
% \oarg{out}: var name to save the result (scalar) to, default: radianToDegreeResult\\
% \marg{scalar}: the scalar which to convert
% \begin{descriptionbox}
% Convert the value of the given scalar to degree.
% \end{descriptionbox}
% \begin{examplebox}
%   \textbackslash newScalarPi\{myNewScalar\}\{0.5\}\\
%   \textbackslash radianToDegree\{\textbackslash myNewScalar\}\\
%   \textbackslash radianToDegreeResult \(\mapsto{} 90\)
% \end{examplebox}

% \setlabel{\textbackslash toRadian}{macro:toRadian}
% \DescribeMacro{toRadian}
% \oarg{out}\marg{scalar}\\[1mm]
% \oarg{out}: var name to save the result (scalar) to, default: degreeToRadianResult\\
% \marg{scalar}: the scalar which to convert
% \begin{descriptionbox}
% Convert the value of the given scalar to radian.
% \end{descriptionbox}
% \begin{examplebox}
%   \textbackslash newScalarPi\{myNewScalar\}\{180\}\\
%   \textbackslash toRadian\{\textbackslash myNewScalar\}\\
%   \textbackslash degreeToRadianResult \(\mapsto{} 1.5707\)
% \end{examplebox}

% \setlabel{\textbackslash addScalar}{macro:addScalar}
% \DescribeMacro{addScalar}
% \oarg{out}\marg{scalar s}\marg{scalar t}\\[1mm]
% \oarg{out}: var name to save the result (scalar) to, default: scalarAddResult\\
% \marg{scalar s}: the first scalar of the sum\\
% \marg{scalar t}: the second scalar of the sum
% \begin{descriptionbox}
% Add the values of two scalars.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = s + t\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newScalar\{myNewScalarA\}\{1\}\\
%   \textbackslash newScalar\{myNewScalarB\}\{2\}\\
%   \textbackslash addScalar\{\textbackslash myNewScalarA\}\{\textbackslash myNewScalarB\}\\
%   \textbackslash scalarAddResult \(\mapsto{} 3\)
% \end{examplebox}

% \setlabel{\textbackslash subScalar}{macro:subScalar}
% \DescribeMacro{subScalar}
% \oarg{out}\marg{scalar s}\marg{scalar t}\\[1mm]
% \oarg{out}: var name to save the result (scalar) to, default: scalarSubResult\\
% \marg{scalar s}: the scalar to subtract from\\
% \marg{scalar t}: the scalar to subtract
% \begin{descriptionbox}
% Subtract the values of two scalars.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = s - t\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newScalar\{myNewScalarA\}\{1\}\\
%   \textbackslash newScalar\{myNewScalarB\}\{2\}\\
%   \textbackslash subScalar\{\textbackslash myNewScalarA\}\{\textbackslash myNewScalarB\}\\
%   \textbackslash scalarSubResult \(\mapsto{} -1\)
% \end{examplebox}

% \setlabel{\textbackslash mulScalar}{macro:mulScalar}
% \DescribeMacro{mulScalar}
% \oarg{out}\marg{scalar s}\marg{scalar t}\\[1mm]
% \oarg{out}: var name to save the result (scalar) to, default: scalarMulResult\\
% \marg{scalar s}: the scalar to multiply\\
% \marg{scalar t}: the scalar with which to multply
% \begin{descriptionbox}
% Multiply the values of two scalars.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = s * t\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newScalar\{myNewScalarA\}\{2\}\\
%   \textbackslash newScalar\{myNewScalarB\}\{3\}\\
%   \textbackslash mulScalar\{\textbackslash myNewScalarA\}\{\textbackslash myNewScalarB\}\\
%   \textbackslash scalarMulResult \(\mapsto{} 6\)
% \end{examplebox}

% \setlabel{\textbackslash divScalar}{macro:divScalar}
% \DescribeMacro{divScalar}
% \oarg{out}\marg{scalar s}\marg{scalar t}\\[1mm]
% \oarg{out}: var name to save the result (scalar) to, default: scalarDivResult\\
% \marg{scalar s}: the scalar to divide\\
% \marg{scalar t}: the scalar to divide with
% \begin{descriptionbox}
% Divide the values of two scalars.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \frac{s}{t}\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newScalar\{myNewScalarA\}\{6\}\\
%   \textbackslash newScalar\{myNewScalarB\}\{3\}\\
%   \textbackslash divScalar\{\textbackslash myNewScalarA\}\{\textbackslash myNewScalarB\}\\
%   \textbackslash scalarDivResult \(\mapsto{} 2\)
% \end{examplebox}
% \begin{warningbox}
%   On division by zero
% \end{warningbox}

% \setlabel{\textbackslash powScalar}{macro:powScalar}
% \DescribeMacro{powScalar}
% \oarg{out}\marg{scalar s}\marg{scalar t}\\[1mm]
% \oarg{out}: var name to save the result (scalar) to, default: scalarPowResult\\
% \marg{scalar s}: the scalar to raise\\
% \marg{scalar t}: the scalar with which to raise
% \begin{descriptionbox}
% Raise the values of one scalar by another.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = s ^ t\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newScalar\{myNewScalarA\}\{2\}\\
%   \textbackslash newScalar\{myNewScalarB\}\{3\}\\
%   \textbackslash powScalar\{\textbackslash myNewScalarA\}\{\textbackslash myNewScalarB\}\\
%   \textbackslash scalarPowResult \(\mapsto{} 8\)
% \end{examplebox}

% \setlabel{\textbackslash negateScalar}{macro:negateScalar}
% \DescribeMacro{negateScalar}
% \oarg{out}\marg{scalar}\\[1mm]
% \oarg{out}: var name to save the result (scalar) to, default: scalarNegateResult\\
% \marg{scalar}: the scalar to negate
% \begin{descriptionbox}
% Negate the value of the given scalar.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = -s\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newScalar\{myNewScalar\}\{2\}\\
%   \textbackslash negateScalar\{\textbackslash myNewScalar\}\\
%   \textbackslash scalarNegateResult \(\mapsto{} -2\)
% \end{examplebox}

% \setlabel{\textbackslash arccosScalar}{macro:arccosScalar}
% \DescribeMacro{arccosScalar}
% \oarg{out}\marg{scalar}\\[1mm]
% \oarg{out}: var name to save the result (scalar) to, default: scalarArccosResult\\
% \marg{scalar}: the scalar to calculate the arccos for
% \begin{descriptionbox}
% Get the arccos of the value of the given scalar.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = arccos(s)\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newScalar\{myNewScalar\}\{TODO\}\\
%   \textbackslash arccosScalar\{\textbackslash myNewScalar\}\\
%   \textbackslash scalarArccosResult \(\mapsto{} TODO\)
% \end{examplebox}

% \setlabel{\textbackslash mulAndAddScalar}{macro:mulAndAddScalar}
% \DescribeMacro{mulAndAddScalar}
% \oarg{out}\marg{scalar s}\marg{scalar t}\marg{scalar u}\\[1mm]
% \oarg{out}: var name to save the result (scalar) to, default: scalarMulAndAddResult\\
% \marg{scalar s}: the scalar to add to\\
% \marg{scalar t}: the scalar that is multiplied and then added\\
% \marg{scalar u}: the scalar that is the muliplier
% \begin{descriptionbox}
% Adds two scalars after multiplying the second one by a scalar.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = s + t * u\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newScalar\{myNewScalarA\}\{2\}\\
%   \textbackslash newScalar\{myNewScalarB\}\{3\}\\
%   \textbackslash mulAndAddScalar\{\textbackslash myNewScalarA\}\{\textbackslash myNewScalarB\}\{\textbackslash myNewScalarB\}\\
%   \textbackslash scalarMulAndAddResult \(\mapsto{} 11\)
% \end{examplebox}

% \setlabel{\textbackslash lerpScalar}{macro:lerpScalar}
% \DescribeMacro{lerpScalar}
% \oarg{out}\marg{scalar i}\marg{scalar j}\marg{scalar t}\\[1mm]
% \oarg{out}: var name to save the result (scalar) to, default: lerpScalarResult\\
% \marg{scalar i}: the start scalar\\
% \marg{scalar j}: the end scalar\\
% \marg{scalar t}: interpolation amount range [0-1]
% \begin{descriptionbox}
% Lineraly interpolate between values of two scalars.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = (1-t) * i + t * j\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newScalar\{myNewScalarA\}\{2\}\\
%   \textbackslash newScalar\{myNewScalarB\}\{3\}\\
%   \textbackslash newScalar\{myNewScalarT\}\{0.5\}\\
%   \textbackslash lerpScalar\{\textbackslash myNewScalarA\}\{\textbackslash myNewScalarB\}\{\textbackslash myNewScalarT\}\\
%   \textbackslash lerpScalarResult \(\mapsto{} 2.5\)
% \end{examplebox}

% \setlabel{\textbackslash minScalar}{macro:minScalar}
% \DescribeMacro{minScalar}
% \oarg{out}\marg{scalar s}\marg{scalar t}\\[1mm]
% \oarg{out}: var name to save the result (scalar) to, default: minScalarResult\\
% \marg{scalar s}: the first scalar\\
% \marg{scalar t}: the second scalar
% \begin{descriptionbox}
% Return the minimum of two scalar values.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = s \text{ falls } s < t \text{ sonst } t\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newScalar\{myNewScalarA\}\{2\}\\
%   \textbackslash newScalar\{myNewScalarB\}\{3\}\\
%   \textbackslash minScalar\{\textbackslash myNewScalarA\}\{\textbackslash myNewScalarB\}\\
%   \textbackslash minScalarResult \(\mapsto{} 2\)
% \end{examplebox}

% \setlabel{\textbackslash maxScalar}{macro:maxScalar}
% \DescribeMacro{maxScalar}
% \oarg{out}\marg{scalar s}\marg{scalar t}\\[1mm]
% \oarg{out}: var name to save the result (scalar) to, default: maxScalarResult\\
% \marg{scalar s}: first scalar value\\
% \marg{scalar t}: second scalar value
% \begin{descriptionbox}
% Return the maximum of two scalar values.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = s \text{ falls } s > t \text{ sonst } t\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newScalar\{myNewScalarA\}\{2\}\\
%   \textbackslash newScalar\{myNewScalarB\}\{3\}\\
%   \textbackslash maxScalar\{\textbackslash myNewScalarA\}\{\textbackslash myNewScalarB\}\\
%   \textbackslash maxScalarResult \(\mapsto{} 3\)\\
%   \textbackslash maxScalar[resultName]\{\textbackslash myNewScalarA\}\{\textbackslash myNewScalarB\}\\
%   \textbackslash resultName \(\mapsto{} 3\)
% \end{examplebox}

% \setlabel{\textbackslash betweenScalar}{macro:betweenScalar}
% \DescribeMacro{betweenScalar}
% \oarg{out}\marg{scalar}\marg{lower bound}\marg{upper bound}\\[1mm]
% \oarg{out}: var name to save the result (scalar) to (0 or 1), default: betweenScalarResult\\
% \marg{scalar}: the scalar to test\\
% \marg{lower bound}: scalar needs to be greater then this for this macro to return 1\\
% \marg{upper bound}: scalar needs to be smaller than this for this macro to return 1
% \begin{descriptionbox}
% Return whether a scalar lies between two other values.
% \end{descriptionbox}
% \begin{examplebox}
%   \textbackslash newScalar\{myNewScalarA\}\{2\}\\
%   \textbackslash newScalar\{myNewScalarB\}\{3\}\\
%   \textbackslash newScalar\{myNewScalarC\}\{4\}\\
%   \textbackslash betweenScalar\{\textbackslash myNewScalarA\}\{\textbackslash myNewScalarB\}\{\textbackslash myNewScalarC\}\\
%   \textbackslash betweenScalarResult \(\mapsto{} 1\)
% \end{examplebox}

% \setlabel{\textbackslash forEachScalar}{macro:forEachScalar}
% \DescribeMacro{forEachScalar}
% \marg{input}\marg{macro}\marg{args}\\[1mm]
% \marg{input}: list of commands (var names) that should be altered\\
% \marg{macro}: the chosen function\\
% \marg{args}: params for function
% \begin{descriptionbox}
% Apply the given function to a list of variables.
% \end{descriptionbox}
% \subsection{vector}
% \label{subsec:vector}
% \begin{center}
% \begin{tabularx}{\textwidth}{l p{8cm}} \hline
% \textbf{Command} & \textbf{Arguments} \\ \hline
% \ref{macro:newVec} & \makecell[t{p{8cm}}]{\marg{out}, \marg{values}} \\
% \ref{macro:newVecPi} & \makecell[t{p{8cm}}]{\marg{out}, \marg{values}} \\
% \ref{macro:randomVec} & \makecell[t{p{8cm}}]{\marg{out}, \marg{dimensions}, \marg{lower bound}, \marg{upper bound}} \\
% \ref{macro:copyVec} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector}\\Default Argument: copyVecResult} \\
% \ref{macro:zeroVec} & \makecell[t{p{8cm}}]{\oarg{dims}, \marg{out}\\Default Argument: 3} \\
% \ref{macro:appendToVec} & \makecell[t{p{8cm}}]{\marg{out}, \marg{vector}, \marg{scalar}} \\
% \ref{macro:printVec} & \makecell[t{p{8cm}}]{\oarg{fraction}, \marg{vector}\\Default Argument: 0} \\
% \ref{macro:printVecT} & \makecell[t{p{8cm}}]{\oarg{fraction}, \marg{vector}\\Default Argument: 0} \\
% \ref{macro:printVecAsPoint} & \makecell[t{p{8cm}}]{\oarg{fraction}, \marg{vector}\\Default Argument: 0} \\
% \ref{macro:printVecAsPi} & \makecell[t{p{8cm}}]{\oarg{fraction}, \marg{vector}\\Default Argument: 0} \\
% \ref{macro:printVecAsPiT} & \makecell[t{p{8cm}}]{\oarg{fraction}, \marg{vector}\\Default Argument: 0} \\
% \ref{macro:printVecContent} & \makecell[t{p{8cm}}]{\marg{vector}} \\
% \ref{macro:printVecContentXY} & \makecell[t{p{8cm}}]{\marg{vector}} \\
% \ref{macro:printVecContentXYZ} & \makecell[t{p{8cm}}]{\marg{vector}} \\
% \ref{macro:printVecContentXYZW} & \makecell[t{p{8cm}}]{\marg{vector}} \\
% \ref{macro:getVecHeight} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector}\\Default Argument: vecHeightResult} \\
% \ref{macro:printScalarPComp} & \makecell[t{p{8cm}}]{\oarg{fraction}, \marg{vector v}, \marg{vector w}\\Default Argument: 0} \\
% \ref{macro:printCrossPComp} & \makecell[t{p{8cm}}]{\oarg{fraction}, \marg{vector v}, \marg{vector w}\\Default Argument: 0} \\
% \ref{macro:roundVec} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector}, \marg{digits}\\Default Argument: roundVecResult} \\
% \ref{macro:ceilVec} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector}\\Default Argument: ceilVecResult} \\
% \ref{macro:floorVec} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector}\\Default Argument: floorVecResult} \\
% \ref{macro:dehomogenVec} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector}\\Default Argument: dehomogenVecResult} \\
% \ref{macro:addVec} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector}, \marg{vectors}\\Default Argument: addVecResult} \\
% \ref{macro:subVec} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector}, \marg{vectors}\\Default Argument: subVecResult} \\
% \ref{macro:mulVec} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector}, \marg{vectors}\\Default Argument: mulVecResult} \\
% \ref{macro:divVec} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector}, \marg{vectors}\\Default Argument: divVecResult} \\
% \ref{macro:scaleVec} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector}, \marg{scalar}\\Default Argument: scaleVecResult} \\
% \ref{macro:divVecScalar} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector}, \marg{scalar}\\Default Argument: divVecScalarResult} \\
% \ref{macro:negateVec} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector}\\Default Argument: negateVecResult} \\
% \ref{macro:scaleAndAddVec} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector v}, \marg{vector w}, \marg{scalar}\\Default Argument: scaleAndAddVecResult} \\
% \ref{macro:lerpVec} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector v}, \marg{vector w}, \marg{scalar t}\\Default Argument: lerpVecResult} \\
% \ref{macro:slerpVec} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector v}, \marg{vector w}, \marg{scalar t}\\Default Argument: slerpVecResult} \\
% \ref{macro:dotVec} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector v}, \marg{vector w}\\Default Argument: dotVecResult} \\
% \ref{macro:lenVec} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector}\\Default Argument: lenVecResult} \\
% \ref{macro:sqrLenVec} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector}\\Default Argument: sqrLenVecResult} \\
% \ref{macro:normalizeVec} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector}\\Default Argument: normalizeVecResult} \\
% \ref{macro:crossVec} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector v}, \marg{vector w}\\Default Argument: crossVecResult} \\
% \ref{macro:crossVecTwoD} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector v}, \marg{vector w}\\Default Argument: crossVecResult} \\
% \ref{macro:angleVec} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector v}, \marg{vector w}\\Default Argument: angleVecResult} \\
% \ref{macro:distVec} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector v}, \marg{vector w}\\Default Argument: distVecResult} \\
% \ref{macro:sqrDistVec} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector v}, \marg{vector w}\\Default Argument: sqrDistVecResult} \\
% \ref{macro:transformVec} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{matrix}, \marg{vector}\\Default Argument: transformVecResult} \\
% \ref{macro:tensorVec} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector}\\Default Argument: tensorVecResult} \\
% \ref{macro:minVec} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector v}, \marg{vector w}\\Default Argument: minVecResult} \\
% \ref{macro:maxVec} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector v}, \marg{vector w}\\Default Argument: maxVecResult} \\
% \ref{macro:solveVecEQL} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector v}, \marg{vector w}\\Default Argument: solveVecEQLResult} \\
% \end{tabularx}
% \end{center}

% \setlabel{\textbackslash newVec}{macro:newVec}
% \DescribeMacro{newVec}
% \marg{out}\marg{values}\\[1mm]
% \marg{out}: var name to save the result (vector) to\\
% \marg{values}: values that are assigned to out
% \begin{descriptionbox}
% Create a new vector and assign the given values.
% \end{descriptionbox}
% \begin{examplebox}
%   \textbackslash newVec\{myNewVec\}\{2, 3, 4\}\\
%   \textbackslash myNewVec \(\mapsto{} \begin{pmatrix}2\\3\\4\end{pmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash newVecPi}{macro:newVecPi}
% \DescribeMacro{newVecPi}
% \marg{out}\marg{values}\\[1mm]
% \marg{out}: var name to save the result (vector) to\\
% \marg{values}: values that are multiplied with pi and assigned to out
% \begin{descriptionbox}
% Create a new vector and assign the given values as a multiple of pi.
% \end{descriptionbox}
% \begin{examplebox}
%   \textbackslash newVec\{myNewVec\}\{0.5, 1, 2\}\\
%   \textbackslash myNewVec \(\mapsto{} \begin{pmatrix}\frac{1}{2}\pi\\\pi\\2\pi\end{pmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash randomVec}{macro:randomVec}
% \DescribeMacro{randomVec}
% \marg{out}\marg{dimensions}\marg{lower bound}\marg{upper bound}\\[1mm]
% \marg{out}: var name to save the result (vector) to\\
% \marg{dimensions}: scalar that defines the number of dimensions out should have\\
% \marg{lower bound}: scalar that limits the possible values at the bottom\\
% \marg{upper bound}: scalar that limits the possible values at the top
% \begin{descriptionbox}
% Create a new vector and assign random values between lower and
% upper bound to its components.
% The value is obtained by creating a random value between 0 and 1
% and then interpolating between lower and upper bound.
% \end{descriptionbox}
% \begin{examplebox}
%   \textbackslash randomVec\{myNewVec\}\{4\}\{3\}\{10\}\\
%   \textbackslash myNewVec \(\mapsto{} \begin{pmatrix}5, 4, 8, 4\end{pmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash copyVec}{macro:copyVec}
% \DescribeMacro{copyVec}
% \oarg{out}\marg{vector}\\[1mm]
% \oarg{out}: var name to save the result (vector) to, default: copyVecResult\\
% \marg{vector}: vector which values are assigned to out
% \begin{descriptionbox}
% Copy values from one vector variable to another.
% \end{descriptionbox}
% \begin{examplebox}
%   \textbackslash newVec\{myNewVec\}\{0.5, 1, 2\}\\
%   \textbackslash copyVec[copyVecResult]\{\textbackslash myNewVec\}\\
%   \textbackslash copyVecResult \(\mapsto{} \begin{pmatrix}0.5\\ 1\\ 2\end{pmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash zeroVec}{macro:zeroVec}
% \DescribeMacro{zeroVec}
% \oarg{dims}\marg{out}\\[1mm]
% \oarg{dims}: number of dimensions (rows), default: 3\\
% \marg{out}: var name to save the result (vector) to
% \begin{descriptionbox}
% Create or override a vector with all its components being 0.
% Obacht: It is not necessary to call this to create a new vector.
% This is just for convenience when requiring a vector with initialized with zero.
% \end{descriptionbox}
% \begin{examplebox}
%   \textbackslash zeroVec[3]\{zeroVecResult\}\\
%   \textbackslash zeroVecResult \(\mapsto{} \begin{pmatrix}0\\ 0\\ 0\end{pmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash appendToVec}{macro:appendToVec}
% \DescribeMacro{appendToVec}
% \marg{out}\marg{vector}\marg{scalar}\\[1mm]
% \marg{out}: var name to save the result (vector) to\\
% \marg{vector}: the currently present values\\
% \marg{scalar}: the scalar to add to vector
% \begin{descriptionbox}
% Append a dimension with the given value to an already defined vector.
% \end{descriptionbox}
% \begin{examplebox}
%   \textbackslash newVec\{myNewVec\}\{0.5, 1\}\\
%   \textbackslash appendToVec\{myNewVec\}\{\textbackslash myNewVec\}\{-10\}\\
%   \textbackslash myNewVec \(\mapsto{} \begin{pmatrix}0.5\\ 1\\ -10\end{pmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash printVec}{macro:printVec}
% \DescribeMacro{printVec}
% \oarg{fraction}\marg{vector}\\[1mm]
% \oarg{fraction}: whether or not the value should be printed as a fraction (val=1), default: 0\\
% \marg{vector}: the vector that should be printed
% \begin{descriptionbox}
% Print the values of the given vector in vector notation.
% \end{descriptionbox}
% \begin{equationbox}
%   \(\begin{pmatrix} \mathbf{v}_1\\ \ldots\\ \mathbf{v}_n \end{pmatrix}\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newVec\{myNewVec\}\{1, 2, 3\}\\
%   \textbackslash printVec\{\textbackslash myNewVec\} \(\mapsto{} \begin{pmatrix}1\\2\\3\end{pmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash printVecT}{macro:printVecT}
% \DescribeMacro{printVecT}
% \oarg{fraction}\marg{vector}\\[1mm]
% \oarg{fraction}: whether or not the value should be printed as a fraction (val=1), default: 0\\
% \marg{vector}: the vector that should be printed
% \begin{descriptionbox}
% Print the values of the given vector in transposed notation.
% \end{descriptionbox}
% \begin{equationbox}
%   \(\trans{(\mathbf{v}_1, \ldots, \mathbf{v}_n)}\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newVec\{myNewVec\}\{1, 2, 3\}\\
%   \textbackslash printVecT\{\textbackslash myNewVec\} \(\mapsto{} \trans{(1, 2, 3)}\)
% \end{examplebox}

% \setlabel{\textbackslash printVecAsPoint}{macro:printVecAsPoint}
% \DescribeMacro{printVecAsPoint}
% \oarg{fraction}\marg{vector}\\[1mm]
% \oarg{fraction}: whether or not the value should be printed as a fraction (val=1), default: 0\\
% \marg{vector}: the vector that should be printed
% \begin{descriptionbox}
% Print the values of the given vector in point notation.
% \end{descriptionbox}
% \begin{equationbox}
%   \(\begin{bmatrix}\mathbf{v}_1\\ \ldots\\ \mathbf{v}_n\end{bmatrix}\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newVec\{myNewVec\}\{1, 2, 3\}\\
%   \textbackslash printVecAsPoint\{\textbackslash myNewVec\} \(\mapsto{} \begin{bmatrix}1\\2\\3\end{bmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash printVecAsPi}{macro:printVecAsPi}
% \DescribeMacro{printVecAsPi}
% \oarg{fraction}\marg{vector}\\[1mm]
% \oarg{fraction}: whether or not the value should be printed as a fraction (val=1), default: 0\\
% \marg{vector}: the vector that should be printed
% \begin{descriptionbox}
% Print the values of the given vector as a multiple of \(\pi\) in vector notation.
% \end{descriptionbox}
% \begin{equationbox}
%   \(\begin{pmatrix}\left\{\frac{\mathbf{v}_1}{\pi}\right\}\\ \ldots\\ \left\{\frac{\mathbf{v}_n}{\pi}\right\}\end{pmatrix}\pi\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newVec\{myNewVec\}\{0.5, 1, 2\}\\
%   \textbackslash printVecAsPi\{\textbackslash myNewVec\} \(\mapsto{} \begin{pmatrix}0.5\pi\\\pi\\2\pi\end{pmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash printVecAsPiT}{macro:printVecAsPiT}
% \DescribeMacro{printVecAsPiT}
% \oarg{fraction}\marg{vector}\\[1mm]
% \oarg{fraction}: whether or not the value should be printed as a fraction (val=1), default: 0\\
% \marg{vector}: the vector that should be printed
% \begin{descriptionbox}
% Print the values of the given vector as a multiple of Pi in transposed notation.
% \end{descriptionbox}
% \begin{equationbox}
%   \(\trans{\left(\left\{\frac{\mathbf{v}_1}{\pi}\right\}, \ldots, \left\{\frac{\mathbf{v}_n}{\pi}\right\}\right)}\pi\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newVec\{myNewVec\}\{0.5, 1, 2\}\\
%   \textbackslash printVecAsPi\{\textbackslash myNewVec\} \(\mapsto{} \trans{(0.5\pi,\pi,2\pi)}\)
% \end{examplebox}

% \setlabel{\textbackslash printVecContent}{macro:printVecContent}
% \DescribeMacro{printVecContent}
% \marg{vector}\\[1mm]
% \marg{vector}: the vector which values should be printed
% \begin{descriptionbox}
% Print the values of the given vector comma separated.
% \end{descriptionbox}
% \begin{equationbox}
%   \(\mathbf{v}_1, \ldots, \mathbf{v}_n\)
% \end{equationbox}

% \setlabel{\textbackslash printVecContentXY}{macro:printVecContentXY}
% \DescribeMacro{printVecContentXY}
% \marg{vector}\\[1mm]
% \marg{vector}: the vector which values should be printed
% \begin{descriptionbox}
% Returns the x and y component of the given vector.
% \end{descriptionbox}
% \begin{equationbox}
%   \(\mathbf{v}_1, \mathbf{v}_2\)
% \end{equationbox}

% \setlabel{\textbackslash printVecContentXYZ}{macro:printVecContentXYZ}
% \DescribeMacro{printVecContentXYZ}
% \marg{vector}\\[1mm]
% \marg{vector}: the vector which values should be printed
% \begin{descriptionbox}
% Returns the x, y and z component of the given vector.
% \end{descriptionbox}
% \begin{equationbox}
%   \(\mathbf{v}_1, \mathbf{v}_2, \mathbf{v}_3\)
% \end{equationbox}

% \setlabel{\textbackslash printVecContentXYZW}{macro:printVecContentXYZW}
% \DescribeMacro{printVecContentXYZW}
% \marg{vector}\\[1mm]
% \marg{vector}: the vector which values should be printed
% \begin{descriptionbox}
% Returns the x, y, z and w component of the given vector
% \end{descriptionbox}
% \begin{equationbox}
%   \(\mathbf{v}_1, \mathbf{v}_2, \mathbf{v}_3, \mathbf{v}_4\)
% \end{equationbox}

% \setlabel{\textbackslash getVecHeight}{macro:getVecHeight}
% \DescribeMacro{getVecHeight}
% \oarg{out}\marg{vector}\\[1mm]
% \oarg{out}: var name to save the result (scalar) to, default: vecHeightResult\\
% \marg{vector}: the vector of which to return the height
% \begin{descriptionbox}
% Returns the number of components that given vector has (number of dimensions).
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = dim(\mathbf{v})\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newVec\{myNewVec\}\{0.5, 1, 2\}\\
%   \textbackslash getVecHeight\{\textbackslash myNewVec\}\\
%   \textbackslash vecHeightResult \(\mapsto{} 3\)
% \end{examplebox}

% \setlabel{\textbackslash printScalarPComp}{macro:printScalarPComp}
% \DescribeMacro{printScalarPComp}
% \oarg{fraction}\marg{vector v}\marg{vector w}\\[1mm]
% \oarg{fraction}: whether or not the value should be printed as a fraction (val=1), default: 0\\
% \marg{vector v}: the first vector\\
% \marg{vector w}: the second vector
% \begin{descriptionbox}
% Print the intermediate components of the scalarproduct calculation.
% \end{descriptionbox}
% \begin{equationbox}
%   \(\mathbf{v}_1 * \mathbf{w}_1 + \ldots + \mathbf{v}_n * \mathbf{w}_n\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newVec\{myNewVecA\}\{0.5, 1, 2\}\\
%   \textbackslash newVec\{myNewVecB\}\{0.5, 1, 2\}\\
%   \textbackslash printScalarPComp\{\textbackslash myNewVecA\}\{\textbackslash myNewVecB\} \(\mapsto{} 0.5*0.5+1*1+2*2\)
% \end{examplebox}
% \begin{warningbox}
%   When both vectors do not have the same length
% \end{warningbox}

% \setlabel{\textbackslash printCrossPComp}{macro:printCrossPComp}
% \DescribeMacro{printCrossPComp}
% \oarg{fraction}\marg{vector v}\marg{vector w}\\[1mm]
% \oarg{fraction}: whether or not the value should be printed as a fraction (val=1), default: 0\\
% \marg{vector v}: the first vector\\
% \marg{vector w}: the second vector
% \begin{descriptionbox}
% Print the intermediate components of the crossproduct calculation.
% \end{descriptionbox}
% \begin{equationbox}
%   \(\begin{pmatrix} \mathbf{v}_2*\mathbf{w}_3 - \mathbf{v}_3*\mathbf{w}_2\\ \mathbf{v}_3*\mathbf{w}_1-\mathbf{v}_1*\mathbf{w}_3\\ \mathbf{v}_1*\mathbf{w}_2-\mathbf{w}_2*\mathbf{w}_1 \end{pmatrix}\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newVec\{myNewVecA\}\{0.5, 1, 2\}\\
%   \textbackslash newVec\{myNewVecB\}\{3, 4, 5\}\\
%   \textbackslash printScalarPComp\{\textbackslash myNewVecA\}\{\textbackslash myNewVecB\} \(\mapsto{} \begin{pmatrix}1*5 - 2*4\\ 2*3 - 0.5*5\\ 0.5*4 -1*3\end{pmatrix}\)
% \end{examplebox}
% \begin{warningbox}
%   When one of both vectors does not have length 3
% \end{warningbox}

% \setlabel{\textbackslash roundVec}{macro:roundVec}
% \DescribeMacro{roundVec}
% \oarg{out}\marg{vector}\marg{digits}\\[1mm]
% \oarg{out}: var name to save the result (vector) to, default: roundVecResult\\
% \marg{vector}: the vector that schould be rounded\\
% \marg{digits}: number of digits after comma
% \begin{descriptionbox}
% Round the values ot the given vector.
% \end{descriptionbox}
% \begin{equationbox}
%   \(\mathbf{v} = \begin{pmatrix}\lfloor d_1\rceil\\\ldots\\\lfloor d_n\rceil\end{pmatrix}\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newVec\{myNewVec\}\{0.5, 1, 2\}\\
%   \textbackslash roundVec[roundVecResult]\{\textbackslash myNewVec\}\{0\}\\
%   \textbackslash roundVecResult \(\mapsto{} \begin{pmatrix}1\\1\\2\end{pmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash ceilVec}{macro:ceilVec}
% \DescribeMacro{ceilVec}
% \oarg{out}\marg{vector}\\[1mm]
% \oarg{out}: var name to save the result (vector) to, default: ceilVecResult\\
% \marg{vector}: the vector that should be ceiled
% \begin{descriptionbox}
% Ceil the values of the given vector.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \begin{pmatrix}\lceil \mathbf{v}_1\rceil\\\ldots\\\lceil \mathbf{v}_n\rceil\end{pmatrix}\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newVec\{myNewVec\}\{0.5, 1, 2\}\\
%   \textbackslash ceilVec[ceilVecResult]\{\textbackslash myNewVec\}\\
%   \textbackslash ceilVecResult \(\mapsto{} \begin{pmatrix}1\\1\\2\end{pmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash floorVec}{macro:floorVec}
% \DescribeMacro{floorVec}
% \oarg{out}\marg{vector}\\[1mm]
% \oarg{out}: var name to save the result (vector) to, default: floorVecResult\\
% \marg{vector}: the vector that should be floored
% \begin{descriptionbox}
% Floor the values of the given vector.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \begin{pmatrix}\lfloor \mathbf{v}_1\rfloor\\\ldots\\\lfloor \mathbf{v}_n\rfloor\end{pmatrix}\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newVec\{myNewVec\}\{0.5, 1, 2\}\\
%   \textbackslash floorVec[floorVecResult]\{\textbackslash myNewVec\}\\
%   \textbackslash floorVecResult \(\mapsto{} \begin{pmatrix}0\\1\\2\end{pmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash dehomogenVec}{macro:dehomogenVec}
% \DescribeMacro{dehomogenVec}
% \oarg{out}\marg{vector}\\[1mm]
% \oarg{out}: var name to save the result (vector) to, default: dehomogenVecResult\\
% \marg{vector}: the vector that should be dehomogenized
% \begin{descriptionbox}
% Dehomogenize the values of the given vector. This divides all vector components by the last component.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \begin{pmatrix} \frac{\mathbf{v}_1}{\mathbf{v}_n} \\ \ldots \\ \frac{\mathbf{v}_{n-1}}{\mathbf{v}_n} \end{pmatrix}\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newVec\{myNewVec\}\{0.5, 1, 2, 2\}\\
%   \textbackslash dehomogenVec[dehomogenVecResult]\{\textbackslash myNewVec\}\\
%   \textbackslash dehomogenVecResult \(\mapsto{} \begin{pmatrix}0.25\\0.5\\1\\1\end{pmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash addVec}{macro:addVec}
% \DescribeMacro{addVec}
% \oarg{out}\marg{vector}\marg{vectors}\\[1mm]
% \oarg{out}: var name to save the result (vector) to, default: addVecResult\\
% \marg{vector}: the vector to add to\\
% \marg{vectors}: the list of vectors with which to add
% \begin{descriptionbox}
% Add the values of \(1\) to \(m\) vectors to the values of the given vector.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \begin{pmatrix}\mathbf{v}_1 + \mathbf{vs}_{1,1} + \ldots + \mathbf{vs}_{m,1}\\\ldots\\\mathbf{v}_n + \mathbf{vs}_{1,n} + \ldots + \mathbf{vs}_{m,n}\end{pmatrix}\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newVec\{myNewVecA\}\{0.5, 1, 2\}\\
%   \textbackslash newVec\{myNewVecB\}\{0.5, 1, 2\}\\
%   \textbackslash addVec\{\textbackslash myNewVecA\}\{\textbackslash myNewVecB\}\\
%   \textbackslash addVecResult \(\mapsto{} \begin{pmatrix}1.5\\3\\6\end{pmatrix}\)\\
%   \textbackslash newVec\{myNewVecA\}\{0.5, 1, 2\}\\
%   \textbackslash newVec\{myNewVecB\}\{0.5, 1, 2\}\\
%   \textbackslash newVec\{myNewVecC\}\{0.5, 1, 2\}\\
%   \textbackslash addVec[resultName]\{\textbackslash myNewVecA\}\{\textbackslash myNewVecB, \textbackslash myNewVecC\}\\
%   \textbackslash resultName \(\mapsto{} \begin{pmatrix}1.5\\3\\6\end{pmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash subVec}{macro:subVec}
% \DescribeMacro{subVec}
% \oarg{out}\marg{vector}\marg{vectors}\\[1mm]
% \oarg{out}: var name to save the result (vector) to, default: subVecResult\\
% \marg{vector}: the vector to subtract from\\
% \marg{vectors}: the list of vectors with which to subtract
% \begin{descriptionbox}
% Subract the values of \(1\) to \(m\) vectors from the values of the given vector.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \begin{pmatrix}\mathbf{v}_1 - \mathbf{vs}_{1,1} - \ldots - \mathbf{vs}_{m,1}\\\ldots\\\mathbf{v}_n - \mathbf{vs}_{1,n} - \ldots - \mathbf{vs}_{m,n}\end{pmatrix}\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newVec\{myNewVecA\}\{0.5, 1, 2\}\\
%   \textbackslash newVec\{myNewVecB\}\{0.5, 1, 2\}\\
%   \textbackslash subVec\{\textbackslash myNewVecA\}\{\textbackslash myNewVecB\}\\
%   \textbackslash subVecResult \(\mapsto{} \begin{pmatrix}0\\0\\0\end{pmatrix}\)\\
%   \textbackslash newVec\{myNewVecA\}\{0.5, 1, 2\}\\
%   \textbackslash newVec\{myNewVecB\}\{0.5, 1, 2\}\\
%   \textbackslash newVec\{myNewVecC\}\{0.5, 1, 2\}\\
%   \textbackslash subVec[resultName]\{\textbackslash myNewVecA\}\{\textbackslash myNewVecB, \textbackslash myNewVecC\}\\
%   \textbackslash resultName \(\mapsto{} \begin{pmatrix}-0.5\\-1\\-2\end{pmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash mulVec}{macro:mulVec}
% \DescribeMacro{mulVec}
% \oarg{out}\marg{vector}\marg{vectors}\\[1mm]
% \oarg{out}: var name to save the result (vector) to, default: mulVecResult\\
% \marg{vector}: the vector to multiply\\
% \marg{vectors}: the list of vectors with which to multiply
% \begin{descriptionbox}
% Multiply the values of \(1\) to \(m\) vectors with the values of the given vector.
% See Hadamard product (element-wise product) for more information.
% \end{descriptionbox}
% \begin{equationbox}
%   \begin{align*}o &= \mathbf{v} \odot \mathbf{vs}_1 \odot \ldots \odot \mathbf{vs}_m\\ &= \begin{pmatrix}\mathbf{v}_1 * \mathbf{vs}_{1,1} * \ldots * \mathbf{vs}_{m,1}\\\ldots\\\mathbf{v}_n * \mathbf{vs}_{1,n} * \ldots * \mathbf{vs}_{m,n}\end{pmatrix}\end{align*}
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newVec\{myNewVecA\}\{0.5, 1, 2\}\\
%   \textbackslash newVec\{myNewVecB\}\{0.5, 1, 2\}\\
%   \textbackslash mulVec\{\textbackslash myNewVecA\}\{\textbackslash myNewVecB\} \(\mapsto{} \begin{pmatrix}0.25\\1\\4\end{pmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash divVec}{macro:divVec}
% \DescribeMacro{divVec}
% \oarg{out}\marg{vector}\marg{vectors}\\[1mm]
% \oarg{out}: var name to save the result (vector) to, default: divVecResult\\
% \marg{vector}: the vector to divide\\
% \marg{vectors}: the list of vectors to divide with
% \begin{descriptionbox}
% Divide the values of the given vector by the values of \(1\) to \(m\) vectors (element-wise division).
% \end{descriptionbox}
% \begin{equationbox}
%   \begin{align*}o &= \mathbf{v} \oslash \mathbf{vs}_1 \oslash \ldots \oslash \mathbf{vs}_m\\ &= \begin{pmatrix}\mathbf{v}_1 / \mathbf{vs}_{1,1} / \ldots / \mathbf{vs}_{m,1}\\\ldots\\\mathbf{v}_n / \mathbf{vs}_{1,n} / \ldots / \mathbf{vs}_{m,n}\end{pmatrix}\end{align*}
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newVec\{myNewVecA\}\{0.5, 1, 2\}\\
%   \textbackslash newVec\{myNewVecB\}\{0.5, 1, 2\}\\
%   \textbackslash divVec\{\textbackslash myNewVecA\}\{\textbackslash myNewVecB\} \(\mapsto{} \begin{pmatrix}1\\1\\1\end{pmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash scaleVec}{macro:scaleVec}
% \DescribeMacro{scaleVec}
% \oarg{out}\marg{vector}\marg{scalar}\\[1mm]
% \oarg{out}: var name to save the result (vector) to, default: scaleVecResult\\
% \marg{vector}: the vector to scale\\
% \marg{scalar}: the scalar to scale with
% \begin{descriptionbox}
% Multiply the values of the given vector by a scalar.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \begin{pmatrix}\mathbf{v}_1 * s\\\ldots\\\mathbf{v}_n * s\end{pmatrix}\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newVec\{myNewVecA\}\{0.5, 1, 2\}\\
%   \textbackslash newScalar\{myNewScalar\}\{2\}\\
%   \textbackslash scaleVec\{\textbackslash myNewVecA\}\{\textbackslash myNewScalar\}\\
%   \textbackslash scaleVecResult \(\mapsto{} \begin{pmatrix}1\\2\\4\end{pmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash divVecScalar}{macro:divVecScalar}
% \DescribeMacro{divVecScalar}
% \oarg{out}\marg{vector}\marg{scalar}\\[1mm]
% \oarg{out}: var name to save the result (vector) to, default: divVecScalarResult\\
% \marg{vector}: the vector to divide\\
% \marg{scalar}: the scalar to divide with
% \begin{descriptionbox}
% Divide the values of the given vector by a scalar.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \begin{pmatrix}\frac{\mathbf{v}_1}{s}\\\ldots\\\frac{\mathbf{v}_n}{s}\end{pmatrix}\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newVec\{myNewVecA\}\{0.5, 1, 2\}\\
%   \textbackslash newScalar\{myNewScalar\}\{2\}\\
%   \textbackslash divVecScalar\{\textbackslash myNewVecA\}\{\textbackslash myNewScalar\}\\
%   \textbackslash divVecScalarResult \(\mapsto{} \begin{pmatrix}0.25\\0.5\\1\end{pmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash negateVec}{macro:negateVec}
% \DescribeMacro{negateVec}
% \oarg{out}\marg{vector}\\[1mm]
% \oarg{out}: var name to save the result (vector) to, default: negateVecResult\\
% \marg{vector}: the vector to negate
% \begin{descriptionbox}
% Negate the values of the given vector.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \begin{pmatrix}-\mathbf{v}_1\\\ldots\\-\mathbf{v}_n\end{pmatrix}\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newVec\{myNewVecA\}\{0.5, 1, 2\}\\
%   \textbackslash negateVecResult\{\textbackslash myNewVecA\}\\
%   \textbackslash negateVecResult \(\mapsto{} \begin{pmatrix}-0.5\\-1\\-2\end{pmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash scaleAndAddVec}{macro:scaleAndAddVec}
% \DescribeMacro{scaleAndAddVec}
% \oarg{out}\marg{vector v}\marg{vector w}\marg{scalar}\\[1mm]
% \oarg{out}: var name to save the result (vector) to, default: scaleAndAddVecResult\\
% \marg{vector v}: the vector to add to\\
% \marg{vector w}: the vector that is multiplied and then added\\
% \marg{scalar}: the scalar that is the muliplier
% \begin{descriptionbox}
% Adds two vectors after multiplying the second one by a scalar.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \mathbf{v} + \mathbf{w} * s = \begin{pmatrix}\mathbf{v}_1 + \mathbf{w}_1 * s\\\ldots\\\mathbf{v}_n + \mathbf{w}_n * s\end{pmatrix}\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newVec\{myNewVecA\}\{0.5, 1, 2\}\\
%   \textbackslash newVec\{myNewVecB\}\{0.5, 1, 2\}\\
%   \textbackslash newScalar\{myNewScalar\}\{2\}\\
%   \textbackslash scaleAndAddVec\{\textbackslash myNewVecA\}\{\textbackslash myNewVecB\}\{\textbackslash myNewScalar\}\\
%   \textbackslash scaleAndAddVecResult \(\mapsto{} \begin{pmatrix}1.5\\3\\6\end{pmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash lerpVec}{macro:lerpVec}
% \DescribeMacro{lerpVec}
% \oarg{out}\marg{vector v}\marg{vector w}\marg{scalar t}\\[1mm]
% \oarg{out}: var name to save the result (vector) to, default: lerpVecResult\\
% \marg{vector v}: the start vector\\
% \marg{vector w}: the end vector\\
% \marg{scalar t}: interpolation amount range [0-1]
% \begin{descriptionbox}
% Lineraly interpolate between the values of two vectors (element-wise interpolation).
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = (1-t) * \mathbf{v} + t * \mathbf{w} = \begin{pmatrix}(1-t) \mathbf{v}_1 + t *\mathbf{w}_1\\\ldots\\(1-t) \mathbf{v}_n + t *\mathbf{w}_n\end{pmatrix}\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newVec\{myNewVecA\}\{0.5, 1, 2\}\\
%   \textbackslash newVec\{myNewVecB\}\{1, 2, 4\}\\
%   \textbackslash newScalar\{myNewScalar\}\{0.5\}\\
%   \textbackslash lerpVec\{\textbackslash myNewVecA\}\{\textbackslash myNewVecB\}\{\textbackslash myNewScalar\}\\
%   \textbackslash lerpVecResult \(\mapsto{} \begin{pmatrix}0.75\\1.5\\3\end{pmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash slerpVec}{macro:slerpVec}
% \DescribeMacro{slerpVec}
% \oarg{out}\marg{vector v}\marg{vector w}\marg{scalar t}\\[1mm]
% \oarg{out}: var name to save the result (vector) to, default: slerpVecResult\\
% \marg{vector v}: the start vector\\
% \marg{vector w}: the end vector\\
% \marg{scalar t}: interpolation amount range [0-1]
% \begin{descriptionbox}
% Performs a spherical linear interpolation between two vectors.
% This expects vector v and vector w to be normalized.
% \end{descriptionbox}
% \begin{equationbox}
%   TODO
% \end{equationbox}

% \setlabel{\textbackslash dotVec}{macro:dotVec}
% \DescribeMacro{dotVec}
% \oarg{out}\marg{vector v}\marg{vector w}\\[1mm]
% \oarg{out}: var name to save the result (scalar) to, default: dotVecResult\\
% \marg{vector v}: the first vector\\
% \marg{vector w}: the second vector
% \begin{descriptionbox}
% Calculate the dotproduct of the given two vectors.
% Other names for this operation are inner product and scalarproduct.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \mathbf{v}_1 * \mathbf{w}_1 + \ldots + \mathbf{v}_n * \mathbf{w}_n\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newVec\{myNewVecA\}\{0.5, 1, 2\}\\
%   \textbackslash newVec\{myNewVecB\}\{1, 2, 4\}\\
%   \textbackslash dotVec\{\textbackslash myNewVecA\}\{\textbackslash myNewVecB\}\\
%   \textbackslash dotVecResult \(\mapsto{} 10.5\)\\
%   \textbackslash dotVec[resultName]\{\textbackslash myNewVecA\}\{\textbackslash myNewVecB\}\\
%   \textbackslash resultName \(\mapsto{} 10.5\)
% \end{examplebox}
% \begin{warningbox}
%   When both vectors do not have the same length
% \end{warningbox}

% \setlabel{\textbackslash lenVec}{macro:lenVec}
% \DescribeMacro{lenVec}
% \oarg{out}\marg{vector}\\[1mm]
% \oarg{out}: var name to save the result (scalar) to, default: lenVecResult\\
% \marg{vector}: the vector for which to calculate the length
% \begin{descriptionbox}
% Calculate the length of the given vector.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \norm{\mathbf{v}} = \sqrt{\mathbf{v}_1^2 + \ldots + \mathbf{v}_n^2}\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newVec\{myNewVecA\}\{0.5, 1, 2\}\\
%   \textbackslash lenVec\{\textbackslash myNewVecA\}\\
%   \textbackslash lenVecResult \(\mapsto{} 2.29\)
% \end{examplebox}

% \setlabel{\textbackslash sqrLenVec}{macro:sqrLenVec}
% \DescribeMacro{sqrLenVec}
% \oarg{out}\marg{vector}\\[1mm]
% \oarg{out}: var name to save the result (scalar) to, default: sqrLenVecResult\\
% \marg{vector}: the vector for which to calculate the squared length
% \begin{descriptionbox}
% Calculate the squared length of the given vector.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \norm{\mathbf{v}}^2 = \mathbf{v}_1^2 + \ldots + \mathbf{v}_n^2\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newVec\{myNewVecA\}\{0.5, 1, 2\}\\
%   \textbackslash sqrLenVec\{\textbackslash myNewVecA\}\\
%   \textbackslash sqrLenVecResult \(\mapsto{} 5.25\)
% \end{examplebox}

% \setlabel{\textbackslash normalizeVec}{macro:normalizeVec}
% \DescribeMacro{normalizeVec}
% \oarg{out}\marg{vector}\\[1mm]
% \oarg{out}: var name to save the result (vector) to, default: normalizeVecResult\\
% \marg{vector}: the vector which to normalize
% \begin{descriptionbox}
% Divide all components of the vector by its length.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \begin{pmatrix} \frac{\mathbf{v}_1}{\norm{\mathbf{v}}}\\ \ldots\\ \frac{\mathbf{v}_n}{\norm{\mathbf{v}}}\end{pmatrix}\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newVec\{myNewVecA\}\{0.5, 1, 2\}\\
%   \textbackslash normalizeVec\{\textbackslash myNewVecA\}\\
%   \textbackslash normalizeVecResult \(\mapsto{} \begin{pmatrix} 0.12\\ 0.24\\ 0.96\end{pmatrix}\)\\
%   \textbackslash normalizeVec[resultName]\{\textbackslash myNewVecA\}\\
%   \textbackslash resultName \(\mapsto{} \begin{pmatrix} 0.12\\ 0.24\\ 0.96\end{pmatrix}\)
% \end{examplebox}

% \setlabel{\textbackslash crossVec}{macro:crossVec}
% \DescribeMacro{crossVec}
% \oarg{out}\marg{vector v}\marg{vector w}\\[1mm]
% \oarg{out}: var name to save the result (vector) to, default: crossVecResult\\
% \marg{vector v}: the first vector\\
% \marg{vector w}: the second vector
% \begin{descriptionbox}
% Calculate crossproduct for the two given vectors.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \begin{pmatrix} \mathbf{v}_2*\mathbf{w}_3 - \mathbf{v}_3*\mathbf{w}_2\\ \mathbf{v}_3*\mathbf{w}_1-\mathbf{v}_1*\mathbf{w}_3\\ \mathbf{v}_1*\mathbf{w}_2-\mathbf{w}_2*\mathbf{w}_1 \end{pmatrix}\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newVec\{myNewVecA\}\{0.5, 1, 2\}\\
%   \textbackslash newVec\{myNewVecB\}\{0.5, 0, 2\}\\
%   \textbackslash crossVec\{\textbackslash myNewVecA\}\{\textbackslash myNewVecB\}\\
%   \textbackslash crossVecResult \(\mapsto{} \begin{pmatrix} 2\\ 0\\ -0.5\end{pmatrix}\)
% \end{examplebox}
% \begin{warningbox}
%   When one of both vectors does not have length 3
% \end{warningbox}

% \setlabel{\textbackslash crossVecTwoD}{macro:crossVecTwoD}
% \DescribeMacro{crossVecTwoD}
% \oarg{out}\marg{vector v}\marg{vector w}\\[1mm]
% \oarg{out}: var name to save the result (vector) to, default: crossVecResult\\
% \marg{vector v}: the first vector\\
% \marg{vector w}: the second vector
% \begin{descriptionbox}
% Calculate crossproduct for the two given vectors.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \mathbf{v}_1*\mathbf{w}_2 - \mathbf{v}_2*\mathbf{w}_1\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newVec\{myNewVecA\}\{0.5, 1\}\\
%   \textbackslash newVec\{myNewVecB\}\{0.5, 0\}\\
%   \textbackslash crossVecTwoD\{\textbackslash myNewVecA\}\{\textbackslash myNewVecB\}\\
%   \textbackslash crossVecResult \(\mapsto{} -0.5\)
% \end{examplebox}
% \begin{warningbox}
%   When one of both vectors does not have length 3
% \end{warningbox}

% \setlabel{\textbackslash angleVec}{macro:angleVec}
% \DescribeMacro{angleVec}
% \oarg{out}\marg{vector v}\marg{vector w}\\[1mm]
% \oarg{out}: var name to save the result (scalar) to, default: angleVecResult\\
% \marg{vector v}: the first vector\\
% \marg{vector w}: the second vector
% \begin{descriptionbox}
% Get the angle between the given two vectors in radian.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \angle(\mathbf{v}, \mathbf{w})\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newVec\{myNewVecA\}\{0.5, 1, 2\}\\
%   \textbackslash newVec\{myNewVecB\}\{0.5, 1, 2\}\\
%   \textbackslash angleVec\{\textbackslash myNewVecA\}\{\textbackslash myNewVecB\}\\
%   \textbackslash angleVecResult \(\mapsto{} TODO scalar\)
% \end{examplebox}

% \setlabel{\textbackslash distVec}{macro:distVec}
% \DescribeMacro{distVec}
% \oarg{out}\marg{vector v}\marg{vector w}\\[1mm]
% \oarg{out}: var name to save the result (scalar) to, default: distVecResult\\
% \marg{vector v}: the first vector\\
% \marg{vector w}: the second vector
% \begin{descriptionbox}
% Calculates the euclidian distance between the given two vectors.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \norm{\mathbf{v} - \mathbf{w}}\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newVec\{myNewVecA\}\{0.5, 1, 2\}\\
%   \textbackslash newVec\{myNewVecB\}\{0.5, 1, 2\}\\
%   \textbackslash distVec\{\textbackslash myNewVecA\}\{\textbackslash myNewVecB\}\\
%   \textbackslash distVecResult \(\mapsto{} TODO scalar\)
% \end{examplebox}
% \begin{warningbox}
%   When vector v and vector w do not have the same length
% \end{warningbox}

% \setlabel{\textbackslash sqrDistVec}{macro:sqrDistVec}
% \DescribeMacro{sqrDistVec}
% \oarg{out}\marg{vector v}\marg{vector w}\\[1mm]
% \oarg{out}: var name to save the result (scalar) to, default: sqrDistVecResult\\
% \marg{vector v}: the first vector\\
% \marg{vector w}: the second vector
% \begin{descriptionbox}
% Calculates the squared euclidian distance between two vectors.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \norm{\mathbf{v} - \mathbf{w}}^2\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newVec\{myNewVecA\}\{0.5, 1, 2\}\\
%   \textbackslash newVec\{myNewVecB\}\{0.5, 1, 2\}\\
%   \textbackslash sqrDistVec\{\textbackslash myNewVecA\}\{\textbackslash myNewVecB\}\\
%   \textbackslash sqrDistVecResult \(\mapsto{} TODO scalar\)
% \end{examplebox}
% \begin{warningbox}
%   When vector v and vector w do not have the same length
% \end{warningbox}

% \setlabel{\textbackslash transformVec}{macro:transformVec}
% \DescribeMacro{transformVec}
% \oarg{out}\marg{matrix}\marg{vector}\\[1mm]
% \oarg{out}: var name to save the result (vector) to, default: transformVecResult\\
% \marg{matrix}: the matrix to transform the vetor with\\
% \marg{vector}: the vector to transform
% \begin{descriptionbox}
% Multiply the given vector with a matrix (for transformation).
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \mathbf{M} \cdot \mathbf{v}\ \vert\ \mathbf{M} \in \R^{m\times n}, \mathbf{v} \in \R^n\)
% \end{equationbox}
% \begin{examplebox}
%   \textbackslash newVec\{myNewVec\}\{0.5, 1, 2\}\\
%   \textbackslash newMat\{myNewMatrix\}\{\{\{0.5, 1, 2\}\{4, 5, 6\}\{7, 8, 9\}\}\}\\
%   \textbackslash transformVec\{\textbackslash myNewMatrix\}\{\textbackslash myNewVec\}\\
%   \textbackslash transformVecResult \(\mapsto{} \begin{pmatrix} 5.25\\ 19\\ 29.5\end{pmatrix}\)\\
%   \textbackslash transformVec[resultName]\{\textbackslash myNewMatrix\}\{\textbackslash myNewVec\}\\
%   \textbackslash resultName \(\mapsto{} \begin{pmatrix} 5.25\\ 19\\ 29.5\end{pmatrix}\)
% \end{examplebox}
% \begin{warningbox}
%   When matrix and vector have a dimension mismatch
% \end{warningbox}

% \setlabel{\textbackslash tensorVec}{macro:tensorVec}
% \DescribeMacro{tensorVec}
% \oarg{out}\marg{vector}\\[1mm]
% \oarg{out}: var name to save the result (matrix) to, default: tensorVecResult\\
% \marg{vector}: the vector to multiply with itself
% \begin{descriptionbox}
% Outer product: Multiply a vector (column) with itself (row) resulting in a matrix. (Dyadic product, Tensor product)
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \mathbf{v} \trans{\mathbf{v}} = \mathbf{v} \otimes \mathbf{v}\)
% \end{equationbox}
% \begin{warningbox}
%   When matrix and vector have a dimension mismatch
% \end{warningbox}

% \setlabel{\textbackslash minVec}{macro:minVec}
% \DescribeMacro{minVec}
% \oarg{out}\marg{vector v}\marg{vector w}\\[1mm]
% \oarg{out}: var name to save the result (vector) to, default: minVecResult\\
% \marg{vector v}: the first vector\\
% \marg{vector w}: the second vector
% \begin{descriptionbox}
% Return the componentwise minimum of the given two vectors.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \begin{pmatrix} \min(\mathbf{v}_1, \mathbf{w}_1)\\ \ldots\\ \min(\mathbf{v}_n, \mathbf{w}_n)\end{pmatrix}\)
% \end{equationbox}
% \begin{warningbox}
%   When vector v and vector w do not have the same length
% \end{warningbox}

% \setlabel{\textbackslash maxVec}{macro:maxVec}
% \DescribeMacro{maxVec}
% \oarg{out}\marg{vector v}\marg{vector w}\\[1mm]
% \oarg{out}: var name to save the result (vector) to, default: maxVecResult\\
% \marg{vector v}: the first vector\\
% \marg{vector w}: the second vector
% \begin{descriptionbox}
% Return the componentwise maximum of the given two vectors.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \begin{pmatrix} \max(\mathbf{v}_1, \mathbf{w}_1)\\ \ldots\\ \max(\mathbf{v}_n, \mathbf{w}_n)\end{pmatrix}\)
% \end{equationbox}
% \begin{warningbox}
%   When vector v and vector w do not have the same length
% \end{warningbox}

% \setlabel{\textbackslash solveVecEQL}{macro:solveVecEQL}
% \DescribeMacro{solveVecEQL}
% \oarg{out}\marg{vector v}\marg{vector w}\\[1mm]
% \oarg{out}: var name to save the result (scalar) to, default: solveVecEQLResult\\
% \marg{vector v}: the first vector\\
% \marg{vector w}: the second vector
% \begin{descriptionbox}
% Solve the equation \(vector v*x+vector w=0\) for \(x\).
% The command expects the input to be two vectors of the same length.
% The command iterates both vectors componentwise and solves the equation per component.
% If the the result does not match across all components the equation can not be solved.
% \end{descriptionbox}
% \begin{equationbox}
%   \(o = \frac{-\mathbf{w}_1}{\mathbf{v}_1} = \ldots = \frac{-\mathbf{w}_n}{\mathbf{v}_n}\)
% \end{equationbox}

% \section{Implementation}

% \iffalse
%<*package>
% \fi
% \subsection{matrix}
% \begin{center}
% \begin{tabularx}{\textwidth}{l p{8cm}} \hline
% \textbf{Command} & \textbf{Arguments} \\ \hline
% \ref{macro:newMat_impl} & \makecell[t{p{8cm}}]{\marg{out}, \marg{scalars}} \\
% \ref{macro:newMatFromRow_impl} & \makecell[t{p{8cm}}]{\marg{out}, \marg{row}} \\
% \ref{macro:newMatFromRowVecs_impl} & \makecell[t{p{8cm}}]{\marg{out}, \marg{rows}} \\
% \ref{macro:newMatFromColVecs_impl} & \makecell[t{p{8cm}}]{\marg{out}, \marg{columns}} \\
% \ref{macro:newEmptyMat_impl} & \makecell[t{p{8cm}}]{\marg{out}} \\
% \ref{macro:newDiagMat_impl} & \makecell[t{p{8cm}}]{\marg{out}, \marg{scalars}} \\
% \ref{macro:appendRowToMat_impl} & \makecell[t{p{8cm}}]{\marg{out}, \marg{matrix}, \marg{vector r}} \\
% \ref{macro:newTransMat_impl} & \makecell[t{p{8cm}}]{\marg{out}, \marg{vector t}} \\
% \ref{macro:newScaleMat_impl} & \makecell[t{p{8cm}}]{\marg{out}, \marg{vector s}} \\
% \ref{macro:newRotMatTwoD_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{scalar}\\rotMatResult} \\
% \ref{macro:newRotMat_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector}, \marg{scalar}\\rotMatResult} \\
% \ref{macro:newLookAtMat_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{right}, \marg{up}, \marg{dir}, \marg{pos}\\lookAtMatResult} \\
% \ref{macro:newProjMat_impl} & \makecell[t{p{8cm}}]{\marg{out}} \\
% \ref{macro:newProjMatGen_impl} & \makecell[t{p{8cm}}]{\marg{out}} \\
% \ref{macro:newFrustumMat_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{fovx}, \marg{fovy}, \marg{near}, \marg{far}\\frustMatResult} \\
% \ref{macro:printMat_impl} & \makecell[t{p{8cm}}]{\oarg{fraction}, \marg{matrix}\\0} \\
% \ref{macro:printMatDiag_impl} & \makecell[t{p{8cm}}]{\oarg{fraction}, \marg{matrix}\\0} \\
% \ref{macro:getMatHeight_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{matrix}\\matHeightResult} \\
% \ref{macro:getMatWidth_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{matrix}\\matWidthResult} \\
% \ref{macro:transposeMat_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{matrix}\\transposeMatResult} \\
% \ref{macro:addMat_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{matrix}, \marg{matrices}\\addMatResult} \\
% \ref{macro:subMat_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{matrix}, \marg{matrices}\\subMatResult} \\
% \ref{macro:mulMatScalar_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{matrix}, \marg{scalar}\\mulMatScalarResult} \\
% \ref{macro:mulMatVec_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{matrix}, \marg{vector}\\mulMatVecResult} \\
% \ref{macro:mulMat_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{matrix M}, \marg{matrix N}\\mulMatResult} \\
% \ref{macro:getMatTranslation_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{matrix}\\matTranslationResult} \\
% \ref{macro:detMat_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{matrix}\\detMatResult} \\
% \end{tabularx}
% \end{center}


% \setlabel{\textbackslash newMat}{macro:newMat_impl}
% \begin{macro}{\newMat}
% Create a new matrix from the given values.
% 
% \#1 - out: var name to save the result (matrix) to\\
% \#2 - scalars: matrix values that are assigned to \#1
%    \begin{macrocode}
\newcommand\newMat[2]{
    \xintFor* ##1 in #2 \do {%
        \newVec{matRow}{##1}
        \xintifForFirst{%
            \newMatFromRow{#1}{\matRow}
        }{%
            \appendRowToMat{#1}{\csname #1\endcsname}{\matRow}
        }
    }
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash newMatFromRow}{macro:newMatFromRow_impl}
% \begin{macro}{\newMatFromRow}
% Create a new matrix from the given row.
% 
% \#1 - out: var name to save the result (matrix) to\\
% \#2 - row: matrix row that is assigned to \#1
%    \begin{macrocode}
\newcommand\newMatFromRow[2]{
    \newScalar{tmpWidth}{\expandafter\xintLength\expandafter{#2}}%
    \FPifeq{\tmpWidth}{1}
        \expandafter\edef\csname #1\endcsname{{\xintCSVtoList{\matRow}}}
    \else
        \expandafter\edef\csname #1\endcsname{\xintCSVtoList{\matRow}}
    \fi
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash newMatFromRowVecs}{macro:newMatFromRowVecs_impl}
% \begin{macro}{\newMatFromRowVecs}
% Create a new matrix from the given row vectors.
% 
% \#1 - out: var name to save the result (matrix) to\\
% \#2 - rows: the rows that are used to construct the matrix
%    \begin{macrocode}
\newcommand\newMatFromRowVecs[2]{%
    % TODO remove this?
    \FPset\numParam{\expandafter\xintLength{#2}}%
    \FPsub\numParam\numParam{1}
    \FPdiv\numParam\numParam{2}
    \FPadd\numParam\numParam{1}
    % In case only one item/row was given the
    % matrix-datastructure must be adjusted
    \FPifeq{\numParam}{1}
        \expandafter\edef\csname #1\endcsname{\xintCSVtoList{#2}}%
    \else
        \expandafter\edef\csname #1\endcsname{\xintCSVtoList{#2}}%
    \fi
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash newMatFromColVecs}{macro:newMatFromColVecs_impl}
% \begin{macro}{\newMatFromColVecs}
% Create a new matrix from the given column vectors.
% 
% \#1 - out: var name to save the result (matrix) to\\
% \#2 - columns: the columns that are used to construct the matrix
%    \begin{macrocode}
\newcommand\newMatFromColVecs[2]{%
    \edef\tmpVecList{\xintCSVtoList{#2}}%
    \copyVec[tmpHeightVec]{{\xintNthElt{1}{\tmpVecList}}}
    \getVecHeight[numRows]{\tmpHeightVec}
    \edef\numColumns{\expandafter\xintLength\expandafter{\tmpVecList}}
    \edef\colSequence{\xintSeq[+1]{+1}{\numColumns}}
    \edef\rowSequence{\xintSeq[+1]{+1}{\numRows}}
    \newEmptyMat{#1}
    \xintFor* ##1 in \colSequence \do {%
        \xintFor* ##2 in \rowSequence \do {%
            \newScalar{tmpValue}{\xintNthElt{##1}{\xintNthElt{##2}{\tmpVecList}}}
            \xintifForFirst{%
                \newVec{matRow}{\tmpValue}
            }{%
                \appendToVec{matRow}{\matRow}{\tmpValue}
            }
        }
        \appendRowToMat{#1}{\csname #1\endcsname}{\matRow}
    }
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash newEmptyMat}{macro:newEmptyMat_impl}
% \begin{macro}{\newEmptyMat}
% Create a new empty matrix.
% Obacht: It is not necessary to call this to create a new matrix before using any of the arithmetic commands.
% 
% \#1 - out: var name to save the result (matrix) to
%    \begin{macrocode}
\newcommand\newEmptyMat[1]{
    \expandafter\edef\csname #1\endcsname{}%
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash newDiagMat}{macro:newDiagMat_impl}
% \begin{macro}{\newDiagMat}
% Create a new diagonal matrix from the given vector.
% 
% \#1 - out: var name to save the result (matrix) to\\
% \#2 - scalars: the values that define the diagonal of the matrix
%    \begin{macrocode}
\newcommand\newDiagMat[2]{
    \if\noexpand#1\relax
        \PackageError{glmatrix package}{argument mismatch}{Argument 1 of newDiagMat seems to be a command but must be a string. If it is not a command you might have used two identical letter at the beginning of the argument, please change that.}
    \else
        \edef\tmpVector{\xintCSVtoList{#2}}%
        \newVec{rowA}{\xintNthElt{1}{\tmpVector}, 0, 0}
        \newVec{rowB}{0, \xintNthElt{2}{\tmpVector}, 0}
        \newVec{rowC}{0, 0, \xintNthElt{3}{\tmpVector}}
        \newMatFromRowVecs{#1}{\rowA, \rowB, \rowC}
    \fi
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash appendRowToMat}{macro:appendRowToMat_impl}
% \begin{macro}{\appendRowToMat}
% Append the given row to the given matrix.
% 
% \#1 - out: var name to save the result (matrix) to\\
% \#2 - matrix: the matrix to append the vector to\\
% \#3 - vector r: the row vector that should be appended to the matrix
%    \begin{macrocode}
\newcommand\appendRowToMat[3]{
    \newScalar{tmpWidth}{\expandafter\xintLength\expandafter{#3}}%
    \FPifeq{\tmpWidth}{1}
        \expandafter\edef\csname #1\endcsname{#2 {\xintCSVtoList{#3}}}%
    \else
        \expandafter\edef\csname #1\endcsname{#2 \xintCSVtoList{#3}}%
    \fi
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash newTransMat}{macro:newTransMat_impl}
% \begin{macro}{\newTransMat}
% Create translation matrix from the given vector.
% 
% \#1 - out: var name to save the result (matrix) to\\
% \#2 - vector t: the translation vector to construct the matrix from
%    \begin{macrocode}
\newcommand\newTransMat[2]{%
    \edef\vecLength{\expandafter\xintLength\expandafter{#2 1}}
    \edef\innersequence{\xintSeq[+1]{+1}{\expandafter\xintLength\expandafter{#2}+1}}
    \xintFor* ##1 in \innersequence \do {%
        \xintifForFirst{%
            \xintFor* ##2 in \innersequence \do {%
                \newScalar{tmp}{0}
                \FPifeq{##2}{\vecLength}
                    \setScalar{tmp}{\xintNthElt{##1}{#2}}
                \else
                \fi
                \FPifeq{##1}{##2}
                    \setScalar{tmp}{1}
                \else
                \fi
                \xintifForFirst{%
                    \newVec{matRow}{\tmp}
                }{%
                    \appendToVec{matRow}{\matRow}{\tmp}
                }
            }
            \newMatFromRow{#1}{\matRow}
        }{%
            \xintFor* ##2 in \innersequence \do {%
                \newScalar{tmp}{0}
                \FPifeq{##2}{\vecLength}
                    \setScalar{tmp}{\xintNthElt{##1}{#2}}
                \else
                \fi
                \FPifeq{##1}{##2}
                    \setScalar{tmp}{1}
                \else
                \fi
                \xintifForFirst{%
                    \newVec{matRow}{\tmp}
                }{%
                    \appendToVec{matRow}{\matRow}{\tmp}
                }
            }
            \appendRowToMat{#1}{\csname #1\endcsname}{\matRow}
        }
    }
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash newScaleMat}{macro:newScaleMat_impl}
% \begin{macro}{\newScaleMat}
% Create scaling matrix from the given vector.
% 
% \#1 - out: var name to save the result (matrix) to\\
% \#2 - vector s: the scaling vector to construct the matrix from
%    \begin{macrocode}
\newcommand\newScaleMat[2]{%
    \edef\vecLength{\expandafter\xintLength\expandafter{#2 1}}
    \edef\innersequence{\xintSeq[+1]{+1}{\expandafter\xintLength\expandafter{#2}+1}}
    \xintFor* ##1 in \innersequence \do {%
        \xintifForFirst{%
            \xintFor* ##2 in \innersequence \do {%
                \FPiflt{##2}{\vecLength}
                    \setScalar{tmp}{\xintNthElt{##1}{#2}}
                \else
                    \setScalar{tmp}{1}
                \fi
                \FPifeq{##1}{##2}
                \else
                    \setScalar{tmp}{0}
                \fi
                \xintifForFirst{%
                    \newVec{matRow}{\tmp}
                }{%
                    \appendToVec{matRow}{\matRow}{\tmp}
                }
            }
            \newMatFromRow{#1}{\matRow}
        }{%
            \xintFor* ##2 in \innersequence \do {%
                \FPiflt{##2}{\vecLength}
                    \setScalar{tmp}{\xintNthElt{##1}{#2}}
                \else
                    \setScalar{tmp}{1}
                \fi
                \FPifeq{##1}{##2}
                \else
                    \setScalar{tmp}{0}
                \fi
                \xintifForFirst{%
                    \newVec{matRow}{\tmp}
                }{%
                    \appendToVec{matRow}{\matRow}{\tmp}
                }
            }
            \appendRowToMat{#1}{\csname #1\endcsname}{\matRow}
        }
    }
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash newRotMatTwoD}{macro:newRotMatTwoD_impl}
% \begin{macro}{\newRotMatTwoD}
% Create rotation matrix from the given scalar (2D).
% 
% \#1 - out: var name to save the result (matrix) to\\
% \#2 - scalar: the rotation value
%    \begin{macrocode}
\newcommand\newRotMatTwoD[2][rotMatResult]{%
    \FPcos\tmpCos{#2}
    \FPsin\tmpSin{#2}
    \newVec{rowB}{\tmpSin, \tmpCos, 0}
    \FPmul\tmpSin\tmpSin{-1}
    \newVec{rowA}{\tmpCos, \tmpSin, 0}
    \newVec{rowC}{0, 0, 1}
    \newMatFromRowVecs{#1}{\rowA, \rowB, \rowC}
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash newRotMat}{macro:newRotMat_impl}
% \begin{macro}{\newRotMat}
% Create a rotation matrix using the rodrigues’ matrix
% 
% \#1 - out: var name to save the result (matrix) to\\
% \#2 - vector: the axis to rotate around\\
% \#3 - scalar: the angle in degree to rotate with (counterclockwise)
%    \begin{macrocode}
\newcommand\newRotMat[3][rotMatResult]{%
    \normalizeVec[normalizedAxis]{#2}
    \toRadian[angleInRadian]{#3}
    \FPcos\tmpCos{\angleInRadian}
    \FPsin\tmpSin{\angleInRadian}
    \subScalar[tmpCosMOne]{1}{\tmpCos}
    \mulScalar[xsquared]{\xintNthElt{1}{\normalizedAxis}}{\xintNthElt{1}{\normalizedAxis}}
    \mulScalar[xy]{\xintNthElt{1}{\normalizedAxis}}{\xintNthElt{2}{\normalizedAxis}}
    \mulScalar[xz]{\xintNthElt{1}{\normalizedAxis}}{\xintNthElt{2}{\normalizedAxis}}
    \mulScalar[ysquared]{\xintNthElt{2}{\normalizedAxis}}{\xintNthElt{2}{\normalizedAxis}}
    \mulScalar[yz]{\xintNthElt{2}{\normalizedAxis}}{\xintNthElt{3}{\normalizedAxis}}
    \mulScalar[zsquared]{\xintNthElt{3}{\normalizedAxis}}{\xintNthElt{3}{\normalizedAxis}}
    %
    \mulScalar[xsin]{\xintNthElt{1}{\normalizedAxis}}{\tmpSin}
    \mulScalar[ysin]{\xintNthElt{2}{\normalizedAxis}}{\tmpSin}
    \mulScalar[zsin]{\xintNthElt{3}{\normalizedAxis}}{\tmpSin}
    %
    \mulScalar[oneone]{\xsquared}{\tmpCosMOne}
    \addScalar[oneone]{\oneone}{\tmpCos}
    \mulScalar[onetwo]{\xy}{\tmpCosMOne}
    \subScalar[onetwo]{\onetwo}{\zsin}
    \mulScalar[onethree]{\xz}{\tmpCosMOne}
    \addScalar[onethree]{\onethree}{\ysin}
    %
    \mulScalar[twoone]{\xsquared}{\tmpCosMOne}
    \addScalar[twoone]{\twoone}{\zsin}
    \mulScalar[twotwo]{\xy}{\tmpCosMOne}
    \addScalar[twotwo]{\twotwo}{\tmpCos}
    \mulScalar[twothree]{\xz}{\tmpCosMOne}
    \subScalar[twothree]{\twothree}{\xsin}
    %
    \mulScalar[threeone]{\xsquared}{\tmpCosMOne}
    \subScalar[threeone]{\threeone}{\ysin}
    \mulScalar[threetwo]{\xy}{\tmpCosMOne}
    \addScalar[threetwo]{\threetwo}{\xsin}
    \mulScalar[threethree]{\xz}{\tmpCosMOne}
    \addScalar[threethree]{\threethree}{\tmpCos}
    %
    \newVec{rowA}{\oneone, \onetwo, \onethree}
    \newVec{rowB}{\twoone, \twotwo, \twothree}
    \newVec{rowC}{\threeone, \threetwo, \threethree}
    \newMatFromRowVecs{#1}{\rowA, \rowB, \rowC}
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash newLookAtMat}{macro:newLookAtMat_impl}
% \begin{macro}{\newLookAtMat}
% Create a new lookAt matrix.
% 
% \#1 - out: var name to save the result (matrix) to\\
% \#2 - right: the right vector\\
% \#3 - up: the up vector\\
% \#4 - dir: the direction vector\\
% \#5 - pos: the camera position vector
%    \begin{macrocode}
\newcommand\newLookAtMat[5][lookAtMatResult]{%
    \dotVec[scalarRC]{#2}{#5}
    \mulScalar[scalarRC]{\scalarRC}{-1}
    \copyVec[tmpVecA]{#2}
    \appendToVec{tmpVecA}{\tmpVecA}{\scalarRC}
    % \printVec[1]{\tmpVecA}
    %
    \dotVec[scalarUC]{#3}{#5}
    \mulScalar[scalarUC]{\scalarUC}{-1}
    \copyVec[tmpVecB]{#3}
    \appendToVec{tmpVecB}{\tmpVecB}{\scalarUC}
    %
    \dotVec[scalarDC]{#4}{#5}
    \copyVec[tmpVecC]{#4}
    \negateVec[tmpVecC]{\tmpVecC}
    \appendToVec{tmpVecC}{\tmpVecC}{\scalarDC}
    %
    \newVec{tmpVecD}{0, 0, 0, 1}
    \newMatFromRowVecs{#1}{\tmpVecA, \tmpVecB, \tmpVecC, \tmpVecD}
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash newProjMat}{macro:newProjMat_impl}
% \begin{macro}{\newProjMat}
% Create a new default projection matrix.
% 
% \#1 - out: var name to save the result (matrix) to
%    \begin{macrocode}
\newcommand\newProjMat[1]{%
    \newVec{tmpVecA}{1, 0, 0, 0}
    \newVec{tmpVecB}{0, 1, 0, 0}
    \newVec{tmpVecC}{0, 0, 1, 0}
    \newVec{tmpVecD}{0, 0, -1, 0}
    \newMatFromRowVecs{#1}{\tmpVecA, \tmpVecB, \tmpVecC, \tmpVecD}
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash newProjMatGen}{macro:newProjMatGen_impl}
% \begin{macro}{\newProjMatGen}
% Create a new projection matrix from normal and distance from origin.
% 
% \#1 - out: var name to save the result (matrix) to
%    \begin{macrocode}
\newcommand\newProjMatGen[3]{%
    \divScalar[glmNxDelta]{\xintNthElt{1}{#2}}{#3}
    \divScalar[glmNyDelta]{\xintNthElt{2}{#2}}{#3}
    \divScalar[glmNzDelta]{\xintNthElt{3}{#2}}{#3}
    \newVec{tmpVecA}{1, 0, 0, 0}
    \newVec{tmpVecB}{0, 1, 0, 0}
    \newVec{tmpVecC}{0, 0, 1, 0}
    \newVec{tmpVecD}{\glmNxDelta, \glmNyDelta, \glmNzDelta, 0}
    \newMatFromRowVecs{#1}{\tmpVecA, \tmpVecB, \tmpVecC, \tmpVecD}
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash newFrustumMat}{macro:newFrustumMat_impl}
% \begin{macro}{\newFrustumMat}
% Create a new frustum matrix.
% 
% \#1 - out: var name to save the result (matrix) to\\
% \#2 - fovx: the fovx scalar\\
% \#3 - fovy: the fovy scalar\\
% \#4 - near: the position of the near plane (scalar)\\
% \#5 - far: the psition of the far lane (scalar)
%    \begin{macrocode}
\newcommand\newFrustumMat[5][frustMatResult]{%
    \FPdiv\tmp{#2}{2}
    \FPtan\frustumRight\tmp
    \FPmul\frustumRight{#4}\frustumRight
    \FPmul\frustumLeft\frustumRight{-1}
    \FPdiv\tmp{#3}{2}
    \FPtan\frustumTop\tmp
    \FPmul\frustumTop{#4}\frustumTop
    \FPmul\frustumBottom\frustumTop{-1}
    %
    \FPmul\cellAA{2}{#4} % AA
    \FPsub\tmp\frustumRight\frustumLeft
    \FPdiv\cellAA\cellAA\tmp
    \FPadd\cellAC\frustumRight\frustumLeft % AC
    \FPdiv\cellAC\cellAC\tmp
    \FPmul\cellBB{2}{#4} % BB
    \FPsub\tmp\frustumTop\frustumBottom
    \FPdiv\cellBB\cellBB\tmp
    \FPadd\cellBC\frustumTop\frustumBottom % BC
    \FPdiv\cellBC\cellBC\tmp
    \FPmul\cellCC{#5}{-1} % CC
    \FPsub\cellCC\cellCC{#4}
    \FPsub\tmp{#5}{#4}
    \FPdiv\cellCC\cellCC\tmp
    \FPmul\cellCD{#5}{#4} % CD
    \FPmul\cellCD{-2}\cellCD
    \FPdiv\cellCD\cellCD\tmp
    %
    \newVec{rowA}{\cellAA, 0, \cellAC, 0}
    \newVec{rowB}{0, \cellBB, \cellBC, 0}
    \newVec{rowC}{0, 0, \cellCC, \cellCD}
    \newVec{rowD}{0, 0, -1, 0}
    \newMatFromRowVecs{#1}{\rowA, \rowB, \rowC, \rowD}
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash printMat}{macro:printMat_impl}
% \begin{macro}{\printMat}
% Print the values of this matrix variable.
% 
% \#1 - fraction: whether or not the value should be printed as a fraction (val=1)\\
% \#2 - matrix: the matrix that should be printed
%    \begin{macrocode}
\newcommand\printMat[2][0]{%
    \ensuremath{%
        \begin{bmatrix}
            \xintFor* ##1 in #2 \do {%
                \xintFor* ##2 in {##1} \do {%
                    \xintifForLast{%
                        \xintifForFirst{}{&}
                        \FPifeq{#1}{0}
                            \roundScalar{##2}
                            \scalarRoundResult
                        \else
                            \numToFractionA{##2}
                        \fi
                        \\
                    }{%
                        \xintifForFirst{}{&}
                        \FPifeq{#1}{0}
                            \roundScalar{##2}
                            \scalarRoundResult
                        \else
                            \numToFractionA{##2}
                        \fi
                    }
                }
            }
        \end{bmatrix}
    }
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash printMatDiag}{macro:printMatDiag_impl}
% \begin{macro}{\printMatDiag}
% Print only the diagonal values of this matrix variable.
% 
% \#1 - fraction: whether or not the value should be printed as a fraction (val=1)\\
% \#2 - matrix: the matrix that should be printed
%    \begin{macrocode}
\newcommand\printMatDiag[2][0]{%
    \ensuremath{%
        \text{diag}\left(
        \xintNthElt{1}{\xintNthElt{1}{#2}},
        \xintNthElt{2}{\xintNthElt{2}{#2}},
        \xintNthElt{3}{\xintNthElt{3}{#2}}
        \right)
    }
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash getMatHeight}{macro:getMatHeight_impl}
% \begin{macro}{\getMatHeight}
% Get the height of the given matrix.
% 
% \#1 - out: var name to save the result (scalar) to\\
% \#2 - matrix: the matrix from which to get the height
%    \begin{macrocode}
\newcommand\getMatHeight[2][matHeightResult]{%
    \newScalar{#1}{\expandafter\xintLength\expandafter{#2}}%
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash getMatWidth}{macro:getMatWidth_impl}
% \begin{macro}{\getMatWidth}
% Get the width of the given matrix.
% 
% \#1 - out: var name to save the result (scalar) to\\
% \#2 - matrix: the matrix from which to get the width
%    \begin{macrocode}
\newcommand\getMatWidth[2][matWidthResult]{%
    \edef\rowElements{\xintNthElt{1}{#2}}%
    \newScalar{#1}{\expandafter\xintLength\expandafter{\rowElements}}%
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash transposeMat}{macro:transposeMat_impl}
% \begin{macro}{\transposeMat}
% Transpose a given Matrix. The parameter can also be a vector,
% but the result will be a matrix.
% 
% \#1 - out: var name to save the result (matrix) to\\
% \#2 - matrix: the matrix to transpose
%    \begin{macrocode}
\newcommand\transposeMat[2][transposeMatResult]{%
    \getMatWidth{#2}
    \getMatHeight{#2}
    \edef\widthSequence{\xintSeq[+1]{+1}{\matWidthResult}}
    \edef\heightSequence{\xintSeq[+1]{+1}{\matHeightResult}}
    \newEmptyMat{#1}
    \xintFor* ##1 in \widthSequence \do {%
        \xintFor* ##2 in \heightSequence \do {%
            \FPset\tmpValue{\xintNthElt{##1}{\xintNthElt{##2}{#2}}}
            \xintifForFirst{%
                \newVec{rowVec}{\tmpValue}
            }{%
                \appendToVec{rowVec}{\rowVec}{\tmpValue}
            }
        }
        \appendRowToMat{#1}{\csname #1\endcsname}{\rowVec}
    }
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash addMat}{macro:addMat_impl}
% \begin{macro}{\addMat}
% Add two or more matrices.
% 
% \#1 - out: var name to save the result (matrix) to\\
% \#2 - matrix: the matrix to add to\\
% \#3 - matrices: the matrizes to add
%    \begin{macrocode}
\newcommand\addMat[3][addMatResult]{%
    \if\noexpand#1\relax
        \PackageError{glmatrix package}{argument mismatch}{Argument 1 of addMat seems to be a command but must be a string. If it is not a command you might have used two identical letter at the beginning of the argument, please change that.}
    \else
    \fi
    \if\noexpand#2\relax
    \else
        \PackageError{glmatrix package}{argument mismatch}{argument 2 of addMat does not seem to be a command}
    \fi
    % TODO this does not work if it is a list
    % \if\noexpand#3\relax
    % \else
    %     \PackageError{glmatrix package}{argument mismatch}{argument 3 of addMat does not seem to be a command}
    % \fi
    \def\matlist{\xintCSVtoList{#3}}
    \edef\elemsRow{\xintNthElt{1}{\xintNthElt{1}{\matlist}}}
    \edef\widthsequence{\xintSeq[+1]{+1}{\expandafter\xintLength\expandafter{\elemsRow}}}%
    \edef\elemsMat{\xintNthElt{1}{\matlist}}
    \edef\heightsequence{\xintSeq[+1]{+1}{\expandafter\xintLength\expandafter{\elemsMat}}}%
    %
    \newEmptyMat{#1}
    \xintFor* ##2 in \heightsequence \do {%
        \xintFor* ##3 in \widthsequence \do {%
            \FPset\tmpValue{\xintNthElt{##3}{\xintNthElt{##2}{#2}}}
            \xintifForFirst{%
                \xintFor* ##1 in \matlist \do {%
                    \FPadd\tmpValue\tmpValue{\xintNthElt{##3}{\xintNthElt{##2}{##1}}}
                }
                \newVec{rowVec}{\tmpValue}
            }{%
                % \xintifForLast{
                % }{
                    \xintFor* ##1 in \matlist \do {%
                        \FPadd\tmpValue\tmpValue{\xintNthElt{##3}{\xintNthElt{##2}{##1}}}
                    }
                    \appendToVec{rowVec}{\rowVec}{\tmpValue}
                % }
            }
        }
        \appendRowToMat{#1}{\csname #1\endcsname}{\rowVec}
    }
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash subMat}{macro:subMat_impl}
% \begin{macro}{\subMat}
% Subtract two or more matrices.
% 
% \#1 - out: var name to save the result (matrix) to\\
% \#2 - matrix: the matrix to subtract from\\
% \#3 - matrices: the matrizes to subtract
%    \begin{macrocode}
\newcommand\subMat[3][subMatResult]{%
    % \getMatWidth{#2}
    % \edef\widthsequence{\xintSeq[+1]{+1}{\matWidthResult}}%
    \getMatHeight{#2}
    \edef\heightsequence{\xintSeq[+1]{+1}{\matHeightResult}}%
    %
    \def\matlist{\xintCSVtoList{#3}}
    \edef\elemsRow{\xintNthElt{1}{\xintNthElt{1}{\matlist}}}
    \edef\widthsequence{\xintSeq[+1]{+1}{\expandafter\xintLength\expandafter{\elemsRow}}}%
    % \edef\elemsMat{\xintNthElt{1}{\matlist}}
    % \edef\heightsequence{\xintSeq[+1]{+1}{\expandafter\xintLength\expandafter{\elemsMat}}}%
    %
    \newEmptyMat{#1}
    \xintFor* ##2 in \heightsequence \do {%
        \xintFor* ##3 in \widthsequence \do {%
            \FPset\tmpValue{\xintNthElt{##3}{\xintNthElt{##2}{#2}}}
            \xintifForFirst{%
                \xintFor* ##1 in \matlist \do {%
                    \FPsub\tmpValue\tmpValue{\xintNthElt{##3}{\xintNthElt{##2}{##1}}}
                }
                \newVec{rowVec}{\tmpValue}
            }{%
                \xintFor* ##1 in \matlist \do {%
                    \FPsub\tmpValue\tmpValue{\xintNthElt{##3}{\xintNthElt{##2}{##1}}}
                }
                \appendToVec{rowVec}{\rowVec}{\tmpValue}
            }
        }
        \appendRowToMat{#1}{\csname #1\endcsname}{\rowVec}
    }
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash mulMatScalar}{macro:mulMatScalar_impl}
% \begin{macro}{\mulMatScalar}
% Multiply the given matrix with a scalar.
% 
% \#1 - out: var name to save the result (matrix) to\\
% \#2 - matrix: the matrix to multiply\\
% \#3 - scalar: the scalar to multiply with
%    \begin{macrocode}
\newcommand\mulMatScalar[3][mulMatScalarResult]{%
    \if\noexpand#1\relax
        \PackageError{glmatrix package}{argument mismatch}{Argument 1 of mulMatScalar seems to be a command but must be a string. If it is not a command you might have used two identical letter at the beginning of the argument, please change that.}
    \else
    \fi
    \if\noexpand#2\relax
    \else
        \PackageError{glmatrix package}{argument mismatch}{argument 2 of mulMatScalar does not seem to be a command}
    \fi
    \edef\elemOne{\xintNthElt{1}{#2}}
    \edef\innersequence{\xintSeq[+1]{+1}{\expandafter\xintLength\expandafter{\elemOne}}}%
    %
    \newEmptyMat{#1}
    \xintFor* ##1 in #2 \do {%
        \xintFor* ##2 in \innersequence \do {%
            \FPset\elem{\xintNthElt{##2}{##1}}
            \FPmul\elem\elem{#3}
            \xintifForFirst{%
                \newVec{rowVec}{\elem}
            }{%
                \appendToVec{rowVec}{\rowVec}{\elem}
            }
        }
        \appendRowToMat{#1}{\csname #1\endcsname}{\rowVec}
    }
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash mulMatVec}{macro:mulMatVec_impl}
% \begin{macro}{\mulMatVec}
% Multiply the given matrix with a vector (for transformation).
% 
% \#1 - out: var name to save the result (vector) to\\
% \#2 - matrix: the matrix to transform the vetor with\\
% \#3 - vector: the vector to transform
%    \begin{macrocode}
\newcommand\mulMatVec[3][mulMatVecResult]{%
    \if\noexpand#1\relax
        \PackageError{glmatrix package}{argument mismatch}{Argument 1 of transformVec seems to be a command but must be a string. If it is not a command you might have used two identical letter at the beginning of the argument, please change that.}
    \else
    \fi
    \if\noexpand#2\relax
    \else
        \PackageError{glmatrix package}{argument mismatch}{argument 2 of transformVec does not seem to be a command}
    \fi
    \if\noexpand#3\relax
    \else
        \PackageError{glmatrix package}{argument mismatch}{argument 3 of transformVec does not seem to be a command}
    \fi
    \getVecHeight{#3}%
    \getMatHeight{#2}%
    \getMatWidth{#2}%
    % Check that matrix and vector can be multiplied
    \FPifeq{\matWidthResult}{\vecHeightResult}
    \else
        \PackageError{glmatrix package}{Dimension mismatch for matrix and vector, could not multiply}{width (\matWidthResult) of matrix #2 and height (\vecHeightResult) of vector #3 do not match}
    \fi
    % Create iterator sequences from height of vector and matrix
    \edef\vecHeightSequence{\xintSeq[+1]{+1}{\vecHeightResult}}%
    \edef\matHeightSequence{\xintSeq[+1]{+1}{\matHeightResult}}%
    % Iterate all rows of the matrix
    \xintFor* ##2 in \matHeightSequence \do {%
        \FPset\cellVal{0}
        % Differentiate between first and other entries to create the new vector variable
        \xintifForFirst{%
            % Now iterate each entry of the current row
            % Use this indec to access the entry in the matrix and in the vector
            \xintFor* ##3 in \vecHeightSequence \do {%
                \FPmul\tmp{%
                    \xintNthElt{##3}{\xintNthElt{##2}{#2}}%
                }{%
                    \xintNthElt{##3}{#3}%
                }
                % Add to storage variable
                \FPadd\cellVal\cellVal\tmp
            }
            \FPclip\cellVal\cellVal
            \newVec{#1}{\cellVal}
        }{
            \xintFor* ##3 in \vecHeightSequence \do {%
                \FPmul\tmp{%
                    \xintNthElt{##3}{\xintNthElt{##2}{#2}}%
                }{%
                    \xintNthElt{##3}{#3}%
                }
                \FPadd\cellVal\cellVal\tmp
            }
            \FPclip\cellVal\cellVal
            \appendToVec{#1}{\csname #1\endcsname}{\cellVal}
        }
    }
    % Test if width and height is correct
    \expandafter\getVecHeight\expandafter{\csname #1\endcsname}%
    \FPifeq{\matHeightResult}{\vecHeightResult}
    \else
        \PackageError{glmatrix package}{Vector height does not match expectation}{height of vector is \vecHeightResult but should be \matHeightResult}
    \fi
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash mulMat}{macro:mulMat_impl}
% \begin{macro}{\mulMat}
% Multiply the given matrix with another matrix.
% 
% \#1 - out: var name to save the result (matrix) to\\
% \#2 - matrix M: the matrix to multiply\\
% \#3 - matrix N: the matrix to multiply with
%    \begin{macrocode}
\newcommand\mulMat[3][mulMatResult]{%
    \edef\elemsRow{\xintNthElt{1}{#3}}
    \edef\widthsequence{\xintSeq[+1]{+1}{\expandafter\xintLength\expandafter{\elemsRow}}}%
    %
    % TODO remove one of these
    \edef\elemsMat{#2}
    \edef\heightsequence{\xintSeq[+1]{+1}{\expandafter\xintLength\expandafter{\elemsMat}}}%
    %
    \edef\elemsMat{#3}
    \edef\heightsequenceB{\xintSeq[+1]{+1}{\expandafter\xintLength\expandafter{\elemsMat}}}%
    %
    \edef\elemsRowTmp{\xintNthElt{1}{#2}}
    \FPset\widthMatA{\expandafter\xintLength\expandafter{\elemsRowTmp}}%
    \FPset\heightMatB{\expandafter\xintLength\expandafter{\elemsMat}}%
    % TODO check this
    \FPifeq{\widthMatA}{\heightMatB}
    \else
        \PackageError{glmatrix package}{Dimension mismatch for matrix, could not multiply}{width (\widthMatA) of matrix #2 and height (\heightMatB) of matrix #3 do not match}
    \fi
    %
    \newEmptyMat{#1}
    \xintFor* ##2 in \heightsequence \do {%
        \xintFor* ##3 in \widthsequence \do {%
            \FPset\tmpValue{0}
            \xintifForFirst{%
                \xintFor* ##4 in \heightsequenceB \do {%
                    \FPmul\tmptmp{%
                        \xintNthElt{##4}{\xintNthElt{##2}{#2}}%
                    }{%
                        \xintNthElt{##3}{\xintNthElt{##4}{#3}}%
                    }
                    \FPadd\tmpValue\tmpValue\tmptmp
                }
                \newVec{rowVec}{\tmpValue}
            }{%
                \xintFor* ##4 in \heightsequenceB \do {%
                    \FPmul\tmptmp{%
                        \xintNthElt{##4}{\xintNthElt{##2}{#2}}%
                    }{%
                        \xintNthElt{##3}{\xintNthElt{##4}{#3}}%
                    }
                    \FPadd\tmpValue\tmpValue\tmptmp
                }
                \appendToVec{rowVec}{\rowVec}{\tmpValue}
            }
        }
        \appendRowToMat{#1}{\csname #1\endcsname}{\rowVec}
    }
    % Test if width and height is correct
    \edef\expectedheight{\expandafter\xintLength\expandafter{#2}}%
    \edef\elemsRow{\xintNthElt{1}{#3}}
    \edef\expectedwidth{\expandafter\xintLength\expandafter{\elemsRow}}%
    %
    \edef\elemsRow{\xintNthElt{1}{\csname #1\endcsname}}
    \edef\actualwidth{\expandafter\xintLength\expandafter{\elemsRow}}%
    \edef\elemsMat{\csname #1\endcsname}
    \edef\actualheight{\expandafter\xintLength\expandafter{\elemsMat}}%
    %
    \FPifeq{\expectedwidth}{\actualwidth}
    \else
        \PackageError{glmatrix package}{Matrix width does not match expectation}{width seems to be incorrect}
    \fi
    \FPifeq{\expectedheight}{\actualheight}
    \else
        \PackageError{glmatrix package}{Matrix height does not match expectation}{height seems to be incorrect}
    \fi
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash getMatTranslation}{macro:getMatTranslation_impl}
% \begin{macro}{\getMatTranslation}
% Get the translation component from the given matrix.
% 
% \#1 - out: var name to save the result (vector) to\\
% \#2 - matrix: the matrix to extract the translation from
%    \begin{macrocode}
\newcommand\getMatTranslation[2][matTranslationResult]{%
    \getMatWidth{#2}
    \getMatHeight{#2}
    \edef\sequence{\xintSeq[+1]{+1}{\matHeightResult}}
    \xintFor* ##1 in \sequence \do {%
        \FPset\tmpValue{\xintNthElt{\matWidthResult}{\xintNthElt{##1}{#2}}}
        \xintifForFirst{%
            \newVec{#1}{\tmpValue}
        }{%
            \xintifForLast{}{
                \appendToVec{#1}{\csname #1\endcsname}{\tmpValue}
            }
        }
    }
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash detMat}{macro:detMat_impl}
% \begin{macro}{\detMat}
% Get the determinate of the given matrix.
% 
% \#1 - out: var name to save the result (scalar) to\\
% \#2 - matrix: the matrix to calculate the determinate for
%    \begin{macrocode}
\newcommand\detMat[2][detMatResult]{%
    \getMatWidth{#2}
    \getMatHeight{#2}
    \FPifgt{\matWidthResult}{2}
        \PackageError{glmatrix package}{Function not yet implemented}{Determinante can only be calculated for \(2 \times 2\) matrices}
    \else
    \fi
    \FPifgt{\matHeightResult}{2}
        \PackageError{glmatrix package}{Function not yet implemented}{Determinante can only be calculated for \(2 \times 2\) matrices}
    \else
    \fi
    %
    \mulScalar[tmpAD]{\xintNthElt{1}{\xintNthElt{1}{#2}}}{\xintNthElt{2}{\xintNthElt{2}{#2}}}
    \mulScalar[tmpBC]{\xintNthElt{1}{\xintNthElt{2}{#2}}}{\xintNthElt{2}{\xintNthElt{1}{#2}}}
    \subScalar[#1]{\tmpAD}{\tmpBC}
}
%    \end{macrocode}
% \end{macro}

% \subsection{scalar}
% \begin{center}
% \begin{tabularx}{\textwidth}{l p{8cm}} \hline
% \textbf{Command} & \textbf{Arguments} \\ \hline
% \ref{macro:newScalar_impl} & \makecell[t{p{8cm}}]{\marg{out}, \marg{scalar}} \\
% \ref{macro:newScalarPi_impl} & \makecell[t{p{8cm}}]{\marg{out}, \marg{scalar}} \\
% \ref{macro:newScalarFraction_impl} & \makecell[t{p{8cm}}]{\marg{out}, \marg{scalar n}, \marg{scalar d}} \\
% \ref{macro:randomScalar_impl} & \makecell[t{p{8cm}}]{\marg{out}, \marg{lower bound}, \marg{upper bound}} \\
% \ref{macro:copyScalar_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{scalar}\\scalarCopyResult} \\
% \ref{macro:setScalar_impl} & \makecell[t{p{8cm}}]{\marg{out}, \marg{scalar}} \\
% \ref{macro:zeroScalar_impl} & \makecell[t{p{8cm}}]{\marg{out}} \\
% \ref{macro:printScalar_impl} & \makecell[t{p{8cm}}]{\oarg{fraction}, \marg{scalar}\\0} \\
% \ref{macro:printScalarAsPi_impl} & \makecell[t{p{8cm}}]{\oarg{fraction}, \marg{scalar}\\0} \\
% \ref{macro:printPiScalarInDegree_impl} & \makecell[t{p{8cm}}]{\oarg{fraction}, \marg{scalar}\\0} \\
% \ref{macro:printScalarRounded_impl} & \makecell[t{p{8cm}}]{\oarg{digits}, \marg{scalar}\\4} \\
% \ref{macro:roundScalar_impl} & \makecell[t{p{8cm}}]{\oarg{digits}, \marg{scalar}\\4} \\
% \ref{macro:ceilScalar_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{scalar}\\scalarCeilResult} \\
% \ref{macro:floorScalar_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{scalar}\\scalarFloorResult} \\
% \ref{macro:clipScalar_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{scalar}\\clipScalarResult} \\
% \ref{macro:radianToDegree_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{scalar}\\radianToDegreeResult} \\
% \ref{macro:toRadian_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{scalar}\\degreeToRadianResult} \\
% \ref{macro:addScalar_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{scalar s}, \marg{scalar t}\\scalarAddResult} \\
% \ref{macro:subScalar_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{scalar s}, \marg{scalar t}\\scalarSubResult} \\
% \ref{macro:mulScalar_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{scalar s}, \marg{scalar t}\\scalarMulResult} \\
% \ref{macro:divScalar_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{scalar s}, \marg{scalar t}\\scalarDivResult} \\
% \ref{macro:powScalar_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{scalar s}, \marg{scalar t}\\scalarPowResult} \\
% \ref{macro:negateScalar_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{scalar}\\scalarNegateResult} \\
% \ref{macro:arccosScalar_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{scalar}\\scalarArccosResult} \\
% \ref{macro:mulAndAddScalar_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{scalar s}, \marg{scalar t}, \marg{scalar u}\\scalarMulAndAddResult} \\
% \ref{macro:lerpScalar_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{scalar i}, \marg{scalar j}, \marg{scalar t}\\lerpScalarResult} \\
% \ref{macro:minScalar_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{scalar s}, \marg{scalar t}\\minScalarResult} \\
% \ref{macro:maxScalar_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{scalar s}, \marg{scalar t}\\maxScalarResult} \\
% \ref{macro:betweenScalar_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{scalar}, \marg{lower bound}, \marg{upper bound}\\betweenScalarResult} \\
% \ref{macro:forEachScalar_impl} & \makecell[t{p{8cm}}]{\marg{input}, \marg{macro}, \marg{args}} \\
% \end{tabularx}
% \end{center}


% \setlabel{\textbackslash newScalar}{macro:newScalar_impl}
% \begin{macro}{\newScalar}
% Create a new scalar and assign the given value.
% 
% \#1 - out: var name to save the result (scalar) to\\
% \#2 - scalar: scalar value that is assigned to out
%    \begin{macrocode}
\newcommand\newScalar[2]{%
    \expandafter\edef\csname #1\endcsname{#2}%
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash newScalarPi}{macro:newScalarPi_impl}
% \begin{macro}{\newScalarPi}
% Create a new scalar and assign the given value as a multiple of pi.
% 
% \#1 - out: var name to save the result (scalar) to\\
% \#2 - scalar: scalar value that is multiplied with pi and assigned to out
%    \begin{macrocode}
\newcommand\newScalarPi[2]{
    \FPmul\divNumRes{\FPpi}{#2}
    \expandafter\edef\csname #1\endcsname{\divNumRes}%
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash newScalarFraction}{macro:newScalarFraction_impl}
% \begin{macro}{\newScalarFraction}
% Create a scalar from a given fraction
% 
% \#1 - out: var name to save the result (scalar) to\\
% \#2 - scalar n: nominator\\
% \#3 - scalar d: denominator
%    \begin{macrocode}
\newcommand\newScalarFraction[3]{
    \FPdiv\divNumRes{#2}{#3}
    \expandafter\edef\csname #1\endcsname{\divNumRes}%
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash randomScalar}{macro:randomScalar_impl}
% \begin{macro}{\randomScalar}
% Create a new scalar variable with a random value between lower and
% upper bound. The value is obtained by creating a random value between 0 and 1
% and then interpolating between lower and upper bound.
% 
% \#1 - out: var name to save the result (scalar) to\\
% \#2 - lower bound: scalar that limits the possible values at the bottom\\
% \#3 - upper bound: scalar that limits the possible values at the top
%    \begin{macrocode}
\newcommand\randomScalar[3]{%
    \FPrandom\tmp
    \lerpScalar[#1]{#2}{#3}{\tmp}
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash copyScalar}{macro:copyScalar_impl}
% \begin{macro}{\copyScalar}
% Copy the value of one scalar variable to another.
% 
% \#1 - out: var name to save the result (scalar) to\\
% \#2 - scalar: scalar which value is assigned to out
%    \begin{macrocode}
\newcommand\copyScalar[2][scalarCopyResult]{%
    \setScalar{#1}{#2}
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash setScalar}{macro:setScalar_impl}
% \begin{macro}{\setScalar}
% Set the value of a given scalar.
% 
% \#1 - out: var name to save the result (scalar) to\\
% \#2 - scalar: scalar value that is assigned to out
%    \begin{macrocode}
\newcommand\setScalar[2]{%
    \newScalar{#1}{#2}
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash zeroScalar}{macro:zeroScalar_impl}
% \begin{macro}{\zeroScalar}
% Set or create a scalar with value 0.
% 
% \#1 - out: var name to save the result (scalar) to
%    \begin{macrocode}
\newcommand\zeroScalar[1]{%
    \expandafter\edef\csname #1\endcsname{0}%
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash printScalar}{macro:printScalar_impl}
% \begin{macro}{\printScalar}
% Print the value of the given scalar.
% 
% \#1 - fraction: whether or not the value should be printed as a fraction (val=1)\\
% \#2 - scalar: the scalar that should be printed
%    \begin{macrocode}
\newcommand\printScalar[2][0]{%
    \FPifeq{#1}{0}%
        \roundScalar{#2}%
        \scalarRoundResult%
    \else%
        \numToFractionA{#2}%
    \fi%
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash printScalarAsPi}{macro:printScalarAsPi_impl}
% \begin{macro}{\printScalarAsPi}
% Print the value of the given scalar as a multiple of Pi.
% 
% \#1 - fraction: whether or not the value should be printed as a fraction (val=1)\\
% \#2 - scalar: the scalar that should be printed
%    \begin{macrocode}
\newcommand\printScalarAsPi[2][0]{%
    \FPdiv\divNumRes{#2}{\FPpi}
    \FPifeq{#1}{0}
        \roundScalar{\divNumRes}
        \scalarRoundResult
    \else
        \numToFractionA{\divNumRes}
    \fi
    \pi
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash printPiScalarInDegree}{macro:printPiScalarInDegree_impl}
% \begin{macro}{\printPiScalarInDegree}
% Print the value of the given scalar in degree.
% This macro does do a conversion and therefore expects the input to be in radian.
% A degree sign is automatically added.
% 
% \#1 - fraction: whether or not the value should be printed as a fraction (val=1)\\
% \#2 - scalar: the value that schould be printed
%    \begin{macrocode}
\newcommand\printPiScalarInDegree[2][0]{%
    \FPmul\tmp{#2}{180}
    \FPdiv\divNumRes{\tmp}{\FPpi}
    \FPifeq{#1}{0}
        \roundScalar{\divNumRes}
        \scalarRoundResult
    \else
        \numToFractionA{\divNumRes}
    \fi
    ^\circ
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash printScalarRounded}{macro:printScalarRounded_impl}
% \begin{macro}{\printScalarRounded}
% Print the rounded value of the given scalar.
% 
% \#1 - digits: number of digits after comma\\
% \#2 - scalar: the value that schould be printed
%    \begin{macrocode}
\newcommand\printScalarRounded[2][4]{%
    \FPround\tmp{#2}{#1}
    \FPclip\tmp\tmp
    \tmp
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash roundScalar}{macro:roundScalar_impl}
% \begin{macro}{\roundScalar}
% Round the value ot the given scalar and save it.
% 
% \#1 - digits: number of digits after comma\\
% \#2 - scalar: the value that schould be rounded
%    \begin{macrocode}
\newcommand\roundScalar[2][4]{%
    \FPround\tmp{#2}{#1}%
    \FPclip\tmp\tmp%
    \newScalar{scalarRoundResult}{\tmp}%
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash ceilScalar}{macro:ceilScalar_impl}
% \begin{macro}{\ceilScalar}
% Ceil the value of the given scalar.
% 
% \#1 - out: var name to save the result (scalar) to\\
% \#2 - scalar: the scalar that schould be ceiled
%    \begin{macrocode}
\newcommand\ceilScalar[2][scalarCeilResult]{
    \FPtrunc\tmp{#2}{0}
    \FPset\tmpSave{\tmp}
    %
    \FPifpos{#2}
        \FPadd\tmpSave{\tmp}{1}
    \else
    \fi
    \FPifint{#2}
        \FPset\tmpSave{\tmp}
    \else
    \fi
    \newScalar{#1}{\tmpSave}
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash floorScalar}{macro:floorScalar_impl}
% \begin{macro}{\floorScalar}
% Floor the value of the given scalar.
% 
% \#1 - out: var name to save the result (scalar) to\\
% \#2 - scalar: the scalar that schould be floored
%    \begin{macrocode}
\newcommand\floorScalar[2][scalarFloorResult]{
    \FPtrunc\tmp{#2}{0}
    \FPset\tmpSave{\tmp}
    %
    \FPifneg{#2}
        \FPsub\tmpSave{\tmp}{1}
    \else
    \fi
    \FPifint{#2}
        \FPset\tmpSave{\tmp}
    \else
    \fi
    \newScalar{#1}{\tmpSave}
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash clipScalar}{macro:clipScalar_impl}
% \begin{macro}{\clipScalar}
% Remove all trailing zeros from the value of the given scalar.
% 
% \#1 - out: var name to save the result (scalar) to\\
% \#2 - scalar: the scalar from which the zeros should be removed
%    \begin{macrocode}
\newcommand\clipScalar[2][clipScalarResult]{
    \FPclip\tmp{#2}
    \newScalar{#1}{\tmp}
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash radianToDegree}{macro:radianToDegree_impl}
% \begin{macro}{\radianToDegree}
% Convert the value of the given scalar to degree.
% 
% \#1 - out: var name to save the result (scalar) to\\
% \#2 - scalar: the scalar which to convert
%    \begin{macrocode}
\newcommand\radianToDegree[2][radianToDegreeResult]{
    \FPmul\tmp{#2}{180}
    \FPdiv\tmp{\tmp}{\FPpi}
    \newScalar{#1}{\tmp}
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash toRadian}{macro:toRadian_impl}
% \begin{macro}{\toRadian}
% Convert the value of the given scalar to radian.
% 
% \#1 - out: var name to save the result (scalar) to\\
% \#2 - scalar: the scalar which to convert
%    \begin{macrocode}
\newcommand\toRadian[2][degreeToRadianResult]{
    \FPdiv\tmp{#2}{180}
    \FPmul\tmp{\tmp}{\FPpi}
    \newScalar{#1}{\tmp}
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash addScalar}{macro:addScalar_impl}
% \begin{macro}{\addScalar}
% Add the values of two scalars.
% 
% \#1 - out: var name to save the result (scalar) to\\
% \#2 - scalar s: the first scalar of the sum\\
% \#3 - scalar t: the second scalar of the sum
%    \begin{macrocode}
\newcommand\addScalar[3][scalarAddResult]{%
    \FPadd\tmp{#2}{#3}
    \newScalar{#1}{\tmp}
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash subScalar}{macro:subScalar_impl}
% \begin{macro}{\subScalar}
% Subtract the values of two scalars.
% 
% \#1 - out: var name to save the result (scalar) to\\
% \#2 - scalar s: the scalar to subtract from\\
% \#3 - scalar t: the scalar to subtract
%    \begin{macrocode}
\newcommand\subScalar[3][scalarSubResult]{%
    \FPsub\tmp{#2}{#3}
    \newScalar{#1}{\tmp}
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash mulScalar}{macro:mulScalar_impl}
% \begin{macro}{\mulScalar}
% Multiply the values of two scalars.
% 
% \#1 - out: var name to save the result (scalar) to\\
% \#2 - scalar s: the scalar to multiply\\
% \#3 - scalar t: the scalar with which to multply
%    \begin{macrocode}
\newcommand\mulScalar[3][scalarMulResult]{
    \FPmul\tmp{#2}{#3}
    \newScalar{#1}{\tmp}
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash divScalar}{macro:divScalar_impl}
% \begin{macro}{\divScalar}
% Divide the values of two scalars.
% 
% \#1 - out: var name to save the result (scalar) to\\
% \#2 - scalar s: the scalar to divide\\
% \#3 - scalar t: the scalar to divide with
%    \begin{macrocode}
\newcommand\divScalar[3][scalarDivResult]{%
    \FPifeq{#3}{0}
        \PackageError{glmatrix package}{In divScalar function: division by zero}{parameter 3 is zero therefore you are trying to divide by 0}
    \else
    \fi
    \FPdiv\tmp{#2}{#3}
    \newScalar{#1}{\tmp}
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash powScalar}{macro:powScalar_impl}
% \begin{macro}{\powScalar}
% Raise the values of one scalar by another.
% 
% \#1 - out: var name to save the result (scalar) to\\
% \#2 - scalar s: the scalar to raise\\
% \#3 - scalar t: the scalar with which to raise
%    \begin{macrocode}
\newcommand\powScalar[3][scalarPowResult]{%
    \FPpow\tmp{#2}{#3}
    \newScalar{#1}{\tmp}
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash negateScalar}{macro:negateScalar_impl}
% \begin{macro}{\negateScalar}
% Negate the value of the given scalar.
% 
% \#1 - out: var name to save the result (scalar) to\\
% \#2 - scalar: the scalar to negate
%    \begin{macrocode}
\newcommand\negateScalar[2][scalarNegateResult]{%
    \FPneg\tmp{#2}
    \newScalar{#1}{\tmp}
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash arccosScalar}{macro:arccosScalar_impl}
% \begin{macro}{\arccosScalar}
% Get the arccos of the value of the given scalar.
% 
% \#1 - out: var name to save the result (scalar) to\\
% \#2 - scalar: the scalar to calculate the arccos for
%    \begin{macrocode}
\newcommand\arccosScalar[2][scalarArccosResult]{%
    \FPround\tmp{#2}{10}
    \FPclip\tmp\tmp
    \FParccos\tmp\tmp
    \newScalar{#1}{\tmp}
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash mulAndAddScalar}{macro:mulAndAddScalar_impl}
% \begin{macro}{\mulAndAddScalar}
% Adds two scalars after multiplying the second one by a scalar.
% 
% \#1 - out: var name to save the result (scalar) to\\
% \#2 - scalar s: the scalar to add to\\
% \#3 - scalar t: the scalar that is multiplied and then added\\
% \#4 - scalar u: the scalar that is the muliplier
%    \begin{macrocode}
\newcommand\mulAndAddScalar[4][scalarMulAndAddResult]{%
    \FPmul\tmp{#3}{#4}
    \FPadd\tmp{#2}{\tmp}
    \newScalar{#1}{\tmp}
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash lerpScalar}{macro:lerpScalar_impl}
% \begin{macro}{\lerpScalar}
% Lineraly interpolate between values of two scalars.
% 
% \#1 - out: var name to save the result (scalar) to\\
% \#2 - scalar i: the start scalar\\
% \#3 - scalar j: the end scalar\\
% \#4 - scalar t: interpolation amount range [0-1]
%    \begin{macrocode}
\newcommand\lerpScalar[4][lerpScalarResult]{%
    \FPsub\tmpA{1}{#4}
    \FPmul\tmpA{#2}\tmpA
    \FPmul\tmpB{#3}{#4}
    \FPadd\tmpA\tmpA\tmpB
    \newScalar{#1}{\tmpA}
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash minScalar}{macro:minScalar_impl}
% \begin{macro}{\minScalar}
% Return the minimum of two scalar values.
% 
% \#1 - out: var name to save the result (scalar) to\\
% \#2 - scalar s: the first scalar\\
% \#3 - scalar t: the second scalar
%    \begin{macrocode}
\newcommand\minScalar[3][minScalarResult]{%
    % TODO use \FPmin#1#2#3
    \FPiflt{#2}{#3}
        \expandafter\edef\csname #1\endcsname{#2}%
    \else
        \expandafter\edef\csname #1\endcsname{#3}%
    \fi
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash maxScalar}{macro:maxScalar_impl}
% \begin{macro}{\maxScalar}
% Return the maximum of two scalar values.
% 
% \#1 - out: var name to save the result (scalar) to\\
% \#2 - scalar s: first scalar value\\
% \#3 - scalar t: second scalar value
%    \begin{macrocode}
\newcommand\maxScalar[3][maxScalarResult]{%
    % TODO use \FPmax#1#2#3
    \FPiflt{#2}{#3}
        \expandafter\edef\csname #1\endcsname{#3}%
    \else
        \expandafter\edef\csname #1\endcsname{#2}%
    \fi
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash betweenScalar}{macro:betweenScalar_impl}
% \begin{macro}{\betweenScalar}
% Return whether a scalar lies between two other values.
% 
% \#1 - out: var name to save the result (scalar) to (0 or 1)\\
% \#2 - scalar: the scalar to test\\
% \#3 - lower bound: \#2 needs to be greater then this for this macro to return 1\\
% \#4 - upper bound: \#2 needs to be smaller than this for this macro to return 1
%    \begin{macrocode}
\newcommand\betweenScalar[4][betweenScalarResult]{%
    \FPset\betweenScalarResult{0}
    \FPiflt{#2}{#3}
    \else
        \FPadd\betweenScalarResult\betweenScalarResult{1}
    \fi
    \FPifgt{#2}{#4}
    \else
        \FPadd\betweenScalarResult\betweenScalarResult{1}
    \fi
    % TODO
    \FPifeq{\betweenScalarResult}{2}
        % \FPset\betweenScalarResult{1}
        \expandafter\edef\csname #1\endcsname{1}%
    \else
        % \FPset\betweenScalarResult{0}
        \expandafter\edef\csname #1\endcsname{0}%
    \fi
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash forEachScalar}{macro:forEachScalar_impl}
% \begin{macro}{\forEachScalar}
% Apply the given function to a list of variables.
% 
% \#1 - input: list of commands (var names) that should be altered\\
% \#2 - macro: the chosen function\\
% \#3 - args: params for function
%    \begin{macrocode}
\newcommand\forEachScalar[3]{
    \FPiflt{#2}{10}
    \else
        \PackageError{glmatrix package}{In forEach scalar}{selection function that is not implemented (chose between 1 to 9 for parameter 2)}
    \fi
    %
    \def\varList{\xintCSVtoList{#1}}
    \def\paramList{\xintCSVtoList{#3}}
    \xintFor* ##1 in \varList \do {%
        \FPifeq{#2}{1}
            \addScalar[##1]{\csname ##1\endcsname}{\xintNthElt{1}{\paramList}}
        \else
        \fi
        \FPifeq{#2}{2}
            \subScalar[##1]{\csname ##1\endcsname}{\xintNthElt{1}{\paramList}}
        \else
        \fi
        \FPifeq{#2}{3}
            \mulScalar[##1]{\csname ##1\endcsname}{\xintNthElt{1}{\paramList}}
        \else
        \fi
        \FPifeq{#2}{4}
            \divScalar[##1]{\csname ##1\endcsname}{\xintNthElt{1}{\paramList}}
        \else
        \fi
        \FPifeq{#2}{5}
            \powScalar[##1]{\csname ##1\endcsname}{\xintNthElt{1}{\paramList}}
        \else
        \fi
        \FPifeq{#2}{6}
            \negateScalar[##1]{\csname ##1\endcsname}
        \else
        \fi
        \FPifeq{#2}{7}
            \lerpScalar[##1]{\csname ##1\endcsname}{\xintNthElt{1}{\paramList}}{\xintNthElt{2}{\paramList}}
        \else
        \fi
        \FPifeq{#2}{8}
            \mulAndAddScalar[##1]{\csname ##1\endcsname}{\xintNthElt{1}{\paramList}}{\xintNthElt{2}{\paramList}}
        \else
        \fi
        \FPifeq{#2}{9}
            \arccosScalar[##1]{\csname ##1\endcsname}
        \else
        \fi
    }
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash fractionToNum}{macro:fractionToNum_impl}
% \begin{macro}{\fractionToNum}
% Convert a fraction with root to a decimal number
% 
%    \begin{macrocode}
\newcommand\fractionToNum[3]{%
    \FProot\tmpA{#3}{2}
    \FPmul\tmpA\tmpA{#2}
    \FPdiv\tmpB{#1}\tmpA
    \FPset\fractionNumRes{\tmpB}
    \ensuremath{
        \tmpB
    }
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash solutionC}{macro:solutionC_impl}
% \begin{macro}{\solutionC}
% Convert a decimal number to a fraction with root
% 
%    \begin{macrocode}
\newcommand\solutionC{%
    \FPset\finalmul{1}
    \FPset\tmptmptmptmp\tmptmptmp
    %
    \edef\innersequence{\xintSeq[+1]{+1}{+10}}%
    \xintFor* ##1 in \innersequence \do {%
        \FPtrunc\floored\tmptmptmptmp{0}
        \FPsub\remainder\tmptmptmptmp\floored
        \FPifgt{\remainder}{0.00001}
            \FPdiv\mulmul{1}{\remainder}
            \FPmul\finalmul\finalmul\mulmul
        \else
            \xintBreakFor
        \fi
        \FPset\tmptmptmptmp\mulmul
    }
    \FPround\finalmul\finalmul{8}
    \FPclip\finalmul\finalmul
    \FPset\finalmultmp\finalmul
    % The result will be a multiplicator that is able to round
    % the number to a whole number, but the result might not be a
    % nice number to root e.g. 8/sqrt(6), 0.09375 will result in 32
    % 0.09375 * 32 = 3, but sqrt(32) = 5,65.. but given this we know
    % that the searched for number must be a multiple of 32, in this case 64
    % Note: rounding to 6 & 36 does not work since 0.09375 * 36 = 3.375
    \xintFor* ##1 in \innersequence \do {%
        \FProot\finalmulsqrt\finalmultmp{2}
        \FPround\finalmulsqrt\finalmulsqrt{4}
        \FPclip\finalmulsqrt\finalmulsqrt
        \FPifint{\finalmulsqrt}
            \xintBreakFor
        \else
            \FPadd\finalmultmp\finalmultmp\finalmul
        \fi
    }
    \FPset\finalmul\finalmultmp
    \FProot\finalmulsqrt\finalmul{2}
    \FPround\finalmulsqrt\finalmulsqrt{4}
    \FPclip\finalmulsqrt\finalmulsqrt
    \FPmul\divisor\divisor\finalmul
    \FPmul\dividend\dividend\finalmulsqrt
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash numToFraction}{macro:numToFraction_impl}
% \begin{macro}{\numToFraction}
% 
%    \begin{macrocode}
\newcommand\numToFraction[1]{%
    \FPset\dividend{1}
    \FPset\divisor{#1}
    \FPset\minusSign{1}
    \FPiflt{\divisor}{0}
        \FPset\minusSign{-1}
    \else
    \fi
    \ensuremath{
        % reverse fraction
        \FPdiv\divisor{1}{#1}
        % Reverse root
        % Use FPmul instead of FPpow to allow for neg values
        \FPmul\divisor\divisor\divisor
        \FPset\tmptmptmp\divisor
        \FPround\divisor\divisor{10}
        \FPclip\divisor\divisor
        \FPifint{\divisor}
        \else
            \solutionC
        \fi
        %
        \FPround\divisor\divisor{4}
        \FPclip\divisor\divisor
        \FPmul\dividend\dividend\minusSign
        \FPround\dividend\dividend{4}
        \FPclip\dividend\dividend
        % TODO this should not be necessary
        \FPset\outputVar{#1}
        % Create fraction from dividend and divisor
        \FPset\outputVar{\frac{\dividend}{\sqrt{\divisor}}}
        % If the sqrt can be resolved
        \FPset\tmpDivisor{\divisor}
        \FProot\tmpDivisor\tmpDivisor{2}
        \FPround\tmpDivisor\tmpDivisor{8}
        \FPclip\tmpDivisor\tmpDivisor
        \FPifint{\tmpDivisor}
            \FPset\outputVar{\frac{\dividend}{\tmpDivisor}}
        \else
        \fi
        %
        \FPset\inputVar{#1}
        \FPmul\inputVar\inputVar\inputVar
        \FPmul\inputVar\inputVar\minusSign
        \FPround\inputVar\inputVar{8}
        \FPclip\inputVar\inputVar
        \FPifint{\inputVar}
            \FPset\outputVar{\,\sqrt{\inputVar}}
        \else
        \fi
        % If #1 was an int all along
        \FPset\inputVarA{#1}
        \FPround\inputVarA\inputVarA{10}
        \FPclip\inputVarA\inputVarA
        \FPifint{\inputVarA}
            \FPset\outputVar{\inputVarA}
        \else
        \fi
        \outputVar
    }
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash numToFractionA}{macro:numToFractionA_impl}
% \begin{macro}{\numToFractionA}
% 
%    \begin{macrocode}
\newcommand\numToFractionA[1]{%
    \FPset\inputVarA{#1}
    \FPround\inputVarA\inputVarA{10}
    \FPclip\inputVarA\inputVarA
    % Prevent division by 0
    \FPifint{\inputVarA}
        \FPset\outputVar{\inputVarA}
        \outputVar
    \else
        \numToFraction{#1}
    \fi
}
%    \end{macrocode}
% \end{macro}

% \subsection{vector}
% \begin{center}
% \begin{tabularx}{\textwidth}{l p{8cm}} \hline
% \textbf{Command} & \textbf{Arguments} \\ \hline
% \ref{macro:newVec_impl} & \makecell[t{p{8cm}}]{\marg{out}, \marg{values}} \\
% \ref{macro:newVecPi_impl} & \makecell[t{p{8cm}}]{\marg{out}, \marg{values}} \\
% \ref{macro:randomVec_impl} & \makecell[t{p{8cm}}]{\marg{out}, \marg{dimensions}, \marg{lower bound}, \marg{upper bound}} \\
% \ref{macro:copyVec_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector}\\copyVecResult} \\
% \ref{macro:zeroVec_impl} & \makecell[t{p{8cm}}]{\oarg{dims}, \marg{out}\\3} \\
% \ref{macro:appendToVec_impl} & \makecell[t{p{8cm}}]{\marg{out}, \marg{vector}, \marg{scalar}} \\
% \ref{macro:printVec_impl} & \makecell[t{p{8cm}}]{\oarg{fraction}, \marg{vector}\\0} \\
% \ref{macro:printVecT_impl} & \makecell[t{p{8cm}}]{\oarg{fraction}, \marg{vector}\\0} \\
% \ref{macro:printVecAsPoint_impl} & \makecell[t{p{8cm}}]{\oarg{fraction}, \marg{vector}\\0} \\
% \ref{macro:printVecAsPi_impl} & \makecell[t{p{8cm}}]{\oarg{fraction}, \marg{vector}\\0} \\
% \ref{macro:printVecAsPiT_impl} & \makecell[t{p{8cm}}]{\oarg{fraction}, \marg{vector}\\0} \\
% \ref{macro:printVecContent_impl} & \makecell[t{p{8cm}}]{\marg{vector}} \\
% \ref{macro:printVecContentXY_impl} & \makecell[t{p{8cm}}]{\marg{vector}} \\
% \ref{macro:printVecContentXYZ_impl} & \makecell[t{p{8cm}}]{\marg{vector}} \\
% \ref{macro:printVecContentXYZW_impl} & \makecell[t{p{8cm}}]{\marg{vector}} \\
% \ref{macro:getVecHeight_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector}\\vecHeightResult} \\
% \ref{macro:printScalarPComp_impl} & \makecell[t{p{8cm}}]{\oarg{fraction}, \marg{vector v}, \marg{vector w}\\0} \\
% \ref{macro:printCrossPComp_impl} & \makecell[t{p{8cm}}]{\oarg{fraction}, \marg{vector v}, \marg{vector w}\\0} \\
% \ref{macro:roundVec_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector}, \marg{digits}\\roundVecResult} \\
% \ref{macro:ceilVec_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector}\\ceilVecResult} \\
% \ref{macro:floorVec_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector}\\floorVecResult} \\
% \ref{macro:dehomogenVec_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector}\\dehomogenVecResult} \\
% \ref{macro:addVec_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector}, \marg{vectors}\\addVecResult} \\
% \ref{macro:subVec_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector}, \marg{vectors}\\subVecResult} \\
% \ref{macro:mulVec_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector}, \marg{vectors}\\mulVecResult} \\
% \ref{macro:divVec_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector}, \marg{vectors}\\divVecResult} \\
% \ref{macro:scaleVec_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector}, \marg{scalar}\\scaleVecResult} \\
% \ref{macro:divVecScalar_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector}, \marg{scalar}\\divVecScalarResult} \\
% \ref{macro:negateVec_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector}\\negateVecResult} \\
% \ref{macro:scaleAndAddVec_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector v}, \marg{vector w}, \marg{scalar}\\scaleAndAddVecResult} \\
% \ref{macro:lerpVec_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector v}, \marg{vector w}, \marg{scalar t}\\lerpVecResult} \\
% \ref{macro:slerpVec_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector v}, \marg{vector w}, \marg{scalar t}\\slerpVecResult} \\
% \ref{macro:dotVec_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector v}, \marg{vector w}\\dotVecResult} \\
% \ref{macro:lenVec_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector}\\lenVecResult} \\
% \ref{macro:sqrLenVec_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector}\\sqrLenVecResult} \\
% \ref{macro:normalizeVec_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector}\\normalizeVecResult} \\
% \ref{macro:crossVec_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector v}, \marg{vector w}\\crossVecResult} \\
% \ref{macro:crossVecTwoD_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector v}, \marg{vector w}\\crossVecResult} \\
% \ref{macro:angleVec_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector v}, \marg{vector w}\\angleVecResult} \\
% \ref{macro:distVec_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector v}, \marg{vector w}\\distVecResult} \\
% \ref{macro:sqrDistVec_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector v}, \marg{vector w}\\sqrDistVecResult} \\
% \ref{macro:transformVec_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{matrix}, \marg{vector}\\transformVecResult} \\
% \ref{macro:tensorVec_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector}\\tensorVecResult} \\
% \ref{macro:minVec_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector v}, \marg{vector w}\\minVecResult} \\
% \ref{macro:maxVec_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector v}, \marg{vector w}\\maxVecResult} \\
% \ref{macro:solveVecEQL_impl} & \makecell[t{p{8cm}}]{\oarg{out}, \marg{vector v}, \marg{vector w}\\solveVecEQLResult} \\
% \end{tabularx}
% \end{center}


% \setlabel{\textbackslash newVec}{macro:newVec_impl}
% \begin{macro}{\newVec}
% Create a new vector and assign the given values.
% 
% \#1 - out: var name to save the result (vector) to\\
% \#2 - values: values that are assigned to \#1
%    \begin{macrocode}
\newcommand\newVec[2]{%
    \if\noexpand#1\relax
        \PackageError{glmatrix package}{argument mismatch}{Argument 1 of newVec seems to be a command but must be a string. If it is not a command you might have used two identical letter at the beginning of the argument, please change that.}
    \else
        \expandafter\edef\csname #1\endcsname{\xintCSVtoList{#2}}%
    \fi
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash newVecPi}{macro:newVecPi_impl}
% \begin{macro}{\newVecPi}
% Create a new vector and assign the given values as a multiple of pi.
% 
% \#1 - out: var name to save the result (vector) to\\
% \#2 - values: values that are multiplied with pi and assigned to \#1
%    \begin{macrocode}
\newcommand\newVecPi[2]{%
    \def\tmpVec{\xintCSVtoList{#2}}
    \xintFor* ##1 in \tmpVec \do {%
        \newScalarPi{tmp}{##1}
        \xintifForFirst{%
            \newVec{#1}{\tmp}
        }{%
            \appendToVec{#1}{\csname #1\endcsname}{\tmp}
        }
    }
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash randomVec}{macro:randomVec_impl}
% \begin{macro}{\randomVec}
% Create a new vector and assign random values between lower and
% upper bound to its components.
% The value is obtained by creating a random value between 0 and 1
% and then interpolating between lower and upper bound.
% 
% \#1 - out: var name to save the result (vector) to\\
% \#2 - dimensions: scalar that defines the number of dimensions \#1 should have\\
% \#3 - lower bound: scalar that limits the possible values at the bottom\\
% \#4 - upper bound: scalar that limits the possible values at the top
%    \begin{macrocode}
\newcommand\randomVec[4]{
    \edef\innersequence{\xintSeq[+1]{+1}{#2}}%
    \xintFor* ##1 in \innersequence \do {%
        \FPrandom\tmp
        \lerpScalar{#3}{#4}{\tmp}
        \xintifForFirst{%
            \newVec{#1}{\lerpScalarResult}
        }{%
            \appendToVec{#1}{\csname #1\endcsname}{\lerpScalarResult}
        }
    }
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash copyVec}{macro:copyVec_impl}
% \begin{macro}{\copyVec}
% Copy values from one vector variable to another.
% 
% \#1 - out: var name to save the result (vector) to\\
% \#2 - vector: vector which values are assigned to \#1
%    \begin{macrocode}
\newcommand\copyVec[2][copyVecResult]{
    \xintFor* ##1 in #2 \do {%
        \xintifForFirst{%
            \newVec{#1}{##1}
        }{%
            \appendToVec{#1}{\csname #1\endcsname}{##1}
        }
    }
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash zeroVec}{macro:zeroVec_impl}
% \begin{macro}{\zeroVec}
% Create or override a vector with all its components being 0.
% Obacht: It is not necessary to call this to create a new vector.
% This is just for convenience when requiring a vector with initialized with zero.
% 
% \#1 - dims: number of dimensions (rows)\\
% \#2 - out: var name to save the result (vector) to
%    \begin{macrocode}
\newcommand\zeroVec[2][3]{%
    \edef\sequence{\xintSeq[+1]{+1}{#1}}%
    \xintFor* ##1 in \sequence \do {%
        \xintifForFirst{%
            \newVec{#2}{0}
        }{%
            \appendToVec{#2}{\csname #2\endcsname}{0}
        }
    }
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash appendToVec}{macro:appendToVec_impl}
% \begin{macro}{\appendToVec}
% Append a dimension with the given value to an already defined vector.
% 
% \#1 - out: var name to save the result (vector) to\\
% \#2 - vector: the currently present values\\
% \#3 - scalar: the scalar to add to \#2
%    \begin{macrocode}
\newcommand\appendToVec[3]{%
    \expandafter\edef\csname #1\endcsname{#2 \xintCSVtoList{#3}}%
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash printVec}{macro:printVec_impl}
% \begin{macro}{\printVec}
% Print the values of the given vector in vector notation.
% 
% \#1 - fraction: whether or not the value should be printed as a fraction (val=1)\\
% \#2 - vector: the vector that should be printed
%    \begin{macrocode}
\newcommand\printVec[2][0]{%
    \if\noexpand#2\relax
    \else
        \PackageError{glmatrix package}{argument mismatch}{Argument 1 of printVec seems to be a string but must be a command.}
    \fi
    \ensuremath{%
        \begin{pmatrix}
            \xintFor* ##1 in {#2} \do {%
                \xintifForLast{
                    \FPifeq{#1}{0}
                        \roundScalar{##1}
                        \scalarRoundResult
                    \else
                        \numToFractionA{##1}
                    \fi
                }{%
                    \FPifeq{#1}{0}
                        \roundScalar{##1}
                        \scalarRoundResult
                    \else
                        \numToFractionA{##1}
                    \fi
                    \\
                }
            }
        \end{pmatrix}
    }
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash printVecT}{macro:printVecT_impl}
% \begin{macro}{\printVecT}
% Print the values of the given vector in transposed notation.
% 
% \#1 - fraction: whether or not the value should be printed as a fraction (val=1)\\
% \#2 - vector: the vector that should be printed
%    \begin{macrocode}
\newcommand\printVecT[2][0]{%
    \if\noexpand#2\relax
    \else
        \PackageError{glmatrix package}{argument mismatch}{Argument 1 of printVecT seems to be a string but must be a command.}
    \fi
    \ensuremath{\trans{\left(
        \xintFor* ##1 in {#2} \do {%
            \xintifForLast{
                \FPifeq{#1}{0}
                    \roundScalar{##1}
                    \scalarRoundResult
                \else
                    \numToFractionA{##1}
                \fi
            }{%
                \FPifeq{#1}{0}
                    \roundScalar{##1}
                    \scalarRoundResult
                \else
                    \numToFractionA{##1}
                \fi
                ,
            }
        }
    \right)}}%
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash printVecAsPoint}{macro:printVecAsPoint_impl}
% \begin{macro}{\printVecAsPoint}
% Print the values of the given vector in point notation.
% 
% \#1 - fraction: whether or not the value should be printed as a fraction (val=1)\\
% \#2 - vector: the vector that should be printed
%    \begin{macrocode}
\newcommand\printVecAsPoint[2][0]{%
    \ensuremath{%
        \begin{bmatrix}
            \xintFor* ##1 in {#2} \do {%
                \FPifeq{#1}{0}
                    \roundScalar{##1}
                    \scalarRoundResult
                \else
                    \numToFractionA{##1}
                \fi
                \xintifForLast{}{%
                    \\
                }
            }
        \end{bmatrix}
    }
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash printVecAsPi}{macro:printVecAsPi_impl}
% \begin{macro}{\printVecAsPi}
% Print the values of the given vector as a multiple of \(\pi\) in vector notation.
% 
% \#1 - fraction: whether or not the value should be printed as a fraction (val=1)\\
% \#2 - vector: the vector that should be printed
%    \begin{macrocode}
\newcommand\printVecAsPi[2][0]{%
    \ensuremath{%
        \begin{pmatrix}
            \xintFor* ##1 in #2 \do {%
                \printScalarAsPi[#1]{##1}
                % \FPifeq{#1}{0}
                %     \roundScalar{##1}
                %     \scalarRoundResult
                % \else
                %     \numToFractionA{##1}
                % \fi
                \xintifForLast{}{%
                    \\
                }
            }
        \end{pmatrix}
    }
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash printVecAsPiT}{macro:printVecAsPiT_impl}
% \begin{macro}{\printVecAsPiT}
% Print the values of the given vector as a multiple of Pi in transposed notation.
% 
% \#1 - fraction: whether or not the value should be printed as a fraction (val=1)\\
% \#2 - vector: the vector that should be printed
%    \begin{macrocode}
\newcommand\printVecAsPiT[2][0]{%
    \ensuremath{\trans{\left(
        \xintFor* ##1 in #2 \do {%
            \printScalarAsPi[#1]{##1}
            \xintifForLast{}{%
                ,
            }
        }
    \right)}}
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash printVecContent}{macro:printVecContent_impl}
% \begin{macro}{\printVecContent}
% Print the values of the given vector comma separated.
% 
% \#1 - vector: the vector which values should be printed
%    \begin{macrocode}
\newcommand\printVecContent[1]{%
    \xintNthElt{1}{#1},\xintNthElt{3}{#1},\xintNthElt{2}{#1}%
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash printVecContentXY}{macro:printVecContentXY_impl}
% \begin{macro}{\printVecContentXY}
% Returns the x and y component of the given vector.
% 
% \#1 - vector: the vector which values should be printed
%    \begin{macrocode}
\newcommand\printVecContentXY[1]{%
    \xintNthElt{1}{#1}, \xintNthElt{2}{#1}
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash printVecContentXYZ}{macro:printVecContentXYZ_impl}
% \begin{macro}{\printVecContentXYZ}
% Returns the x, y and z component of the given vector.
% 
% \#1 - vector: the vector which values should be printed
%    \begin{macrocode}
\newcommand\printVecContentXYZ[1]{%
    \xintNthElt{1}{#1}, \xintNthElt{2}{#1}, \xintNthElt{3}{#1}%
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash printVecContentXYZW}{macro:printVecContentXYZW_impl}
% \begin{macro}{\printVecContentXYZW}
% Returns the x, y, z and w component of the given vector
% 
% \#1 - vector: the vector which values should be printed
%    \begin{macrocode}
\newcommand\printVecContentXYZW[1]{%
    \xintNthElt{1}{#1}, \xintNthElt{2}{#1}, \xintNthElt{3}{#1}, \xintNthElt{4}{#1}
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash getVecHeight}{macro:getVecHeight_impl}
% \begin{macro}{\getVecHeight}
% Returns the number of components that given vector has (number of dimensions).
% 
% \#1 - out: var name to save the result (scalar) to\\
% \#2 - vector: the vector of which to return the height
%    \begin{macrocode}
\newcommand\getVecHeight[2][vecHeightResult]{%
    \newScalar{#1}{\expandafter\xintLength\expandafter{#2}}
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash printScalarPComp}{macro:printScalarPComp_impl}
% \begin{macro}{\printScalarPComp}
% Print the intermediate components of the scalarproduct calculation.
% 
% \#1 - fraction: whether or not the value should be printed as a fraction (val=1)\\
% \#2 - vector v: the first vector\\
% \#3 - vector w: the second vector
%    \begin{macrocode}
\newcommand\printScalarPComp[3][0] {%
    \FPifeq{\expandafter\xintLength\expandafter{#2}}{\expandafter\xintLength\expandafter{#3}}
    \else
        \PackageError{glmatrix package}{In scalar product}{vector A and B do not have same length}
    \fi
    \edef\innersequence{\xintSeq[+1]{+1}{\expandafter\xintLength\expandafter{#2}}}%
    \ensuremath{
        \xintFor* ##1 in \innersequence \do {%
            \FPifeq{#1}{0}
                \printScalarRounded{\xintNthElt{##1}{#2}}*\printScalarRounded{\xintNthElt{##1}{#3}}
            \else
                \numToFractionA{\xintNthElt{##1}{#2}}*\numToFractionA{\xintNthElt{##1}{#3}}
            \fi
            \xintifForLast{}{%
                +
            }
        }
    }
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash printCrossPComp}{macro:printCrossPComp_impl}
% \begin{macro}{\printCrossPComp}
% Print the intermediate components of the crossproduct calculation.
% 
% \#1 - fraction: whether or not the value should be printed as a fraction (val=1)\\
% \#2 - vector v: the first vector\\
% \#3 - vector w: the second vector
%    \begin{macrocode}
\newcommand\printCrossPComp[3][0] {%
    \FPifeq{\expandafter\xintLength\expandafter{#2}}{3}
    \else
        \PackageError{glmatrix package}{In cross product}{vector A is not of length 3}
    \fi
    \FPifeq{\expandafter\xintLength\expandafter{#3}}{3}
    \else
        \PackageError{glmatrix package}{In cross product}{vector A is not of length 3}
    \fi
    \FPset\aa{\xintNthElt{1}{#2}}
    \FPset\ab{\xintNthElt{2}{#2}}
    \FPset\ac{\xintNthElt{3}{#2}}
    \FPset\ba{\xintNthElt{1}{#3}}
    \FPset\bb{\xintNthElt{2}{#3}}
    \FPset\bc{\xintNthElt{3}{#3}}
    %
    \ensuremath{
        \FPifeq{#1}{0}
            \begin{pmatrix}
                \printScalarRounded{\ab}*\printScalarRounded{\bc} - \printScalarRounded{\ac}*\printScalarRounded{\bb}\\
                \printScalarRounded{\ac}*\printScalarRounded{\ba} - \printScalarRounded{\aa}*\printScalarRounded{\bc}\\
                \printScalarRounded{\aa}*\printScalarRounded{\bb} - \printScalarRounded{\ab}*\printScalarRounded{\ba}
            \end{pmatrix}
        \else
            \begin{pmatrix}
                \numToFractionA{\ab}*\numToFractionA{\bc} - \numToFractionA{\ac}*\numToFractionA{\bb}\\
                \numToFractionA{\ac}*\numToFractionA{\ba} - \numToFractionA{\aa}*\numToFractionA{\bc}\\
                \numToFractionA{\aa}*\numToFractionA{\bb} - \numToFractionA{\ab}*\numToFractionA{\ba}
            \end{pmatrix}
        \fi
    }
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash roundVec}{macro:roundVec_impl}
% \begin{macro}{\roundVec}
% Round the values ot the given vector.
% 
% \#1 - out: var name to save the result (vector) to\\
% \#2 - vector: the vector that schould be rounded\\
% \#3 - digits: number of digits after comma
%    \begin{macrocode}
\newcommand\roundVec[3][roundVecResult]{%
    \xintFor* ##3 in #2 \do {%
        \FPround\tmp{##3}{#3}
        \xintifForFirst{%
            \newVec{#1}{\tmp}
        }{%
            \appendToVec{#1}{\csname #1\endcsname}{\tmp}
        }
    }
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash ceilVec}{macro:ceilVec_impl}
% \begin{macro}{\ceilVec}
% Ceil the values of the given vector.
% 
% \#1 - out: var name to save the result (vector) to\\
% \#2 - vector: the vector that should be ceiled
%    \begin{macrocode}
\newcommand\ceilVec[2][ceilVecResult]{
    \xintFor* ##1 in #2 \do {%
        \ceilScalar[tmp]{##1}
        \xintifForFirst{%
            \newVec{#1}{\tmp}
        }{%
            \appendToVec{#1}{\csname #1\endcsname}{\tmp}
        }
    }
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash floorVec}{macro:floorVec_impl}
% \begin{macro}{\floorVec}
% Floor the values of the given vector.
% 
% \#1 - out: var name to save the result (vector) to\\
% \#2 - vector: the vector that should be floored
%    \begin{macrocode}
\newcommand\floorVec[2][floorVecResult]{
    \xintFor* ##1 in #2 \do {%
        \floorScalar[tmp]{##1}
        \xintifForFirst{%
            \newVec{#1}{\tmp}
        }{%
            \appendToVec{#1}{\csname #1\endcsname}{\tmp}
        }
    }
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash dehomogenVec}{macro:dehomogenVec_impl}
% \begin{macro}{\dehomogenVec}
% Dehomogenize the values of the given vector. This divides all vector components by the last component.
% 
% \#1 - out: var name to save the result (vector) to\\
% \#2 - vector: the vector that should be dehomogenized
%    \begin{macrocode}
\newcommand\dehomogenVec[2][dehomogenVecResult]{
    \getVecHeight{#2}
    \FPset\tmpDiv{\xintNthElt{\vecHeightResult}{#2}}
    \edef\sequence{\xintSeq[+1]{+1}{\vecHeightResult}}%
    \xintFor* ##1 in \sequence \do {%
        \xintifForFirst{%
            \FPdiv\divResult{\xintNthElt{##1}{#2}}{\tmpDiv}
            \newVec{tmpVec}{\divResult}
        }{%
            % \xintifForLast{
            % }{
                \FPdiv\divResult{\xintNthElt{##1}{#2}}{\tmpDiv}
                \appendToVec{tmpVec}{\tmpVec}{\divResult}
            % }
        }
    }
    \copyVec[#1]{\tmpVec}
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash addVec}{macro:addVec_impl}
% \begin{macro}{\addVec}
% Add the values of \(1\) to \(m\) vectors to the values of the given vector.
% 
% \#1 - out: var name to save the result (vector) to\\
% \#2 - vector: the vector to add to\\
% \#3 - vectors: the list of vectors with which to add
%    \begin{macrocode}
\newcommand\addVec[3][addVecResult]{%
    \def\vecList{\xintCSVtoList{#3}}
    \getVecHeight{#2}
    \edef\sequence{\xintSeq[+1]{+1}{\vecHeightResult}}%
    % Iterate each row / dimension
    \xintFor* ##1 in \sequence \do {%
        % Assign value of start vector (param #2)
        \FPset\sumValue{\xintNthElt{##1}{#2}}%
        % If this is the first iteration create a new vector
        \xintifForFirst{%
            % Iterate all vectors that are part of param #3
            \xintFor* ##2 in \vecList \do {%
                % Multiply with row value of current vector
                \FPadd\sumValue\sumValue{\xintNthElt{##1}{##2}}%
            }
            \newVec{#1}{\sumValue}
        }{%
            \xintFor* ##2 in \vecList \do {%
                \FPadd\sumValue\sumValue{\xintNthElt{##1}{##2}}%
            }
            \appendToVec{#1}{\csname #1\endcsname}{\sumValue}
        }
    }
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash subVec}{macro:subVec_impl}
% \begin{macro}{\subVec}
% Subract the values of \(1\) to \(m\) vectors from the values of the given vector.
% 
% \#1 - out: var name to save the result (vector) to\\
% \#2 - vector: the vector to subtract from\\
% \#3 - vectors: the list of vectors with which to subtract
%    \begin{macrocode}
\newcommand\subVec[3][subVecResult]{%
    \if\noexpand#1\relax
        \PackageError{glmatrix package}{argument mismatch}{Argument 1 of subVec seems to be a command but must be a string. If it is not a command you might have used two identical letter at the beginning of the argument, please change that.}
    \else
    \fi
    \if\noexpand#2\relax
    \else
        \PackageError{glmatrix package}{argument mismatch}{argument 2 of subVec does not seem to be a command}
    \fi
    % TODO does not work on list of commands
    % \if\noexpand#3\relax
    % \else
    %     \PackageError{glmatrix package}{argument mismatch}{argument 3 of subVec does not seem to be a command}
    % \fi
    %
    \def\vecList{\xintCSVtoList{#3}}
    \getVecHeight{#2}
    \edef\sequence{\xintSeq[+1]{+1}{\vecHeightResult}}%
    % Iterate each row / dimension
    \xintFor* ##1 in \sequence \do {%
        % Assign value of start vector (param #2)
        \FPset\subValue{\xintNthElt{##1}{#2}}%
        % If this is the first iteration create a new vector
        \xintifForFirst{%
            % Iterate all vectors that are part of param #3
            \xintFor* ##2 in \vecList \do {%
                % Multiply with row value of current vector
                \FPsub\subValue\subValue{\xintNthElt{##1}{##2}}%
            }
            \newVec{#1}{\subValue}
        }{%
            \xintFor* ##2 in \vecList \do {%
                \FPsub\subValue\subValue{\xintNthElt{##1}{##2}}%
            }
            \appendToVec{#1}{\csname #1\endcsname}{\subValue}
        }
    }
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash mulVec}{macro:mulVec_impl}
% \begin{macro}{\mulVec}
% Multiply the values of \(1\) to \(m\) vectors with the values of the given vector.
% See Hadamard product (element-wise product) for more information.
% 
% \#1 - out: var name to save the result (vector) to\\
% \#2 - vector: the vector to multiply\\
% \#3 - vectors: the list of vectors with which to multiply
%    \begin{macrocode}
\newcommand\mulVec[3][mulVecResult]{
    \def\vecList{\xintCSVtoList{#3}}
    \getVecHeight{#2}
    \edef\sequence{\xintSeq[+1]{+1}{\vecHeightResult}}%
    % Iterate each row / dimension
    \xintFor* ##1 in \sequence \do {%
        % Assign value of start vector (param #2)
        \FPset\mulValue{\xintNthElt{##1}{#2}}%
        % If this is the first iteration create a new vector
        \xintifForFirst{%
            % Iterate all vectors that are part of param #3
            \xintFor* ##2 in \vecList \do {%
                % Multiply with row value of current vector
                \FPmul\mulValue\mulValue{\xintNthElt{##1}{##2}}%
            }
            \newVec{#1}{\mulValue}
        }{%
            \xintFor* ##2 in \vecList \do {%
                \FPmul\mulValue\mulValue{\xintNthElt{##1}{##2}}%
            }
            \appendToVec{#1}{\csname #1\endcsname}{\mulValue}
        }
    }
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash divVec}{macro:divVec_impl}
% \begin{macro}{\divVec}
% Divide the values of the given vector by the values of \(1\) to \(m\) vectors (element-wise division).
% 
% \#1 - out: var name to save the result (vector) to\\
% \#2 - vector: the vector to divide\\
% \#3 - vectors: the list of vectors to divide with
%    \begin{macrocode}
\newcommand\divVec[3][divVecResult]{
    \def\vecList{\xintCSVtoList{#3}}
    \getVecHeight{#2}
    \edef\sequence{\xintSeq[+1]{+1}{\vecHeightResult}}%
    % Iterate each row / dimension
    \xintFor* ##1 in \sequence \do {%
        % Assign value of start vector (param #2)
        \FPset\divValue{\xintNthElt{##1}{#2}}%
        % If this is the first iteration create a new vector
        \xintifForFirst{%
            % Iterate all vectors that are part of param #3
            \xintFor* ##2 in \vecList \do {%
                \FPifeq{\xintNthElt{##1}{##2}}{0}
                    \PackageError{glmatrix package}{In divVec function: division by zero}{you are trying to divide by 0}
                \else
                \fi
                % Divide with row value of current vector
                \FPdiv\divValue\divValue{\xintNthElt{##1}{##2}}%
            }
            \newVec{#1}{\divValue}
        }{%
            \xintFor* ##2 in \vecList \do {%
                \FPifeq{\xintNthElt{##1}{##2}}{0}
                    \PackageError{glmatrix package}{In divVec function: division by zero}{you are trying to divide by 0}
                \else
                \fi
                \FPdiv\divValue\divValue{\xintNthElt{##1}{##2}}%
            }
            \appendToVec{#1}{\csname #1\endcsname}{\divValue}
        }
    }
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash scaleVec}{macro:scaleVec_impl}
% \begin{macro}{\scaleVec}
% Multiply the values of the given vector by a scalar.
% 
% \#1 - out: var name to save the result (vector) to\\
% \#2 - vector: the vector to scale\\
% \#3 - scalar: the scalar to scale with
%    \begin{macrocode}
\newcommand\scaleVec[3][scaleVecResult] {%
    \xintFor* ##1 in #2 \do {%
        \FPmul\tmpVal{##1}{#3}
        \xintifForFirst{%
            \newVec{#1}{\tmpVal}
        }{%
            \appendToVec{#1}{\csname #1\endcsname}{\tmpVal}
        }
    }
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash divVecScalar}{macro:divVecScalar_impl}
% \begin{macro}{\divVecScalar}
% Divide the values of the given vector by a scalar.
% 
% \#1 - out: var name to save the result (vector) to\\
% \#2 - vector: the vector to divide\\
% \#3 - scalar: the scalar to divide with
%    \begin{macrocode}
\newcommand\divVecScalar[3][divVecScalarResult] {%
    \if\noexpand#1\relax
        \PackageError{glmatrix package}{argument mismatch}{Argument 1 of divVecScalar seems to be a command but must be a string. If it is not a command you might have used two identical letter at the beginning of the argument, please change that.}
    \else
    \fi
    \if\noexpand#2\relax
    \else
        \PackageError{glmatrix package}{argument mismatch}{argument 2 of divVecScalar does not seem to be a command}
    \fi
    \FPifeq{#3}{0}
        \PackageError{glmatrix package}{In div vector by scalar}{divisor is 0}
    \else
    \fi
    \xintFor* ##1 in #2 \do {%
        \FPdiv\divNumRes{##1}{#3}
        \xintifForFirst{%
            \newVec{#1}{\divNumRes}
        }{%
            \appendToVec{#1}{\csname #1\endcsname}{\divNumRes}
        }
    }
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash negateVec}{macro:negateVec_impl}
% \begin{macro}{\negateVec}
% Negate the values of the given vector.
% 
% \#1 - out: var name to save the result (vector) to\\
% \#2 - vector: the vector to negate
%    \begin{macrocode}
\newcommand\negateVec[2][negateVecResult]{
    \xintFor* ##1 in #2 \do {%
        \FPneg\tmp{##1}
        \xintifForFirst{%
            \newVec{#1}{\tmp}
        }{%
            \appendToVec{#1}{\csname #1\endcsname}{\tmp}
        }
    }
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash scaleAndAddVec}{macro:scaleAndAddVec_impl}
% \begin{macro}{\scaleAndAddVec}
% Adds two vectors after multiplying the second one by a scalar.
% 
% \#1 - out: var name to save the result (vector) to\\
% \#2 - vector v: the vector to add to\\
% \#3 - vector w: the vector that is multiplied and then added\\
% \#4 - scalar: the scalar that is the muliplier
%    \begin{macrocode}
\newcommand\scaleAndAddVec[4][scaleAndAddVecResult]{
    \scaleVec{#3}{#4}
    \addVec[#1]{#2}{\scaleVecResult}
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash lerpVec}{macro:lerpVec_impl}
% \begin{macro}{\lerpVec}
% Lineraly interpolate between the values of two vectors (element-wise interpolation).
% 
% \#1 - out: var name to save the result (vector) to\\
% \#2 - vector v: the start vector\\
% \#3 - vector w: the end vector\\
% \#4 - scalar t: interpolation amount range [0-1]
%    \begin{macrocode}
\newcommand\lerpVec[4][lerpVecResult]{
    % \def\vecList{\xintCSVtoList{#3}}
    \getVecHeight{#2}
    \edef\sequence{\xintSeq[+1]{+1}{\vecHeightResult}}%
    % Iterate each row / dimension
    \xintFor* ##1 in \sequence \do {%
        % Assign value of start vector (param #2)
        % \FPset\divValue{\xintNthElt{##1}{#2}}%
        % If this is the first iteration create a new vector
        \xintifForFirst{%
            \lerpScalar{\xintNthElt{##1}{#2}}{\xintNthElt{##1}{#3}}{#4}
            \newVec{#1}{\lerpScalarResult}
        }{%
            \lerpScalar{\xintNthElt{##1}{#2}}{\xintNthElt{##1}{#3}}{#4}
            \appendToVec{#1}{\csname #1\endcsname}{\lerpScalarResult}
        }
    }
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash slerpVec}{macro:slerpVec_impl}
% \begin{macro}{\slerpVec}
% Performs a spherical linear interpolation between two vectors.
% This expects vector v and vector w to be normalized.
% 
% \#1 - out: var name to save the result (vector) to\\
% \#2 - vector v: the start vector\\
% \#3 - vector w: the end vector\\
% \#4 - scalar t: interpolation amount range [0-1]
%    \begin{macrocode}
\newcommand\slerpVec[4][slerpVecResult] {%
    \angleVec{#2}{#3}
    \FPifeq{\angleVecResult}{0}
        \lerpVec[#1]{#2}{#3}{#4}
    \else
        \FPsin\angleTotal{\angleVecResult}
        \FPsub\ratioA{1}{#4}
        \FPmul\ratioA\ratioA{\angleVecResult}
        \FPsin\ratioA\ratioA
        \FPdiv\ratioA\ratioA\angleTotal
        \FPmul\ratioB{#4}{\angleVecResult}
        \FPsin\ratioB\ratioB
        \FPdiv\ratioB\ratioB\angleTotal
        \scaleVec[tmpA]{#2}{\ratioA}
        \scaleVec[tmpB]{#3}{\ratioB}
        \addVec[#1]{\tmpA}{\tmpB}
    \fi
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash dotVec}{macro:dotVec_impl}
% \begin{macro}{\dotVec}
% Calculate the dotproduct of the given two vectors.
% Other names for this operation are inner product and scalarproduct.
% 
% \#1 - out: var name to save the result (scalar) to\\
% \#2 - vector v: the first vector\\
% \#3 - vector w: the second vector
%    \begin{macrocode}
\newcommand\dotVec[3][dotVecResult] {%
    \if\noexpand#1\relax
        \PackageError{glmatrix package}{argument mismatch}{Argument 1 of dotVec seems to be a command but must be a string. If it is not a command you might have used two identical letter at the beginning of the argument, please change that.}
    \else
    \fi
    \if\noexpand#2\relax
    \else
        \PackageError{glmatrix package}{argument mismatch}{argument 2 of dotVec does not seem to be a command}
    \fi
    \if\noexpand#3\relax
    \else
        \PackageError{glmatrix package}{argument mismatch}{argument 3 of dotVec does not seem to be a command}
    \fi
    \FPifeq{\expandafter\xintLength\expandafter{#2}}{\expandafter\xintLength\expandafter{#3}}
    \else
        \PackageError{glmatrix package}{In dot product}{vector A and B do not have same length}
    \fi
    \FPset\res{0}
    \FPset\tmp{0}
    \edef\innersequence{\xintSeq[+1]{+1}{\expandafter\xintLength\expandafter{#2}}}%
    \xintFor* ##1 in \innersequence \do {%
        \FPset\valueA{\xintNthElt{##1}{#2}}
        \FPset\valueB{\xintNthElt{##1}{#3}}
        \FPmul\tmp\valueA\valueB
        \FPadd\res\res\tmp
    }
    \newScalar{#1}{\res}
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash lenVec}{macro:lenVec_impl}
% \begin{macro}{\lenVec}
% Calculate the length of the given vector.
% 
% \#1 - out: var name to save the result (scalar) to\\
% \#2 - vector: the vector for which to calculate the length
%    \begin{macrocode}
\newcommand\lenVec[2][lenVecResult] {%
    \if\noexpand#1\relax
        \PackageError{glmatrix package}{argument mismatch}{Argument 1 of lenVec seems to be a command but must be a string. If it is not a command you might have used two identical letter at the beginning of the argument, please change that.}
    \else
    \fi
    \if\noexpand#2\relax
    \else
        \PackageError{glmatrix package}{argument mismatch}{argument 2 of lenVec does not seem to be a command}
    \fi
    \FPset\normTotal{0}
    \FPset\iterVal{0}
    % Iterate each value, multiply it with itself and sum up
    \xintFor* ##1 in #2 \do {%
        % No idea why this needs to be abs,
        % but negative values are a problem here
        \FPabs\iterVal{##1}
        \FPpow\tmpNormB\iterVal{2}
        \FPadd\normTotal\normTotal\tmpNormB
    }
    % Evaluate root for numbered result
    \FProot\normRooted\normTotal{2}
    % Set output var
    \newScalar{#1}{\normRooted}
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash sqrLenVec}{macro:sqrLenVec_impl}
% \begin{macro}{\sqrLenVec}
% Calculate the squared length of the given vector.
% 
% \#1 - out: var name to save the result (scalar) to\\
% \#2 - vector: the vector for which to calculate the squared length
%    \begin{macrocode}
\newcommand\sqrLenVec[2][sqrLenVecResult] {%
    \FPset\normTotal{0}
    \FPset\iterVal{0}
    % Iterate each value, multiply it with itself and sum up
    \xintFor* ##1 in #2 \do {%
        % No idea why this needs to be abs,
        % but negative values are a problem here
        \FPabs\iterVal{##1}
        \FPpow\tmpNormB\iterVal{2}
        \FPadd\normTotal\normTotal\tmpNormB
    }
    % Set output var
    \newScalar{#1}{\normTotal}
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash normalizeVec}{macro:normalizeVec_impl}
% \begin{macro}{\normalizeVec}
% Divide all components of the vector by its length.
% 
% \#1 - out: var name to save the result (vector) to\\
% \#2 - vector: the vector which to normalize
%    \begin{macrocode}
\newcommand\normalizeVec[2][normalizeVecResult] {%
    \if\noexpand#1\relax
        \PackageError{glmatrix package}{argument mismatch}{Argument 1 of normalizeVec seems to be a command but must be a string. If it is not a command you might have used two identical letter at the beginning of the argument, please change that.}
    \else
    \fi
    \if\noexpand#2\relax
    \else
        \PackageError{glmatrix package}{argument mismatch}{argument 2 of normalizeVec does not seem to be a command}
    \fi
    \lenVec{#2}
    \divVecScalar[#1]{#2}{\lenVecResult}
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash crossVec}{macro:crossVec_impl}
% \begin{macro}{\crossVec}
% Calculate crossproduct for the two given vectors.
% 
% \#1 - out: var name to save the result (vector) to\\
% \#2 - vector v: the first vector\\
% \#3 - vector w: the second vector
%    \begin{macrocode}
\newcommand\crossVec[3][crossVecResult] {%
    \FPifeq{\expandafter\xintLength\expandafter{#2}}{3}
    \else
        \PackageError{glmatrix package}{In cross product}{vector A is not of length 3}
    \fi
    \FPifeq{\expandafter\xintLength\expandafter{#3}}{3}
    \else
        \PackageError{glmatrix package}{In cross product}{vector A is not of length 3}
    \fi
    \FPset\aa{\xintNthElt{1}{#2}}
    \FPset\ab{\xintNthElt{2}{#2}}
    \FPset\ac{\xintNthElt{3}{#2}}
    \FPset\ba{\xintNthElt{1}{#3}}
    \FPset\bb{\xintNthElt{2}{#3}}
    \FPset\bc{\xintNthElt{3}{#3}}
    \FPset\tmp{0}
    % x component
    \FPset\scalarX{0}
    \FPmul\scalarX\ab\bc
    \FPmul\tmp\ac\bb
    \FPsub\scalarX\scalarX\tmp
    % y component
    \FPset\scalarY{0}
    \FPmul\scalarY\ac\ba
    \FPmul\tmp\aa\bc
    \FPsub\scalarY\scalarY\tmp
    % z component
    \FPset\scalarZ{0}
    \FPmul\scalarZ\aa\bb
    \FPmul\tmp\ab\ba
    \FPsub\scalarZ\scalarZ\tmp
    \newVec{#1}{\scalarX,\scalarY,\scalarZ}
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash crossVecTwoD}{macro:crossVecTwoD_impl}
% \begin{macro}{\crossVecTwoD}
% Calculate crossproduct for the two given vectors.
% 
% \#1 - out: var name to save the result (vector) to\\
% \#2 - vector v: the first vector\\
% \#3 - vector w: the second vector
%    \begin{macrocode}
\newcommand\crossVecTwoD[3][crossVecResult] {%
    \FPifeq{\expandafter\xintLength\expandafter{#2}}{2}
    \else
        \PackageError{glmatrix package}{In cross product}{vector A is not of length 2}
    \fi
    \FPifeq{\expandafter\xintLength\expandafter{#3}}{2}
    \else
        \PackageError{glmatrix package}{In cross product}{vector A is not of length 2}
    \fi
    \FPset\aa{\xintNthElt{1}{#2}}
    \FPset\ab{\xintNthElt{2}{#2}}
    \FPset\ba{\xintNthElt{1}{#3}}
    \FPset\bb{\xintNthElt{2}{#3}}
    \FPmul\scalarUxVy{\xintNthElt{1}{#2}}{\xintNthElt{2}{#3}}
    \FPmul\scalarUyVx{\xintNthElt{2}{#2}}{\xintNthElt{1}{#3}}
    \FPsub\scalarResult{\scalarUxVy}{\scalarUyVx}
    \newScalar{#1}{\scalarResult}
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash angleVec}{macro:angleVec_impl}
% \begin{macro}{\angleVec}
% Get the angle between the given two vectors in radian.
% 
% \#1 - out: var name to save the result (scalar) to\\
% \#2 - vector v: the first vector\\
% \#3 - vector w: the second vector
%    \begin{macrocode}
\newcommand\angleVec[3][angleVecResult] {%
    \dotVec[dotVW]{#2}{#3}
    \lenVec[normV]{#2}
    \lenVec[normW]{#3}
    \mulScalar[mulNormVW]{\normV}{\normW}
    \divScalar{\dotVW}{\mulNormVW}
    \arccosScalar[#1]{\scalarDivResult}
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash distVec}{macro:distVec_impl}
% \begin{macro}{\distVec}
% Calculates the euclidian distance between the given two vectors.
% 
% \#1 - out: var name to save the result (scalar) to\\
% \#2 - vector v: the first vector\\
% \#3 - vector w: the second vector
%    \begin{macrocode}
\newcommand\distVec[3][distVecResult] {%
    \sqrDistVec{#2}{#3}
    \FProot\res\sqrDistVecResult{2}
    \newScalar{#1}{\res}
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash sqrDistVec}{macro:sqrDistVec_impl}
% \begin{macro}{\sqrDistVec}
% Calculates the squared euclidian distance between two vectors.
% 
% \#1 - out: var name to save the result (scalar) to\\
% \#2 - vector v: the first vector\\
% \#3 - vector w: the second vector
%    \begin{macrocode}
\newcommand\sqrDistVec[3][sqrDistVecResult] {%
    \getVecHeight[getVecHeightA]{#2}
    \getVecHeight[getVecHeightB]{#3}
    \FPifeq{\getVecHeightA}{\getVecHeightB}
    \else
        \PackageError{glmatrix package}{In sqrt distance}{vector #2 and #3 do not have same length}
    \fi
    \FPset\res{0}
    \FPset\tmp{0}
    \edef\sequence{\xintSeq[+1]{+1}{\getVecHeightA}}%
    \xintFor* ##1 in \sequence \do {%
        \FPset\valueA{\xintNthElt{##1}{#2}}
        \FPset\valueB{\xintNthElt{##1}{#3}}
        \FPsub\tmp\valueA\valueB
        \FPmul\tmp\tmp\tmp
        \FPadd\res\res\tmp
    }
    \newScalar{#1}{\res}
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash transformVec}{macro:transformVec_impl}
% \begin{macro}{\transformVec}
% Multiply the given vector with a matrix (for transformation).
% 
% \#1 - out: var name to save the result (vector) to\\
% \#2 - matrix: the matrix to transform the vetor with\\
% \#3 - vector: the vector to transform
%    \begin{macrocode}
\newcommand\transformVec[3][transformVecResult] {%
    \if\noexpand#1\relax
        \PackageError{glmatrix package}{argument mismatch}{Argument 1 of transformVec seems to be a command but must be a string. If it is not a command you might have used two identical letter at the beginning of the argument, please change that.}
    \else
    \fi
    \if\noexpand#2\relax
    \else
        \PackageError{glmatrix package}{argument mismatch}{argument 2 of transformVec does not seem to be a command}
    \fi
    \if\noexpand#3\relax
    \else
        \PackageError{glmatrix package}{argument mismatch}{argument 3 of transformVec does not seem to be a command}
    \fi
    \getVecHeight{#3}%
    \getMatHeight{#2}%
    \getMatWidth{#2}%
    % Check that matrix and vector can be multiplied
    \FPifeq{\matWidthResult}{\vecHeightResult}
    \else
        \PackageError{glmatrix package}{Dimension mismatch for matrix and vector, could not multiply}{width (\matWidthResult) of matrix #2 and height (\vecHeightResult) of vector #3 do not match}
    \fi
    % Create iterator sequences from height of vector and matrix
    \edef\vecHeightSequence{\xintSeq[+1]{+1}{\vecHeightResult}}%
    \edef\matHeightSequence{\xintSeq[+1]{+1}{\matHeightResult}}%
    % Iterate all rows of the matrix
    \xintFor* ##2 in \matHeightSequence \do {%
        \FPset\cellVal{0}
        % Differentiate between first and other entries to create the new vector variable
        \xintifForFirst{%
            % Now iterate each entry of the current row
            % Use this indec to access the entry in the matrix and in the vector
            \xintFor* ##3 in \vecHeightSequence \do {%
                \FPmul\tmp{%
                    \xintNthElt{##3}{\xintNthElt{##2}{#2}}%
                }{%
                    \xintNthElt{##3}{#3}%
                }
                % Add to storage variable
                \FPadd\cellVal\cellVal\tmp
            }
            \FPclip\cellVal\cellVal
            \newVec{#1}{\cellVal}
        }{
            \xintFor* ##3 in \vecHeightSequence \do {%
                \FPmul\tmp{%
                    \xintNthElt{##3}{\xintNthElt{##2}{#2}}%
                }{%
                    \xintNthElt{##3}{#3}%
                }
                \FPadd\cellVal\cellVal\tmp
            }
            \FPclip\cellVal\cellVal
            \appendToVec{#1}{\csname #1\endcsname}{\cellVal}
        }
    }
    % Test if width and height is correct
    \expandafter\getVecHeight\expandafter{\csname #1\endcsname}%
    \FPifeq{\matHeightResult}{\vecHeightResult}
    \else
        \PackageError{glmatrix package}{Vector height does not match expectation}{height of vector is \vecHeightResult but should be \matHeightResult}
    \fi
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash tensorVec}{macro:tensorVec_impl}
% \begin{macro}{\tensorVec}
% Outer product: Multiply a vector (column) with itself (row) resulting in a matrix. (Dyadic product, Tensor product)
% 
% \#1 - out: var name to save the result (matrix) to\\
% \#2 - vector: the vector to multiply with itself
%    \begin{macrocode}
\newcommand\tensorVec[2][tensorVecResult]{%
    \newMatFromRowVecs{rowMatrix}{#2}
    \newMatFromColVecs{colMatrix}{#2}
    \mulMat[#1]{\colMatrix}{\rowMatrix}
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash minVec}{macro:minVec_impl}
% \begin{macro}{\minVec}
% Return the componentwise minimum of the given two vectors.
% 
% \#1 - out: var name to save the result (vector) to\\
% \#2 - vector v: the first vector\\
% \#3 - vector w: the second vector
%    \begin{macrocode}
\newcommand\minVec[3][minVecResult]{
    \if\noexpand#1\relax
        \PackageError{glmatrix package}{argument mismatch}{Argument 1 of minVec seems to be a command but must be a string. If it is not a command you might have used two identical letter at the beginning of the argument, please change that.}
    \else
    \fi
    \FPifeq{\expandafter\xintLength\expandafter{#2}}{\expandafter\xintLength\expandafter{#3}}
    \else
        \PackageError{glmatrix package}{incompatible size}{vector A and B of minVec do not have same length}
    \fi
    \edef\innersequence{\xintSeq[+1]{+1}{\expandafter\xintLength\expandafter{#2}}}%
    \xintFor* ##1 in \innersequence \do {%
        \minScalar{\xintNthElt{##1}{#2}}{\xintNthElt{##1}{#3}}
        \xintifForFirst{%
            \newVec{#1}{\minScalarResult}
        }{%
            \appendToVec{#1}{\csname #1\endcsname}{\minScalarResult}
        }
    }
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash maxVec}{macro:maxVec_impl}
% \begin{macro}{\maxVec}
% Return the componentwise maximum of the given two vectors.
% 
% \#1 - out: var name to save the result (vector) to\\
% \#2 - vector v: the first vector\\
% \#3 - vector w: the second vector
%    \begin{macrocode}
\newcommand\maxVec[3][maxVecResult]{
    \if\noexpand#1\relax
        \PackageError{glmatrix package}{argument mismatch}{Argument 1 of maxVec seems to be a command but must be a string. If it is not a command you might have used two identical letter at the beginning of the argument, please change that.}
    \else
    \fi
    \FPifeq{\expandafter\xintLength\expandafter{#2}}{\expandafter\xintLength\expandafter{#3}}
    \else
        \PackageError{glmatrix package}{incompatible size}{vector A and B of maxVec do not have same length}
    \fi
    \edef\innersequence{\xintSeq[+1]{+1}{\expandafter\xintLength\expandafter{#2}}}%
    \xintFor* ##1 in \innersequence \do {%
        \maxScalar{\xintNthElt{##1}{#2}}{\xintNthElt{##1}{#3}}
        \xintifForFirst{%
            \newVec{#1}{\maxScalarResult}
        }{%
            \appendToVec{#1}{\csname #1\endcsname}{\maxScalarResult}
        }
    }
}
%    \end{macrocode}
% \end{macro}


% \setlabel{\textbackslash solveVecEQL}{macro:solveVecEQL_impl}
% \begin{macro}{\solveVecEQL}
% Solve the equation \(vector v*x+vector w=0\) for \(x\).
% The command expects the input to be two vectors of the same length.
% The command iterates both vectors componentwise and solves the equation per component.
% If the the result does not match across all components the equation can not be solved.
% 
% \#1 - out: var name to save the result (scalar) to\\
% \#2 - vector v: the first vector\\
% \#3 - vector w: the second vector
%    \begin{macrocode}
\newcommand\solveVecEQL[3][solveVecEQLResult]{
    \getVecHeight{#3}%
    \edef\vecHeightSequence{\xintSeq[+1]{+1}{\vecHeightResult}}%
    \xintFor* ##1 in \vecHeightSequence \do {%
        % \FPneg\tmpVar{\xintNthElt{##1}{#3}}
        \FPlsolve\glCurSol{\xintNthElt{##1}{#2}}{\xintNthElt{##1}{#3}}
        \xintifForFirst{%
            \setScalar{#1}{\glCurSol}
        }{%
            \FPifeq{\csname #1\endcsname}{\glCurSol}
            \else
                \PackageError{glmatrix package}{Could not solve equation}{varying results for different dimensions}
            \fi
        }
    }
}%    \end{macrocode}
% \end{macro}

% \iffalse
%<*package>
% \fi
