VS2017 verwendet die Eigen-Bibliothek

In C++ werden Vektortypen normalerweise von Bibliotheken bereitgestellt. Die <vector>-Headerdatei in der C++-Standardbibliothek stellt einen Vektorcontainer std::vector bereit, es handelt sich jedoch nicht um einen Vektortyp im mathematischen Sinne, sondern um einen Array-Container variabler Größe. Wenn Sie Vektortypen im mathematischen Sinne verwenden möchten, können Sie einige häufig verwendete mathematische Bibliotheken verwenden, wie zum Beispiel:

GLM (OpenGL Mathematics): Es handelt sich um eine Mathematikbibliothek, die speziell für die OpenGL-Entwicklung verwendet wird. Sie stellt mathematische Typen wie Matrizen, Vektoren und Quaternionen bereit und unterstützt gängige mathematische Operationen und Transformationen.

Eigen: Es handelt sich um eine C++-Vorlagenbibliothek für lineare Algebra-Berechnungen. Sie stellt mathematische Typen wie Matrizen, Vektoren und Quaternionen bereit und unterstützt effiziente mathematische Berechnungen und lineare Algebra-Operationen.

Boost.Geometry: Es handelt sich um eine Geometriebibliothek in der Boost-Bibliothek. Sie stellt geometrische Typen wie Vektoren, Punkte, Liniensegmente und Strahlen bereit und unterstützt verschiedene geometrische Operationen und Algorithmen.

Diese Bibliotheken müssen auf die entsprechenden Header-Dateien und Bibliotheksdateien im Code verweisen. Die spezifischen Referenzmethoden und Kompilierungsmethoden können unterschiedlich sein und müssen entsprechend den spezifischen Bibliotheksdokumenten festgelegt und konfiguriert werden.

Offizielle Eigen-Website:

http://eigen.tuxfamily.org/index.php?title=Main_Page

Zwei Möglichkeiten, Eigen in VS2017 zu verwenden:

  1. https://blog.csdn.net/weixin_45590473/article/details/122857933

  1. https://blog.csdn.net/weixin_42655134/article/details/107414089

Erleben Sie anhand der folgenden Fälle die Anwendung der Eigen-Bibliothek in C++

1. Verwenden Sie in C++ die Eigen-Vorlagenbibliothek, um ein neues Koordinatensystem mit drei Punkten im Raum zu erstellen und die Koordinaten dieser drei Punkte im neuen Koordinatensystem über die Transfermatrix zu berechnen?

Die Idee ist wie folgt:

a. Berechnen Sie die drei Achsenvektoren des neuen Koordinatensystems durch diese drei Punkte.

b. Die Transfermatrix kann durch Invertieren der Matrix bestehend aus den drei Achsenvektoren des neuen Koordinatensystems erhalten werden.

c. Verwenden Sie die Transfermatrix, um die Koordinaten des Punktes im neuen Koordinatensystem zu berechnen.

1.1. Warum ist die Umkehrung der drei Achsenvektoren im neuen Koordinatensystem die Transfermatrix?

Im dreidimensionalen Raum kann ein Koordinatensystem aus drei nicht kollinearen Vektoren bestehen, die die drei Achsen des Koordinatensystems darstellen. Für eine Transformationsmatrix vom alten Koordinatensystem zum neuen Koordinatensystem können wir sie als 3x3-Matrix ausdrücken, wobei jede Spalte die Koordinatendarstellung eines Achsenvektors des neuen Koordinatensystems im alten Koordinatensystem darstellt.

Angenommen, wir haben die drei Achsenvektoren x_axis_new, y_axis_new und z_axis_new des neuen Koordinatensystems bestimmt, dann können wir sie in eine 3x3-Matrix umwandeln, die als Rotation bezeichnet wird, das heißt:

Eigen::Matrix3d rotation;
rotation << x_axis_new, y_axis_new, z_axis_new;

Da jede Rotationsspalte die Koordinatendarstellung eines Achsenvektors des neuen Koordinatensystems im alten Koordinatensystem darstellt, stellt die inverse Rotationsmatrix die Koordinatendarstellung der drei Achsenvektoren des alten Koordinatensystems im neuen Koordinatensystem dar. Auf diese Weise können wir einen Vektor vom alten Koordinatensystem in das neue Koordinatensystem transformieren, indem wir den Vektor als Spaltenvektor ausdrücken und ihn dann mit der inversen Rotationsmatrix multiplizieren, das heißt:

Eigen::Vector3d v_old(x_old, y_old, z_old);
Eigen::Vector3d v_new = rotation.inverse() * v_old;

