/// <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); }
/// <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); }
/// <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; } } }