stm32 实现3D图形动态绘制

一、基础知识

计算机3D图形学最最最基本的目标就是:将构建好的3D物体显示在2D屏幕坐标上;可以先了解一下相关知识。

防丢:下面两篇文章内容我打包到资源中了,可以在我的资源中找到;
要将一个3维图形 在二维界面旋转显示,可以采用旋转矩阵的方式;一个点需要进行三次矩阵点乘,然后把图形所有的顶点全部进行三次点乘就可以获得最终的点坐标

1.矩阵运算

大学唯一挂的科-线性代数;必须先补充一下,链接是讲的比较简单的文章;不用回去翻书。
线性代数- 矩阵运算

2.三维坐标旋转矩阵变换

二维旋转矩阵推导
下面的文章是坐标变换的过程
三维坐标旋转矩阵推导过程(包看懂)

3.三维旋转矩阵

绕X轴旋转 θ \theta θ角度的旋转矩阵Rx(θ)

R x ( θ ) = [ 1 0 0 0 cos ⁡ θ − sin ⁡ θ 0 sin ⁡ θ cos ⁡ θ ] R_x(\theta) = \begin{bmatrix} 1 & 0 & 0 \\ 0 & \cos\theta & -\sin\theta \\ 0 & \sin\theta & \cos\theta \end{bmatrix} Rx(θ)= 1000cosθsinθ0sinθcosθ

绕Y轴旋转 θ \theta θ角度的旋转矩阵 Ry(θ)

R y ( θ ) = [ cos ⁡ θ 0 sin ⁡ θ 0 1 0 − sin ⁡ θ 0 cos ⁡ θ ] R_y(\theta) = \begin{bmatrix} \cos\theta & 0 & \sin\theta \\ 0 & 1 & 0 \\ -\sin\theta & 0 & \cos\theta \end{bmatrix} Ry(θ)= cosθ0sinθ010sinθ0cosθ

绕Z轴旋转 θ \theta θ角度的旋转矩阵Rz(θ)

R z ( θ ) = [ cos ⁡ θ − sin ⁡ θ 0 sin ⁡ θ cos ⁡ θ 0 0 0 1 ] R_z(\theta) = \begin{bmatrix} \cos\theta & -\sin\theta & 0 \\ \sin\theta & \cos\theta & 0 \\ 0 & 0 & 1 \end{bmatrix} Rz(θ)= cosθsinθ0sinθcosθ0001

二、C语言实现

矩阵运算库-C https://github.com/Amoiensis/Matrix_hub

1. 关键函数-C

// 矩阵乘法运算-通用
// a[m][n] * b[n][p] = c[m][p]
// mid = n;
// 序号 = 列数*行索引 + 列索引
// c的元素个数  m*p   序号 :  p*(0 -- m-1) + (0 -- p-1)   
// a的元素个数  m*n   序号 :   n*(0 -- m-1) + (0 -- n-1)
// b的元素个数  n*p   序号 :   p*(0 -- n-1) + (0 -- p-1)
float* Matrex_Conv(int l_row,int l_col,int r_row,int r_col, float* martex_l, float* martex_r)// a[m][n] * b[n][p] = c[m][p]
{
    int i,j,k,mid;
    float* martex_o;
    if(l_col != r_row)
    {
        return NULL;
    }
    mid = r_row;

    for(i = 0; i < l_row;+ i++)  //m
    {
        for(k = 0; k < r_col; k++)    //p
        {
            for (j = 0; j < mid; j++)  //n
            {
                martex_o[i*r_col+k] +=  martex_l[i*l_col + j] * martex_r[j*r_col+k];// martex_l 行不变 列++ martex_r 列不变 行++
            }
        }
    }
    return martex_o;
}

 //计算矩阵乘法 - 简化版 因为行列已知
 // float a[3] = {x,y.z};
float* Matrex_Conv(float* a, float b[3][3])
{
    float res[3];
    for(int i = 0; i < 3; i++)
        res[i] = b[i][0] * a[0] + b[i][1] * a[1] + b[i][2] * a[2];
    for(int i = 0; i < 3; i++)a[i] = res[i];
    return a;
}

//x,y,z为弧度制
void rotate(float* obj, float x, float y, float z) //旋转该向量
{

    float rx[3][3] = { {1,       0,          0}, 
                       {0,    cos(y),  -sin(y)},
                       {0,    sin(y),  cos(y)}};
    float ry[3][3] = { {cos(x),   0,    sin(x)},
                       {0,        1,         0}, 
                       {-sin(x),  0,    cos(x)}};
    float rz[3][3] = { {cos(z),  -sin(z),   0}, 
                       {sin(z),   cos(z),   0}, 
                       {0,        0,        1}};
    obj = Matrex_Conv(obj,rx);
    obj = Matrex_Conv(obj,ry);
    obj = Matrex_Conv(obj,rz);
}

2.继续简化

实际还能简化
绕x轴旋转时,x坐标不变,转换为2维点旋转,分别进行3次二维点旋转即可。

// 绕y轴旋转x′ = x*cosβ - y*sinβ
//         y′ =  x*sinβ + y*cosβ
void rotate(float* obj, float pitch, float yow, float roll)
{
    
    float  sin_p,cos_p,sin_y,cos_y,sin_r,cos_r;
    float  xt,yt,zt,x,y,z;
    x = obj[0];
    y = obj[1];
    z = obj[2];

    sin_p = sin(pitch); 
    cos_p = cos(pitch); 

    sin_y = sin(yow); 
    cos_y = cos(yow); 

    sin_r = sin(roll); 
    cos_r = cos(roll); 

   //绕x轴旋转;x轴坐标不变
    yt = y * cos_p - z * sin_p;       
    zt = y * sin_p + z * cos_p;       
    y = yt;
    z = zt;

    //绕y轴旋转;y轴坐标不变
    xt = x * cos_y - z * sin_y;        
    zt = x * sin_y + z * cos_y;        
    x = xt;
    z = zt;

    //绕x轴旋转;z轴坐标不变
    xt = x * cos_r - y * sin_r;        // finaly rotate around the Z axis
    yt = x * sin_r + y * cos_r;        // using X and Y
    x = xt;
    y = yt;

    obj[0] = x;
    obj[1] = y;
    obj[2] = z;
}

3. 旋转图形

有了前面对单个点的旋转后,将图形所有顶点进行旋转后就可以得到整体图形的旋转效果;
常在各种视频中看到旋转的3d立方体,实际上;项目中通常用于模型姿态显示可以说效果会很好。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值