Call the code written in c++ in matlab. The eigen library is used in the c++ code. The eigen library needs a compiler above c++ 14. Compile in matlab:
mex CoorTransformer.cpp -IE:\git\eigen
The eigen library reports that the minGW used by matlab does not support the c++14 standard, and only supports c++11.
Solution:
I am using MATLAB R2019b, the compile option is in C:\Users\Administrator\AppData\Roaming\MathWorks\MATLAB\R2019b\mex_C++ _win64.xml
In the file, change “$CFLAGS -std=c++11” to “$CFLAGS -std=c++14”.
minGW is in the link given by matlab: https://ww2.mathworks.cn/matlabcentral/fileexchange/52848-matlab-support-for-mingw-w64-c-c-compiler
Attach the test code:
#include "CoorTransformer.h" #include <iostream> #include <Eigen/Dense> #include <Eigen/Geometry> #include "mex.h" using namespace std; /** * CoorTransformer implementation */ Interpolation::Interpolation() { } void Interpolation::interpolate(const float q1w, const float q1x, const float q1y, const float q1z, const float p1x, const float p1y, const float p1z, const float q2w, const float q2x, const float q2y, const float q2z, const float p2x, const float p2y, const float p2z, float & amp;q3w, float & amp;q3x, float & amp;q3y, float & amp;q3z, float & amp;p3x, float & amp;p3y, float & amp;p3z, float scalar) { // interpolation quaternion Eigen::Quaterniond point1_q(q1w, q1x, q1y, q1z); point1_q.normalize(); Eigen::Quaterniond point2_q(q2w, q2x, q2y, q2z); point2_q.normalize(); Eigen::Quaterniond inter_q(1, 0, 0, 0); inter_q = point1_q.slerp(scalar, point2_q); inter_q.normalize(); mexPrintf("point1 q normalize: %f %f %f %f\ ", point1_q.w(), point1_q.x(), point1_q.y(), point1_q.z()); mexPrintf("point2 q normalize: %f %f %f %f\ ", point2_q.w(), point2_q.x(), point2_q.y(), point2_q.z()); mexPrintf("inter q normalize: %f %f %f %f\ ", inter_q.w(), inter_q.x(), inter_q.y(), inter_q.z()); // interpolation position const Eigen::Vector3d point1_p(p1x, p1y, p1z); const Eigen::Vector3d point2_p(p2x, p2y, p2z); Eigen::Vector3d inter_p(0, 0, 0); inter_p = (point2_p - point1_p) * scalar + point1_p; mexPrintf("point1 p normalize: %f %f %f\ ", point1_p.x(), point1_p.y(), point1_p.z()); mexPrintf("point2 p normalize: %f %f %f\ ", point2_p.x(), point2_p.y(), point2_p.z()); mexPrintf("inter p normalize: %f %f %f\ ", inter_p.x(), inter_p.y(), inter_p.z()); // Output interpolation q3w = inter_q.w(); q3x = inter_q.x(); q3y = inter_q.y(); q3z = inter_q.z(); p3x = inter_p.x(); p3y = inter_p.y(); p3z = inter_p.z(); } // MEX function /* The calling method on matlab is: [q3w,q3x,q3y,q3z,p3x,p3y,p3z] = CoorTransformer(q1w,q1x,q1y,q1z,p1x,p1y,p1z,q2w,q2x,q2y,q2z,p2x ,p2y,p2z,0.5) Input 15 parameters and output 7 parameters */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { mexPrintf("input number: %d\ ", nrhs); mexPrintf("output number: %d\ ", nlhs); // input float q1w = *(mxGetPr(prhs[0])); float q1x = *(mxGetPr(prhs[1])); float q1y = *(mxGetPr(prhs[2])); float q1z = *(mxGetPr(prhs[3])); float p1x = *(mxGetPr(prhs[4])); float p1y = *(mxGetPr(prhs[5])); float p1z = *(mxGetPr(prhs[6])); float q2w = *(mxGetPr(prhs[7])); float q2x = *(mxGetPr(prhs[8])); float q2y = *(mxGetPr(prhs[9])); float q2z = *(mxGetPr(prhs[10])); float p2x = *(mxGetPr(prhs[11])); float p2y = *(mxGetPr(prhs[12])); float p2z = *(mxGetPr(prhs[13])); float scalar = *(mxGetPr(prhs[14])); mexPrintf("input1: (%f %f %f %f)(%f %f %f)\ ", q1w, q1x, q1y, q1z, p1x, p1y, p1z); mexPrintf("input2: (%f %f %f %f)(%f %f %f)\ ", q2w, q2x, q2y, q2z, p2x, p2y, p2z); float q3w; float q3x; float q3y; float q3z; float p3x; float p3y; float p3z; Interpolation intp; intp.interpolate(q1w, q1x, q1y, q1z, p1x, p1y, p1z, q2w, q2x, q2y, q2z, p2x, p2y, p2z, q3w, q3x, q3y, q3z, p3x ,p3y, p3z, scalar); // output plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL); *(mxGetPr(plhs[0])) = q3w; plhs[1] = mxCreateDoubleMatrix(1, 1, mxREAL); *(mxGetPr(plhs[1])) = q3x; plhs[2] = mxCreateDoubleMatrix(1, 1, mxREAL); *(mxGetPr(plhs[2])) = q3y; plhs[3] = mxCreateDoubleMatrix(1, 1, mxREAL); *(mxGetPr(plhs[3])) = q3z; plhs[4] = mxCreateDoubleMatrix(1, 1, mxREAL); *(mxGetPr(plhs[4])) = p3x; plhs[5] = mxCreateDoubleMatrix(1, 1, mxREAL); *(mxGetPr(plhs[5])) = p3y; plhs[6] = mxCreateDoubleMatrix(1, 1, mxREAL); *(mxGetPr(plhs[6])) = p3z; mexPrintf("output: (%f %f %f %f)(%f %f %f)\ ", q3w, q3x, q3y, q3z, p3x, p3y, p3z); }
Execute in matlab:
mex -setup C++
mex CoorTransformer.cpp -IE:\git\eigen
q1w=0.9659;
q1x=0;
q1y=0;
q1z=0.2588;
p1x=100;
p1y=200;
p1z=300;
q2w=0.866;
q2x=0;
q2y=0;q2z=0.5;
p2x=200;
p2y=300;
p2z=400;
q3w=0;
q3x=0;
q3y=0;
q3z=0;
p3x=0;
p3y=0;
p3z=0;
[q3w,q3x,q3y,q3z,p3x,p3y,p3z] = CoorTransformer(q1w,q1x,q1y,q1z,p1x,p1y,p1z,q2w,q2x,q2y,q2z,p2x,p2y,p2z,0.2);
The correct result can be obtained:
>> [q3w,q3x,q3y,q3z,p3x,p3y,p3z] = CoorTransformer(q1w,q1x,q1y,q1z,p1x,p1y,p1z,q2w,q2x,q2y,q2z,p2x,p2y,p2z,0.2) ;
input number: 15
output number: 7
input1: (0.965900 0.000000 0.000000 0.258800)(100.000000 200.000000 300.000000)
input2: (0.866000 0.000000 0.000000 0.500000)(200.000000 300.000000 400.000000)
point1 q normalize: 0.965929 0.000000 0.000000 0.258808
point2 q normalize: 0.866019 0.000000 0.000000 0.500011
inter q normalize: 0.951059 0.000000 0.000000 0.309010
point1 p normalize: 100.000000 200.000000 300.000000
point2 p normalize: 200.000000 300.000000 400.000000
inter p normalize: 120.000000 220.000000 320.000000
output: (0.951059 0.000000 0.000000 0.309011)(120.000000 220.000000 320.000000)