public SpiralSegment Next()
        {
            var nextSegment = new SpiralSegment();

              // Update X and Y direction according to the cycle:
              // ... Right -> Down -> Left -> Up -> Right ...
              //
              // dX  dY   Direction
              //-------------------
              //  1   0   Right
              //  0   1   Down
              // -1   0   Left
              //  0  -1   Up

              nextSegment.Direction = new Vector2D(
            x: -1 * this.Direction.Y,
            y: this.Direction.X);

              // If changing from vertical to horizontal movement, increase the length of the segment by 1
              nextSegment.Length = nextSegment.Direction.X == 0 ? this.Length : this.Length + 1;

              return nextSegment;
        }
示例#2
0
        /// <summary>
        /// Calculates the dimensions required for the spiral data matrix
        /// by simulating a run through the spiral.
        /// </summary>
        /// <param name="width">Output: width of matrix</param>
        /// <param name="height">Output: height of matrix</param>
        private void CalculateGridDimensions(out int width, out int height)
        {
            int minX = 0;
              int minY = 0;
              int maxX = 0;
              int maxY = 0;

              var location = new Vector2D(0, 0);
              var segment = new SpiralSegment(1, UnitVectors.Right);

              int index = 0;

              do
              {
            int remainingCells = _maxValue - index;
            Vector2D distanceToTravel;

            if (remainingCells >= segment.Length)
            {
              // travel the full segment and then get the next segment
              index += segment.Length;
              distanceToTravel = segment.Direction.Multiply(segment.Length);

              segment = segment.Next();
            }
            else
            {
              // travel the remaining cells
              index += remainingCells;
              distanceToTravel = segment.Direction.Multiply(remainingCells);
            }

            location = location.Add(distanceToTravel);

            // Update the observed bounds
            minX = (int)Math.Min(minX, location.X);
            minY = (int)Math.Min(minY, location.Y);
            maxX = (int)Math.Max(maxX, location.X);
            maxY = (int)Math.Max(maxY, location.Y);
              } while (index < _maxValue);

              width = maxX - minX + 1;
              height = maxY - minY + 1;
        }
示例#3
0
        /// <summary>
        /// Generates a matrix representing a clockwise spiral of numbers 
        /// with zero at the center
        /// </summary>
        /// <returns>Returns a matrix representing a spiral of numbers</returns>
        private int[,] GenerateSpiral()
        {
            // initialize the grid
              var output = InitializeGrid();

              int width = output.GetLength(0);
              int height = output.GetLength(1);

              // Start at the center of the grid
              var location = new Vector2D(
            x: (int)((width - 1) / 2),
            y: (int)((height - 1) / 2));

              // Set the initial segment (move 1 cell to the right)
              var segment = new SpiralSegment(1, UnitVectors.Right);
              int segmentIndex = 0;

              for (var i = 0; i <= _maxValue; i++)
              {
            output[location.X, location.Y] = i;

            // Move to the next cell
            segmentIndex++;
            location = location.Add(segment.Direction);

            // If this is the end of a segment, then change directions
            // and start a new segment
            if (segmentIndex >= segment.Length)
            {
              segmentIndex = 0;
              segment = segment.Next();
            }
              }

              return output;
        }