Daher können wir die inverse Rotationsmatrix als Übertragungsmatrix verwenden, um den Vektor vom alten Koordinatensystem in das neue Koordinatensystem zu transformieren.

1.2. Welche Methode sollte verwendet werden, um die Koordinaten eines Punktes im ursprünglichen Koordinatensystem im neuen Koordinatensystem zu ermitteln?

(1) Um die Koordinaten eines Punktes im ursprünglichen Koordinatensystem im neuen Koordinatensystem zu ermitteln, können Sie die folgenden zwei Methoden verwenden, um dies zu erreichen:

Verwenden Sie die Funktion „solve()“: Auf diese Weise werden die drei Achsenvektoren des neuen Koordinatensystems als Spaltenvektoren der Matrix und die Punkte im ursprünglichen Koordinatensystem als Vektor b verwendet, um das lineare Gleichungssystem Ax = zu lösen b, wobei x der Punkt im neuen Koordinatensystem ist. Koordinaten in einem Koordinatensystem. Konkret lautet der Code wie folgt:

Eigen::Matrix3d transMat;
transMat.col(0) = axis1_new;
transMat.col(1) = axis2_new;
transMat.col(2) = axis3_new;
Eigen::Vector3d p_old; // 原始坐标系中的点
Eigen::Vector3d origin; // 新坐标系的原点
Eigen::Vector3d p_new = transMat.solve(p_old - origin);

(2) Matrixmultiplikation verwenden: Diese Methode verwendet eine 4x4-Transformationsmatrix T zur Darstellung der Koordinatentransformation, wobei die ersten drei Zeilen die drei Achsenvektoren des neuen Koordinatensystems darstellen und die letzte Zeile den Ursprung des neuen Koordinatensystems darstellt . Stellen Sie den Punkt im ursprünglichen Koordinatensystem als vierdimensionale homogene Koordinate dar. Berechnen Sie die vierdimensionale homogene Koordinate des Punktes im neuen Koordinatensystem durch Matrixmultiplikation. Teilen Sie dann die homogene Koordinate durch die vierte Komponente, um die neue Koordinate von zu erhalten der Punkt. Dreidimensionale Koordinaten im System. Konkret lautet der Code wie folgt:

Eigen::Matrix4d transform;
transform << axis1_new, 0,
             axis2_new, 0,
             axis3_new, 0,
             origin_new, 1;
Eigen::Vector4d p_old_homog(p_old(0), p_old(1), p_old(2), 1);
Eigen::Vector4d p_new_homog = transform * p_old_homog;
Eigen::Vector3d p_new = p_new_homog.head<3>() / p_new_homog(3);

Diese beiden Methoden sind im Wesentlichen gleichwertig, implementieren sie jedoch etwas anders. Die Verwendung der Funktion „solve()“ ist intuitiver, erfordert jedoch das explizite Lösen der linearen Gleichungen, was möglicherweise zeitaufwändiger ist. Die Verwendung einer Matrixmultiplikation ist möglicherweise effizienter, Sie müssen jedoch bei der Implementierung auf die homogene Koordinatentransformation achten. Die spezifische Implementierungsmethode sollte entsprechend der spezifischen Situation ausgewählt werden.

Die Idee in Methode (2) ähnelt dem Code in Referenz 2 für die Quelle der Idee.

1.3

Eigen::Vector3d newP2 = transMat.solve(p2 - origin);

solve函数的使用和下面这句代码有什么不同吗

Eigen::Vector3d p2_new = transform * (p2_old - origin_new);

In Eigen können sowohl die Funktionsolve() als auch die Matrixmultiplikation verwendet werden, um die Koordinaten eines Vektors relativ zu einem neuen Koordinatensystem zu berechnen. Die Art und Weise, wie sie umgesetzt werden, ist jedoch unterschiedlich.

Die Funktion „solve()“ wird verwendet, um die lineare Gleichung Ax=b zu lösen, wobei A eine Matrix, b ein Vektor und x ein unbekannter Vektor ist, und wird zur Berechnung des Werts des Vektors x verwendet. In Eigen ist das Aufrufformat der Funktionsolve() x = A.solve(b).

Bei diesem Problem können wir uns die Transfermatrix transMat als eine lineare Transformation vorstellen, die die Vektoren im ursprünglichen Koordinatensystem in Vektoren im neuen Koordinatensystem umwandelt. Wenn wir dann die Koordinaten des Vektors p2 relativ zum neuen Koordinatensystem berechnen möchten, können wir ihn als lineares Gleichungssystem Ax = b ausdrücken, wobei A die Übertragungsmatrix, b der ursprüngliche Vektor p2 und x ist der Vektor im neuen Koordinatensystem p2_new. Daher können wir die Funktionsolve() verwenden, um den Wert von p2_new wie folgt zu berechnen:

