Удаление объектов из SortedSet
Я смотрю на это слишком долго, надеюсь, кто-то может помочь.
Общий jist есть;
У меня есть SortedSet объектов игрока (отсортированных по позиции Y), каждый игрок содержит отсортированный набор объектов "Полигон", которые, в свою очередь, содержат список из трех точечных объектов, очевидно, образующих треугольник.
Этот набор полигонов сортируется по площади указанного полигона, от наименьшего к наибольшему.
Что я хочу сделать, так это перебрать множество игроков и;
I. Назначьте точку по индексу [1] ("вершине" треугольника) от первого объекта в многоугольном SortedSet к другой переменной внутри проигрывателя.
II. После того, как точка с индексом [1] была назначена игроку, мне нужно перебрать каждого игрока и удалить любой экземпляр многоугольника, который содержит текущую точку в ElementAt(1), чтобы никакие последующие игроки в "родительской" итерации не могли назначить многоугольник, который содержит эту точку.
Вероятно, важно отметить, что точка в polygonPoints[1] основана на позиции врага, поэтому они одинаковы для всех игроков, поэтому я пытаюсь использовать ее в качестве "контрольной" точки для удаления любых объектов многоугольника, которые содержать указанную точку.
Это запутанное объяснение, но, надеюсь, вы смогли следовать.
Сейчас я получил первую часть работает, но вторая часть оказывается серьезная боль - я попытался удалить и removewhere (с использованием критериев, которые должны удалить все), а не набор упорно остается той же длины, независимо от того, что я делать.
Для справки вот последняя итерация кода, с которой я спорю.
List<PointF> duplicates = new List<PointF>();
foreach (Player p in playerSet)
{
//Assign lowest cost polygon to current player, then remove all polygons containing the point at p.triangleSet.ElementAt(0).polygonPoints[1] from every other player so it can't be assigned to any subsequent player.
p.currentAttackingPoint = p.triangleSet.ElementAt(0).polygonPoints[1];
//I use this method to keep track of which 'attacking points' have been assigned.
add(p.currentAttackingPoint);
//Then, in theory, I use this method to remove all polygons that contain any point in the duplicates list from every other player. Obviously this is proving to be the troublesome aspect.
remove(duplicates);
}
...
private void add(PointF i)
{
duplicates.Add(i);
}
private void remove(List<PointF> dupes)
{
foreach(PointF p in dupes)
{
foreach (Player l in playerSet)
{
//Outputs 100
textBox3.AppendText(l.triangleSet.Count.ToString() + "\r\n");
l.triangleSet.RemoveWhere(e => e.polygonPoints[1] == p);
//l.pressingTriangleSet.RemoveWhere(e => e.polygonPoints[1].X > 0); --Doesn't work either, despite it being true of every point in the set.
//Still 100
textBox3.AppendText(l.triangleSet.Count.ToString() + "\r\n");
}
}
}
Пожалуйста, имейте в виду, что набор полигонов внутри каждого игрока, хотя и имеет одинаковую длину, имеет в основном разный контент, они основаны на позиции игрока, позиции врага и другом произвольном факте о состоянии игры - так что я могу просто удалите первый полигон из набора каждого игрока.
Я думаю о преобразовании каждого набора в список после того, как он был создан, потому что это странно, это должен быть некоторый порядок операций, который я пропускаю.
Чисто ради собственного здравого смысла я вырубил это http://pastie.org/private/ikq5lhhacxxvfaoervauw и это работает точно так, как вы ожидаете.
РЕДАКТИРОВАТЬ - Для тех, кто считает, что ищет решение аналогичной проблемы, не тратьте свое время, используя sortedsets для сортировки коллекции объектов, вы можете использовать OrderBy для достижения того же с помощью списков.
1 ответ
Это длинный пример, но иногда сравнивать числа с плавающей запятой и double немного сложно из-за точности. Например, точка 1.0 может быть представлена как 1.0000001 из-за ошибок округления. Возможно, что ваши очки не сравниваются правильно
Попробуйте что-то вроде
e.polygonPoints[1].X - p.X < 0.00001
&& p.X - e.polygonPoints[1].X < 0.00001
&& e.polygonPoints[1].Y - p.Y < 0.00001
&& p.Y - e.polygonPoints[1].Y < 0.00001
Я бы предположил, что оператор равенства PointF позаботится об этом, но это не может