p5.j​​s中的3d数组运动?

时间:2017-03-23 12:13:02

标签: javascript multidimensional-array 3d processing p5.js

我迫切需要帮助我正在研究的毕业设计项目。我在下面的代码中试图实现的是 - 非常简单地 - 初始化一个3d数组的box()对象(这个工作),然后引入另一个box()对象(最终目标是有一个这些数组也可以在同一个3D网格中移动。移动单元选择用于初始化的随机位置和用于目的地的随机目标(均在3D网格内) 但问题是我需要移动单元不与静态基本单元重叠,也要正交移动,并且每次都要移动一个单位大小。如果我运行下面的代码,移动单元到达目标但没有我上面提到的任何限制。它只需要最短的矢量并且无论如何都会去那里。

PS:由于p5js在webgl模式下不支持线框,我试图用一些透明度来展示它们,以获得更好的视觉清晰度。尽管如此,loadImage()函数仍然存在,并且可以替换为您喜欢的任何图像,以便更好地区分单元。

我真诚地感谢你的帮助,因为我的时间也很短。提前谢谢。

这是可验证的代码:

var matrixSize = 5;
var locations = new Array(matrixSize);
var locBool = new Array(matrixSize);

//unit stuff
var unitSize = 40;
var units_a = []
var units_b;

function setup() {
    createCanvas(windowWidth, windowHeight, WEBGL);

    //3D array of location vectors & booleans
    for(var i = 0; i < locations.length; i++){
        locations[i] = new Array(matrixSize);
        locBool[i] = new Array(matrixSize);
        for(var j = 0; j < locations[i].length; j++){
            locations[i][j] = new Array(matrixSize);
            locBool[i][j] = new Array(matrixSize);
            for(var k = 0; k < locations[i][j].length; k++){
                locations[i][j][k] = 
                createVector(i*unitSize, j*unitSize, k*unitSize);
                locBool[i][j][k] = false;
            }
        }
    }

    //base units
    var threshold = 2; //decides on the percentage to be initialized
    for (var i = 0; i < matrixSize; i++) {
        for(var j = 0; j < matrixSize; j++){
            for(var k = 0; k < matrixSize; k++){
                stateRndm = random(10);
                if(stateRndm <= threshold){
                    state = 1;
                    locBool[i][j][k] = true;
                }else{
                    state = 0
                }
                units_a.push(new UnitOne(
                    i*unitSize,j*unitSize,k*unitSize, state));
            }
        }
    }
    units_b = new UnitTwo(); 
}

function draw() {
    background(20);
    ambientLight(235);
    orbitControl();
    rotateX(10);
    rotateY(-10);
    rotateZ(0);

    //center the window and display the units
    push();
    translate(-unitSize*matrixSize/2, -unitSize*matrixSize/2, 0);
    for(var i = 0; i < units_a.length; i++){
        units_a[i].display();
    }
    units_b.display();
    units_b.update();
    units_b.move();
    pop();
}

function UnitOne (x, y, z, state){
    this.x = x;
    this.y = y;
    this.z = z;
    this.state = state;

    //this.img = loadImage("assets/tex_1.jpg");

    //basic movement parameters
    this.acceleration = createVector();
    this.velocity = createVector();
    this.location = createVector(this.x, this.y, this.z);


    this.update = function(){
        this.velocity.add(this.acceleration);
        this.location.add(this.velocity);
        this.acceleration.mult(0);
    }

    this.display = function(){
        if(this.state == 1){
            push();
            scale(1);
            //texture(this.img);
            ambientMaterial(50, 200, 100, 20);
            translate(this.x, this.y, this.z);
            box(unitSize);
            pop();
        }
    }
}

function UnitTwo() {
    //assign random initial location
    this.selector;
    for(var i = 0; i < locations.length; i++){
        for(var j = 0; j < locations[i].length; j++){
            for(var k = 0; k < locations[i][j].length; k++){
                this.selector = createVector(
                    floor(random(i))*unitSize, 
                    floor(random(j))*unitSize, 
                    floor(random(k))*unitSize);
            }
        }
    }
    print(this.selector);

    //assign random target 
    this.targetSelector;
    for(var i = 0; i < locations.length; i++){
        for(var j = 0; j < locations[i].length; j++){
            for(var k = 0; k < locations[i][j].length; k++){
                this.targetSelector = createVector(
                    floor(random(i))*unitSize, 
                    floor(random(j))*unitSize, 
                    floor(random(k))*unitSize);
            }
        }
    }
    print(this.targetSelector);

    //basic movement parameters
    this.location = createVector(
                    this.selector.x,
                    this.selector.y,
                    this.selector.z);
    this.acceleration = createVector();
    this.velocity = createVector();

    this.maxSpeed = 1;
    this.maxForce = 2;

    //this.img = loadImage("assets/tex_2.jpg");

    this.display = function(){
        push();
        //texture(this.img);
        ambientMaterial(200, 100, 40);
        translate(this.location.x, 
                this.location.y, this.location.z);
        scale(1);
        box(unitSize);
        pop();
    }

    this.update = function(){
        this.velocity.add(this.acceleration);
        this.location.add(this.velocity);
        this.acceleration.mult(0);
    }
}

UnitTwo.prototype.move = function(){
    var target = createVector(this.targetSelector.x,
                              this.targetSelector.y,
                              this.targetSelector.z);
    var desired = p5.Vector.sub(target, this.location);

    var d = desired.mag();

    //check the distance to slow down
    if (d < unitSize/2)
        desired.setMag(this.maxSpeed/2);
    else
        desired.setMag(this.maxSpeed);

    var steer = p5.Vector.sub(desired, this.velocity);
    steer.limit(this.maxForce);
    this.acceleration.add(steer);
}

1 个答案:

答案 0 :(得分:0)

您已经列出了您需要做的两件事。你坚持哪一部分?

第1步:让您的单位一次移动一个多维数据集。您可以通过简单地向其x,y或z坐标添加或减去1来实现此目的。让这个工作第一。不要担心避免与其他立方体碰撞。

第2步:当你开始工作时,添加代码来检测它将要移动到的立方体何时被占用,然后向另一个方向移动。您可能必须实现基本的路径查找算法,Google就是您的朋友。

您可能还想考虑您的随机生成阻止了目标的所有路径的可能性。那个案子你想做什么?还有一点需要注意:您不需要三嵌套for循环来生成随机值。

如果您遇到其中一个步骤,请将问题范围缩小到MCVE,然后再显示该步骤。祝你好运。