Eigen::Vector3d p2_new = transMat.solve(p2 - origin);

Bei der Matrixmultiplikation hingegen wird ein Vektor einem anderen zugeordnet, was eine weitere Möglichkeit zur Implementierung einer Vektortransformation darstellt. In Eigen können wir die Matrixmultiplikation verwenden, um die Koordinaten eines Vektors relativ zu einem neuen Koordinatensystem zu berechnen. Insbesondere können wir eine Matrixtransformation verwenden, um die Koordinatentransformation darzustellen, den Vektor p2_old verwenden, um den Vektor im ursprünglichen Koordinatensystem darzustellen, und den Vektor origin_new verwenden, um den Ursprung des neuen Koordinatensystems darzustellen. Dann können wir den folgenden Code verwenden, um den Wert von p2_new zu berechnen:

Eigen::Vector3d p2_new = transform * (p2_old - origin_new);

Im Allgemeinen können sowohl die Funktion „solve()“ als auch die Matrixmultiplikation verwendet werden, um die Koordinaten eines Vektors relativ zu einem neuen Koordinatensystem zu berechnen, sie werden jedoch unterschiedlich implementiert. Die Funktion „solve()“ wird zum Lösen linearer Gleichungen verwendet, während die Matrixmultiplikation Vektoren in ein neues Koordinatensystem abbildet. Welche Methode in der Praxis zum Einsatz kommt, hängt vom konkreten Anwendungsszenario und den Anforderungen ab.

1.4. Referenzen für Ideenquellen

  1. https://stackoverflow.com/questions/49769459/convert-points-on-a-3d-plane-to-2d-coordinates/49771112#49771112

  1. https://stackoverflow.com/questions/68506084/i-have-a-plane-between-3-points-and-want-to-get-a-transformation-matrix-which-al

  1. https://stackoverflow.com/questions/52154004/problem-superimposing-and-aligning-3d-triangles/52163563#52163563

  1. https://math.stackexchange.com/questions/1983054/using-3-points-create-new-coordinate-system-and-create-array-of-points-on-xy

1.5. Die Rechte-Hand-Regel bestimmt das räumliche Koordinatensystem

http://www.gaosan.com/gaokao/262408.html

2. Code-Praxis

#include <iostream>
#include <Eigen/Dense>
using namespace Eigen;
using namespace std;

using Eigen::Matrix3d;

// 三个点的坐标信息
//Vector3d p1(1.0, 2.0, 3.0);
//Vector3d p2(4.0, 5.0, 6.0);
//Vector3d p3(7.0, 8.0, 9.0);


Vector3d p1(1.0, 0.0, 0.0);
Vector3d p2(0.0, 1.0, 0.0);
Vector3d p3(0.0, 0.0, 1.0);

Vector3d p4(0.5, 0.5, 0.0);

int main()
{

    //求新坐标的三个轴向量
    Eigen::Matrix3d transMat;
    transMat.col(0) = (p2 - p1).normalized();

    std::cout << transMat.col(0) << std::endl;

    transMat.col(2) = transMat.col(0).cross((p3 - p1)).normalized();

    std::cout << transMat.col(2) << std::endl;

    transMat.col(1) = transMat.col(2).cross(transMat.col(0));

    std::cout << transMat.col(1) << std::endl;

    //求转移矩阵,新坐标的三个轴向量求逆就是转移矩阵
    Eigen::Matrix3d transform1 = transMat.inverse();

    //求点在新坐标系下的坐标
    Eigen::Vector3d origin = p1;
    Eigen::Vector3d newP1 = Eigen::Vector3d::Zero();
    Eigen::Vector3d newP2 = transform1 * (p2 - origin);
    Eigen::Vector3d newP3 = transform1 * (p3 - origin);

    Eigen::Vector3d newP4 = transform1 * (p4 - origin);

    std::cout << newP1 << std::endl;

    std::cout << newP2 << std::endl;

    std::cout << newP3 << std::endl;

    std::cout << newP4 << std::endl;
    
}

3. Es wurde überprüft, dass dieser Code die Koordinaten der Punkte im ursprünglichen Koordinatensystem im neuen Koordinatensystem finden kann.

Guess you like

Origin blog.csdn.net/pingchangxin_6/article/details/129588902
Recommended