0
点赞
收藏
分享

微信扫一扫

threejs室内导航之自动寻路 - 障碍物标注

程序小小黑 2022-01-08 阅读 62
算法

threejs加载楼层的3ds文件后,需要解决自动寻路的网格中障碍物标记问题,因为所画网格和加载的3ds模型文件没有关联关系,要标记有障碍物的网格必须将两者关联。

        我们以同一坐标原点作为参考点,拿出模型中各物体方块的四个顶点的 (x,y) 坐标,然后计算每个网格点是否与物体相交,相交则有障碍物。画图可以更好地说明,但只为自己记录,有时间再补充,直接上代码。

var gridWidth = 40; //导航格宽度

//3D障碍物方块
var objs = [
    [{x:110,y:130},{x:110,y:150},{x:160,y:150},{x:160,y:130}],
    [{x:85,y:20},{x:85,y:70},{x:110,y:20},{x:110,y:70}]
];

//生成数字全部一样的矩阵,比如说0或者1
//row:行,col:列
function produceSameNumber(row, col, number) {
    var result = [];
    var arr;
    for ( var i = 0; i < row; i++ ) {
        arr = (new Array(col)).join(',').split(',').map( function(){
            return number;
        });
        result.push(arr);
    }
    return result;
}
//生成全0的矩阵,row:行,col:列
function zeros(row, col) {
    return produceSameNumber(row, col, 0);
}

//获取物体边界值
function getBoundary(singleObj){
    var max_X=null;
    var max_Y=null;
    var min_X=null;
    var min_Y=null;
    for(var i=0;i<4;i++){
        var point = singleObj[i];
        max_X = max_X == null || point.x > max_X ? point.x : max_X;
        min_X = min_X == null || point.x < min_X ? point.x : min_X;
        max_Y = max_Y == null || point.y > max_Y ? point.y : max_Y;
        min_Y = min_Y == null || point.y < min_Y ? point.y : min_Y;
    }
    return {
        max_X: max_X,
        max_Y: max_Y,
        min_X: min_X,
        min_Y: min_Y
    }
}

function markBlock(grids){
    for(var i=0;i<grids.length;i++){
        var cols = grids[i];
        for(var j=0;j<cols.length;j++){
            var point= {};
            point.x = gridWidth * j;
            point.y = gridWidth * i;
            point.block = false;    //默认为非障碍物
            checkBlock(point);
            if(point.block){
                grids[i][j] = 1;
            }
        }
    }
    return grids;
}
//标记网格点是否有障碍物
function checkBlock(point){
    for(var i=0;i<objs.length;i++){
        var obj = objs[i];
        var boundary = getBoundary(obj);    //取边界值

        //情况1:物体宽度在格子内
        if(point.x < boundary.min_X && (point.x + gridWidth) > boundary.max_X ){
            if(point.y > boundary.min_Y && point.y < boundary.max_Y){
                point.block = true;
            }
            if(point.y < boundary.min_Y && (point.y + gridWidth) > boundary.min_Y){
                point.block = true;
            }
        }
        //情况2:物体高度在格子内
        if(point.y <  boundary.min_Y && (point.y + gridWidth) > boundary.max_Y){
            if(point.x < boundary.min_X && (point.x + gridWidth) > boundary.min_X){
                point.block = true;
            }
            if(point.x > boundary.min_X && point.x < boundary.max_X){
                point.block = true;
            }
        }
        //情况3:物体宽度占满或超出格子
        if(point.x>=boundary.min_X && (point.x + gridWidth) <= boundary.max_X){
            if((point.y>= boundary.min_Y && point.y< boundary.max_Y) 
            || ((point.y + gridWidth) > boundary.min_Y && (point.y + gridWidth) < boundary.max_Y)){
                point.block = true;
            }
        }
        //情况4:物体高度占满或超出格子
        if(point.y >=boundary.min_X && (point.y + gridWidth) <= boundary.max_Y){
            if((point.x >=boundary.min_X && point.x < boundary.max_X)
            || ((point.x + gridWidth) > boundary.min_X && (point.x + gridWidth) < boundary.max_X)){
                point.block = true;
            }
        }
    }
}

var grids = zeros(7,7,0);
console.log(grids);
console.log(markBlock(grids));

 

举报

相关推荐

0 条评论