Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
1980 / 836 / 115
Регистрация: 01.10.2012
Сообщений: 5,222
Записей в блоге: 2

Удалить близкие точки

01.09.2026, 17:22. Показов 7441. Ответов 63
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день

Есть массив/контейнер точек, напр
C++
1
2
3
4
5
struct Point {
 float x, y, z;
};
 
std::vector<Point> points;
Требуется удалить часть точек так чтобы расстояние между любыми двумя не превышало заданное, напр 1.0e-5

Спасибо
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
01.09.2026, 17:22
Ответы с готовыми решениями:

Найти точки наиболее близкие друг к другу
В файле записано количество точек на плоскости и их координаты. Поместить эти координаты в...

Найти две точки, наиболее близкие друг к другу
В файле записано количество точек на плоскости и их координаты. Поместить эти координаты в...

Найти три точки, наиболее близкие к известной точке
Координаты (целые числа) из n точек (3 &lt;n &lt;101) в координатной плоскости хранятся в массивах....

63
Нарушитель
10907 / 5835 / 1289
Регистрация: 12.03.2015
Сообщений: 26,934
01.09.2026, 17:49
Навскидку, без ИИшницы, вот набросал прям в браузере. Не отлаживал, просто показываю, как я это вижу.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#define SQR(x) ((x) * (x)) // x²
 
// расстояние между точками в 3D
double distance(Point &p1, Point &p2)
{
  return sqrt(SQR(p1.x - p2.x) + 
              SQR(p1.y - p2.y) + 
              SQR(p1.z - p2.z));
}
 
// удаление точек так, чтобы расстояние между любыми двумя 
// не превышало max_dist 
void del_pts(vector<Point> &pts, const double max_dist)
{
  for (int idx1 = 0; idx1 < pts.size(); idx1++)
    for (int idx2 = pts.size() - 1; idx2 > idx1; idx2--)
      if (distance(pts[idx1], pts[idx2]) > max_dist)
        pts.erase[idx2];
}
0
 Аватар для MallSerg
102 / 70 / 15
Регистрация: 16.11.2018
Сообщений: 325
01.09.2026, 17:51
Главная сложность задачи в сложности нахождения ближайших точек.
Обычным решением такой задачи является построение R-tree индекса для каждой точки что позволит находить точки в требуемой области. Но это долго есть вариант с неточным но быстрым решением это создание отсортированных индексов по осям x y z и вычислением манхетонских расстояний между точками. так же на ум приходит вариант с триангуляцией Делоне что гарантировано даст связи только с ближайшими точками до которых можно проверять расстояния.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13234 / 6866 / 1827
Регистрация: 18.10.2014
Сообщений: 17,400
01.09.2026, 17:58
Цитата Сообщение от Igor3D Посмотреть сообщение
Удалить близкие точки
[...]
Требуется удалить часть точек так чтобы расстояние между любыми двумя не превышало заданное, напр 1.0e-5
"Не превышало"? Ничего не понял. Почему в заголовке темы говорится об удалении близких точек, а в тексте вопроса все наоборот: требуется удалить далекие точки?

Согласно постановке задачи в тексте вопроса, решение тривиально: удалить все точки, кроме одной. А можно и вообще все удалить. Расстояние в результате не будет превышать любое заданное.
1
1980 / 836 / 115
Регистрация: 01.10.2012
Сообщений: 5,222
Записей в блоге: 2
01.09.2026, 19:02  [ТС]
Виноват, описАлся "не превышало заданное" = наоборот, "было не меньше заданного". Др словами "близких точек" в контейнере остаться не должно
0
 Аватар для Наталья8
638 / 396 / 68
Регистрация: 09.03.2016
Сообщений: 4,374
01.09.2026, 23:42
Verevkin,
Ну да... Я в корнях ничего не понимаю. Не садовник.
Это ты типа сложить и перемешать просто всё.
Как-то подозрительно всё просто. Сложить все координаты и сравнить с остальными....
0
 Аватар для Наталья8
638 / 396 / 68
Регистрация: 09.03.2016
Сообщений: 4,374
01.09.2026, 23:47
Извиняюсь ни кого не хотел обидеть.
Просто поисковик google.


Если вам нужно просто исправить синтаксис текущего алгоритма (жадного удаления с конца), код должен выглядеть так:cpp

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <vector>
#include <cmath>
 
struct Point {
    double x, y, z;
};
 
#define SQR(x) ((x) * (x))
 
