SweepAndPrune的一维实现
2021/5/31 18:52:23
本文主要是介绍SweepAndPrune的一维实现,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
/* * 实现碰撞检测中一个经典的Sweep And Prune算法 * 参考文章:D. Baraff (Ph. D thesis), p 52. * http://www.cs.cmu.edu/~baraff/papers/thesis-part1.ps.Z */ #include <iostream> #include <vector> #include <map> #include <list> #include <algorithm> void sweepAndPrune(std::vector<std::tuple<bool, unsigned int, double>> values, std::map<unsigned int, std::list<unsigned int>> &collision) { // 根据区间端点位置对各个区间端点进行排序 std::sort(values.begin(), values.end(), [](std::tuple<bool, unsigned int, double> a, std::tuple<bool, unsigned int, double> b) { return std::get<2>(a) < std::get<2>(b); }); // 输出排序之后的结果 for (auto ite = values.begin(); ite != values.end(); ite++) { auto t = std::get<0>(*ite) ? "b" : "e"; auto idx = std::get<1>(*ite); std::cout << idx << "," << t << ": " << std::get<2>(*ite) << std::endl; } std::list<unsigned int> activeList = {}; // 遍历区间端点,生成每个区间对应的重叠区间列表。如果区间端点为起始点,那么就activeList中的区间索引就是该区间的重叠区间,并将该区间添加到activeList中 // 否则就在activeList中删除该区间索引 for (auto ite = values.begin(); ite != values.end(); ite++) { auto idx = std::get<1>(*ite); if (std::get<0>(*ite)) // b { collision[idx] = activeList; activeList.push_back(idx); } else // e { activeList.remove(idx); } } } int main() { // 在一个坐标轴上的多个区间 std::vector<std::pair<double, double>> interal = { {3.0,5.0},{7.0,18.0},{0.0,8.0},{10.0,16.0},{6.0,12.0},{1.0,4.0} }; for (auto ite = interal.begin(); ite != interal.end(); ite++) { std::cout << "[" << ite->first << "," << ite->second << "]\n"; } // 保存每个区间端点是否为起始点(b:true, e:false),索引值,位置 std::vector<std::tuple<bool,unsigned int, double>> values; for (unsigned int i = 0; i < interal.size(); i++) { values.push_back({ true, i,interal[i].first }); values.push_back({ false,i,interal[i].second }); } std::map<unsigned int, std::list<unsigned int>> collision; sweepAndPrune(values, collision); // 输出具有重叠的线段 for (auto ite = collision.begin(); ite != collision.end(); ite++) { std::cout << "the " << ite->first + 1<< "th segment is overlapping with segments: "; for (auto i : ite->second) { std::cout << i + 1 <<","; } std::cout << "."<<std::endl; } return 0; }
这篇关于SweepAndPrune的一维实现的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南