EVE系列芯片有个特别的功能,矩阵计算,这是构成图形处理学的基本公式,熟悉它就可以实现不少特殊的效果。

矩阵的公式如下:

EVE-18 矩阵运算,其中A-F对应EVE芯片的寄存器BITMAP_TRANSFORM_A~ BITMAP_TRANSFORM_F。

矩阵计算公式为:

EVE-18 矩阵运算

即:

X’ = X * A + Y * B + C

Y’ = X * D + Y * E + F

默认的矩阵为:

EVE-18 矩阵运算

即X’ = X,Y’ = Y

 

还需要了解什么是齐次坐标和变换通式。齐次坐标是用一个n+1维向量表示一个n维向量的方法。二维点[x y]用[X Y H]表示,H可以是任意值,正常化齐次坐标H为1。变换通式T:

EVE-18 矩阵运算

EVE芯片不支持G, H, I这3个参数(G, H透视变换,实现3D显示重要的因子),所以这3个参数的值为:0, 0, 1,即FT8xx的变换通式T为:

EVE-18 矩阵运算

计算公式为:

EVE-18 矩阵运算

EVE芯片用整数来表示A - F, 256表示1.0,所以0.5即为数字128,2为数字512,以此类推。下面的公式里都会用原始数字表示,而代码里面则会变成原始数字乘以256。

旋转,放大缩小功能都是基于矩阵计算实现的,也就是说也可以直接运算结果实现这些基本功能。

1. 比例变换

将图形放大或缩小的变换方法。

EVE-18 矩阵运算,其中A表示X方向上的缩放大小,E表示Y方向。CMD_SCALE就是这部分的实现。

1.0表示原图大小,小于1.0表示缩小,大于1.0表示放大。比如0.5表示缩小到原来的一半。

2. 旋转

EVE-18 矩阵运算,CMD_ROTATE是这部分的实现。

sin和cos的取值范围为[0…1], 表示角度,为正时逆时针旋转,为负时正时针旋转。默认的旋转点为左上角。

3. 平移

EVE-18 矩阵运算,CMD_TRANSLATE是这部分的实现。

取值范围-8388606~8388607,即平移像素点x256。正数++是从右向左移动,即:

EVE-18 矩阵运算

4. 水平错切变换

水平错切变换的效果就是让所有点的x坐标保持不变,而对应的y坐标则按比例发生平移,且平移的大小和该点到x轴的垂直距离成正比。

假定一个点EVE-18 矩阵运算经过错切变换后得到EVE-18 矩阵运算,对于水平错切而言,应该有如下关系:

EVE-18 矩阵运算

用矩阵表示就是:

EVE-18 矩阵运算

 

显示的效果是:

EVE-18 矩阵运算      

  

     ftWrDispCmd(BITMAP_TRANSFORM_B(100));

     ftWrDispCmd(BITMAP_TRANSFORM_C(-12 * 256));

     ftWrDispCmd(VERTEX2F((LCD_WIDTH / 2 - 30) * 16, (LCD_HEIGHT / 2 - 30) * 16));

BITMAP_TRANSFORM_B写入的参数是100,即100/256,数字越小,斜率越小,更改BITMAP_TRANSFORM_C的目的是改变X轴的起始地址。实际显示效果如下图:

EVE-18 矩阵运算

注意:图片有被切掉的原因还是因为handle中BITMAP_SIZE部分的大小定义不匹配导致。

5. 垂直错切变换

同理,垂直错切变换的效果就是让所有点的y坐标保持不变,而对应的x坐标则按比例发生平移,且平移的大小和该点到y轴的垂直距离成正比。

EVE-18 矩阵运算

它的参数是:

EVE-18 矩阵运算

     ftWrDispCmd(BITMAP_TRANSFORM_D(100));

     ftWrDispCmd(BITMAP_TRANSFORM_F(-12 * 256));

     ftWrDispCmd(VERTEX2F((LCD_WIDTH / 2 - 30) * 16, (LCD_HEIGHT / 2 - 30) * 16));

实际显示效果如下:

EVE-18 矩阵运算

6. 对称变化

a) X轴的对称变换

