概述

上个版本简单的连线在一些复杂场景,尤其层级比较多,连线跨层级比较多的情况下,会出现线条会穿过矩形的情况,这一讲就是在这个基础上,去优化这个连线。

场景分析

在下面几种情况下,简单版本的画法已经没法办规避障碍节点了。

这种情况,由于简单版本,我们只在整条路径上添加了2个拐点,这种画法,当出现上述情况,线条就会被B挡住,实际的需求,我们要规避这种节点,绕开。

应该是下面这种情况:

再复杂一点的场景如下

这时候有2个节点挡住了。我们要做的就是按照图示,绕开节点。

思路分析

观察分析,我们要想绕开,一些障碍节点,我们先要知道哪些节点会挡住,才可以绕开。有两个已经明确数据是,每一层的节点的坐标我们是知道,起点p1, 终点是p6。 我们可以模拟这个过程:

  1. 如果p1 所在直线没有被最近的下一层挡住,也就是图中D,E,F节点挡住的话,那就说明,起点可以先画到p2
  2. 画到p2 之后,继续判断第三层节点,由于B节点会挡住从p2 往下画的竖线,所以绕开B节点,由于P6终点再p2 左侧,所以,在B的左侧找一个空白的地方,即p3
  3. 现在画到p3了,这时候起点编程p3了, 问题转换成画p1的场景了
  4. 一直循环,直到到终点这一层,把这个路径上的所有的折点记录下来,就是我们的路径

具体实现

function drawLine(startX, startY, endX, endY, color, sourceNodeName, targetNodeName, endLayer, startLayer, lineNodes) {var points = []; //  保存路径上的折点var sx =  startX;var ex = endX;for (var layer = startLayer + 1; layer < endLayer; layer++) {//  判断当前这一层有没有节点挡住var coverRectIndex = -1;for(var i = 0; i < lineNodes[layer].length; i++){if(lineNodes[layer][i].x < sx && (sx - lineNodes[layer][i].x) < config.rect.width){coverRectIndex = i;break;}}if(coverRectIndex === -1){//  如果没有挡住,检查下一层continue;}else{//  如果有挡住,则需要根据起点和目标节点相对位置,决定往左边绕还是后边绕var midY = lineNodes[layer][coverRectIndex].y - 40;// 计算是左边的空隙还是右边的空隙var midX = lineNodes[layer][coverRectIndex].x;midX += sx > ex? -(config.rect.space / 2 + config.rect.width) : (config.rect.space / 2 + config.rect.width);while (true) {var flag = false;if (nodeLines[layer]) {for (var i = 0; i < nodeLines[layer].length; i++) {var line = nodeLines[layer][i];if (line.startY === midY) {if (checkCross(sx, midX, line.startX, line.endX)) {flag = true;}}if (flag) break;}} else {nodeLines[layer] = [];}if (!flag) break;midY -= lineDis;}if (sx !== midX) {nodeLines[layer].push({startX: sx,startY: midY,endX: midX,endY: midY})}// 存储路径上点points.push({ x: sx, y: midY });points.push({ x: midX, y: midY });sx = midX;}}//  单独处理最后一层的场景var midY = lineNodes[endLayer][0].y - 40;while (true) {var flag = false;if (nodeLines[endLayer]) {for (var i = 0; i < nodeLines[endLayer].length; i++) {var line = nodeLines[endLayer][i];if (line.startY === midY) {if (checkCross(sx, ex, line.startX, line.endX)) {flag = true;}}if (flag) break;}} else {nodeLines[endLayer] = [];}if (!flag) break;midY -= lineDis;}if (sx !== ex) {nodeLines[layer].push({startX: sx,startY: midY,endX: ex,endY: midY})}points.push({ x: sx, y: midY });points.push({ x: ex, y: midY });return points;
}

总结

这里是在原来的基础上进行优化的,实现了规避障碍节点的功能。一开始,我想到是 A*算法去搜索,但是像素点太多,算法复杂度Hold不住,后面卡在缩点的环节上,经过同事的指点,才实现了当前的这种优化,还是要多学习,多总结!

本文由华为云发布。

