简体   繁体   English

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

[英]3d array movement in p5.js?

I'm in dire need of help with a graduation project that I'm working on. 我正在急需一个我正在研究的毕业设计项目。 What I'm trying to achieve here in the code below is -to put it very simply- to initialize a 3d array of box() objects (this works) and then introduce another box() object (the end goal is to have an array of these as well) to move about within the same 3D grid. 我在下面的代码中试图实现的是 - 非常简单地 - 初始化一个3d数组的box()对象(这个工作),然后引入另一个box()对象(最终目标是有一个这些数组也可以在同一个3D网格中移动。 The moving unit picks a random location for initialization and a random target for destination (both within the 3D grid). 移动单元选择用于初始化的随机位置和用于目的地的随机目标(均在3D网格内)。
But the problem is that I need the moving unit not to overlap with the static base units, also move orthogonally, and always move one unit size each time. 但问题是我需要移动单元不与静态基本单元重叠,也要正交移动,并且每次都要移动一个单位大小。 If I run the code below the moving unit reaches the target but without any of the restrictions that I mentioned above. 如果我运行下面的代码,移动单元到达目标但没有我上面提到的任何限制。 It just takes the shortest vector and goes there regardless. 它只需要最短的向量,无论如何都去那里。

PS: Since p5js doesn't support wireframe in webgl mode I tried to show them with some transparency for better visual legibility. PS:由于p5js在webgl模式下不支持线框,我试图用一些透明度来展示它们以获得更好的视觉清晰度。 Although, the loadImage() functions are still there and could be replaced with any image of your liking to better differentiate units from one another. 尽管如此,loadImage()函数仍然存在,并且可以替换为您喜欢的任何图像,以便更好地区分单元。

I'd sincerely appreciate help with this since I'm also very short on time. 我真诚地感谢你的帮助,因为我的时间也很短。 Thanks in advance. 提前致谢。

Here's the verifiable code: 这是可验证的代码:

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);
}

You've outlined both things you need to do. 您已经概述了需要做的两件事。 Which part of them are you stuck on? 你坚持哪一部分?

Step 1: Make your unit move one cube at a time. 第1步:让您的单位一次移动一个立方体。 You could do this by simply adding or subtracting 1 to its x, y, or z coordinate. 您可以通过简单地向其x,y或z坐标添加或减去1来实现此目的。 Get this working first. 让这个工作第一。 Don't worry about avoiding collisions with the other cubes yet. 不要担心避免与其他立方体碰撞。

Step 2: When you get that working, add code that detects when the cube it's about to move to is occupied, and go in a different direction. 第2步:当你开始工作时,添加代码来检测它将要移动到的立方体何时被占用,并向不同的方向前进。 You might have to implement a basic path finding algorithm, and Google is your friend for that. 您可能必须实现基本的路径查找算法,Google就是您的朋友。

You might also want to consider the possibility that your random generation has blocked all of the paths to the goal. 您可能还想考虑随机生成阻塞目标的所有路径的可能性。 What do you want to do in that case? 那个案子你想做什么? And one more note: you don't need a triple-nested for loop just to generate a random value. 还有一点需要注意:您不需要三嵌套for循环来生成随机值。

If you get stuck on one of these steps, please narrow your problem down to a MCVE showing just that step before you post again. 如果您遇到其中一个步骤,请将问题缩小到MCVE ,然后再显示该步骤。 Good luck. 祝好运。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM