简体   繁体   中英

Rotating object in the direction of movement in p5 js

I have been following The Coding Train's coding challenge where he creates a flocking algorithm using cohesion, separation, and alignment. I challenged myself to see if I could rotate each triangle object so they are looking where they are going, however, I have struggled to implement this into my code.

My Boid class is where all the algorithms are located

 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> 

I modified your code so that the boids will point in the direction that they are moving by using push, translate, rotate and pop.

The change is all within Boid.show()

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

Push allows us to just apply the translate and rotation to one boid at a time as pop will undo the changes. I translate to x, y and then position the triangle at 0, 0 so the rotation will only rotate the boid triangle.

I also had to subtract 90 degrees or 1/2 pi from the velocity heading to get the boid to point in the direction of movement.

  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> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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