// Расстояние между точками в 3D
double distance(const Point &p1, const Point &p2) { 
    return sqrt(SQR(p1.x - p2.x) + SQR(p1.y - p2.y) + SQR(p1.z - p2.z)); 
} 
 
// Удаление точек (исправленная версия жадного алгоритма)
void del_pts(std::vector<Point> &pts, const double max_dist) { 
    for (size_t idx1 = 0; idx1 < pts.size(); idx1++) {
        // Идем с конца. Если точка удаляется, pts.size() уменьшается автоматически
        for (size_t idx2 = pts.size() - 1; idx2 > idx1; idx2--) {
            if (distance(pts[idx1], pts[idx2]) > max_dist) {
                pts.erase(pts.begin() + idx2); 
            }
        }
    }
Продрал через искуственный интелект.
0
 Аватар для Наталья8
638 / 396 / 68
Регистрация: 09.03.2016
Сообщений: 4,374
02.09.2026, 00:03
Он это делает за несколько секунд.........
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13234 / 6866 / 1827
Регистрация: 18.10.2014
Сообщений: 17,400
02.09.2026, 02:40
Для решения задачи нахождения ближайшей пары точек используются алгоритмы, которые предварительно раскидывают входные точки по ближайшим узлам сетки с некоторым шагом d. А затем выполняют поиск пары уже между узлами сетки. При этом для обработки точек, ассоциированных с некоторыми узлом нужно рассмотреть лишь точки в соседних узлах (8-окрестность для 2D случая, 26-окрестность для 3D случая).

Вот я думаю, а не применить ли для этой задачи аналогичный подход, просто использовав это самое 1.0e-5 в качестве шага сетки.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13234 / 6866 / 1827
Регистрация: 18.10.2014
Сообщений: 17,400
02.09.2026, 09:57
Другое дело, что задача содержит элемент оптимизации (не знаю, подразумевал ли его ТС - по постановке вопроса не видно). В паре точек-нарушителей удалить достаточно только одну. Какую именно? Какие точки удалять, а какие оставлять? Понятно, что можно постараться добиться соблюдения требования задачи путем удаления минимального количества точек, а можно просто тупо удалять наугад, не беспокоясь о минимизации.

Минимизация количества удаленных точек выливается в задачу о минимальном вершинном покрытии...
0
Заблокирован
Эксперт функциональных языков программированияЭксперт С++
02.09.2026, 11:31
Цитата Сообщение от Verevkin Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
#define SQR(x) ((x) * (x)) // x²
// расстояние между точками в 3D
double distance(Point &p1, Point &p2)
{
  return sqrt(SQR(p1.x - p2.x) + 
              SQR(p1.y - p2.y) + 
              SQR(p1.z - p2.z));
}
C++
1
2
3
4
double distance(const Point &p1, const Point &p2)
{
    return std::hypot(p1.x - p2.x, p1.y - p2.y, p1.z - p2.z);
}
0
1980 / 836 / 115
Регистрация: 01.10.2012
Сообщений: 5,222
Записей в блоге: 2
02.09.2026, 15:18  [ТС]
Цитата Сообщение от Verevkin Посмотреть сообщение
просто показываю, как я это вижу.
C++
1
2
3
4
5
6
7
8
9
// удаление точек так, чтобы расстояние между любыми двумя 
// не превышало max_dist 
void del_pts(vector<Point> &pts, const double max_dist)
{
  for (int idx1 = 0; idx1 < pts.size(); idx1++)
    for (int idx2 = pts.size() - 1; idx2 > idx1; idx2--)
      if (distance(pts[idx1], pts[idx2]) > max_dist)
        pts.erase[idx2];
}
Впечатление что Вы на личном опыте обнаружили что удаление "с конца" НАМНОГО лучше чем удаление "с начала" Это так, но все-таки erase - тяжелая операция, уже на лимоне точек будет медленновато, а ведь бывают модели и намного больше
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
требуется удалить далекие точки?
Да, это моя описка. Но, как ни странно, и такая задача тоже имеет смысл. Другими словами найти "клубок" в котором больше всего точек. Почему нет? Вполне разумная постановка, правда это уже совсем другая задача
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Вот я думаю, а не применить ли для этой задачи аналогичный подход, просто использовав это самое 1.0e-5 в качестве шага сетки.
Попытки использовать подобные сетки в 3D (часто называют lattice) частенько кончаются нервным срывом, уж слишком много памяти жрет "объем". Есть либы для более умного хранения, но они далеко не простые
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Другое дело, что задача содержит элемент оптимизации (не знаю, подразумевал ли его ТС - по постановке вопроса не видно). В паре точек-нарушителей удалить достаточно только одну. Какую именно? Какие точки удалять, а какие оставлять? Понятно, что можно постараться добиться соблюдения требования задачи путем удаления минимального количества точек, а можно просто тупо удалять наугад, не беспокоясь о минимизации.
Минимизация количества удаленных точек выливается в задачу о минимальном вершинном покрытии...
С точки зрения юзера все "элементарно" просто. Напр есть модель простейшего кубика, у нее 6 граней и.. 24 точки (вертекса). Как 24 если углов у кубика всего 8? Этого требует общепринятая техника рисования. В данном случае у каждой грани должны быть "свои" вертексы, иначе освещенность не будет считаться корректно. Вот и выходит 6 * 4 = 24. Да, но для др целей (напр движка физики) требуется "нормальный" кубик с 8 вертексами. Поэтому от программиста требуется перегонять данные из одного представления в другое. Задача вроде не выглядит сложной, всего лишь "удалить совпадающие точки".

Ладно, программист начинает делать. Берет он этот кубик, и... е-мое, а "повторяющиеся" точки оказывается не совпадают точно. Есть разница, да, в 5-м а то и 6-м знаке после запятой, но не ноль! Приходится решать задачу "удалить близкие точки". Но это еще не все. Оказывается удаление неоднозначно и, по меньшей мере, результат зависит от порядка следования точек в исходном контейнере. Напр есть точки A, B, C
const double epsilon = 1.0e-5;

length(A, B) < epsilon;
length(B, C) < epsilon;
length(A, C) > epsilon;
Если удалить A то придется удалять и B, итого 2 точки удалены. Но можно удалить только B, требования удовлетворяются.

Ну и какие у программиста варианты?

1. Свалить все проблемы на юзера, типа
Моя программа не будет работать с таким кубиком. Возьмите корректную модель у которой вертексы совпадают точно. Это Ваши проблемы где Вы ее возьмете
Ну кубик-то он найдет, а вот более сложную модель может и нет. Взаимопониманию такой подход не способствует

2. Попытаться договориться/объяснить что, мол, это не так просто, возникают сложности и.т.п. Это может встретить понимание, но может и нет
Что это за программист? Неделю сидел с простейшей задачкой, так и не сделал!
3. Гордо молчать и сделать (желательно быстро). Но как?

4. Ваш вариант?

Цитата Сообщение от Royal_X Посмотреть сообщение
C++
1
return std::hypot(p1.x - p2.x, p1.y - p2.y, p1.z - p2.z);
Ах, ну это меняет дело
0
Заблокирован
Эксперт функциональных языков программированияЭксперт С++
02.09.2026, 15:56
Цитата Сообщение от Igor3D Посмотреть сообщение
Это так, но все-таки erase - тяжелая операция, уже на лимоне точек будет медленновато, а ведь бывают модели и намного больше
Про это нужно было оговаривать в условии, а не рассказывать про лимоны, когда человек (ака Verevkin) уже написал код.
Если в условии ничего не сказано про количество точек на входе, а также про ограничения по памяти или вычислительной сложности, то люди вольны написать код как угодно...
Вроде ты старожил форума, но оформляешь условие как нуб

Цитата Сообщение от Igor3D Посмотреть сообщение
ну это меняет дело
другими словами, ЭТО повышает читабельность кода
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13234 / 6866 / 1827
Регистрация: 18.10.2014
Сообщений: 17,400
02.09.2026, 17:03
Цитата Сообщение от Igor3D Посмотреть сообщение
Попытки использовать подобные сетки в 3D (часто называют lattice) частенько кончаются нервным срывом, уж слишком много памяти жрет "объем". Есть либы для более умного хранения, но они далеко не простые
Ну, разумеется, речи не идет о том, чтобы хранить матрицу в виде буквальной трехмерной матрицы. Ясно, что для хранения ячеек стеки будет использоваться ассоциативный массив. В упоминавшихся мною известных алгоритмах поиска ближайшей пары сразу же говорится, что используется хэш-таблица, за счет чего задача и решается в среднем за линейное время. Так что дополнительный расход памяти в худшем случае будет O(n). А уж много это или мало - вопрос отдельный. Так что ничего "непростого" в первом приближении тут нет.

Добавлено через 19 минут
Цитата Сообщение от Igor3D Посмотреть сообщение
Приходится решать задачу "удалить близкие точки".
Во-первых, судя по уточнениям, это вообще не задача "удалить близкие точки". Слово "удалить" тут совершенно неуместно, ибо без дополнительных пояснений сбивает с толку. Это несколько другая задача - "ассоциировать близкие точки друг с другом". Это несколько иная задача, а не то, что написано в исходном вопросе.

Во-вторых, решать такую задачу на голых геометрических принципах "слить близкие точки на с 1.0e-5"... да, бывает нужно... но это уже скорее шаг отчаяния, когда все настолько запустилось/развалилось/исказилось/разъехалось, что другого выхода просто нет. По уму же, те множественные точки, которые с геометрической точки зрения должны являться одной точкой, должны были изначально неким образом "сгруппированы", т.е., непример, ссылаться друг на друга и эти ссылки должны были тщательно поддерживаться сквозь все этапы обработки. Чтобы на том этапе, когда нам потребуется "причесать" данные, то есть свести расползшиеся точки в одну, мы не занимались такой тяжелой обработкой, как геометрический поиск с 1.0e-5, а просто прошлись по готовым группам точек и сразу их "причесали". То есть задача изначально должна была решаться комбинаторно, а не геометрически. Не надо было терять совпадающие точки. И если их не терять, то их не нужно будет и искать.

Другое дело, если нам дали входные данные в таком "непричесаном" виде... Но, еще раз, это уже не по теме.
0
1980 / 836 / 115
Регистрация: 01.10.2012
Сообщений: 5,222
Записей в блоге: 2
02.09.2026, 18:24  [ТС]
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
да, бывает нужно... но это уже скорее шаг отчаяния, когда все настолько запустилось/развалилось/исказилось/разъехалось, что другого выхода просто нет.
...
Не надо было терять совпадающие точки. И если их не терять, то их не нужно будет и искать.
Вертексы и фейсы - базовые данные, при этом вертекс обязан иметь хотя бы координату (точку). Если эти данные имеются - модель/объект существует (пусть очень паршивенькая), иначе нет. Размер этих данных не ограничен, обычно срабатывают практические ограничения, слишком большие модели невыгодны. Дублирование точек/вертексов не является какой-то серьезной проблемой, дело рядовое. Обычно дублируется лишь небольшая часть, часто вообще дубликатов нет, пример с кубиком скорее исключение. Поэтому постоянно поддерживать еще какие-то данные "для удобства перевода" никто никогда не делает. Да, есть форматы для хранения только уникальных данных. Напр .obj файл может хранить для кубика 8 (уникальных) точек (обычно все заняты как получить из них 24 для рисования). Но может хранить и 24, и это никогда не было ошибкой. Поэтому конверсия данных туда/сюда неизбежна. Иногда приходится одновременно работать с 2 представлениями.

В общем нужно сделать "в меру". Десять строчек с квадратичным перебором (как предложил товарищ выше) - перегиб в одну сторону. Рекомендации всяких вумных деревьев - перегиб в другую, не тот это случай когда нужно подходить столь фундаментально. Решение должно быть достаточно простым/дешевым и приличным, пусть и не самым быстрым по скорости. Можно заводить доп данные (с умом), сортировать и.т.п. но не "размахиваться слишком широко"

Как это сделать?
0
фрилансер
 Аватар для Алексей1153
6508 / 5758 / 1135
Регистрация: 11.10.2019
Сообщений: 15,406
02.09.2026, 18:41
Цитата Сообщение от Igor3D Посмотреть сообщение
Десять строчек с квадратичным перебором (как предложил товарищ выше) - перегиб в одну сторону.
с одной стороны, это должно быть медленно, но с другой - это очень простой и чёткий алгоритм, который можно быстро опробовать, чтобы потом сравнивать:
1) скорость более крутого алгоритма
2) правильность работы сложного алгоритма
3) а может оказаться так, что скорость устроит и так, сейчас ЦП очень хитрые при работе с кеш-дружелюбными данными

