在p5 js中沿运动方向旋转对象

时间:2018-12-21 17:17:07

标签: javascript p5.js

我一直在跟踪The Coding Train的编码挑战,他用凝聚力,分离力和对齐力创建了植绒算法。我挑战自己,看看是否可以旋转每个三角形对象,以便他们查看要移动的位置,但是,我一直努力将其实现到我的代码中。

所有算法都位于我的Boid类中

const flock = [];
let alignSlider, cohesionSlider, separationSlider;

function setup() {
  createCanvas(900, 600);
  for (i = 0; i < 50; i++) {
    flock.push(new Boid());
  }
  alignSlider = createSlider(0, 5, 1, 0.1);
  cohesionSlider = createSlider(0, 5, 1, 0.1);
  separationSlider = createSlider(0, 5, 2, 0.1);
}

function draw() {
  background(51);
  for (let boid of flock) {
    boid.show();
    boid.edges();
    boid.flock(flock);
    boid.update();
  }
}

class Boid {
  constructor() {
    this.position = createVector(random(width), random(height));
    this.velocity = p5.Vector.random2D();
    this.velocity.setMag(random(4, 6));
    this.acceleration = createVector();
    this.maxForce = 0.2;
    this.maxSpeed = 4;
  }
  edges() {
    if (this.position.x > width) {
      this.position.x = 0;
    }
    if (this.position.x < 0) {
      this.position.x = width;
    }
    if (this.position.y > height) {
      this.position.y = 0;
    }
    if (this.position.y < 0) {
      this.position.y = height;
    }
  }

  align(boids) {
    let perceptionRadius = 100;
    let steering = createVector();
    let total = 0;
    for (let other of boids) {
      let d = dist(
        this.position.x,
        this.position.y,
        other.position.x,
        other.position.y
      );
      if (other != this && d < perceptionRadius) {
        steering.add(other.velocity);
        total++;
      }
    }
    if (total > 0) {
      steering.div(total);
      steering.setMag(this.maxSpeed);
      steering.sub(this.velocity);
      steering.limit(this.maxForce);
    }
    return steering;
  }

