Ориентация хребта

В D-мерная пространство дано два симплициальных (скажем, 2-мерных треугольник лица в D3 пространство за тетраэдр) смежный фасеты В (видимый) и ЧАС (горизонт), определяемый двумя массивами D D-мерная точки пВ а также пЧАС. Порядок элементов в вышеуказанных массивах строго определен и, в свою очередь, определяет ориентации из фасеты в пространство. Скажем, их индексы в универсальный множество точек U (который участвует в геометрических расчетах) представлен в виде двух std::list< std::size_t >s. хребет является Д — 1 размерный граничный элемент фаска (скажем, 1-мерный края тетраэдра в D3 пространство). Чтобы определить, какие точки являются общими для обоих фасеты Я просто могу сделать следующее:

point_list visible_set_ = visible_facet_.vertices_;
point_list horizon_set_ = horizon_facet_.vertices_;
visible_set_.sort();
horizon_set_.sort();
point_list ridge_;
std::set_intersection(visible_set_.cbegin(), visible_set_.cend(),
horizon_set_.cbegin(), horizon_set_.cend(),
std::back_inserter(ridge_));

Но во время std::sort исполнение я теряю информацию о codirectionality из хребет р, определяется как ridge_ выше, и то же самое хребет любого из обоих фасеты.

codirectionality может быть определен впоследствии с помощью вычисления числа свопов, минимально необходимого для выполнения перестановки из 1.) массива точки из хребет в порядке, как это представлено в данном массиве точки из фаска представляет интерес для 2.) производится массив точки из хребет р сам. Но я уверен, что здесь есть накладные расходы.

Еще один способ определения codirectionality это рассчитать ориентированный квадрат из двух фасеты (один из эксклюзивных точка (разница фаска и хребет) а затем хребет и один произведен простой модификацией фаска: перемещение исключительной точки вперед, так как она расположена в первом из двух фасеты).

Как выполнить пересечение двух несортированных массивов с фиксированным порядком элементов так, чтобы результирующий массив сохранял порядок элементов так, как он представлен в первом (или втором) массиве. Есть ли такой алгоритм, имеющий временную сложность меньше На2)? Особенно интересует СТЛ-возможность автоматизированной реализации.

2

Решение

Если я правильно понимаю проблему, вы можете использовать следующую схему. Сначала сделайте копии ваших оригинальных массивов (назовите их visible_set_for_sorting а также horizon_set_for_sorting). Тогда сортируйте их. Затем сформируйте пересечение следующим образом:

std::set<int> intersection;
std::set_intersection(
visible_set_for_sorting.begin(), visible_set_for_sorting.end(),
horizon_set_for_sorting.begin(), horizon_set_for_sorting.end(),
std::inserter(intersection, intersection.begin()));

Теперь вы можете перебрать любой оригинальный массив (visible_set_ или же horizon_set_), проверьте, находится ли точка в intersection и сформируйте результирующий список в нужном порядке.

std::list<int> list;
for (int p : visible_set_)
{
if (intersection.find(p) != intersection.end())
{
list.push_back(p);
}
}

Сложность не должна быть выше, чем O (N * log (N)).

2

Другие решения

Моя версия заменяет исключительную точку самой дальней точкой, сохраняя ее порядок, как в исходном видимом фасете. Newfacet (с точки зрения оригинала Qhull реализация) создан как результат:

point_set horizon_(horizon_facet_.vertices_.cbegin(),
horizon_facet_.vertices_.cend()); // n * log(n) +
auto const hend = horizon_.end();
point_list ridge_;
for (size_type const p : vertices_) { // n *
auto const h = horizon_.find(p); // (log(n) +
if (h == hend) {
ridge_.push_back(apex);
} else {
ridge_.push_back(p);
horizon_.erase(h); // const)
}
}
1