从零开始画自己的DAG作业依赖图(四)--节点连线优化版相关推荐

  1. 从零开始画自己的DAG作业依赖图(三)--节点连线简单版

    概述 分层布局弄好之后,每一层的节点上下的相对位置基本确定了,我们最简单的方式,就是每一层平铺所有节点,节点宽度固定以及间距固定,每个节点的位置基本就确定了.我们只要基于这些节点进行连线就可以了. 方 ...

  2. 从零开始画自己的DAG作业依赖图(二)--分层布局算法

    概述 当我们把设计稿和技术选型定下来之后,接下来就要开始着手画这个依赖图了.依赖图的组成最简单的就是节点Node 和节点之间的连线.这一节我们要处理的就是节点位置信息的处理.为了确定节点的位置信息,首 ...

  3. 深蓝学院《从零开始手写VIO》作业四

    深蓝学院<从零开始手写VIO>作业四 深蓝学院<从零开始手写VIO>作业四 1. 信息矩阵分析 2. Bundle Adjustment信息矩阵的计算 深蓝学院<从零开始 ...

  4. 深蓝学院《从零开始手写VIO》作业七

    深蓝学院<从零开始手写VIO>作业七 深蓝学院<从零开始手写VIO>作业七 深蓝学院<从零开始手写VIO>作业七 将第二讲中的仿真数据(视觉特征,imu数据)接入V ...

  5. 深蓝学院《从零开始手写VIO》作业五

    深蓝学院<从零开始手写VIO>作业五 1. 完成Bundle Adjustment求解器 2. 完成测试函数 3. 论文总结 1. 完成Bundle Adjustment求解器 完成单目 ...

  6. 北京交通大学Python课程设计大作业(四)——典籍词频统计

    北京交通大学Python课程设计大作业(四)--典籍词频统计 文章目录 北京交通大学Python课程设计大作业(四)--典籍词频统计 一.词频统计任务介绍 二.典籍词频统计python源代码如下 三. ...

  7. 四年级数学作业计算机,四年级数学作业答案

    四年级数学作业答案 四年级数学暑假作业答案 1.P3近似数一般写成用千.万.百万.千万.亿为单位的数 2.P5一格自然数的.近似数是5亿,这个数最大可能是549999999,最小可能是45000000 ...

  8. opencv画火车沿轨道运行-课程作业

    opencv画火车沿轨道运行-课程作业 四个函数,一个循环 一. 轨道函数 二.定义可转弯小车的方法 三.定义角度函数 四.定义约束项 五.一个循环 以下附上总代码 以下效果图 写本次博客的目的主要是 ...

  9. 深蓝学院《从零开始手写VIO》作业六

    深蓝学院<从零开始手写VIO>作业五 深蓝学院<从零开始手写VIO>作业六 1. 证明题 2. 代码题 深蓝学院<从零开始手写VIO>作业六 1. 证明题 证明Dy ...

最新文章

  1. 到底使用接口还是抽象类
  2. boost::describe模块实现打印功能的测试程序
  3. 函数传参字典_Python 函数中的 4 种参数类型
  4. List集合中数据用set集合去重复,用set集合去重复数据重写了equals还是没成功!
  5. 美化下拉框select箭头部分(不彻底)
  6. centos7显示时间的时区修改
  7. Windows程序设计与C语言的主要区别是什么?
  8. JS五彩连珠小游戏(Canvas绘制)
  9. 美国人口普查数据预测收入sklearn算法汇总2: 特征编码, 特征选择, 降维, 递归特征消除
  10. Java:spring Value注解用法详解
  11. 超级科技数据防泄漏系统,管控违规上网行为,保障企业信息安全
  12. 【更新ing】已有5个省份公布2020软考报名时间
  13. 【Windows】关于Windows Powershell找不到打不开修复方法
  14. 2022-2028年中国5G 汽车产业应用市场竞争策略及未来发展潜力报告
  15. 如何提升订单周转,避免订单交期延误?
  16. 系统服务器Fedora和Red Hat Enterprise Linux实用指南(第6版)(上、下册)( 入行必读的Linux圣经)...
  17. c++新鸟的升级路(一)
  18. 发布汇编集成编译器Win-Masm v2.2
  19. 医护管理平台系统服务器,康软智能移动医护管理系统
  20. Android Service服务保活

热门文章

  1. 川土微 数字隔离器 CA-IS3722HS可替代ADUM1201ARZ
  2. greenplum列存
  3. 华为鸿蒙战略发布会内容,万物互联!华为鸿蒙发布会带来无限可能
  4. 基于LLVM编译器的IDA自动结构体分析插件
  5. 【排序】详细聊聊归并排序(含非递归)
  6. 四川企立方:拼多多标题要怎么组成
  7. “Think Different”是个糟糕的想法
  8. 方框如何打勾、打叉与涂黑(转)
  9. css3简单实现页面中出现雪花飘落效果
  10. Charles--使用Charles抓Https包