OCC 逆矩阵

功能实现导入的CAD模型通过选择面线点创建坐标系,获取逆矩阵,把模型按世界坐标系移动到原点,这样机台上实物坐标系和软件中模型坐标系对应,才能开始测量或者加工。一下是一位大佬分享的手搓的逆矩阵获取方法,看到OCC也有4X4矩阵逆矩阵获取方法应该都能实现。一直不明白的是逆矩阵怎么计算转换失败的情况是什么样,希望同学们帮忙解答。

#include <iostream>
#include <vector>

using namespace std;

// 计算矩阵的行列式
float determinant(const vector<vector<float>>& mat, int n) {
    if (n == 1) return mat[0][0];
    if (n == 2) return mat[0][0]*mat[1][1] - mat[0][1]*mat[1][0];

    float det = 0;
    vector<vector<float>> temp(n, vector<float>(n));

    for (int p = 0; p < n; p++) {
        int h = 0, k = 0;
        for (int i = 1; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (j == p) continue;
                temp[h][k++] = mat[i][j];
                if (k == n - 1) {
                    k = 0;
                    h++;
                }
            }
        }
        det += (p % 2 == 0 ? 1 : -1) * mat[0][p] * determinant(temp, n - 1);
    }
    return det;
}

// 计算矩阵的余子式矩阵
vector<vector<float>> getMinor(const vector<vector<float>>& mat, int row, int col, int n) {
    vector<vector<float>> minor(n - 1, vector<float>(n - 1));
    int r = 0, c = 0;
    for (int i = 0; i < n; i++) {
        if (i == row) continue;
        c = 0;
        for (int j = 0; j < n; j++) {
            if (j == col) continue;
            minor[r][c++] = mat[i][j];
        }
        r++;
    }
    return minor;
}

// 计算矩阵的伴随矩阵
vector<vector<float>> adjugate(const vector<vector<float>>& mat, int n) {
    vector<vector<float>> adj(n, vector<float>(n));
    vector<vector<float>> minor(n - 1, vector<float>(n - 1));
    float sign;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            minor = getMinor(mat, i, j, n);
            sign = ((i + j) % 2 == 0) ? 1.0 : -1.0;
            adj[j][i] = sign * determinant(minor, n - 1);  // 转置
        }
    }
    return adj;
}

// 计算矩阵的逆矩阵
vector<vector<float>> inverse(const vector<vector<float>>& mat, int n) {
    vector<vector<float>> inv(n, vector<float>(n));
    float det = determinant(mat, n);

    if (det == 0) {
        cout << "Matrix is singular and cannot be inverted." << endl;
        return inv;
    }

    vector<vector<float>> adj = adjugate(mat, n);
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            inv[i][j] = adj[i][j] / det;
        }
    }
    return inv;
}

// 打印矩阵
void printMatrix(const vector<vector<float>>& mat) {
    for (const auto& row : mat) {
        for (float val : row) {
            cout << val << " ";
        }
        cout << endl;
    }
}

int main() {
    // 定义一个 4x4 矩阵
    vector<vector<float>> mat = {
        {1, 2, 3, 4},
        {5, 6, 7, 8},
        {9, 10, 11, 12},
        {13, 14, 15, 16}
    };

    cout << "Original Matrix:" << endl;
    printMatrix(mat);

    vector<vector<float>> invMat = inverse(mat, 4);

    cout << "Inverse Matrix:" << endl;
    printMatrix(invMat);

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

和光同尘 、Y_____

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值