zoukankan      html  css  js  c++  java
  • 使用寻路算法写的一个小项目

    用寻路算法写的一个小项目

    地址

    https://a1115040996.github.io/arithmetic/html/寻路应用.html

    没来得及仔细优化,后面再优化 

    代码如下

    <!DOCTYPE html>
    <html>
    	<head>
    		<meta charset="UTF-8">
    		<title></title>
    		<link rel="stylesheet" type="text/css" href="../css/way-finding.css"/>
    	</head>
    	<body>
    		<ul id="ul-table">
    		</ul>
    		<script src="../js/plugin/jquery-2.1.0.js" type="text/javascript" charset="utf-8"></script>
    		<script type="text/javascript">
    		/*************************************
    		 * 估价函数
    		 * f(n) = g(n) + h(n)
    		 * g(n) 起始点距离目标点的距离
    		 * h(n) 结束点距离目标点的距离
    		 * f(n) 估价   最小距离为最优解决方案
    		 * 
    		 * 
    		 * 创建矩阵
    		 * 1. 起点
    		 * 2. 终点
    		 * 3. 障碍
    		 * 4. 移动路径
    		**************************************/
    			var sizeGrid = 25;// 点的长宽
    			var startLocation;// 起点
    			var endLocation;// 终点
    			var openArr = [];// 开始点
    			var closeArr = [];// 结束点结果
    			var rocksArr = []; //障碍物
    			var canClose = true; // 是否已经找到路径
    			var mList = [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,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,3,3,0,0,0,0,3,0,0,0,0,3,3,0,0,0,0,
    						 0,0,0,1,3,0,0,0,0,3,0,0,0,0,3,3,0,0,0,0,
    						 0,0,0,0,3,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,
    						 0,0,0,3,3,3,0,0,0,3,0,0,0,0,0,0,0,0,0,0,
    						 0,0,0,0,0,3,0,0,0,3,0,0,0,0,0,0,0,0,0,0,
    						 0,0,0,0,3,3,0,0,0,3,0,0,0,0,0,0,0,0,0,0,
    						 0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,
    						 0,0,0,0,0,0,0,0,0,3,0,3,3,3,0,0,0,0,0,0,
    						 0,0,0,0,0,0,0,0,0,3,0,3,0,0,0,0,0,0,0,0,
    						 0,0,0,3,3,3,3,3,3,3,0,3,3,3,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]
    			function createList(list){
    				$("#ul-table").width(sizeGrid*20+1+1)
    				var fragment = document.createDocumentFragment()
    				for (var i=0;len = list.length,i<len;i++) {
    					var _li = $('<li uid='+(i+1)+' x='+(i % 20 + 1)+' y='+(Math.floor(i / 20)+1)+'></li>').css({'width': sizeGrid,'height':sizeGrid})
    					if(list[i] === 1){ // 起始点
    						startLocation = _li
    						openArr.push(_li)
    						_li.addClass('start')
    					}else if(list[i] === 2){ // 结束点
    						endLocation = _li
    						_li.addClass('end')
    						//closeArr.push(_li)
    					}else if(list[i] === 3){ // 障碍
    						closeArr.push(_li)
    						rocksArr.push(_li)
    						_li.addClass('remora')
    					}else if(list[i] === 4){ // 移动点
    						_li.addClass('move')
    					}
    					fragment.appendChild(_li[0])
    				}
    				return fragment
    			}
    			$("#ul-table").append(createList(mList))
    			
    			
    			// 寻迹算法
    			function f(nodeGrid){
    				return g(nodeGrid) + h(nodeGrid)
    			}
    			
    			// 目标点 距离起始点的距离
    			function g(nodeGrid){
    				var a = nodeGrid.offset().left - startLocation.offset().left
    				var b = nodeGrid.offset().top - startLocation.offset().top
    				return Math.sqrt(a*a + b*b)
    			}
    			
    			// 目标点距离结束点的距离
    			function h(nodeGrid){
    				var a = nodeGrid.offset().left - endLocation.offset().left
    				var b = nodeGrid.offset().top - endLocation.offset().top
    				return Math.sqrt(a*a + b*b)
    			}
    			
    			
    			// 获取可能的落脚点
    			function findNextStepList(){
    				var result = [];// 存储结果集
    				var preStep = openArr.shift()
    				var startX = +preStep.attr('x')
    				var startY = +preStep.attr('y')
    				closeArr.push(preStep)
    				
    				getPossibleGrid(startX, startY)
    				// 获取可能的落脚点
    				function getPossibleGrid(x,y){
    					var _startX = (x-1) > 1 ? (x-1) : x;
    					var _startY = (y-1) > 1 ? (y-1) : y;
    					
    					var _endX = (x+1) <= 20 ? (x+1) : x;
    					var _endY = (y+1) <= 20 ? (y+1) : y;
    					
    					for(var i=_startX;i<=_endX;i++){
    						for (var j=_startY;j<=_endY;j++) {
    							if(!(i===startX&&j===startY)){
    								if(locationFilter(i,j)){
    									console.log()
    									$('li[x='+i+'][y='+j+']')[0].par = preStep
    									$('li[x='+i+'][y='+j+']')[0].distance = f($('li[x='+i+'][y='+j+']'))
    									openArr.push($('li[x='+i+'][y='+j+']'))
    									if(endLocation.attr('x')==i&&endLocation.attr('y')==j){
    										canClose = false
    									}
    								}
    							}
    						}
    					}
    					
    					
    					// 排序
    					openArr.sort(function(v1, v2){
    						return v1[0].distance - v2[0].distance
    					})
    					
    					
    					// 从数据中去除关闭的 和 已经设置父级指针的
    					function locationFilter(x,y){
    						for (var i=0;i<closeArr.length;i++) {
    							if(+closeArr[i].attr('x') === x && +closeArr[i].attr('y') === y){
    								return false
    							}
    						}
    						
    						
    						for (var i=0;i<openArr.length;i++) {
    							if(+openArr[i].attr('x') === x && +openArr[i].attr('y') === y){
    								return false
    							}
    						}
    						return true
    					}
    					
    				}
    				
    			}
    			
    			
    		 	// 寻路
    		 	function findLocationLoop(){
    	 			while(canClose){
    	 				findNextStepList()
    	 			}
    		 	}
    		 	
    		 	
    		 	function getRecallLocation(){
    		 		var result = []
    		 		function getRecall(dom){
    		 			if($(dom).attr('x')==startLocation.attr('x')&&$(dom).attr('y')==startLocation.attr('y')){
    		 				return result
    		 			}else{
    		 				result.push(dom)
    		 				getRecall(dom[0].par)
    		 			}
    		 		}
    		 		getRecall(closeArr.pop())
    		 		return result
    		 	}
    			
    			//findLocationLoop()
    			/*$("#startFind").click(function(){
    				findLocationLoop()
    				var result = getRecallLocation()
    				result.forEach(function(v,i){
    					v.addClass('move')
    				})
    			})
    			*/
    			
    			
    			$("li").click(function(){
    				if(this.className!=='remora'){
    					$("li").removeClass('end').removeClass('move')
    					$(this).addClass('end')
    					endLocation = $("li[uid="+($(this).index()+1)+"]")
    					openArr = [startLocation]
    					closeArr = [...rocksArr]
    					canClose = true
    					findLocationLoop()
    					console.log(openArr)
    					var result = getRecallLocation().reverse()
    					result.push(endLocation)
    					console.log(result)
    					result.forEach(function(v,i){
    						var timer = setTimeout(function(){
    							$("li").removeClass('start')
    							v.addClass('start')
    							if(i>=result.length-1){
    								startLocation = v
    								$("li.end").removeClass('end')
    							}
    						},120*i)
    					})
    				}
    				
    			})
    			
    		</script>
    	</body>
    </html>
    

      

  • 相关阅读:
    IOS Charles(代理服务器软件,可以用来拦截网络请求)
    Javascript中addEventListener和attachEvent的区别
    MVC中实现Area几种方法
    Entity Framework Code First 中使用 Fluent API 笔记。
    自定义JsonResult解决 序列化类型 System.Data.Entity.DynamicProxies 的对象时检测到循环引用
    序列化类型 System.Data.Entity.DynamicProxies 的对象时检测到循环引用
    An entity object cannot be referenced by multiple instances of IEntityChangeTracker 的解决方案
    Code First :使用Entity. Framework编程(8) ----转发 收藏
    Code First :使用Entity. Framework编程(6) ----转发 收藏
    Code First :使用Entity. Framework编程(5) ----转发 收藏
  • 原文地址:https://www.cnblogs.com/MainActivity/p/10342315.html
Copyright © 2011-2022 走看看