【问题标题】:Orientation of ridge山脊方向
【发布时间】:2014-08-01 04:12:27
【问题描述】:

D空间 中给定两个单纯形(例如,D3 空间 中的二维 三角形 面> 对于 四面体) 相邻的 facets V(可见)和 H(水平),由两个数组定义 D D-维 PVPH 。上述数组中元素的顺序是严格定义的,依次在空间中定义一个facetsorientations。比如说,他们在 universal 点集合中的索引 U(涉及几何计算)表示为两个std::list< std::size_t >s。 ridgefacetD - 1 维边界元素(例如 D3 中四面体的 1 维 edges 空格)。要定义两个 facets 共有的 points,我只需执行以下操作:

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 执行期间,我丢失了关于ridge Rcodirectionality 的信息,定义为上面的ridge_,同样两个中任何一个的

同向性可以随后通过计算交换数来定义,最少需要执行从 1 开始的置换。)点的数组 >ridge 按其在给定的 facetpoints 数组中呈现的顺序排列 2.) 生成的 points 数组em> ridge R 本身。但我确信这里有开销。

定义同向性的另一种方法是计算两个定向正方形(一个由唯一的点(facetridge 的区别)然后是 ridge 和一个通过简单修改 facet:将排他点移到前面,因为它位于两个 facets 中的第一个)。

如何以固定的元素顺序执行两个未排序数组的交集,以便结果数组保存第一个(异或第二个)数组中呈现的元素顺序。有没有这样的算法,时间复杂度小于O(n2)?对 STL 辅助实现的可能性特别感兴趣。

【问题讨论】:

  • 掉期数到底是什么意思?只能交换相邻元素还是允许交换任意元素?
  • @user2040251 我认为在单纯复形(D - 1 facet 或 D - 2 ridge)的情况下,我们可以交换不相邻的元素(它们都是线性独立的)。交换数在某种意义上意味着翻转的次数。实际上,交换次数的奇偶性在上述应用中是有意义的(只有两个 D 维半空间由 D - 1 面定义)。

标签: c++ algorithm computational-geometry convex-hull


【解决方案1】:

My version 将排他点替换为最远点,保持其在原始可见方面的顺序。作为结果创建的 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)
    }
}

【讨论】:

    【解决方案2】:

    如果我对问题的理解正确,您可以使用以下方案。首先,制作原始数组的副本(称它们为visible_set_for_sortinghorizon_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))。

    【讨论】:

    • 谢谢,我已经做到了。但是我们可以简单地在 O(n * log(n)) 中做std::set&lt; std::size_t &gt; ridge_(horizon_.cbegin(), horizon_.cend());,然后是你的圈子。
    猜你喜欢
    • 2016-08-03
    • 1970-01-01
    • 1970-01-01
    • 2020-10-08
    • 2016-06-24
    • 2018-05-02
    • 1970-01-01
    • 2020-06-01
    • 1970-01-01
    相关资源
    最近更新 更多