public ParallelActor(Ball[] balls, Cell[,] grid, int start, int end, bool last)
        {
            this.balls = balls;
            gridColumns = grid.GetLength(1);
            gridRows = end - start;

            if (last)
            {
                partOfgrid = new Cell[gridRows, gridColumns];
                for (int i = start; i < end; i++)
                {
                    for (int j = 0; j < gridColumns; j++)
                    {
                        partOfgrid[i - start, j] = grid[i, j];
                    }
                }
                Work = LastWork;
            } else
            {
                Work = UsualWork;
                partOfgrid = new Cell[gridRows+1, gridColumns];
                for (int i = start; i < end+1; i++)
                {
                    for (int j = 0; j < gridColumns; j++)
                    {
                        partOfgrid[i - start, j] = grid[i, j];
                    }
                }
            }
        }
        /// <summary>
        /// Инициализация шариков
        /// </summary>
        protected void InitBalls()
        {
            float x, y, V, angle;
            Random rand = new Random();
            #region Создадим сетку для расстановки шариков
            int columns = field.Width / Ball.Diameter;
            int rows = field.Height / Ball.Diameter;
            List<int> listX = new List<int>(columns * rows);
            List<int> listY = new List<int>(columns * rows);
            //----------------------------------------------
            gridRows = rows+1;
            gridColumns = columns+1;
            grid = new Cell[rows+1, columns+1];
            //----------------------------------------------
            x = field.Left + Ball.Radius;
            y = field.Top + Ball.Radius;
            for (int i = 0; i <= rows; i++)
            {
                for (int j = 0; j <= columns; j++)
                {
                    grid[i, j] = new Cell();
                    listX.Add((int)x);
                    listY.Add((int)y);
                    x += Ball.Diameter;
                }
                #region Переход на начало новой строки
                y += Ball.Diameter;
                x = field.Left + Ball.Radius;
                #endregion
            }
            #endregion

            #region Расставляем шарики на поле
            int index = 0;
            for (int i = 0; i < NumberOfBalls; i++)
            {
                // Выбираем случайную ячейку в сетке
                index = rand.Next(listX.Count);
                x = listX[index];
                y = listY[index];
                balls[i] = new Ball(x, y, i);
                // закрепляем шарик за ячейкой сетки...
                int row = (int)Math.Truncate(y / Ball.Diameter);
                int column = (int)Math.Truncate(x / Ball.Diameter);
                grid[row, column].items.Add(i);
                balls[i].currentCell = grid[row, column];
                // удаляем ячейку из списка незанятых
                listX.RemoveAt(index);
                listY.RemoveAt(index);
                // Возьмём случайную величину скорости 0..1
                V = (float)rand.NextDouble();
                // Возьмём случайную величину - направление движения
                angle = (float)(rand.NextDouble() * 2 * Math.PI);
                // Вычисляем проекции скорости на оси координат
                balls[i].vx = (float)(V * Math.Cos(angle));
                balls[i].vy = (float)(V * Math.Sin(angle));
            }
            #endregion
            listX.Clear(); listY.Clear();
        }