------
Кстати, такой алгоритм легко распараллелить: чистим отдельные области в разных потоках, а потом по приграничным точкам областей ещё фильтром пробегаемся быстро
0
1980 / 836 / 115
Регистрация: 01.10.2012
Сообщений: 5,222
Записей в блоге: 2
02.09.2026, 19:06  [ТС]
Цитата Сообщение от Алексей1153 Посмотреть сообщение
очень простой и чёткий алгоритм,
Да, недостатки есть продолжение достоинств, и наоборот
Цитата Сообщение от Алексей1153 Посмотреть сообщение
3) а может оказаться так, что скорость устроит и так, сейчас ЦП очень хитрые при работе с кеш-дружелюбными данными
Обычно это формулируется чуть иначе
Ну если для него это медленно - так пусть купит компьютер помощнее, какие проблемы?
Цитата Сообщение от Алексей1153 Посмотреть сообщение
Кстати, такой алгоритм легко распараллелить: чистим отдельные области в разных потоках, а потом по приграничным точкам областей ещё фильтром пробегаемся быстро
Интересно, можете развить мысль?
0
фрилансер
 Аватар для Алексей1153
6508 / 5758 / 1135
Регистрация: 11.10.2019
Сообщений: 15,406
02.09.2026, 22:30
Цитата Сообщение от Igor3D Посмотреть сообщение
развить мысль
1) разбиваем пространство на N одинаковых прямоугольных параллелепипедов

