आप चौका गणना कर सकते हैं में से एक से सबसे अच्छा संभव परिवर्तन का प्रतिनिधित्व करने
वेक्टर से Quaternion:
कोड स्निपेट है इस पेपर में वर्णित विधि द्वारा सिस्टम को समन्वयित करें:
पॉल जे। बेसल और नील डी। मैके "3-डी आकार के पंजीकरण के लिए विधि", सेंसर फ़्यूज़न IV: नियंत्रण पैराडिगम्स और डेटा स्ट्रक्चर, 586 (30 अप्रैल, 1 99 2); http://dx.doi.org/10.1117/12.57955
कागज खुली पहुंच नहीं है, लेकिन मैं तुम्हें अजगर कार्यान्वयन दिखा सकते हैं:
def get_quaternion(lst1,lst2,matchlist=None):
if not matchlist:
matchlist=range(len(lst1))
M=np.matrix([[0,0,0],[0,0,0],[0,0,0]])
for i,coord1 in enumerate(lst1):
x=np.matrix(np.outer(coord1,lst2[matchlist[i]]))
M=M+x
N11=float(M[0][:,0]+M[1][:,1]+M[2][:,2])
N22=float(M[0][:,0]-M[1][:,1]-M[2][:,2])
N33=float(-M[0][:,0]+M[1][:,1]-M[2][:,2])
N44=float(-M[0][:,0]-M[1][:,1]+M[2][:,2])
N12=float(M[1][:,2]-M[2][:,1])
N13=float(M[2][:,0]-M[0][:,2])
N14=float(M[0][:,1]-M[1][:,0])
N21=float(N12)
N23=float(M[0][:,1]+M[1][:,0])
N24=float(M[2][:,0]+M[0][:,2])
N31=float(N13)
N32=float(N23)
N34=float(M[1][:,2]+M[2][:,1])
N41=float(N14)
N42=float(N24)
N43=float(N34)
N=np.matrix([[N11,N12,N13,N14],\
[N21,N22,N23,N24],\
[N31,N32,N33,N34],\
[N41,N42,N43,N44]])
values,vectors=np.linalg.eig(N)
w=list(values)
mw=max(w)
quat= vectors[:,w.index(mw)]
quat=np.array(quat).reshape(-1,).tolist()
return quat
यह समारोह चार का समुदाय है कि आप देख रहे थे देता है। तर्क lst1 और lst2 numpy की सूचियां हैं।सरणी जहां हर सरणी एक 3 डी वेक्टर का प्रतिनिधित्व करता है। यदि दोनों सूचियां लंबाई 3 (और ऑर्थोगोनल यूनिट वैक्टर शामिल हैं) हैं, तो quaternion सटीक परिवर्तन होना चाहिए। यदि आप लंबी सूचियां प्रदान करते हैं, तो आपको quaternion मिलता है जो दोनों बिंदु सेटों के बीच अंतर को कम करता है। वैकल्पिक मिलानसूची तर्क का उपयोग फ़ंक्शन को बताने के लिए किया जाता है जो lst2 के बिंदु को lst1 में किस बिंदु पर परिवर्तित किया जाना चाहिए। कोई matchlist प्रदान की जाती है, तो समारोह मानता है कि lst1 में पहला बिंदु lst2 में और बहुत आगे है पहला बिंदु से मेल खाना चाहिए ...
C++ 3 अंक के सेट के लिए एक समान कार्य निम्नलिखित है:
#include <Eigen/Dense>
#include <Eigen/Geometry>
using namespace Eigen;
/// Determine rotation quaternion from coordinate system 1 (vectors
/// x1, y1, z1) to coordinate system 2 (vectors x2, y2, z2)
Quaterniond QuaternionRot(Vector3d x1, Vector3d y1, Vector3d z1,
Vector3d x2, Vector3d y2, Vector3d z2) {
Matrix3d M = x1*x2.transpose() + y1*y2.transpose() + z1*z2.transpose();
Matrix4d N;
N << M(0,0)+M(1,1)+M(2,2) ,M(1,2)-M(2,1) , M(2,0)-M(0,2) , M(0,1)-M(1,0),
M(1,2)-M(2,1) ,M(0,0)-M(1,1)-M(2,2) , M(0,1)+M(1,0) , M(2,0)+M(0,2),
M(2,0)-M(0,2) ,M(0,1)+M(1,0) ,-M(0,0)+M(1,1)-M(2,2) , M(1,2)+M(2,1),
M(0,1)-M(1,0) ,M(2,0)+M(0,2) , M(1,2)+M(2,1) ,-M(0,0)-M(1,1)+M(2,2);
EigenSolver<Matrix4d> N_es(N);
Vector4d::Index maxIndex;
N_es.eigenvalues().real().maxCoeff(&maxIndex);
Vector4d ev_max = N_es.eigenvectors().col(maxIndex).real();
Quaterniond quat(ev_max(0), ev_max(1), ev_max(2), ev_max(3));
quat.normalize();
return quat;
}
हालांकि आपका कोड दिलचस्प था, यह वास्तव में मेरी समस्या का समाधान नहीं करता था। अंत में मैंने नौकरी करने के लिए एक दिशा कोसिनस मैट्रिक्स (डीसीएम) का उपयोग किया।मुझे अभी भी दिलचस्पी है यदि कोई व्यक्ति रूपांतरण quaternion प्राप्त करने के लिए एक तरीका प्रदान कर सकता है, लेकिन मुझे सच में यकीन नहीं है कि यूलर या डीसीएम का उपयोग किए बिना सीधे इस quaternion प्राप्त करना संभव है। – Mo3bius