// Demo1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // #include #include #include #include #include #include #include #include void print(int x, int y, std::string str) { COORD p = { x, y }; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), p); std::cout << str; } // 2D环形遍历 // 中心点是数学坐标(0, 0), 每环从右下(N, -N)开始逆时针遍历 void RingSearch_Next(int& nX, int& nY) { // 开始 if (nX == 0 && nY == 0) { nX = 1; nY = -1; return; } // 下1环(右下) if (nY<0 && nX+nY== -1) { ++nX; // 到右下 // 下1环 ++nX; --nY; return; } // 右边线(向上) if (nY+nX>=0 && nY-nX<0) { ++nY; return; } // 上边线(向左) if (nY - nX >= 0 && nY + nX > 0) { --nX; return; } // 左边线(向下) if (nY + nX <= 0 && nY - nX > 0) { --nY; return; } // 下边线(向右) if (nY-nX<=0 && nY+nX<0) { ++nX; return; } // 无法到这里 int x = 0; x++; } // 2D环形遍历 // 中心点是数学坐标(0, 0), 每环从右下(N, -N)开始逆时针遍历 // 根据序号直接计算点坐标 void RingSearch_Index(int nIndex, int& nX, int& nY) { // (0, 0) 做为第0环, 且 nIndex=0 if (nIndex <= 0) { nX = 0; nY = 0; return; } // 次外层第K环, 共有 (2K+1)*(2K+1)个点 // 最外层 int k = (sqrt(nIndex) + 1) / 2; // 第k环点的序号 int nIdx = nIndex - (2*k-1)*(2*k-1); // 第k环每条边的点数 int nL = 2 * k; // 只能包含一个端点 // 第几条边的第几个点 int nD = nIdx / nL; int nIdx2 = nIdx % nL; // (下面边的序号对应的边可以随意修改: 代表了不同的遍历方法) switch (nD) { case 0: // 第一条边(右) nX = k; nY = -k; nY += nIdx2; break; case 1: // 第二条边(上) nX = k; nY = k; nX -= nIdx2; break; case 2: // 第三条边(左) nX = -k; nY = k; nY -= nIdx2; break; case 3: // 第四条边(下) nX = -k; nY = -k; nX += nIdx2; break; default: // 出错 break; } } // 2D环形遍历 // 中心点是数学坐标(0, 0), 每环从右下(N, -N)开始逆时针遍历 // 根据点坐标计算序号(从0开始) int GetRingIndex(int nX, int nY) { if (nX == 0 && nY == 0) { return 0; } int k = max(abs(nX), abs(nY)); // 环内的数量 int nN = (2 * k - 1) * (2 * k - 1); // 边长 int nL = 2 * k; if (nX == k && nY != k) { // 第一边(右) nN += (k + nY); } else if (nY == k && nX != -k) { // 第二边(上) nN += 2*k; nN += (k - nX); } else if (nX == -k && nY != -k) { // 第三边(左) nN += 4 * k; nN += (k-nY); } else if(nY == -k && nX != k) { // 第四边(下) nN += 6 * k; nN += (k + nX); } else { // 不会到这里 } return nN; } int main() { int nX = 0, nY = 0; //std::cout << "0 : (" << nX << ", " << nY << ")" << std::endl; int K = 5; for (int i = 1; i < (2*K+1)*(2*K+1); i++) { // 第一种算法 RingSearch_Next(nX, nY); // 第二种算法 int nX2, nY2; RingSearch_Index(i, nX2, nY2); if (nX != nX2 || nY != nY2) { std::cout << "Error" << std::endl; } // 反向计算序号 int iii = GetRingIndex(nX, nY); if (i != iii) { std::cout << "Error" << std::endl; } print((nX2 + 10) * 3, (nY2 + 10) * 3, std::to_string(i)); //std::cout <