1. 程式人生 > >二維變換矩陣的座標變換,逆矩陣,角度的實現

二維變換矩陣的座標變換,逆矩陣,角度的實現

二維矩陣可表示為:
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座標時,沒有搜到相關的內容。不得已自己動手寫了一個,記下以備後用。