码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 前端使用 Konva 实现可视化设计器(13)- 折线 - 最优路径应用【思路篇】


    合集 - 前端使用 Konva 实现可视化设计器(14)
    1.前端使用 Konva 实现可视化设计器(2)- 参考线、svg、gif图片加载04-062.前端使用 Konva 实现可视化设计器(1)- 无限画布、比例尺04-053.前端使用 Konva 实现可视化设计器(4)- 快捷键移动元素04-114.前端使用 Konva 实现可视化设计器(3)- 单选、多选、选择框04-105.前端使用 Konva 实现可视化设计器(5)- 磁贴效果04-166.前端使用 Konva 实现可视化设计器(6)- 复制粘贴、删除、位置、zIndex调整04-207.前端使用 Konva 实现可视化设计器(7)- 导入导出、上一步、下一步04-248.前端使用 Konva 实现可视化设计器(8)- 预览框04-309.前端使用 Konva 实现可视化设计器(9)- 另存为SVG05-0710.前端使用 Konva 实现可视化设计器(10)- 对齐线05-1111.前端使用 Konva 实现可视化设计器(11)- 对齐效果05-1812.前端使用 Konva 实现可视化设计器(12)- 连接线 - 直线06-02
    13.前端使用 Konva 实现可视化设计器(13)- 折线 - 最优路径应用【思路篇】06-08
    14.前端使用 Konva 实现可视化设计器(14)- 折线 - 最优路径应用【代码篇】06-11
    收起

    这一章把直线连接改为折线连接,沿用原来连接点的关系信息。关于折线的计算,使用的是开源的 AStar 算法进行路径规划,启发方式为 曼哈顿距离,且不允许对角线移动。

    请大家动动小手,给我一个免费的 Star 吧~

    大家如果发现了 Bug,欢迎来提 Issue 哟~

    github源码

    gitee源码

    示例地址

    灵感来源主要来自于下面优秀的文章:

    关联线探究,如何连接流程图的两个节点

    主要参考了:如何挑选连接点及其真正的出入口、算法的选型。具体代码没有仔细了解,毕竟布局和元素的想法不一样,没必要参考代码。

    路径规划之 A* 算法

    主要了解一下算法的介绍。

    欧式距离、曼哈顿距离、切比雪夫距离、Octile距离

    主要了解一下 AStar 算法的各种启发方式的差异。

    路径规划可视化动画

    形象的感受路径搜索的差异。

    至于算法本身,在目前阶段下不是必须深入分析,这里应用为主。

    最优路径

    image

    参考这张图,基于当前案例,可以把折线想象为路径,目标就是查找最优路径,例如:
    image

    又或者:
    image

    上面明显不是我们直觉最优的路径选择,如:

    • 太贴近节点了
    • 转弯太多

    更希望是这样:
    image
    image

    开启调试模式,来说说连接点的出入口:
    image

    人为地,距离”连接点“偏离一些,定义所谓的”出入口“(途中绿色的点),作为折线真的起点和终点。

    把连线先移除,看看其他点:
    image

    一共定义了 3 种点:

    • 连接点(红色)
    • 出入口(绿色)
    • 途径点(蓝色)

    关于途径点,是人为挑选的,主要(中心点除外)来自于图中不同颜色区域(线框),这里定义了 ?种区域:

    • 连接点最小区域

    为什么不叫节点区域呢?因为此前设计的连接点是动态的,它可以节点内部的其他位置,只是目前定义的都是上下左右边缘而已。所以,它可能比节点区域更小。

    image

    • 连线不可通过区域

    image

    • 连线不可通过扩展区域

    两个区域共同所在的最小区域

    image

    • 连线通过区域

    image

    • 连线通过扩展区域

    同理,两个区域共同所在的最小区域

    image

    算法建模(关键)

    上面说了那么多点和区域,最终目的就是为了建模,可供算法使用。
    这个模型,就是一个数组矩阵 matrix,可以理解成一个格子地图,如:
    image

    0 代表可通过,1 代表不可通过(称之为“墙”吧),对应的数组矩阵,就是

    [
    	[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    	[0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    	[0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    	[0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    	[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0],
    	[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0],
    	[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0],
    	[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    	[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    ]
    

    计算结果是一个途径格子坐标数组:

    坐标就是数组1、2层下标,可以视作 x、y 轴。
    image

    [
    	[5, 3],
    	[6, 3],
    	[7, 3],
    	[8, 3],
    	[8, 4],
    	[8, 5]
    ]
    

    主要问题来了,毕竟在这里的画板,不同于算法示例那样“走格子”,800x800 的画布大小,不可能建一个 800x800 数组矩阵,性能可吃不消,别说更大的画布了。

    所以,如何建模才是这个案例画折线的关键!

    这里,拿一个大一点的例子说明:
    image

    既然,拿“像素”当作格子不现实,可以拿“点”作为格子不就好了吗?
    image

    数组矩阵变成:

    [
    	[0, 0, 0, 0, 0, 0, 0, 0, 0],
    	[0, 0, 0, 0, 0, 0, 0, 0, 0],
    	[0, 0, 0, 0, 0, 0, 0, 0, 0],
    	[0, 0, 0, 0, 0, 0, 0, 0, 0],
    	[0, 0, 0, 0, 0, 0, 0, 0, 0],
    	[0, 0, 0, 0, 0, 0, 0, 0, 0],
    	[0, 0, 0, 0, 0, 0, 0, 0, 0]
    ]
    

    这里缺少了“墙”,哪些是墙?其实就是上面说的不可通过区域:
    image

    “墙”不同于连接点,需要补充一些点:
    image

    数组矩阵变成(增加了 2 列、2 行):

    [
    	[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    	[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    	[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
    	[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    	[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    	[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    	[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
    	[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    	[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    ]
    

    然后给数组矩阵设置“墙”:

    这里把 2 定义为墙,所以 0、1 均能通过,方便后面区分和理解。

    [
    	[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    	[0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0],
    	[0, 2, 2, 2, 0, 0, 0, 2, 2, 2, 0], 
    	[0, 2, 2, 2, 0, 0, 0, 2, 2, 2, 0],
    	[0, 2, 2, 2, 0, 0, 0, 2, 2, 2, 0],
    	[0, 2, 2, 2, 0, 0, 0, 2, 2, 2, 0],
    	[0, 2, 2, 2, 0, 0, 0, 2, 2, 2, 0], 
    	[0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0],
    	[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    ]
    

    连接点、连接线的出入口不应该是“墙”,调整一下:

    设置为 1,方便区分

    image

    起点:[2, 3]
    终点:[8, 5]
    image

    现在交给算法,计算结果得出:
    image

    就是:
    image

    画成线:
    image

    主要思路就是如此,虽然不是完美的,请看:
    image

    原因主要是算法并不知道拐弯的“代价”,暂且如此吧。
    思路的介绍到此为止,下一章再说说代码大概是如何实现的。

    More Stars please!勾勾手指~

    源码

    gitee源码

    示例地址

  • 相关阅读:
    ssh免密登陆
    21 Educational Codeforces Round 136 (Rated for Div. 2)Knowledge Cards(树状数组、set、+思维、数字华容道)
    conda环境中pytorch1.2.0版本安装包安装一直失败解决办法!!!
    交换机与路由技术-16-生成树协议STP
    驱动开发:内核无痕隐藏自身分析
    ArcGIS中如何提取威胁源的csv数据
    LangChain的函数,工具和代理(一):OpenAI的函数调用
    Python多线程(01):进程和线程的区别与使用
    2024Selenium自动化常见问题!
    大数据安全认证
  • 原文地址:https://www.cnblogs.com/xachary/p/18238704
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号