コード例 #1
0
        /// <summary>
        /// Удаляет все пиксели региона без пересчета параметров региона
        /// </summary>
        /// <returns>Массив удаленных пикселей региона</returns>
        public Pixel[] RemovePixels()
        {
            Pixel[] removedPixels = new Pixel[RegionPixels.Count];
            for (int i = 0; i < RegionPixels.Count; i++)
            {
                removedPixels[i] = RegionPixels[i];
            }

            RegionPixels.Clear();
            // удаляем также список расстояний
            DistanceSums.Clear();

            return(removedPixels);
        }
コード例 #2
0
        /// <summary>
        /// Удаляет пиксель из региона и пересчитывает параметры региона
        /// </summary>
        /// <param name="pixelId">Идентификатор удаляемого пикселя - массив с координатами i, j</param>
        public Pixel RemovePixelWithParametersRecalculation(int[] pixelId)
        {
            Pixel removedPixel = null;

            for (int i = 0; i < RegionPixels.Count; i++)
            {
                if (RegionPixels[i].Id[0] == pixelId[0] && RegionPixels[i].Id[1] == pixelId[1])
                {
                    removedPixel = RegionPixels[i];
                    RegionPixels.RemoveAt(i);
                    // удаляем также и из списка расстояний
                    DistanceSums.RemoveAt(i);
                    break;
                }
            }
            CalculateParameters(PixelAction.remove, new Pixel[] { removedPixel });
            return(removedPixel);
        }
コード例 #3
0
        /// <summary>
        /// Пересчитывает центральный пиксель региона
        /// </summary>
        /// <param name="action">Действие выполненной над пикселями региона перед пересчетом центрального пикселя</param>
        /// <param name="pixels">Массив пикселей, который были изменены в регионе перед пересчетом центрального пикселя</param>
        private void CalculateCenter(PixelAction action = PixelAction.none, Pixel[] pixels = null)
        {
            if (RegionPixels == null)
            {
                return;
            }

            // Извлекаем матрицу идентификаторов пикселей - в каждой строке находится идентификатор (координаты x и y пикселя)
            int[][] pixelIds = new int[RegionPixels.Count][];
            for (int i = 0; i < RegionPixels.Count; i++)
            {
                pixelIds[i] = RegionPixels[i].Id;
            }

            if (action == PixelAction.none)
            {
                // Инициализация массива сумм расстояний
                DistanceSums = new List <double>();
                for (int i = 0; i < RegionPixels.Count; i++)
                {
                    DistanceSums.Add(0.0);
                }

                // Ищем суммы расстояний от каждой точки до каждой точки региона
                for (int i = 0; i < RegionPixels.Count; i++)
                {
                    // Считаем сумму расстояний от точки i до всех остальных точек
                    for (int j = 0; j < RegionPixels.Count; j++)
                    {
                        if (i != j)
                        {
                            // Прибавляем к сумме расстояние от пикселя i до пикселя j
                            DistanceSums[i] += Math.Sqrt((pixelIds[i][0] - pixelIds[j][0]) * (pixelIds[i][0] - pixelIds[j][0]) +
                                                         (pixelIds[i][1] - pixelIds[j][1]) * (pixelIds[i][1] - pixelIds[j][1]));
                        }
                    }
                }
            }
            else if (action == PixelAction.add)
            {
                if (pixels == null)
                {
                    return;
                }

                // Добавляем новые элементы списка расстояний для новых пикселей и добавляем к уже существующим суммам новые расстояния
                int oldDistancesSumsCount = DistanceSums.Count; // Фиксируем количество пикселей, которые были в регионе до добавления
                for (int i = 0; i < pixels.Length; i++)
                {
                    int    oldDistancesIterator = 0;
                    double sum = 0.0;
                    for (int j = 0; j < RegionPixels.Count; j++)
                    {
                        double distance = Math.Sqrt((pixels[i].Id[0] - pixelIds[j][0]) * (pixels[i].Id[0] - pixelIds[j][0]) +
                                                    (pixels[i].Id[1] - pixelIds[j][1]) * (pixels[i].Id[1] - pixelIds[j][1]));

                        sum += distance;

                        // Если текущий пиксель относится еще к старым пикселям региона
                        if (oldDistancesIterator < oldDistancesSumsCount)
                        {
                            DistanceSums[j] += distance;
                        }

                        // Увеличиваем счетчик просмотренных пикселей
                        oldDistancesIterator++;
                    }

                    DistanceSums.Add(sum);
                }
            }
            else if (action == PixelAction.remove)
            {
                // В случае удаления пикселей, они удалены из списка пикселей и из списка расстояний уже до текущего момента

                if (pixels == null)
                {
                    return;
                }

                // Уменьшаем суммы расстояний оставшихся пикселей на величины расстояний до удаленных пикселей
                for (int i = 0; i < pixels.Length; i++)
                {
                    for (int j = 0; j < RegionPixels.Count; j++)
                    {
                        DistanceSums[j] -= Math.Sqrt((pixels[i].Id[0] - pixelIds[j][0]) * (pixels[i].Id[0] - pixelIds[j][0]) +
                                                     (pixels[i].Id[1] - pixelIds[j][1]) * (pixels[i].Id[1] - pixelIds[j][1]));
                    }
                }
            }
            else
            {
                return;
            }

            // Определение центрального пикселя региона
            double minSum = DistanceSums.Min();

            for (int i = 0; i < DistanceSums.Count; i++)
            {
                if (DistanceSums[i] == minSum)
                {
                    SpacialSenterId = pixelIds[i];
                    break;
                }
            }
        }