2) каждый из них чистим в отдельном потоке

3) после потом по секущим плоскостям между блоками ещё проходим отдельно

Добавлено через 2 минуты
но тут, правда, точки придётся помечать удалёнными, а не сразу удалять.

Или раскидать по отдельным контейнерам.

В общем, дополнительная память потребуется


Добавлено через 53 секунды
Цитата Сообщение от Алексей1153 Посмотреть сообщение
помечать удалёнными
например, координату x делать inf
0
1980 / 836 / 115
Регистрация: 01.10.2012
Сообщений: 5,222
Записей в блоге: 2
02.09.2026, 23:53  [ТС]
Цитата Сообщение от Алексей1153 Посмотреть сообщение
1) разбиваем пространство на N одинаковых прямоугольных параллелепипедов
Примечание: говорят просто "куб" (кубов), все понимают что размеры куба по осям различны.
По существу. Да, это решает проблему оптимизации, но разбиение пространства - удовольствие дорогое. Беда в том что кубы надо заряжать точками и хранить. А точки могут быть весьма sparse(d), т.е. разбросанными. Типа вот "кучка" точек и вот, а между ними километр, и заполняйте его бесполезными кубами. Приходится выдумывать структуры посложнее и.т.п. Если уж хотели распараллелить, есть простой способ
C++
1
2
3
4
5
std::vector<int> dups(point.size(), -1);
 
