- // 假设 PI 的归一化定义
- #define PI_FIXED 2147483648.0 // Q31
- /**
- * @brief 性能展示:旋转的三角形
- * @param centerX, centerY: 旋转中心
- * @param radius: 三角形外接圆半径
- * @param angle_step: 每一帧旋转的角度增量 (0-360)
- */
- void Demo_Hardware_Rotation(u16 centerX, u16 centerY, u8 radius, float angle_step)
- {
- static float current_angle = 0;
- u16 x[3], y[3];
- u16 old_x[3], old_y[3];
- static u8 first_run = 1;
- // 1. 清除上一帧 (用黑色画一遍旧的)
- if (!first_run) {
- LCD_DrawLine(old_x[0], old_y[0], old_x[1], old_y[1], BLACK);
- LCD_DrawLine(old_x[1], old_y[1], old_x[2], old_y[2], BLACK);
- LCD_DrawLine(old_x[2], old_y[2], old_x[0], old_y[0], BLACK);
- }
- // 2. 计算新坐标 (这里可以使用硬件加速思想)
- // 实际上旋转坐标公式: x' = r*cos(a), y' = r*sin(a)
- // 我们可以通过步进角度,演示硬件在处理大量三角运算时的稳定
- for (int i = 0; i < 3; i++) {
- float theta = current_angle + (i * 120.0f); // 三个角相隔120度
- float rad = theta * 3.1415926f / 180.0f;
-
- // 这里的 sin/cos 如果有硬件加速,速度会极快
- x[i] = centerX + (u16)(radius * cos(rad));
- y[i] = centerY + (u16)(radius * sin(rad));
-
- old_x[i] = x[i];
- old_y[i] = y[i];
- }
- // 3. 画出新三角形
- LCD_DrawLine(x[0], y[0], x[1], y[1], CYAN);
- LCD_DrawLine(x[1], y[1], x[2], y[2], MAGENTA);
- LCD_DrawLine(x[2], y[2], x[0], y[0], YELLOW);
- current_angle += angle_step;
- if (current_angle >= 360) current_angle = 0;
- first_run = 0;
- }
最后展示效果
再来一个托影的看看
- void Demo_Hardware_Rotation_Cool(u16 centerX, u16 centerY, u8 radius, float angle_step)
- {
- #define GHOST_COUNT 6 // 拖尾长度(包含当前帧共6帧)
-
- static float angles[GHOST_COUNT]; // 存储过去几帧的角度
- static u16 ghost_x[GHOST_COUNT][3]; // 存储过去几帧的X坐标
- static u16 ghost_y[GHOST_COUNT][3]; // 存储过去几帧的Y坐标
- static u8 frame_count = 0; // 运行帧数累计
- static float current_angle = 0;
- // 预设拖尾颜色:从深灰色到亮彩色
- // 越旧的帧颜色越暗,越新的帧颜色越亮
- u16 ghost_colors[GHOST_COUNT] = {
- 0x2104, // 极深灰 (最旧的一帧)
- 0x4208, // 深灰
- 0x632C, // 中灰
- 0x8410, // 灰蓝
- 0xAD55, // 浅蓝
- WHITE // 纯白 (当前帧)
- };
- // 1. 【擦除】只擦除最旧的那一帧(即数组第0位)
- if (frame_count >= GHOST_COUNT) {
- LCD_DrawLine(ghost_x[0][0], ghost_y[0][0], ghost_x[0][1], ghost_y[0][1], BLACK);
- LCD_DrawLine(ghost_x[0][1], ghost_y[0][1], ghost_x[0][2], ghost_y[0][2], BLACK);
- LCD_DrawLine(ghost_x[0][2], ghost_y[0][2], ghost_x[0][0], ghost_y[0][0], BLACK);
- }
- // 2. 【位移缓冲区】将旧坐标向前覆盖
- for (int i = 0; i < GHOST_COUNT - 1; i++) {
- for (int j = 0; j < 3; j++) {
- ghost_x[i][j] = ghost_x[i+1][j];
- ghost_y[i][j] = ghost_y[i+1][j];
- }
- }
- // 3. 【计算新坐标】存入缓冲区最后一位(当前帧)
- for (int i = 0; i < 3; i++) {
- float rad = (current_angle + (i * 120.0f)) * 3.1415926f / 180.0f;
- ghost_x[GHOST_COUNT-1][i] = (u16)(centerX + radius * cosf(rad));
- ghost_y[GHOST_COUNT-1][i] = (u16)(centerY + radius * sinf(rad));
- }
- // 4. 【渲染】按照由暗到亮的顺序重新画出所有残影
- // 注意:只画那些已经有数据的帧
- u8 start_idx = (frame_count < GHOST_COUNT) ? (GHOST_COUNT - frame_count) : 0;
-
- for (int i = start_idx; i < GHOST_COUNT; i++) {
- u16 color = (i == GHOST_COUNT - 1) ? CYAN : ghost_colors[i]; // 当前帧用青色,残影用灰色
-
- LCD_DrawLine(ghost_x[i][0], ghost_y[i][0], ghost_x[i][1], ghost_y[i][1], color);
- LCD_DrawLine(ghost_x[i][1], ghost_y[i][1], ghost_x[i][2], ghost_y[i][2], color);
- LCD_DrawLine(ghost_x[i][2], ghost_y[i][2], ghost_x[i][0], ghost_y[i][0], color);
- }
- // 5. 变量递增
- current_angle += angle_step;
- if (current_angle >= 360.0f) current_angle -= 360.0f;
- if (frame_count < GHOST_COUNT) frame_count++;
- }