对于基础的矩形填充来说比较简单,只需找到最大最小坐标然后画线挨行填充即可
设定画线接口函数为Draw_Line(int x1,int y1,int x2,int y2,int color); 则矩形填充程序为:int maxx, maxy, minx, miny;int i;for (i = miny; i < maxy; i++){ Draw_Line(minx,i,maxx i, 0xF800);}填充圆形的方式为:在以圆的外接正方形范围内挨行判断坐标点和圆心的距离,小于等于半径的时候才画点(灰色区域的半径黄色箭头大于半径,不画点,橙色区域半径蓝色箭头小于半径,画点)
不过为了加速绘制速度,减少计算量,一般不使用挨个画点的方式,就像画圆一样不用角度递增挨个画点,加速方式是拆分成画线,一次性绘制一条线,因为屏幕最擅长的就是横平竖直的画线,加速方式如下。707/1000=0.707=1.414/2 ≈ √2 / 2 static void draw_hline(uint16_t x0,uint16_t y0,uint16_t len,uint16_t color){ if(len==0)return; Draw_Line(x0,y0,x0+len-1,y0,color);}static void fill_circle(uint16_t x0,uint16_t y0,uint16_t r,uint16_t color){ uint32_t i; uint32_t imax = ((uint32_t)r*707)/1000+1; uint32_t sqmax = (uint32_t)r*(uint32_t)r+(uint32_t)r/2; uint32_t x=r; draw_hline(x0-r,y0,2*r,color); for (i=1; i<=imax; i++) { if ((i*i+x*x)>sqmax)// draw lines from outside { if (x>imax) { draw_hline (x0-i+1,y0+x,2*(i-1),color); draw_hline (x0-i+1,y0-x,2*(i-1),color); } x--; } draw_hline(x0-x,y0+i,2*x,color); draw_hline(x0-x,y0-i,2*x,color); }}更为复杂的图形填充方式有几种,对于凸多边形一般是拆分为三角形,使用三角形填充独立部分,凹多边形等复杂图形还是使用扫描方式判断坐标是否在封闭图形内。
判断程序如下。
uint16_t is_point_in(int nvert, float *vertx, float *verty, float testx, float testy){ uint8_t res; int i, j, c = 0; res = 0; if ((testx > maxx) || (testy > maxy) || (testx < minx) || (testy < miny)) return 1000; for (i = 0, j = nvert - 1; i < nvert; j = i++) { if ( ( (verty > testy) != (verty[j] > testy) ) && (testx < (vertx[j] - vertx) * (testy - verty) / (verty[j] - verty) + vertx) ) c = !c; } return c;}增加原多边形坐标构建和区域显示和填充效果
void draw_shape(int nvert, float *vertx, float *verty){ int i, j; POINT_COLOR = BLUE; for (i = 0; i < nvert - 1; i++) { printf("%5.1f,%5.1f -->> %5.1f,%5.1f\r\n", vertx, verty, vertx[i + 1], verty[i + 1]); LCD_DrawLine((uint16_t)vertx, (uint16_t)verty, (uint16_t)vertx[i + 1], (uint16_t)verty[i + 1]); } LCD_DrawLine((uint16_t)vertx[nvert - 1], (uint16_t)verty[nvert - 1], (uint16_t)vertx[0], (uint16_t)verty[0]);}void create_five_star(float *vertx, float *verty, float x, float y, float r, float offset_angle){ //生成五角星坐标 int i, j; for (i = 0; i < 10; i++) { if (i % 2) { *(vertx + i) = cos((i * 36 + offset_angle) * 3.1415926 / 180) * r + x; *(verty + i) = sin((i * 36 + offset_angle) * 3.1415926 / 180) * r + y; } else { *(vertx + i) = cos((i * 36 + offset_angle) * 3.1415926 / 180) * r * 0.3 + x; *(verty + i) = sin((i * 36 + offset_angle) * 3.1415926 / 180) * r * 0.3 + y; } }}void fill_shape(uint16_t color){ int i, j; int res; for (i = miny; i < maxy; i++) { for (j = minx; j < maxx; j++) { res = is_point_in(points, pointsx, pointsy, j, i); if (res == 1000) { } else if ((res % 2) == 0) { } else if ((res % 2) == 1) { LCD_Fast_DrawPoint(j, i, color); } } }}调用演示
calc_min_max(points, pointsx, pointsy);draw_shape(points, pointsx, pointsy);fill_shape(BLUE);create_five_star(pointsx,pointsy,240,400,200,-36);calc_min_max(10,pointsx,pointsy);draw_shape(10,pointsx,pointsy);
|