Newer
Older
DungeonShooting / DungeonShooting_Godot / src / framework / common / SpiralUtil.cs
  1. using Godot;
  2.  
  3.  
  4. public static class SpiralUtil
  5. {
  6. /// <summary>
  7. /// 螺旋算法 顺时针
  8. /// 7 8 9 10
  9. /// 6 1 2
  10. /// 5 4 3
  11. /// </summary>
  12. private static float[][] SCREW_CLOCKWISE = new float[][] { new float[] { 1, 2, 3, 4 }, new float[] { 4, 1, 2, 3 } };
  13.  
  14. /// <summary>
  15. /// 螺旋算法
  16. /// </summary>
  17. /// <param name="index">当前序列</param>
  18. /// <returns>返回当前序列应该所在的位置</returns>
  19. public static Vector2I Screw(int index)
  20. {
  21. //总体思路是先找到第几圈 然后再找到第几个拐角 然后用switch
  22. //因为一般序列都是从0开始的,所以此处加一以适应规则
  23. index++;
  24. //如果求的是中心点 直接返回就行了
  25. if (index <= 1) return new Vector2I(0, 0);
  26.  
  27. //开平方得到当前序列在哪个阶段中(阶段=第几圈*2)
  28. var n = Mathf.Ceil(Mathf.Sqrt(index));
  29. var step = Mathf.FloorToInt(n / 2) * 2;
  30. //求出当前序列是当前阶段中的第几个数
  31. var stepIndex = index - (step - 1) * (step - 1);
  32. //求出当前序列在当前阶段中的第几条边上
  33. var stepStep = Mathf.CeilToInt((float)stepIndex / step);
  34. //当前序列是当前边上第几个数
  35. var ssi = stepIndex % step;
  36. if (ssi == 0) ssi = step;
  37.  
  38. return new Vector2I(
  39. GetValue(step, ssi, SCREW_CLOCKWISE[0][stepStep - 1]),
  40. GetValue(step, ssi, SCREW_CLOCKWISE[1][stepStep - 1])
  41. );
  42. }
  43.  
  44. private static int GetValue(int step, int ssi, float switchIndex)
  45. {
  46. switch (switchIndex)
  47. {
  48. case 1: return step / 2;
  49. case 2: return step / 2 - ssi;
  50. case 3: return -step / 2;
  51. case 4: return -step / 2 + ssi;
  52. }
  53.  
  54. return 0;
  55. }
  56. }