六边形格子地图坐标计算与转换
2017-04-12 13:29
127 查看
// 世界场景的一些数据管理,如提供坐标转换之类的接口 var WorldMapManager = function () { this.mapSize = null; // 地图大小,像素 this.curViewPos = null; // 当前大地图视野坐标 // 初始化世界地图的数据 this.init = function (mapSize, tileSize) { this.mapSize = { width : globalConsts.WorldMapSize.width * globalConsts.TileSize.width + globalConsts.TileSize.width / 2, height : globalConsts.WorldMapSize.height * ((globalConsts.TileSize.height - globalConsts.TileSize.hex) / 2 + globalConsts.TileSize.hex) + (globalConsts.TileSize.height - globalConsts.TileSize.hex) / 2 }; this.tileSize = globalConsts.TileSize; }; // 大地图坐标转成蜂窝cell this.mapPosToTile = function (pos) { // 算出缩放成正六边形后边长 a 的值 var a = this.tileSize.width / Math.sqrt(3); var x = pos.x, y = (this.mapSize.height - pos.y) / this.tileSize.height * a * 2 + a / 2; // 加 a / 2 是因为矩形网格计算时会在底部增加 a / 2 //位于矩形网格边线上的三个CELL中心点 var points = new Array(cc.p(0, 0), cc.p(0, 0), cc.p(0, 0)); //当前距离的平方 var dist; // index:被捕获的索引 var i, index; //二分之根号3 边长的平方,如果距离比它还小,就必然捕获 var g_MinDistance2 = Math.pow(a * Math.sqrt(3) / 2, 2); // 网格宽、高 var g_unitx = a * Math.sqrt(3); //sqrt(3) * a var g_unity = a * 1.5; //a * 3 / 2 // 网格对角线平方向上取整 var mindist= Math.ceil(Math.pow(g_unitx, 2) + Math.pow(g_unity, 2)); //计算出鼠标点位于哪一个矩形网格中 var cx = parseInt(x/g_unitx); var cy = parseInt(y/g_unity); points[0].x = parseInt(g_unitx * cx); points[1].x = parseInt(g_unitx * (cx+0.5)); points[2].x = parseInt(g_unitx * (cx+1)); //根据cy是否是偶数,决定三个点的纵坐标 if(cy % 2 == 0) { //偶数时,三个点组成倒立三角 points[0].y = points[2].y = parseInt(g_unity * cy); points[1].y = parseInt(g_unity * (cy+1)); } else { //奇数时,三个点组成正立三角 points[0].y = points[2].y = parseInt(g_unity * (cy+1)); points[1].y = parseInt(g_unity * cy); } // 计算两点间距离的平方 function distance2(x1, y1, x2, y2) { return ((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1)); } //现在找出鼠标距离哪一个点最近 for(i = 0; i < 3; ++i) { //求出距离的平方 dist = distance2(x, y, points[i].x, points[i].y); //如果已经肯定被捕获 if(dist < g_MinDistance2) { index = i; break; } //更新最小距离值和索引 if(dist < mindist) { mindist = dist; index = i; } } // x 第 0 个点的列值减 1 等于cell.x ( x 最左半格有 -1 值 ) // cy 偶数时中间点 + 1,奇数时两边点 + 1,减 1 是因为初始为了计算方便 y 补了 a / 2 ( y 最上半格 也会存在 -1 ) return {x : cx - (index > 0? 0 : 1), y : cy + (cy % 2 + index % 2) % 2 - 1}; }; // 格子坐标转成地图坐标 this.tilePosToMap = function (pos) { var tileCenter, xPixel, yPixel; tileCenter = (pos.x * this.tileSize.width) + this.tileSize.width / 2; xPixel = tileCenter + (pos.y % 2) * this.tileSize.width / 2; yPixel = this.tileSize.height / 2 + pos.y * (this.tileSize.height / 2 + this.tileSize.hex / 2); // 因为锚点的关系,y值需要倒过来,这很重要 yPixel = this.mapSize.height - yPixel; return cc.p(xPixel, yPixel); }; // 获取相邻两个六边形格子中心点距离 this.getAdjacentHexagonCenterPointDistance = function (isLeftAndRight) { if (isLeftAndRight) { return this.tileSize.width; } else { return Math.sqrt(Math.pow((this.tileSize.height + this.tileSize.hex) / 2, 2) + Math.pow(this.tileSize.width / 2, 2)); } }; }; // 单例 WorldMapManager.sharedInstance = null; WorldMapManager.getInstance = function(){ if (WorldMapManager.sharedInstance == null) { WorldMapManager.sharedInstance = new WorldMapManager(); WorldMapManager.sharedInstance.init(); } return WorldMapManager.sharedInstance; };
var tileCalculate = {
// 两六边形 tilePos 获取 无视阻挡的最短距离格子数 0~1 return 1
getTwoTileDistance : function(lightTilePos, findTilePos) {
var offX = 1, offY = 1; // 初始 findTilePos 在 lightTilePos 左上,往右下寻
var tilePos, count;
if (lightTilePos.y === findTilePos.y) {
return Math.abs(lightTilePos.x - findTilePos.x);
} else if (lightTilePos.x === findTilePos.x) {
return Math.abs(lightTilePos.y - findTilePos.y);
} else {
count = 0;
tilePos = {x:findTilePos.x, y:findTilePos.y};
// 在右,往左寻
if (lightTilePos.x < tilePos.x) {
offX = -1;
}
// 在下,往上寻
if (lightTilePos.y < tilePos.y) {
offY = -1;
}
do {
++count;
tilePos.x += tilePos.y % 2 > 0 ? (offX > 0 ? offX : 0) : (offX < 0 ? offX : 0);
tilePos.y += offY;
} while (lightTilePos.x !== tilePos.x && lightTilePos.y !== tilePos.y);
count += Math.abs(lightTilePos.x - tilePos.x) + Math.abs(lightTilePos.y - tilePos.y);
return count;
}
},
// 获取格子周围一圈,共六个格子的格子坐标
getAroundTilePos : function(tilePos) {
if (tilePos.y % 2 > 0) {
return [{x : tilePos.x, y : tilePos.y - 1}, {x : tilePos.x, y : tilePos.y + 1}, // 上下
{x : tilePos.x - 1, y : tilePos.y}, {x : tilePos.x + 1, y : tilePos.y}, // 左右
{x : tilePos.x + 1, y : tilePos.y - 1}, {x : tilePos.x + 1, y : tilePos.y + 1}]; // 右上,右下
} else {
return [{x : tilePos.x, y : tilePos.y - 1}, {x : tilePos.x, y : tilePos.y + 1}, // 上下
{x : tilePos.x - 1, y : tilePos.y}, {x : tilePos.x + 1, y : tilePos.y}, // 左右
{x : tilePos.x - 1, y : tilePos.y - 1}, {x : tilePos.x - 1, y : tilePos.y + 1}]; // 左上,左下
}
},
// 获取格子周围两圈,共十八个格子的格子坐标
getAroundTwoLapsTilePos : function(tilePos) {
var i, j, tiles1, tiles2 = [];
var tilePoses = {};
// 把第一圈及第一圈每一个的第一圈都收集起来
tiles1 = this.getAroundTilePos(tilePos);
for (i in tiles1) {
tiles2 = this.getAroundTilePos(tiles1[i]);
for (j in tiles2) {
if (tiles2[j].x !== tilePos.x || tiles2[j].y !== tilePos.y) {
tilePoses[JSON.stringify(tiles2[j])] = tiles2[j];
}
}
4000
}
return tilePoses;
},
};
相关文章推荐
- 百度地图与谷歌地图坐标转换,WGS84、GCJ02、BD09地图坐标系间的坐标转换及坐标距离计算
- WGS84、GCJ02、BD09地图坐标系间的坐标转换及坐标距离计算
- 各地图gps坐标系统比较与转换以及经纬度距离计算MATLAB脚本
- cocos2dx tiledmap 45度地图 世界坐标转换 格子坐标
- 【arcgis】3、如何在ARC/INFO中数字化地图,以及坐标转换
- 地图坐标转换->火星坐标
- 百度地图API二:根据标注点坐标范围计算显示缩放级别zoom自适应显示地图
- 地图经纬度及坐标系统转换的那点事
- 地图坐标转换
- iOS 地图坐标系之间的转换WGS-84世界标准坐标、GCJ-02中国国测局(火星坐标,高德地图)、BD-09百度坐标系转换
- 高德地图计算两坐标之间距离
- 地图坐标与屏幕坐标的转换
- 依据地图上的经纬度坐标计算某个点到多边形各边的距离
- 45度斜角地图菱形坐标转换
- iOS-地理坐标转换,原生地图获取的原始坐标转换为地图真实坐标
- 瓦片地图坐标相关计算
- 计算地图上两坐标点之间的距离
- AS3 RPG游戏引擎开发日志3:地图坐标转换
- 用opencv计算棋盘格内角点坐标(通过多个内角点获得转换矩阵),并同时用halcon和opnecv对图像进行透视变换