SDL2画六角格地板

SDL2画六角格地板 文章目录一、数学基础一单个六边形二相邻六边形二、算法基础一世界坐标二世界方向三推算邻接六边形世界坐标选学四数组与六角格的映射三、代码实现一、数学基础一单个六边形如图所示正六边形有一个内切圆半径r有一个外接圆半径R则r 3 R / 2 r\sqrt 3R/2r3​R/2六边形的高为2r六边形的宽为2R六边形的边长为R。二相邻六边形现在考虑上它的邻接六边形如图可以看到每一列相邻六边形中心之间横坐标不变纵坐标差1个六边形高横坐标差3 R / 2 3R/23R/2二、算法基础一世界坐标显示器窗口左上角是原点水平向右为X轴正向垂直向下为Y轴正向。假如我是一只蚂蚁我只能在六角格之前一块一块地移动于是我的世界就是这些六角格如何确定我的位置呢可以用屏幕像素坐标但那是程序员可得的但我处在自己的世界里于是对六角格进行编号我用如图所示的波浪线作为我的前进方向。首先我站在(0,0)号地板上当我站偶数列的时候下一格是奇数列我向右前方前进一格那个地板记为(1,0)此时我站在奇数列于是向左前方前进一格记为(2,0)…后面依次计数。一行走完之后我站在下一行起始位置开始遍历下一行…二世界方向除了用左、右表示相对方向我的世界也有“东西南北”这种绝对方向按照人类地图上北下南左西右东我的世界具体区分为北0、东北1、东南2、南3、西南4、西北5这六个方向按顺时针进行编号。三推算邻接六边形世界坐标选学观察世界坐标图不管是奇数列还是偶数列方向0和3推算原理是相同的若当前坐标是(x,y)方向0的相邻格坐标是(x,y-1)方向3的相邻格坐标是(x,y1).方向1偶数列在方向1的相邻格行号-1列号1坐标为(x1,y-1)奇数列在方向1的相邻格行号不变列号1坐标为(x1,y)方向2偶数列在方向2的相邻格行号不变列号1坐标为(x1,y)奇数列在方向2的相邻格行号1列号1坐标为(x1,y1)方向4偶数列在方向4的相邻格行号不变列号-1坐标为(x-1,y)奇数列在方向4的相邻格行号1列号-1坐标为(x-1,y1)方向5偶数列在方向5的相邻格行号-1列号-1坐标为(x-1,y-1)奇数列在方向5的相邻格行号不变列号-1坐标为(x-1,y)四数组与六角格的映射用N行N列的数组block[N*N]表示所有的六角格行号用i表示列号用j表示于是第i行j列的六角格世界坐标为(j,i)于是数组block[N*N]和我的世界坐标产生了一一对应关系。三、代码实现用数组px[]、py[]分别表示指定六角格的像素横坐标和像素纵坐标intpx[N*N];//横坐标像素值intpy[N*N];//纵坐标像素值遍历所有世界坐标求出对应的六角格中心像素坐标// 六角格相关常量#defineHEX_RADIUS40// 六边形外接圆半径也是边长side#defineHEX_radius35//六边形内接圆半径HEX_RADIUS * sqrt(3)/2#defineHEX_HEIGHT(HEX_radius1)// 六边形高度#defineHEX_WIDTH(HEX_RADIUS1)// 六边形宽度#defineHEX_ROW_GAPHEX_HEIGHT// 六角格行间距#defineHEX_COLUMN_GAP(HEX_RADIUS*31)// 六角格列间距HEX_HEIGHT*sqrt(3)/2for(inti0;iN;i){//数组行号、六角格行号、世界纵坐标for(intj0;jN;j){//数组列号、六角格列号、世界横从标// 计算六边形中心像素坐标px[i*Nj]j*HEX_COLUMN_GAPHEX_RADIUS;//整体向右偏移R防止第0列块向左出窗口py[i*Nj]i*HEX_HEIGHTHEX_radius(j%2)*HEX_radius;// 整体向下偏移r,防止第0行块向上出窗口偶数列上对齐奇数列向下偏移1个内切圆半径}}对每个六角格绘制相应的六个边for(inti0;iN;i){//行for(intj0;jN;j){//列// 绘制六边形地板intxpx[i*Nj];//中心点像素坐标intypy[i*Nj];//中心点像素坐标SDL_SetRenderDrawColor(Ground::render,0,0,0,255);//黑色边框SDL_RenderDrawLine(Ground::render,x-HEX_RADIUS/2,y-HEX_radius,xHEX_RADIUS/2,y-HEX_radius);//上边线SDL_RenderDrawLine(Ground::render,xHEX_RADIUS/2,y-HEX_radius,xHEX_RADIUS,y);//右上边线SDL_RenderDrawLine(Ground::render,xHEX_RADIUS,y,xHEX_RADIUS/2,yHEX_radius);//右下边线SDL_RenderDrawLine(Ground::render,xHEX_RADIUS/2,yHEX_radius,x-HEX_RADIUS/2,yHEX_radius);//下边线SDL_RenderDrawLine(Ground::render,x-HEX_RADIUS/2,yHEX_radius,x-HEX_RADIUS,y);//左下边线SDL_RenderDrawLine(Ground::render,x-HEX_RADIUS,y,x-HEX_RADIUS/2,y-HEX_radius);//左上边线}}成果如图我在画每个六角格的同时在中心画了1个实心正方形大家可自行实现