Hi,
I know how to calculate an angle between two vectors and did this. But in this example (derived from the NOC steering behavior tutorial) I did calculate the angle from the vehicle to the center of the canvas(grey circle).
But the vehicle also rotates according to the vel.heading. Now I want to calculate the angle
of the (vehicle heading) relative to the (vehicle to the center) vector.
I hope the graphic makes it more clear. Maybe someone has a tip for me on how to achieve this?
sketch.js
let vehicle;
function setup() {
createCanvas(800, 800);
vehicle = new Vehicle(100, 100, new Config());
}
function draw() {
background(20, 200, 100);
noStroke(0);
text("max speed", +150, 25);
text("max force", +150, 50);
text("slowRadius", +150, 75);
let listener = createVector(width / 2, height / 2);
let target = createVector(min(mouseX, this.width), min(mouseY, this.height));
fill(255, 0, 0);
noStroke();
ellipse(target.x, target.y, 32);
noStroke();
fill(50, 0, 50, 20);
ellipse(target.x, target.y, 100);
//How do I get the slow radius from the config class here?
let steering = vehicle.arrive(target);
vehicle.applyForce(steering);
vehicle.distancevalue(listener);
vehicle.listenradius(listener);
vehicle.update();
vehicle.show();
//target.show();
}
//SLIDERS
class Config {
constructor() {
this.maxSpeed = createSlider(0, 10, 10);
this.maxSpeed.position(1, 10);
this.maxForce = createSlider(1, 20, 5);
this.maxForce.position(1, 35);
this.slowRadius = createSlider(1, 500, 100);
this.slowRadius.position(1, 60);
}
getMaxSpeed() {
return this.maxSpeed.value();
}
getMaxForce() {
return this.maxForce.value();
}
getMaxslowRadius() {
return this.slowRadius.value();
}
}
vehicle.js
class Vehicle {
constructor(x, y, config) {
this.pos = createVector(x, y);
this.vel = createVector(0, 0);
this.acc = createVector(0, 0);
this.config = config;
this.r = 16;
}
arrive(target) {
// 2nd argument true enables the arrival behavior
return this.seek(target, true);
}
flee(target) {
return this.seek(target).mult(-1);
}
seek(target, arrival = false) {
let force = p5.Vector.sub(target, this.pos);
let desiredSpeed = this.config.getMaxSpeed();
if (arrival) {
let slowRadius = this.config.getMaxslowRadius();
let distance = force.mag();
if (distance < slowRadius) {
desiredSpeed = map(distance,0,slowRadius,0,this.config.getMaxSpeed());
}
}
force.setMag(desiredSpeed);
force.sub(this.vel);
force.limit(this.config.getMaxForce() * 0.1);
return force;
}
applyForce(force) {
this.acc.add(force);
}
update() {
this.vel.add(this.acc);
this.vel.limit(this.config.getMaxSpeed());
this.pos.add(this.vel);
this.acc.set(0, 0);
}
show() {
noStroke();
//strokeWeight(2);
fill(0, 0, 255);
push();
translate(this.pos.x, this.pos.y);
rotate(this.vel.heading());
circle(0, 0, this.r * 2);
//vehicle heading line
this.angle = this.vel.heading();
stroke(255);
strokeWeight(4);
line(0, 0, (this.r * 2) / 2, 0);
pop();
}
listenradius(listener) {
push();
//draw listener
translate(listener.x, listener.y);
fill(200, 0, 200, 100);
circle(0, 0, this.r * 4);
let postolistener = p5.Vector.sub(this.pos, listener);
let listenerup = createVector(0, -this.r * 2);
fill(10);
strokeWeight(1);
stroke(1);
line(0, 0, listenerup.x, listenerup.y);
line(0, 0, postolistener.x, postolistener.y);
//calculate angle between vehicle and listener
let angleBetween = postolistener.angleBetween(listenerup);
pop();
text("ANGLE TO LISTENER " + angleBetween.toFixed(2) + " radians",20,180,300,55);
}
distancevalue(listener) {
let distvalue = p5.Vector.sub(listener, this.pos);
strokeWeight(0);
fill(255, 255, 0);
textSize(16);
textStyle(NORMAL);
text("DISTANCE TO LISTENER " + floor(distvalue.mag()), 20, 120, 300, 55);
text("DISTANCE X TO LISTENER " + floor(distvalue.x), 20, 140, 300, 55);
text("DISTANCE Y TO LISTENER " + floor(distvalue.y), 20, 160, 300, 55);
}
edges() {
if (this.pos.x > width + this.r) {
this.pos.x = -this.r;
} else if (this.pos.x < -this.r) {
this.pos.x = width + this.r;
}
if (this.pos.y > height + this.r) {
this.pos.y = -this.r;
} else if (this.pos.y < -this.r) {
this.pos.y = height + this.r;
}
}
}
class Target {
constructor(x, y) {
this.vel = p5.Vector.random2D();
this.vel.mult(5);
}
show() {
push();
stroke(255);
strokeWeight(2);
fill(255, 0, 255);
translate(this.pos.x, this.pos.y);
rotate(this.vel.heading());
circle(0, 0, 100);
this.angle = this.vel.heading();
stroke(0, 220, 220);
strokeWeight(4);
line(0, 0, this.r / 2, 0);
fill(255);
pop();
}
}