基于HTML5的WebGL呈现A星算法的3D可视化
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
基于HTML5的WebGL呈现A星算法的3D可视化的更多相关文章
- 基于HTML5的WebGL呈现A星算法3D可视化
http://www.hightopo.com/demo/astar/astar.html 最近搞个游戏遇到最短路径的常规游戏问题,一时起兴基于HT for Web写了个A*算法的WebGL 3D呈现 ...
- 基于 HTML5 的 WebGL 楼宇自控 3D 可视化监控
前言 智慧楼宇和人们的生活息息相关,楼宇智能化程度的提高,会极大程度的改善人们的生活品质,在当前工业互联网大背景下受到很大关注.目前智慧楼宇可视化监控的主要优点包括: 智慧化 -- 智慧楼宇是一个生态 ...
- 基于 HTML5 的 WebGL 和 VR 技术的 3D 机房数据中心可视化
前言 在 3D 机房数据中心可视化应用中,随着视频监控联网系统的不断普及和发展, 网络摄像机更多的应用于监控系统中,尤其是高清时代的来临,更加快了网络摄像机的发展和应用. 在监控摄像机数量的不断庞大的 ...
- 基于 HTML5 的 WebGL 自定义 3D 摄像头监控模型
前言 随着视频监控联网系统的不断普及和发展, 网络摄像机更多的应用于监控系统中,尤其是高清时代的来临,更加快了网络摄像机的发展和应用. 在监控摄像机数量的不断庞大的同时,在监控系统中面临着严峻的现状问 ...
- 基于HTML5的WebGL电信网管3D机房监控应用
先上段视频,不是在玩游戏哦,是规规矩矩的电信网管企业应用,嗯,全键盘的漫游3D机房: http://www.hightopo.com/guide/guide/core/3d/examples/exam ...
- 基于 HTML5 的 WebGL 3D 档案馆可视化管理系统
前言 档案管理系统是通过建立统一的标准以规范整个文件管理,包括规范各业务系统的文件管理的完整的档案资源信息共享服务平台,主要实现档案流水化采集功能.为企事业单位的档案现代化管理,提供完整的解决方案,档 ...
- 基于 HTML5 和 WebGL 的地铁站 3D 可视化系统
前言 工业互联网,物联网,可视化等名词在我们现在信息化的大背景下已经是耳熟能详,日常生活的交通,出行,吃穿等可能都可以用信息化的方式来为我们表达,在传统的可视化监控领域,一般都是基于 Web SCAD ...
- 基于HTML5的WebGL结合Box2DJS物理应用
上篇我们基于HT for Web呈现了A* Search Algorithm的3D寻路效果,这篇我们将采用HT for Web 3D来呈现Box2DJS物理引擎的碰撞效果,同上篇其实Box2DJS只是 ...
- 基于HTML5的WebGL结合Box2DJS物理引擎应用
上篇我们基于HT for Web呈现了A* Search Algorithm的3D寻路效果,这篇我们将采用HT for Web 3D来呈现Box2DJS物理引擎的碰撞效果,同上篇其实Box2DJS只是 ...
随机推荐
- Winform启动隐藏,WebBrowser交互JS
一.启动隐藏 Winform比较奇怪,Load的时候设置Visiable=false,无效.webBrowser_DocumentCompleted之后调用hide隐藏了窗体,但是在notifyIco ...
- Java多线程系列--“JUC锁”07之 LockSupport
概述 本章介绍JUC(java.util.concurrent)包中的LockSupport.内容包括:LockSupport介绍LockSupport函数列表LockSupport参考代码(基于JD ...
- 在cocos2dx和unity3d之间选择
人生最纠结的事,莫过于有选择………… cocos2dx和unity3d从某种意义上讲,都很不错.但当面对特定需求以及团队情况的时候,总是能分出高下的. 假设,目标游戏是一款类似 刀塔传奇 的游戏 我们 ...
- 成都亚马逊AWSome Day回顾
6月25日我和公司同仁一起参加了亚马逊在成都的第一场AWSome Day活动.整个活动时间异常紧促,短短一天包含了7堂session,讲师的狂轰乱炸使得我们同学们普遍觉得比上班累多了.好了,废话不多说 ...
- linux环境 c 中如何执行shell命令
1 system 相当简单: int system(const char *command); system("ps -aux"); 2 popen popen有两个参数,第一个是 ...
- Redis学习笔记~关于空间换时间的查询案例
回到目录 空间与时间 空间换时间是在数据库中经常出现的术语,简单说就是把查询需要的条件进行索引的存储,然后查询时为O(1)的时间复杂度来快速获取数据,从而达到了使用空间存储来换快速的时间响应!对于re ...
- [Spring框架]Spring AOP基础入门总结二:Spring基于AspectJ的AOP的开发.
前言: 在上一篇中: [Spring框架]Spring AOP基础入门总结一. 中 我们已经知道了一个Spring AOP程序是如何开发的, 在这里呢我们将基于AspectJ来进行AOP 的总结和学习 ...
- Atitit 图片 验证码生成attilax总结
Atitit 图片 验证码生成attilax总结 1.1. 图片验证码总结1 1.2. 镂空文字 打散 干扰线 文字扭曲 粘连2 1.1. 图片验证码总结 因此,CAPTCHA在图片验证码这一应用点 ...
- .net生成随机字符串
生成随机字符串的工具类: /// <summary> /// 随机字符串工具类 /// </summary> public class RandomTools { /// &l ...
- jquerymobile仿微信 - 01
jquerymobile仿微信 - 01 jquerymobile的组件感觉不咋地哇 本地调试最好是开一个web server,不然数据访问会有问题 <div data-role="p ...