测试代码:

     ftWrDispCmd(BITMAP_TRANSFORM_A(256));

     ftWrDispCmd(BITMAP_TRANSFORM_B(0));

     ftWrDispCmd(BITMAP_TRANSFORM_C(0));

     ftWrDispCmd(BITMAP_TRANSFORM_D(0));

     ftWrDispCmd(BITMAP_TRANSFORM_E((int16_t)-256));

     ftWrDispCmd(BITMAP_TRANSFORM_F(60 * 256));//偏移图片高度

显示结果:

EVE-18 矩阵运算

b) Y轴的对称变换

EVE-18 矩阵运算

测试代码:

ftWrDispCmd(BITMAP_TRANSFORM_A((int16_t)-256));

ftWrDispCmd(BITMAP_TRANSFORM_B(0));

ftWrDispCmd(BITMAP_TRANSFORM_C(60*256));

ftWrDispCmd(BITMAP_TRANSFORM_D(0));

ftWrDispCmd(BITMAP_TRANSFORM_E((int16_t)256));

ftWrDispCmd(BITMAP_TRANSFORM_F(0));

显示结果如下:

EVE-18 矩阵运算

c. 45度平分线的对称变换

EVE-18 矩阵运算

测试代码:

ftWrDispCmd(BITMAP_TRANSFORM_A(0));

ftWrDispCmd(BITMAP_TRANSFORM_B((int16_t)256));

ftWrDispCmd(BITMAP_TRANSFORM_C(0 * 256));

ftWrDispCmd(BITMAP_TRANSFORM_D((int16_t)256));

ftWrDispCmd(BITMAP_TRANSFORM_E(0));

ftWrDispCmd(BITMAP_TRANSFORM_F(0 * 256));

显示结果:

EVE-18 矩阵运算

d. -45度平分线的对称变换

EVE-18 矩阵运算

测试代码:

ftWrDispCmd(BITMAP_TRANSFORM_A(0));

ftWrDispCmd(BITMAP_TRANSFORM_B((int16_t)-256));

ftWrDispCmd(BITMAP_TRANSFORM_C(60 * 256));

ftWrDispCmd(BITMAP_TRANSFORM_D((int16_t)-256));

ftWrDispCmd(BITMAP_TRANSFORM_E(0));

ftWrDispCmd(BITMAP_TRANSFORM_F(60 * 256));

显示结果:

EVE-18 矩阵运算

e. 坐标原点的对称变换

EVE-18 矩阵运算

测试代码:

ftWrDispCmd(BITMAP_TRANSFORM_A((int16_t)-256));

ftWrDispCmd(BITMAP_TRANSFORM_B(0));

ftWrDispCmd(BITMAP_TRANSFORM_C(60 * 256));

ftWrDispCmd(BITMAP_TRANSFORM_D(0));

ftWrDispCmd(BITMAP_TRANSFORM_E((int16_t)-256));

ftWrDispCmd(BITMAP_TRANSFORM_F(60 * 256));

显示结果:

EVE-18 矩阵运算

 

二维组合变换

由多个基本变换的连续实施而成的复杂变换,又称基本变换的级连。数学上就是多个矩阵的乘法,这里就说明了为什么需要用到齐次坐标(两个3x3的矩阵相乘得到的还是3x3的矩阵)。

EVE-18 矩阵运算

最常用的是居中旋转的例子,如果用CMD的方式,即:

CMD_TRANSLATE

CMD_ROTATE

CMD_TRANSLATE

那如果直接采用写矩阵的方式,以上面的图片为例:

平移

EVE-18 矩阵运算

旋转:

EVE-18 矩阵运算

平移

EVE-18 矩阵运算

最终的计算结果:

EVE-18 矩阵运算

所有参数都乘以256即得到矩阵:

EVE-18 矩阵运算

测试代码:

    ftWrDispCmd(BITMAP_TRANSFORM_A((int16_t)181));

    ftWrDispCmd(BITMAP_TRANSFORM_B((int16_t)-181));

    ftWrDispCmd(BITMAP_TRANSFORM_C(30 * 256));

    ftWrDispCmd(BITMAP_TRANSFORM_D((int16_t)181));

    ftWrDispCmd(BITMAP_TRANSFORM_E((int16_t)181));

    ftWrDispCmd(BITMAP_TRANSFORM_F(-12 * 256));

显示结果如下:

EVE-18 矩阵运算

相关文章: