基于WebGL 的3D呈现A* Search Algorithm

http://www.hightopo.com/demo/astar/astar.html
最近搞个游戏遇到最短路径的常规游戏问题,一时起兴基于HT for Web写了个A*算法的WebGL 3D呈现,算法基于开源 https://github.com/bgrins/javascript-astar 的javascript实现,其实作者也有个不错的2D例子实现 http://www.briangrinstead.com/files/astar/ ,只不过觉得所有A*算法的可视化实现都是平面的不够酷,另外还有不少参数需要调节控制,还是值得好好搞个全面的Demo,先上张2D和3D例子的对照图。

实现代码比较容易一百多行,不过算法核心在astar.js了,界面核心在ht.js里面了,我只需要构建网格信息,只需监听用户点击,然后调用astar.js进行最短路径计算,将结果通过动画的方式呈现出走动的过程,所有代码如下:
function init() {
w = 40; m = 20; d = w * m / 2;
gridRows = [];
dm = new ht.DataModel();
g3d = new ht.graph3d.Graph3dView(dm);
g3d.setGridVisible(true);
g3d.setGridColor('#BBBBBB');
g3d.setGridSize(m);
g3d.setGridGap(w);
g3d.addToDOM();
g3d.sm().setSelectionMode('none');
anim = startBall = endBall = null;
g3d.getView().addEventListener(ht.Default.isTouchable ? 'touchstart' : 'mousedown', function(e){
if(!anim){
var p = g3d.getHitPosition(e);
var x = Math.floor((p[0] + d)/ w);
var y = Math.floor((p[2] + d)/ w);
var endBall = dm.getDataByTag("cell_" + x + "_" + y);
if(endBall && endBall.s('batch') !== 'wall'){
if(startBall.a('x') === x && startBall.a('y') === y){
return;
}
var g = new Graph(gridRows, {
diagonal: formPane.v('diagonal')
});
var start = g.grid[startBall.a('x')][startBall.a('y')];
var end = g.grid[x][y];
var result = astar.search(g, start, end, {
closest: formPane.v('closest')
});
if(!result.length){
return;
}
x = result[result.length-1].x;
y = result[result.length-1].y;
endBall = dm.getDataByTag("cell_" + x + "_" + y);
endBall.s('3d.visible', true);
startBall.s('3d.visible', false);
formPane.setDisabled(true);
anim = ht.Default.startAnim({
duration: 700,
finishFunc: function(){
for(var i=0; i<result.length; i++){
var ball = dm.getDataByTag("cell_" + result[i].x + "_" + result[i].y);
ball.s({
'3d.visible': false,
'shape3d.opacity': 1,
'shape3d.transparent': false
});
startBall.p3(-d+w*x+w/2, w/2, -d+w*y+w/2);
startBall.a({x: x, y: y});
startBall.s('3d.visible', true);
}
anim = null;
formPane.setDisabled(false);
},
action: function(v){
var index = Math.round(v*result.length);
for(var i=0; i<index; i++){
var ball = dm.getDataByTag("cell_" + result[i].x + "_" + result[i].y);
ball.s({
'3d.visible': true,
'shape3d.opacity': i/index*0.3 + 0.7,
'shape3d.transparent': true
});
}
}
});
}
}
}, false);
createFormPane();
createGrid();
}
function createGrid(){
dm.clear();
var ball;
gridRows.length = 0;
for(var x = 0; x < m; x++) {
var nodeRow = [];
gridRows.push(nodeRow);
for(var y = 0; y < m; y++) {
var isWall = Math.floor(Math.random()*(1/formPane.v('frequency')));
if(isWall === 0){
nodeRow.push(0);
createNode(x, y).s({
'batch': 'wall',
'all.color': '#9CA69D'
});
}else{
nodeRow.push(1);
ball = createNode(x, y).s({
'shape3d': 'sphere',
'shape3d.color': '#FF703F',
'3d.visible': false
});
}
}
}
if(!ball){
createGrid();
return;
}
startBall = createNode(ball.a('x'), ball.a('y'), 'start').s({
'shape3d': 'sphere',
'shape3d.color': '#FF703F'
});
shape = new ht.Shape();
shape.setPoints(new ht.List([
{x: -d, y: d},
{x: d, y: d},
{x: d, y: -d},
{x: -d, y: -d},
{x: -d, y: d}
]));
shape.setThickness(4);
shape.setTall(w);
shape.setElevation(w/2);
shape.setClosePath(true);
shape.s({
'all.color': 'rgba(187, 187, 187, 0.8)',
'all.transparent': true,
'all.reverse.cull': true
});
dm.add(shape);
}
function createNode(x, y, tag){
var node = new ht.Node();
tag = tag || "cell_" + x + "_" + y;
node.setTag(tag);
node.a({ x: x, y: y });
node.s3(w*0.9, w*0.9, w*0.9);
node.p3(-d+w*x+w/2, w/2, -d+w*y+w/2);
node.s({
'all.reverse.cull': true,
'shape3d.reverse.cull': true
});
dm.add(node);
return node;
}
function createFormPane() {
formPane = new ht.widget.FormPane();
formPane.setWidth(230);
formPane.setHeight(70);
formPane.getView().className = 'formpane';
document.body.appendChild(formPane.getView());
formPane.addRow(['Wall Frequency', {
id: 'frequency',
slider: {
min: 0,
max: 0.8,
value: 0.1,
onValueChanged: function(){
createGrid();
}
}
}], [100, 0.1]);
formPane.addRow([
{
id: 'closest',
checkBox: {
label: 'Try Closest'
}
},
{
id: 'diagonal',
checkBox: {
label: 'Allow Diagonal'
}
}
], [0.1, 0.1]);
}
自从iOS8支持WebGL后在移动终端上测试3D应用比当前的大部分Android平板舒服多了,以上的例子在iOS系统下呈现和算法都挺流畅,http://v.youku.com/v_show/id_XODMzOTU1Njcy.html,当然这个小例子数据量也不大,本质其实还是2D的最短路径算法,并非真正意义的3D空间最短路径,但还是足够解决很多实际应用问题了。http://www.hightopo.com/demo/astar/astar.html

基于WebGL 的3D呈现A* Search Algorithm的更多相关文章
- 基于HT for Web的3D呈现A* Search Algorithm
最近搞个游戏遇到最短路径的常规游戏问题,正巧看到老同事写的3D机房最短路径巡线文章,一时起兴基于HT for Web写了个A*算法的WebGL 3D呈现,算法基于开源 https://github.c ...
- 基于 WebGL 的 3D 动态柱状图表
发现现在工业SCADA上或者电信网管方面用图表的特别多,虽然绝大部分人在图表制作方面用的是echarts,他确实好用,但是有些时候我们不能调用别的插件,这个时候就得自己写这些美丽的图表了,然而图表轻易 ...
- 基于 HTML5 WebGL 的 3D 网络拓扑图
在数据量很大的2D 场景下,要找到具体的模型比较困难,并且只能显示出模型的的某一部分,显示也不够直观,这种时候能快速搭建出 3D 场景就有很大需求了.但是搭建 3D 应用场景又依赖于通过 3ds Ma ...
- 用基于WebGL的BabylonJS来共享你的3D扫描模型
转自:http://www.geekfan.net/6578/ 用基于WebGL的BabylonJS来共享你的3D扫描模型 杰克祥子 2014 年 2 月 26 日 0 条评论 标签:3D扫描 , B ...
- 基于HT for Web 3D呈现Box2DJS物理引擎
上篇我们基于HT for Web呈现了A* Search Algorithm的3D寻路效果,这篇我们将采用HT for Web 3D来呈现Box2DJS物理引擎的碰撞效果,同上篇其实Box2DJS只是 ...
- 基于 WebGL 3D 的 HTML5 档案馆可视化管理系统
前言 档案管理系统是通过建立统一的标准以规范整个文件管理,包括规范各业务系统的文件管理的完整的档案资源信息共享服务平台,主要实现档案流水化采集功能.为企事业单位的档案现代化管理,提供完整的解决方案,档 ...
- 基于 HTML5 的 WebGL 自定义 3D 摄像头监控模型
前言 随着视频监控联网系统的不断普及和发展, 网络摄像机更多的应用于监控系统中,尤其是高清时代的来临,更加快了网络摄像机的发展和应用. 在监控摄像机数量的不断庞大的同时,在监控系统中面临着严峻的现状问 ...
- B/S 端构建的基于 WebGL 3D 可视化档案馆管理系统
前言 档案管理系统是通过建立统一的标准以规范整个文件管理,包括规范各业务系统的文件管理的完整的档案资源信息共享服务平台,主要实现档案流水化采集功能.为企事业单位的档案现代化管理,提供完整的解决方案,档 ...
- 基于 HTML5 WebGL 的 3D 风机 Web 组态工业互联网应用
基于 HTML5 WebGL 的 3D 风机 Web 组态工业互联网应用 前言 在目前大数据时代背景之下,数据可视化的需求也变得越来越庞大,在数据可视化的背景之下,通过智能机器间的链接并最终将人机链接 ...
随机推荐
- pt-table-checksum
pt-table-checksum是percona公司提供的一个用于在线比对主从数据一致性的工具. 实现原理 将一张大表分成多个chunk,每次针对一个chunk进行校验,同时将校验的结果通过REPL ...
- 利用SQLServer数据库发送邮件
汇总篇:http://www.cnblogs.com/dunitian/p/4822808.html#tsql 这个应用案例很多,一般都是预警,比如异常连接的时候,或者数据库报错的时候.等等,,, 先 ...
- 深入理解BFC
定义 在解释BFC之前,先说一下文档流.我们常说的文档流其实分为定位流.浮动流和普通流三种.而普通流其实就是指BFC中的FC.FC是formatting context的首字母缩写,直译过来是格式化上 ...
- 理解 .NET Platform Standard
相关博文:ASP.NET 5 Target framework dnx451 and dnxcore50 .NET Platform Standard:https://github.com/dotne ...
- spring源码分析之context
重点类: 1.ApplicationContext是核心接口,它为一个应用提供了环境配置.当应用在运行时ApplicationContext是只读的,但你可以在该接口的实现中来支持reload功能. ...
- Drawable实战解析:Android XML shape 标签使用详解(apk瘦身,减少内存好帮手)
Android XML shape 标签使用详解 一个android开发者肯定懂得使用 xml 定义一个 Drawable,比如定义一个 rect 或者 circle 作为一个 View 的背景. ...
- css选择器
常用css选择器,希望对大家有所帮助,不喜勿喷. 1.*:通用选择器 * { margin: 0; padding: 0; } 选择页面上的全部元素,通常用于清除浏览器默认样式,不推荐使用. 2.#i ...
- 网站里加入QQ在线客服
1.开启"QQ在线状态"服务 http://jingyan.baidu.com/article/b24f6c823425a586bfe5da1f.html http://www. ...
- SAP CRM 性能小技巧
导言 本页面打算收集SAP CRM实施中可以用于避免性能问题的注意事项,重要的事项会由图标标识. 如果你有其他的技巧想要说出来,别犹豫! 性能注意事项 通用 缓存读取类访问,特别是在性能关键的地方,比 ...
- 【SAP业务模式】之ICS(二):基础数据
讲完业务,计划在前台做一下ICS的基本操作,不过在操作之前,得先建立好基本的基础数据. 1.首先创建接单公司LEON,对应工厂是ADA: 2.创建生产公司MXPL,对应工厂是PL01: 3.创建接单公 ...