#pragma omp parallel for
for (int i = 0; i < points.size(); ++i)
 dups[i] = find_dup(points, i);
Напр для 100 точек на 4 рабочих нитках первые 25 будут выполнены первой ниткой, вторые 25 второй и.т.д. Так OpenMP делает по умолчанию. Ф-ция find_dup возвращает индекс точки достаточно близкой к points[i] или -1 если такой нет. Заметим что никаких блокировок/примитивов синхронизации не требуется, данные удачно разделены. Теперь надо удалить точки за 1 проход используя данные что посчитали в dups

Да, но проблему оптимизации мы пока не решили, не должна же find_dup молотить весь контейнер точек
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13234 / 6866 / 1827
Регистрация: 18.10.2014
Сообщений: 17,400
03.09.2026, 02:28
Для варианта, который я описал выше и именно для удаления точек. Опять же, не заморачиваясь выбором точек для удаления, а просто удаляя первых подвернувшихся нарушителей

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// C++20
#include <cmath>
#include <list>
#include <vector>
#include <unordered_map>
#include <limits>
#include <random>
#include <iostream>
 
struct Point
{
  float x, y, z;
 
  friend float distance(const Point &a, const Point &b)
    { return std::hypot(a.x - b.x, a.y - b.y, a.z - b.z); }
};
 
struct MeshKey
{
  int ix, iy, iz;
 
  friend MeshKey operator +(const MeshKey &lhs, const MeshKey &rhs)
    { return { lhs.ix + rhs.ix, lhs.iy + rhs.iy, lhs.iz + rhs.iz }; }
 
  friend bool operator ==(const MeshKey &, const MeshKey &) = default;
 
  struct Hash
  {
    std::size_t operator ()(const MeshKey &key) const
      { return ((std::hash<int>()(key.ix) << 1) ^ std::hash<int>()(key.iy) << 1) ^ std::hash<int>()(key.iz); }
  };
};
 
using Points = std::list<Point>;
using Mesh = std::unordered_map<MeshKey, std::vector<Points::iterator>, MeshKey::Hash>;
using MeshNode = Mesh::value_type;
 
