二維變換矩陣的座標變換,逆矩陣,角度的實現
阿新 • • 發佈:2019-01-06
二維矩陣可表示為:
a b c d e f
矩陣原型為
a b 0
c d 0
e f 1
座標變換
座標(x,y)經矩陣M變換後得到座標(x1,y1)的過程,可以當作矩陣乘法來對待:
M * [x, y, 1] = [x1, y1, 1]
其中M表示為:
[a b 0]
[c d 0]
[e f 1]
用c程式碼可表示為:
void MatTransform(const double *m, double x_in, double y_in, double *x_out, double *y_out){
double x = x_in;
double y = y_in;
*x_out = m[0]*x + m[2]*y + m[4];
*y_out = m[1]*x + m[3]*y + m[5];
}
矩陣相乘
用c程式碼表示為:
// [a b 0] [a1 b1 0] [a2 b1 0]
// [c d 0] [c1 d1 0] [c2 d2 0]
// [e f 1] * [e1 f1 1] = [e2 f2 1]
// m1_in m2_in m_out
void MatMul(const double *m1_in, const double *m2_in, double *m_out){
double m1[6 ], m2[6];
m1[0] = m1_in[0];
m1[1] = m1_in[1];
m1[2] = m1_in[2];
m1[3] = m1_in[3];
m1[4] = m1_in[4];
m1[5] = m1_in[5];
m2[0] = m2_in[0];
m2[1] = m2_in[1];
m2[2] = m2_in[2];
m2[3] = m2_in[3];
m2[4] = m2_in[4];
m2[5] = m2_in[5];
m_out[0] = m1[0]*m2[0] + m1[1 ]*m2[2];
m_out[1] = m1[0]*m2[1] + m1[1]*m2[3];
m_out[2] = m1[2]*m2[0] + m1[3]*m2[2];
m_out[3] = m1[2]*m2[1] + m1[3]*m2[3];
m_out[4] = m1[4]*m2[0] + m1[5]*m2[2] + m2[4];
m_out[5] = m1[4]*m2[1] + m1[5]*m2[3] + m2[5];
}
逆矩陣的快速演算法
用c程式碼可表示為:
// m[6] = {a, b c, d, e, f};
bool MatInverse(const double *m_in, double *m_out){
double det;
double m[6];
det = m_in[0]*m_in[3] - m_in[1]*m_in[2];
// Singular Matrix
if( det<0.000001 && det>-0.000001 ){
return false;
}
m[0] = m_in[0];
m[1] = m_in[1];
m[2] = m_in[2];
m[3] = m_in[3];
m[4] = m_in[4];
m[5] = m_in[5];
m_out[0] = m[3]/det;
m_out[1] = -m[1]/det;
m_out[2] = -m[2]/det;
m_out[3] = m[0]/det;
m_out[4] = (m[2]*m[5] - m[3]*m[4])/det;
m_out[5] = (m[1]*m[4] - m[0]*m[5])/det;
return true;
}
二維矩陣的角度的求法:
將座標(1,0)與矩陣M做乘法運算,得到一個變換後的座標(x, y),這時,線段(0,0)-(x, y) 與 線段(0,0)-(1, 0)所成的角就是M的旋轉角。
用c程式碼表示為:
// m[6] = {a, b c, d, e, f};
bool MatGetRotation(const double *m, double *rot){
double det, r;
det = m[0]*m[3] - m[1]*m[2];
// Singular Matrix
if( det<0.000001 && det>-0.000001 ){
return false;
}
r = sqrt(m[0]*m[0] + m[1]*m[1]);
*rot = asin(m[1]/r)*180.0/3.14159265358979323846;
return true;
}
近期處理2d座標時,沒有搜到相關的內容。不得已自己動手寫了一個,記下以備後用。