  cohesion(boids) {
    let perceptionRadius = 100;
    let steering = createVector();
    let total = 0;
    for (let other of boids) {
      let d = dist(
        this.position.x,
        this.position.y,
        other.position.x,
        other.position.y
      );
      if (other != this && d < perceptionRadius) {
        steering.add(other.position);
        total++;
      }
    }
    if (total > 0) {
      steering.div(total);
      steering.sub(this.position);
      steering.setMag(this.maxSpeed);
      steering.sub(this.velocity);
      steering.limit(this.maxForce);
    }
    return steering;
  }
  separation(boids) {
    let perceptionRadius = 50;
    let steering = createVector();
    let total = 0;
    for (let other of boids) {
      let d = dist(
        this.position.x,
        this.position.y,
        other.position.x,
        other.position.y
      );
      if (other != this && d < perceptionRadius) {
        let diff = p5.Vector.sub(this.position, other.position);
        diff.div(d);
        steering.add(diff);
        total++;
      }
    }
    if (total > 0) {
      steering.div(total);
      steering.setMag(this.maxSpeed);
      steering.sub(this.velocity);
      steering.limit(this.maxForce);
    }
    return steering;
  }
  flock(boids) {
    let alignment = this.align(boids);
    let cohesion = this.cohesion(boids);
    let separation = this.separation(boids);
    alignment.mult(alignSlider.value());
    cohesion.mult(cohesionSlider.value());
    separation.mult(separationSlider.value());
    this.acceleration.add(alignment);
    this.acceleration.add(cohesion);
    this.acceleration.add(separation);
  }
  update() {
    this.position.add(this.velocity);
    this.velocity.add(this.acceleration);
    this.velocity.limit(this.maxSpeed);
    this.acceleration.mult(0);
  }
  show() {
    //this is where i create my triangle and this is where i would like to be able to rotate it
    let triangleSize = 12;

    let x = this.position.x;
    let y = this.position.y;

    fill(51);
    stroke(255);
    // ellipseMode(CENTER);
    // rotate(this.velocity.heading());

    triangle(
      x,
      y,
      x + triangleSize,
      y,
      x + triangleSize / 2,
      y + triangleSize * 1.2
    );
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.3/p5.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.3/addons/p5.dom.min.js"></script>

1 个答案:

答案 0 :(得分:0)

我修改了您的代码,以便使用推,平移,旋转和弹出方式使波德指向它们的移动方向。

更改全部在Boid.show()

push();
translate(x, y);
rotate(this.velocity.heading() - radians(90));
triangle(0,0,triangleSize,0,triangleSize / 2,triangleSize * 1.2);
pop()

Push允许我们一次仅对一个boid应用平移和旋转,因为pop会撤消更改。我将其转换为x,y,然后将三角形定位为0、0,这样旋转只会旋转boid三角形。

我还必须从速度航向中减去90度或1/2 pi,才能使指向的物体指向运动方向。

    const flock = [];
    let alignSlider, cohesionSlider, separationSlider;
	var theta = 0.1;
    function setup() {
      createCanvas(900, 600);
      for (i = 0; i < 50; i++) {
        flock.push(new Boid());
      }
      alignSlider = createSlider(0, 5, 1, 0.1);
      cohesionSlider = createSlider(0, 5, 1, 0.1);
      separationSlider = createSlider(0, 5, 2, 0.1);
    }

    function draw() {
	theta += .01;
      background(51);
      for (let boid of flock) {
        boid.show();
        boid.edges();
        boid.flock(flock);
        boid.update();
      }
    }    
	
    class Boid {
      constructor() {
        this.position = createVector(random(width), random(height));
        this.velocity = p5.Vector.random2D();
        this.velocity.setMag(random(4, 6));
        this.acceleration = createVector();
        this.maxForce = 0.2;
        this.maxSpeed = 4;
      }
      edges() {
        if (this.position.x > width) {
          this.position.x = 0;
        }
        if (this.position.x < 0) {
          this.position.x = width;
        }
        if (this.position.y > height) {
          this.position.y = 0;
        }
        if (this.position.y < 0) {
          this.position.y = height;
        }
      }

      align(boids) {
        let perceptionRadius = 100;
        let steering = createVector();
        let total = 0;
        for (let other of boids) {
          let d = dist(
            this.position.x,
            this.position.y,
            other.position.x,
            other.position.y
          );
          if (other != this && d < perceptionRadius) {
            steering.add(other.velocity);
            total++;
          }
        }
        if (total > 0) {
          steering.div(total);
          steering.setMag(this.maxSpeed);
          steering.sub(this.velocity);
          steering.limit(this.maxForce);
        }
        return steering;
      }

      cohesion(boids) {
        let perceptionRadius = 100;
        let steering = createVector();
        let total = 0;
        for (let other of boids) {
          let d = dist(
            this.position.x,
            this.position.y,
            other.position.x,
            other.position.y
          );
          if (other != this && d < perceptionRadius) {
            steering.add(other.position);
            total++;
          }
        }
        if (total > 0) {
          steering.div(total);
          steering.sub(this.position);
          steering.setMag(this.maxSpeed);
          steering.sub(this.velocity);
          steering.limit(this.maxForce);
        }
        return steering;
      }
      separation(boids) {
        let perceptionRadius = 50;
        let steering = createVector();
        let total = 0;
        for (let other of boids) {
          let d = dist(
            this.position.x,
            this.position.y,
            other.position.x,
            other.position.y
          );
          if (other != this && d < perceptionRadius) {
            let diff = p5.Vector.sub(this.position, other.position);
            diff.div(d);
            steering.add(diff);
            total++;
          }
        }
        if (total > 0) {
          steering.div(total);
          steering.setMag(this.maxSpeed);
          steering.sub(this.velocity);
          steering.limit(this.maxForce);
        }
        return steering;
      }
      flock(boids) {
        let alignment = this.align(boids);
        let cohesion = this.cohesion(boids);
        let separation = this.separation(boids);
        alignment.mult(alignSlider.value());
        cohesion.mult(cohesionSlider.value());
        separation.mult(separationSlider.value());
        this.acceleration.add(alignment);
        this.acceleration.add(cohesion);
        this.acceleration.add(separation);
      }
      update() {
        this.position.add(this.velocity);
        this.velocity.add(this.acceleration);
        this.velocity.limit(this.maxSpeed);
        this.acceleration.mult(0);
      }
      show() {
        //this is where i create my triangle and this is where i would like to be able to rotate it
        let triangleSize = 12;

        let x = this.position.x;
        let y = this.position.y;
        fill(51);
        stroke(255);
        push();
        translate(x, y);
        rotate(this.velocity.heading() - radians(90));
        triangle(
          0,
          0,
          triangleSize,
          0,
          triangleSize / 2,
          triangleSize * 1.2
        );
        pop();
      }
    }
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.3/p5.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.3/addons/p5.dom.min.js"></script>