void populate(Mesh &mesh, float step, Points &points)
{
  for (auto it = points.begin(); it != points.end(); ++it)
    mesh[{ (int) (it->x / step), (int) (it->y / step), (int) (it->z / step) }].push_back(it);
}
 
const MeshKey HALF_ADJ_DXYZ[] = 
{
  { -1, +1,  0 }, {  0, +1,  0 }, { +1, +1,  0 }, 
                                  { +1,  0,  0 },
 
  { -1, +1, +1 }, {  0, +1, +1 }, { +1, +1, +1 }, 
  { -1,  0, +1 },                 { +1,  0, +1 }, 
  { -1, -1, +1 }, {  0, -1, +1 }, { +1, -1, +1 }
};
 
std::size_t count_violations(const Mesh &mesh, const MeshKey &key, const Point &point, float min_dist,
                             std::size_t n_violations = 0,
                             std::size_t n_limit = std::numeric_limits<std::size_t>::max())
{
  for (const MeshKey &dxyz : HALF_ADJ_DXYZ)
  {
    auto it_adj_node = mesh.find(key + dxyz);
    if (it_adj_node == mesh.end())
      continue;
 
    for (auto it_adj_point : it_adj_node->second)
    {
      float dist = distance(point, *it_adj_point);
      if (dist < min_dist)
        if (++n_violations > n_limit)
          return n_violations;
    }
  }
 
  return n_violations;
}
 
std::size_t count_violations(const Mesh &mesh, float min_dist)
{
  std::size_t n_violations = 0;
 
  for (const MeshNode &node : mesh)
    for (auto it_point : node.second)
      n_violations = count_violations(mesh, node.first, *it_point, min_dist, n_violations);
 
  return n_violations;
}
 
void cleanup(Points &points, Mesh &mesh, float min_dist)
{
  for (auto it_node = mesh.begin(); it_node != mesh.end(); )
  {
    for (auto itit_point = it_node->second.begin(); itit_point != it_node->second.end(); )
    {
      auto it_point = *itit_point;
      if (count_violations(mesh, it_node->first, *it_point, min_dist, 0, 0) > 0)
      {
        points.erase(it_point);
        itit_point = it_node->second.erase(itit_point);
      }
      else
        ++itit_point;
    }
 
    if (it_node->second.empty())
      it_node = mesh.erase(it_node);
    else
      ++it_node;
  }
}
 
int main()
{
  Points points(1000000);
 
  std::random_device rd;
  std::mt19937 gen(rd());
  std::uniform_real_distribution<float> dis(0.f, 1.f);
  for (Point &point : points)
    point = { dis(gen), dis(gen), dis(gen) };
 
  const float MIN_DIST = 1.e-2f;
 
  Mesh mesh;
  populate(mesh, MIN_DIST, points);
 
  std::size_t n_initial = points.size();
  std::cout << "Initial points: " << n_initial << std::endl;
  std::cout << "Violating pairs: " << count_violations(mesh, MIN_DIST) << std::endl;
 
  cleanup(points, mesh, MIN_DIST);
 
  std::cout << "Points after cleanup: " << points.size() << std::endl;
  std::cout << "Removed points: " << n_initial - points.size() << std::endl; 
 
  std::cout << "Violating pairs after cleanup: " << count_violations(mesh, MIN_DIST) << std::endl;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
03.09.2026, 02:28

Определить две самые близкие к началу координат точки из n имеющихся
Здравствуйте, подскажите пожалуйста как можно перебрать весь вектор pair и выбрать оттуда и две...

Значения близкие к нулю
Накидал табулирование функции. Одна только проблемка: при задании достаточно малого шага, начиная с...

Определить наиболее близкие из точек координаты которых записаны в двумерный массив
Дано натуральное число n. С помощью двумерного действительного числового массива i=1,2; j=1,...,n...

Найти близкие по значению элементы матрицы
Дана матрица А размером M x N , в которой нет повторяющихся элементов. Нужно найти наиболее близкие...

Вывести все возможные числа, которые при возведении в квадрат дадут результаты, наиболее близкие к N
На вход поступает неотрицательное число N. Необходимо вывести все возможные числа, которые при...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Запустил конкурс "тем и промптов для текстовых квестов созданных почти чисто ИИ"
Adler 06.10.2026
Всем привет! За последние три-четыре дня я создал более 16 текстовых квестовых игр используя преимущественно по одному запросу к ИИ на игру. Мне так понравилось смотреть все ветки/ сцены во всех. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru