[{"data":1,"prerenderedAt":331},["ShallowReactive",2],{"\u002Fbefore\u002Fastar-qt":3,"surround-\u002Fbefore\u002Fastar-qt":320},{"id":4,"title":5,"body":6,"categories":282,"date":284,"description":285,"draft":286,"extension":287,"image":288,"meta":289,"navigation":290,"path":294,"permalink":295,"published":295,"readingTime":296,"recommend":301,"references":302,"seo":309,"sitemap":310,"stem":311,"tags":312,"type":317,"updated":318,"__hash__":319},"content\u002Fposts\u002Fbefore\u002Fastar-qt.md","路径规划：一个基于 Qt 的 A* 算法演示器",{"type":7,"value":8,"toc":271},"minimark",[9,16,20,28,31,38,41,44,63,66,71,74,77,80,88,91,119,122,125,128,131,138,141,152,155,161,172,175,178,186,189,193,196,200,203,207,210,214,217,221,224,228,231,235,238,241,244,253,256,259,262,265],[10,11,12],"quote",{},[13,14,15],"p",{},"比起单纯把算法跑出来，我更想看到它“是怎么跑的”。于是这个小项目最后就变成了一个路径搜索算法演示器。",[17,18,19],"h2",{"id":19},"写在前面",[13,21,22,23,27],{},"这是我在《算法设计与优化》课设里做的一个小软件，题目方向是",[24,25,26],"strong",{},"无人机路径搜索与优化","。更准确一点说，它并不只是“实现一个 A* 算法”，而是想把常见路径规划算法做成一个可交互、可视化、方便演示的小工具。",[13,29,30],{},"这篇文章其实在 2023 年底就写过一版了，不过当时演示内容一直没补完整。前段时间刚好抽空把一些演示 GIF 和细节重新整理了一下，所以索性重发一次，也顺手把内容按现在的新博客框架重新收拾一下。",[13,32,33,34,37],{},"从完成度上看，这个项目当然算不上多成熟。它更像是一个",[24,35,36],{},"带界面的算法实验场","：可以自己画地图、设置起点终点和障碍物，切换不同算法，看它们怎么搜索、怎么扩展节点、最后怎么得到路径。对课设展示来说，这种“看得见过程”的形式，比单纯打印几行结果要直观得多。",[17,39,40],{"id":40},"项目环境与界面",[13,42,43],{},"项目基于 Qt 框架，使用 C++ 开发，开发环境如下：",[45,46,47],"card-list",{},[48,49,50,54,57,60],"ul",{},[51,52,53],"li",{},"OS：Windows",[51,55,56],{},"IDE：Qt Creator",[51,58,59],{},"Language：C++",[51,61,62],{},"Framework：Qt",[13,64,65],{},"主界面长这样：",[67,68],"pic",{"caption":69,"src":70},"主界面布局预览","https:\u002F\u002Fwww.freeimg.cn\u002Fi\u002F2023\u002F12\u002F27\u002F658c4264e5507.jpg",[13,72,73],{},"界面本身没有什么特别高深的设计，主要目标还是围绕“演示”服务：地图区域尽量清晰，工具栏操作尽量直接，底部状态栏可以辅助调试，算法执行结果则尽量用颜色、路径和节点状态展示出来。说白了，它不是一个追求工业级美观的产品，而是一个偏实用的教学和展示工具。",[17,75,76],{"id":76},"这个项目能做什么",[13,78,79],{},"如果只看名字，“A* 算法演示器”听起来好像功能不多，但实际做着做着，还是往里面塞了不少东西。",[13,81,82,83,87],{},"先说地图交互这部分。项目支持自定义地图宽高，单元格大小也可以调整；起点、终点、障碍物都能手动设置；绘制好的地图支持保存成本地 ",[84,85,86],"code",{"code":86},".Amap"," 文件，方便下次直接载入，不用每次都现场手画。为了让演示过程更灵活，我还加了随机地图、导入背景图、清除背景图这些功能，虽然有些地方做得还比较粗糙，但至少把“可操作性”这一块补上了。",[13,89,90],{},"算法部分则不止 A* 一种。我把自己当时课设里涉及到的一些经典搜索算法都做进去了，包括：",[45,92,93],{},[48,94,95,98,101,104,107,110,113,116],{},[51,96,97],{},"深度优先搜索（DFS）",[51,99,100],{},"广度优先搜索（BFS）",[51,102,103],{},"Dijkstra 算法",[51,105,106],{},"最佳优先搜索",[51,108,109],{},"传统 A* 算法",[51,111,112],{},"双向 A* 算法",[51,114,115],{},"优化版 A* 算法",[51,117,118],{},"三种增量式搜索算法（这一部分还不够完善）",[13,120,121],{},"其中我自己投入最多的，还是优化版 A* 这一块。为了让它更有“可调参数”的感觉，我加入了几种不同的启发式距离定义，包括切比雪夫距离、曼哈顿距离和欧几里得距离；同时还加入了动态权重、拐角代价和安全距离模式等参数，方便观察不同策略对最终路径结果的影响。",[13,123,124],{},"严格来说，这些优化还谈不上多么系统，更多还是面向课设场景下的一种工程化尝试：既想让它比“最原始版本”更灵活一点，又希望界面上能比较直观地把差异体现出来。",[17,126,127],{"id":127},"如何获取与使用",[13,129,130],{},"源码我放在 GitHub 上了，直接下载或者克隆都可以。",[132,133],"link-card",{"description":134,"icon":135,"link":136,"title":137},"项目 GitHub 仓库，包含源码与工程文件。","https:\u002F\u002Fgithub.com\u002Ffavicon.ico","https:\u002F\u002Fgithub.com\u002FJJLibra\u002FAstar","Astar",[13,139,140],{},"如果你习惯直接拉仓库，也可以用下面这条命令：",[142,143,150],"pre",{"className":144,"code":146,"filename":147,"language":148,"meta":149},[145],"language-bash","git clone git@github.com:JJLibra\u002FAstar.git\n","clone.sh","bash","",[84,151,146],{"__ignoreMap":149},[13,153,154],{},"考虑到 GitHub 访问有时候比较慢，我当时也顺手留了一个网盘备份，不过网盘里通常只放最新版代码：",[132,156],{"description":157,"icon":158,"link":159,"title":160},"备用下载地址，提取码：16ca","https:\u002F\u002Fpan.baidu.com\u002Ffavicon.ico","https:\u002F\u002Fpan.baidu.com\u002Fs\u002F1SwZ1t9c0dEq-w0hxFZM_XA","百度网盘下载",[13,162,163,164,167,168,171],{},"下载源码之后，比较推荐直接用 ",[24,165,166],{},"Qt Creator"," 打开项目里的 ",[84,169,170],{"code":170},"Astar.pro"," 工程文件。这样最省事，也方便你顺手改代码做二次开发。",[13,173,174],{},"如果只是想在 Windows 下打包成可执行文件，我当时用的是 Enigma Virtual Box。这块不是本文重点，就不展开讲了，有需要的话可以自己搜相关教程。",[17,176,177],{"id":177},"一些实际演示",[179,180,183],"alert",{"title":181,"type":182},"先说明一下","warning",[13,184,185],{},"因为图床和流量原因，下面这些 GIF 的画质会有一点压缩。实际运行时的界面观感会比动图里更顺一点。",[13,187,188],{},"先是最基础的地图设置。这个项目支持自由设置地图大小，然后在网格里标记起点、终点和障碍物。整个交互其实不复杂，但对演示来说已经够用了：",[67,190],{"caption":191,"src":192},"设置地图与编辑单元格状态","https:\u002F\u002Fpicsur.xxfer.cn\u002Fi\u002Fc3a189bc-526d-4f70-9222-9bebd2e25146.gif",[13,194,195],{},"下面这个是优化版 A* 的演示，同时还把贝塞尔曲线作为最终轨迹做了绘制。也就是说，程序给出的原始路径并不是最后的展示结果，我又额外做了一层平滑处理，让它看起来更像“无人机轨迹”而不是简单折线：",[67,197],{"caption":198,"src":199},"优化 A* 算法演示，以及贝塞尔曲线路径平滑","https:\u002F\u002Fd.kstore.space\u002Fdownload\u002F7746\u002FA星﹠贝塞尔.gif",[13,201,202],{},"随机地图和一键重置也加进去了。这里的随机地图逻辑其实比较朴素，就是基于伪随机数去生成障碍，严格来说还不够聪明，不能保证每次都生成存在可行解的地图。这个地方如果以后要继续做，我觉得最值得优先重构的就是它：",[67,204],{"caption":205,"src":206},"生成随机地图与重置参数","https:\u002F\u002Fpicsur.xxfer.cn\u002Fi\u002Ffe25fc09-01e1-4074-875b-d402ed68fe74.gif",[13,208,209],{},"为了适配课设答辩这种场景，我还做了地图保存功能。毕竟现场再一点点手画地图既费时间，也容易翻车，提前把测试地图存好显然更稳：",[67,211],{"caption":212,"src":213},"保存地图到本地文件","https:\u002F\u002Fd.kstore.space\u002Fdownload\u002F7746\u002F保存地图.gif",[13,215,216],{},"载入地图同样是支持的。下面这个演示里还顺便展示了深度优先搜索。这里有个小插曲：录视频的时候我忘了演示“深搜最短”这个按钮，实际它是能工作的，只是操作时要稍微按顺序来，不然有些状态切换容易把自己绕晕：",[67,218],{"caption":219,"src":220},"打开地图文件，以及深度优先搜索演示","https:\u002F\u002Fpicsur.xxfer.cn\u002Fi\u002F5f630723-86b5-48d0-b750-989a6ff79598.gif",[13,222,223],{},"背景图导入这个功能，本来是我给“地图栅格化”留的一个过渡方案。原本我确实想继续往“真实地图栅格化”方向做，但当时课设时间已经有点紧了，最后就退一步，先支持导入本地图片作为背景，再手动在上面描地图。虽然只是个折中方案，但至少把这个思路跑通了：",[67,225],{"caption":226,"src":227},"导入背景图与清除背景图","https:\u002F\u002Fd.kstore.space\u002Fdownload\u002F7746\u002F打开﹠清除背景.gif",[13,229,230],{},"除此之外，还有一些不太显眼、但我自己当时做得挺上头的小细节，比如关于页、性能分析可视化、状态栏提示、操作反馈，以及一些不太成熟但多少有点意思的界面动画：",[67,232],{"caption":233,"src":234},"其他界面细节与功能展示","https:\u002F\u002Fpicsur.xxfer.cn\u002Fi\u002F943232fc-8901-429a-8e00-c2a66cd8c233.gif",[17,236,237],{"id":237},"做这个项目时的一些取舍",[13,239,240],{},"现在回头看，这个项目其实挺典型：想做的东西很多，真正能在课设周期里做完的东西却很有限。",[13,242,243],{},"比如我原本很想把“真实地图栅格化”“更稳定的随机地图生成”“增量式搜索算法的完整交互”这些部分做扎实，但最后都只能在时间、复杂度和展示效果之间做妥协。于是项目里就出现了很多这种状态：功能已经有雏形，能演示，也能跑，但还远没到我自己心里那个“做舒服了”的程度。",[10,245,246],{},[13,247,248,249,252],{},"很多学生项目最后的样子，都不是“全做完了”，",[250,251],"br",{},"\n而是“在截止日期之前，把最值得展示的部分先做出来了”。",[13,254,255],{},"所以如果你下载代码以后，看到里面有些写法不太规范、某些逻辑有点糙、局部实现带着明显的课设味道，也不用太意外。这个项目本来就是一边学、一边试、一边补出来的。小细节不少，bug 其实也不少，改到后面代码确实有点朝着“能跑就先别动”那个方向滑过去了。",[17,257,258],{"id":258},"最后",[13,260,261],{},"由于这个项目本身是学校课设，所以里面有些图标素材会带一点校内元素。如果你只是想参考算法实现、界面思路或者工程组织方式，直接看源码就够了；如果你想要一个更早期、相对更原始的版本，我也可以单独提供。",[13,263,264],{},"总之，这个项目的定位一直都很明确：它不是一个成熟产品，而是一个把路径搜索算法“做给人看”的小工具。对我来说，它最大的意义不只是把 A* 写出来，而是把算法、界面、交互和演示这一整套流程都亲手串了一遍。",[13,266,267,268,270],{},"如果你正好对这个项目感兴趣，或者准备拿它做一点自己的二次开发，欢迎去仓库里看看。",[250,269],{},"\n当然，别忘了顺手点个免费的 Star，这个对学生项目来说还是很有鼓励意义的。",{"title":149,"searchDepth":272,"depth":272,"links":273},4,[274,276,277,278,279,280,281],{"id":19,"depth":275,"text":19},2,{"id":40,"depth":275,"text":40},{"id":76,"depth":275,"text":76},{"id":127,"depth":275,"text":127},{"id":177,"depth":275,"text":177},{"id":237,"depth":275,"text":237},{"id":258,"depth":275,"text":258},[283],"开发","2024-03-15 22:00:00","这是我做的一个课设小项目。核心目标很简单：把常见路径搜索算法做成一个可交互、可视化、可演示的小工具，而不只是停留在控制台输出结果。",false,"md","https:\u002F\u002Fwmimg.com\u002Fi\u002F1546\u002F2026\u002F03\u002F69aeeacd1bf42.webp",{"coverDim":290,"zoom":290,"aside":291,"slots":293},true,[292],"toc",{},"\u002Fbefore\u002Fastar-qt",null,{"text":297,"minutes":298,"time":299,"words":300},"12 min read",11.54,692400,2308,0,[303,306],{"link":304,"title":305},"https:\u002F\u002Fgithub.com\u002FJJLibra\u002FAstar-qt","GitHub 项目仓库：Astar",{"link":307,"title":308},"https:\u002F\u002Fblog.csdn.net\u002Fsinat_35676815\u002Farticle\u002Fdetails\u002F120884682","贝塞尔曲线参考资料",{"title":5,"description":285},{"loc":294},"posts\u002Fbefore\u002Fastar-qt",[313,314,315,316],"A星算法","C++","Qt","路径规划","story","2024-03-16 00:00:00","aJ1m6doyXg9Xx3iJVHsLLPtAG2cjTfb718csVil2Jvw",[321,326],{"title":322,"path":323,"stem":324,"date":325,"type":317,"children":-1},"GitHub 首页 DIY：花里胡哨指数++","\u002Fbefore\u002Fgithub-diy","posts\u002Fbefore\u002Fgithub-diy","2024-01-20 00:00:00",{"title":327,"path":328,"stem":329,"date":330,"type":317,"children":-1},"Docker 折腾记：国内镜像源失效之后，我是怎么把环境重新拉起来的","\u002Fbefore\u002Fdocker","posts\u002Fbefore\u002Fdocker","2024-11-03 18:00:00",1789965463398]