步骤:
1.建立多边形:按顺时针顺序逐个提供坐标点。
2.绘制。
绘制步骤:
1.计算外接矩形:就是逐个坐标点比较,最后得到一个刚好框住该多边形的矩形。
2.制作bitMap(位图或者说栅格图):根据外接矩形的大小,自行分配内存,制作一个栅格图。
3.填写栅格图–画线:在栅格图把各个点坐标和连线先画上(画直线的方法网上很多),别忘了要把坐标偏移一下。
4.填写栅格图–递归填充:上面的栅格图在制作时上下左右都多余1条边,然后在(0,0)点开始“递归填充”。递归的函数可以分为5个,调用方式如下:
static void _view_infaceU(int x, int y, unsigned char **map, int mapWidth, int mapHeight);
static void _view_infaceD(int x, int y, unsigned char **map, int mapWidth, int mapHeight);
static void _view_infaceL(int x, int y, unsigned char **map, int mapWidth, int mapHeight);
static void _view_infaceR(int x, int y, unsigned char **map, int mapWidth, int mapHeight);
static void _view_infaceU(int x, int y, unsigned char **map, int mapWidth, int mapHeight)
{
if(map[y][x])
return;
map[y][x] = 1;//画自己所在的点
if(y-1 >= 0) _view_infaceU(x, y-1, map, mapWidth, mapHeight);
// if(y+1 < mapHeight) _view_infaceD(x, y+1, map, mapWidth, mapHeight);
if(x-1 >= 0) _view_infaceL(x-1, y, map, mapWidth, mapHeight);
if(x+1 < mapWidth) _view_infaceR(x+1, y, map, mapWidth, mapHeight);
}
static void _view_infaceD(int x, int y, unsigned char **map, int mapWidth, int mapHeight)
{
if(map[y][x])
return;
map[y][x] = 1;//画自己所在的点
// if(y-1 >= 0) _view_infaceU(x, y-1, map, mapWidth, mapHeight);
if(y+1 < mapHeight) _view_infaceD(x, y+1, map, mapWidth, mapHeight);
if(x-1 >= 0) _view_infaceL(x-1, y, map, mapWidth, mapHeight);
if(x+1 < mapWidth) _view_infaceR(x+1, y, map, mapWidth, mapHeight);
}
static void _view_infaceL(int x, int y, unsigned char **map, int mapWidth, int mapHeight)
{
if(map[y][x])
return;
map[y][x] = 1;//画自己所在的点
if(y-1 >= 0) _view_infaceU(x, y-1, map, mapWidth, mapHeight);
if(y+1 < mapHeight) _view_infaceD(x, y+1, map, mapWidth, mapHeight);
if(x-1 >= 0) _view_infaceL(x-1, y, map, mapWidth, mapHeight);
// if(x+1 < mapWidth) _view_infaceR(x+1, y, map, mapWidth, mapHeight);
}
static void _view_infaceR(int x, int y, unsigned char **map, int mapWidth, int mapHeight)
{
if(map[y][x])
return;
map[y][x] = 1;//画自己所在的点
if(y-1 >= 0) _view_infaceU(x, y-1, map, mapWidth, mapHeight);
if(y+1 < mapHeight) _view_infaceD(x, y+1, map, mapWidth, mapHeight);
// if(x-1 >= 0) _view_infaceL(x-1, y, map, mapWidth, mapHeight);
if(x+1 < mapWidth) _view_infaceR(x+1, y, map, mapWidth, mapHeight);
}
void _view_infaceStart(int x, int y, unsigned char **map, int mapWidth, int mapHeight)
{
if(map[y][x])
return;
map[y][x] = 1;//画自己所在的点
if(y-1 >= 0) _view_infaceU(x, y-1, map, mapWidth, mapHeight);
if(y+1 < mapHeight) _view_infaceD(x, y+1, map, mapWidth, mapHeight);
if(x-1 >= 0) _view_infaceL(x-1, y, map, mapWidth, mapHeight);
if(x+1 < mapWidth) _view_infaceR(x+1, y, map, mapWidth, mapHeight);
}
简单概括就是:画完自己脚下的点,然后向上下左右继续找点,如果自己是从“下面上来”的,那就不在往下找了,碰到边界或已经画过的点,递归停止。
5.绘制多边形:遍历栅格图,根据填格情况,在需要的地方绘制多边形。
缺陷:
1.如果你的多边形是个类似圆环,中空的图形,是没办法填充完全的
----------续----------
函数递归次数是有限的,如何在有限次递归下完成超大张图片的绘制?
分块递归
简单的描述就是:
1.把图像切块,然后在切线上投放递归点,而每次递归的范围严格限制在切块内;
2.在填充下一切块时,相邻的切线会传递相邻像素点的信息,告知当前投放点是在图像外还是在图像的边沿上;
3.反复轮询每一条切线,直至线上的每一个点都不满足投放递归点的条件为止,此时图像填充完成。
下面是做横向切块(横条状),然后从上往下扫描切线,再从下往上扫描,如此反复的一个填充过程。