网格道路中的格子状态计算
一、分析
下图包含了由正方形格子组成的道路的全部形态。(没有斜向)
单个格子的状态共有6种:
已知构成道路的格子集合:[(x1,y1),(x2,y2)…(xn,yn)],(x,y)代表格子位置。计算道路上每个格子的状态。(格子坐标系,x右正,y上正)
因为每个格子有4个临边,对格子(x,y)有临边:
左边 L: (x-1, y)
上边 T: (x,y+1)
右边 R: (x+1, y)
下边 B: (x,y-1)
假设最终格子状态为s。计算过程:
1、设置s=无邻格
2、判断L,如果有格,则s=s + L,否则s不变。(s + L)含义为s增加L方向有邻格
3、按步骤2依次判断T R B。为了方便记,如果对应临边有道路格子,则记为1,没有记为0。对于一个格子描述其临边状态可表示为:_ _ _ _
State(LTRB):0000 State(LTRB):1101 State(LTRB):1010 State(LTRB):1011 State(LTRB):1111 State(LTRB):0110
由图可见,(2)有4种旋转,(3)有两种,(4)有3种,(6)有4种。
二、主要思路
//按位记录4个方向的邻格状态,有为1,无为0 const int L = 1 << 0; const int T = 1 << 1; const int R = 1 << 2; const int B = 1 << 3; //计算x,y 格子的邻格状态 int s = 0; // 初始为无邻格 // 依次检查 if(IsExist(x-1, y)) s |= L; if(IsExist(x, y+1)) s |= T; if(IsExist(x+1, y)) s |= R; if(IsExist(x, y-1)) s |= B; // 最终s的值可知道在各个方向上的邻格情况
三、实现
class Road { //对邻格按左->上->右->下的顺序检查 const int L = 1 << 0; const int T = 1 << 1; const int R = 1 << 2; const int B = 1 << 3; const int NONE = 0; // 坐标 struct Coord { public int x; public int y; } /// 格子邻居 struct Neibour { // 与格子的偏移量 public int ox; public int oy; // 标识自己是哪个方向的邻居,左->上->右->下 public int state; } // 邻居描述集合 List<Neibour> _neibourMap = new List<Neibour>() { // 左 new Neibour { ox = -1, oy = 0, state = L }, // 上 new Neibour { ox = 0, oy = 1, state = T }, // 右 new Neibour { ox = 1, oy = 0, state = R }, // 下 new Neibour { ox = 0, oy = -1, state = B } }; int GetState(int x, int y) { var s = NONE; foreach (var neibour in _neibourMap) { if (IsExist(x + neibour.ox, y + neibour.oy)) s |= neibour.state; } return s; } bool IsExist(int x, int y) { // TODO:判断是否存在 } /// 格子状态对应的信息 class StateInfo { // 比如表现 } // 格子状态描述 Dictionary<int, StateInfo> _stateInfoConfig = new Dictionary<int, StateInfo>() { // 单格路 { NONE, new StateInfo()}, // 末端 { L, new StateInfo()}, { T, new StateInfo()}, { R, new StateInfo()}, { B, new StateInfo()}, // 转角 { L | T, new StateInfo()}, { T | R, new StateInfo()}, { R | B, new StateInfo()}, { B | L, new StateInfo()}, // 直路 水平或竖直 { L | R, new StateInfo()}, { T | B, new StateInfo()}, // T字路口 { L | T | R, new StateInfo()}, { T | R | B, new StateInfo()}, { R | B | L, new StateInfo()}, { B | L | T, new StateInfo()}, // 十字路口 { L | T | R | B, new StateInfo()} }; /// 测试 void Test(Coord[] coords) { foreach (var coord in coords) { var s = GetState(coord.x, coord.y); var info = _stateInfoConfig[s]; Print(info); } } private void Print(StateInfo info) { //TODO:状态信息 } }