基于STM32的虚线绘制函数改造
改造前:
uint16_t DrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
{
// GUI_DrawLine( x1, y1, x2, y2);
// return 1;int16_t deltaX, deltaY;int16_t error, stepErrorLT, stepErrorGE;int16_t stepX, stepY;int16_t steep;int16_t temp;int16_t style, type;if (x1 == x2){if (y1 > y2){temp = y1;y1 = y2;y2 = temp;}for (temp = y1; temp < y2 + 1; temp++){MoveToPixel(x1, temp);*pixel_P = 1;}return (1);}if (y1 == y2){if (x1 > x2){temp = x1;x1 = x2;x2 = temp;}MoveToPixel(x1, y1);for (temp = x1; temp < x2 + 1; temp++){*pixel_P = 1;pixel_P += 8;}return (1);}stepX = 0;deltaX = x2 - x1;if (deltaX < 0){deltaX = -deltaX;--stepX;}else{++stepX;}stepY = 0;deltaY = y2 - y1;if (deltaY < 0){deltaY = -deltaY;--stepY;}else{++stepY;}steep = 0;if (deltaX < deltaY){++steep;temp = deltaX;deltaX = deltaY;deltaY = temp;temp = x1;x1 = y1;y1 = temp;temp = stepX;stepX = stepY;stepY = temp;PutPixel(y1, x1);}else{PutPixel(x1, y1);}// If the current error greater or equal zerostepErrorGE = deltaX << 1;// If the current error less than zerostepErrorLT = deltaY << 1;// Error for the first pixelerror = stepErrorLT - deltaX;style = 0;type = 1;while (--deltaX >= 0){if (error >= 0){y1 += stepY;error -= stepErrorGE;}x1 += stepX;error += stepErrorLT;if ((++style) == 0){type ^= 1;style = 0;}if (type){if (steep){PutPixel(y1, x1);}else{PutPixel(x1, y1);}}} // end of whilereturn (1);
}
改造后的虚线绘制函数:
uint16_t DrawDashedLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint8_t dashLen)
{int16_t deltaX, deltaY;int16_t error, stepErrorLT, stepErrorGE;int16_t stepX, stepY;int16_t steep;int16_t temp;uint16_t pixelCount = 0; // 用于计算虚线间隔的计数器// 处理垂直线特殊情况if (x1 == x2) {if (y1 > y2) {temp = y1;y1 = y2;y2 = temp;}for (temp = y1; temp < y2 + 1; temp++) {if ((pixelCount / dashLen) % 2 == 0) { // 画线段PutPixel(x1, temp);}pixelCount++;}return 1;}// 处理水平线特殊情况if (y1 == y2) {if (x1 > x2) {temp = x1;x1 = x2;x2 = temp;}for (temp = x1; temp < x2 + 1; temp++) {if ((pixelCount / dashLen) % 2 == 0) { // 画线段PutPixel(temp, y1);}pixelCount++;}return 1;}// 通用斜线处理stepX = (x2 > x1) ? 1 : -1;deltaX = (x2 > x1) ? (x2 - x1) : (x1 - x2);stepY = (y2 > y1) ? 1 : -1;deltaY = (y2 > y1) ? (y2 - y1) : (y1 - y2);steep = (deltaY > deltaX);if (steep) {// 交换x和y的值temp = deltaX; deltaX = deltaY; deltaY = temp;temp = x1; x1 = y1; y1 = temp;temp = stepX; stepX = stepY; stepY = temp;}stepErrorGE = deltaX << 1;stepErrorLT = deltaY << 1;error = stepErrorLT - deltaX;while (deltaX-- >= 0) {if ((pixelCount / dashLen) % 2 == 0) { // 画线段if (steep) {PutPixel(y1, x1);} else {PutPixel(x1, y1);}}pixelCount++;if (error >= 0) {y1 += stepY;error -= stepErrorGE;}error += stepErrorLT;x1 += stepX;}return 1;
}
使用说明
参数说明:
x1, y1: 起点坐标
x2, y2: 终点坐标
dashLen: 虚线每段的长度(像素数)
调用示例:
// 绘制从(10,10)到(100,50)的虚线,每段长度5像素
DrawDashedLine(10, 10, 100, 50, 5);
优化版本(支持自定义样式)
uint16_t DrawStyledLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t pattern)
{int16_t deltaX, deltaY;int16_t error, stepErrorLT, stepErrorGE;int16_t stepX, stepY;int16_t steep;int16_t temp;uint16_t pixelCount = 0;uint16_t mask = 0x8000; // 16位样式掩码// ... (前面的特殊情况和初始化代码与上面相同)while (deltaX-- >= 0) {if (pattern & mask) { // 根据样式掩码决定是否绘制if (steep) {PutPixel(y1, x1);} else {PutPixel(x1, y1);}}// 更新样式掩码mask = (mask >> 1) | (mask << 15);pixelCount++;// ... (后面的误差计算与上面相同)}return 1;
}
样式示例:
// 点线:0xAAAA (1010101010101010)
DrawStyledLine(10, 10, 100, 50, 0xAAAA);// 点划线:0xF8F8 (1111100011111000)
DrawStyledLine(10, 30, 100, 70, 0xF8F8);
这个改造后的函数保留了原Bresenham算法的效率,同时增加了虚线绘制功能,适用于嵌入式系统。