package com.zy.common.utils; import com.zy.common.model.NavigateNode; import java.util.*; /** * A*算法使用工具 */ public class NavigateUtils { public static List calc(String startPoint, String endPoint, String mapType) { //通过开始编号和结束编号获取对应的xy轴坐标 int[] startArr = NavigatePositionConvert.positionToXY(startPoint);//开始节点 int[] endArr = NavigatePositionConvert.positionToXY(endPoint);//结束节点 //初始化开始节点 NavigateNode start = new NavigateNode(startArr[0], startArr[1]); //开始节点无父节点 start.setFather(null); NavigateNode end = new NavigateNode(endArr[0], endArr[1]); NavigateSolution solution = new NavigateSolution(mapType); NavigateNode res_node = solution.astarSearch(start, end); if (res_node == null) { System.out.println("未找到路径"); return null; } else { ArrayList list = new ArrayList<>(); //渲染 NavigateNode fatherNode = null;//当前循环上一节点,用于拐点计算 while (res_node != null) { HashMap data = new HashMap<>(); res_node.setDirection(null); res_node.setIsInflectionPoint(false); //寻找拐点 HashMap result = searchInflectionPoint(res_node, fatherNode, res_node.getFather());//分别传入当前节点、父节点、下一节点 //判断当前节点是否为拐点 if (Boolean.parseBoolean(result.get("result").toString())) { //当前为拐点 res_node.setIsInflectionPoint(true); //拐点方向 res_node.setDirection(result.get("direction").toString()); } list.add(res_node); fatherNode = res_node;//把当前节点保存成一个父节点 res_node = res_node.getFather();//迭代操作 } Collections.reverse(list); //将每个节点里面的fatherNode至为null(方便后续计算时父节点过多导致显示的节点太多) for (NavigateNode navigateNode : list) { //父节点设置为null,不影响计算结果,不影响后续操作。 //此操作仅为后续排查处理提供视觉方便。 navigateNode.setFather(null); } //起始节点计算方向 String direction = calcDirection(list.get(0), list.get(1)); NavigateNode startNode = list.get(0); startNode.setDirection(direction); //更新节点列表 list.set(0, startNode); return list; } } //判断当前节点到下一个节点是否为拐点 public static HashMap searchInflectionPoint(NavigateNode currentNode, NavigateNode fatherNode, NavigateNode nextNode) { HashMap map = new HashMap<>(); map.put("result", false);//是否为拐点,true:拐点,false:直线 // 第一个点或直线点 if (fatherNode == null || nextNode == null || nextNode.getX() == fatherNode.getX() || nextNode.getY() == fatherNode.getY()) { return map;//不是拐点直接返回 } //拐点方向 String direction = calcDirection(currentNode, fatherNode); map.put("result", true);//拐点 map.put("direction", direction);//拐点方向(从当前节点视角看的方向) return map; } /** * 计算方向 */ public static String calcDirection(NavigateNode currentNode, NavigateNode fatherNode) { //拐点方向 String direction = ""; // 普通拐点 //计算拐点方向 if (fatherNode.getX() != currentNode.getX()) { //x轴数据有差异,判断x轴方向 //当前节点X - 父节点X if (currentNode.getX() - fatherNode.getX() > 0) { //大于0,方向top direction = "top"; }else { //小于0,方向bottom direction = "bottom"; } } if (fatherNode.getY() != currentNode.getY()) { //y轴数据有差异,判断y轴方向 //当前节点Y - 父节点Y if (currentNode.getY() - fatherNode.getY() > 0) { //大于0,方向left direction = "left"; }else { //小于0,方向right direction = "right"; } } return direction; } /** * 获取分段路径,每当有一个拐点则进行一次分段,最终返回总分段数据 */ public static ArrayList> getSectionPath(List mapList) { ArrayList> list = new ArrayList<>(); ArrayList data = new ArrayList<>(); for (NavigateNode mapNode : mapList) { boolean isInflectionPoint = mapNode.getIsInflectionPoint(); data.add(mapNode); if (isInflectionPoint) { //拐点 //分割数据 list.add(data);//添加某一段数据 data = new ArrayList<>(); } } //将最后一段数据添加进入 list.add(data); return list; } public static void main(String[] args) { //计算路径 List calc = calc("1000901", "0201801", "out"); System.out.println(calc); System.out.println("------------------------"); // List calc = calc("0501401", "0201801", "out"); //将路径分割成多段 ArrayList> data = getSectionPath(calc); for (ArrayList list : data) { System.out.println(list); } } }