update
This commit is contained in:
parent
b2534c7efd
commit
072a92ec54
@ -33,7 +33,7 @@ function drawVector(vector, color = "#FFFFFF") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function vectorProjection(v1, v2) {
|
function vectorProjection(v1, v2) {
|
||||||
const v = v2.copy().normalize();
|
const v2n = v2.copy().normalize();
|
||||||
const sp = v1.dot(v);
|
const sp = v1.dot(v2n);
|
||||||
return v.setMag(sp);
|
return v2n.setMag(sp);
|
||||||
}
|
}
|
||||||
|
29
4.太阳公公.js
Normal file
29
4.太阳公公.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
function setup() {
|
||||||
|
createCanvas(400, 400);
|
||||||
|
stroke("#FFFF00");
|
||||||
|
strokeWeight(8);
|
||||||
|
angleMode(DEGREES);
|
||||||
|
frameRate(60);
|
||||||
|
noCursor();
|
||||||
|
}
|
||||||
|
|
||||||
|
function draw() {
|
||||||
|
background("skyblue");
|
||||||
|
// 移动原点坐标
|
||||||
|
push();
|
||||||
|
translate(mouseX, mouseY);
|
||||||
|
const a = 1 + (frameCount % 30);
|
||||||
|
// 画太阳
|
||||||
|
fill("#FFCC00");
|
||||||
|
circle(0, 0, 100);
|
||||||
|
noFill();
|
||||||
|
arc(-20, 0, 20, 20, -135, -45);
|
||||||
|
arc(20, 0, 20, 20, -135, -45);
|
||||||
|
arc(0, 10, 40, 40, 45, 135);
|
||||||
|
// 画阳光
|
||||||
|
for (let i = 0, n = 36; i < n; i++) {
|
||||||
|
line(0, -60 - a * 10, 0, -80 - a * 10);
|
||||||
|
rotate(360 / n);
|
||||||
|
}
|
||||||
|
pop();
|
||||||
|
}
|
@ -21,7 +21,7 @@
|
|||||||
</style>
|
</style>
|
||||||
<script src="p5/p5.min.js"></script>
|
<script src="p5/p5.min.js"></script>
|
||||||
<script src="p5/addons/p5.sound.min.js"></script>
|
<script src="p5/addons/p5.sound.min.js"></script>
|
||||||
<script src="vehicle.js"></script>
|
<script src="4.太阳公公.js"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
49
particle.js
Normal file
49
particle.js
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
class Particle {
|
||||||
|
constructor(x, y) {
|
||||||
|
this.mass = 1;
|
||||||
|
this.position = createVector(x, y);
|
||||||
|
this.velocity = createVector(0, 0);
|
||||||
|
this.gravity = createVector(0, 10); // G = 9.81
|
||||||
|
this.hue = 0;
|
||||||
|
this.saturation = 0;
|
||||||
|
this.brightness = 100;
|
||||||
|
this.alpha = 1;
|
||||||
|
this.size = 8;
|
||||||
|
this.lifetime = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
move(force) {
|
||||||
|
if (this.position.y > 600) return;
|
||||||
|
// 计算加速度
|
||||||
|
const acceleration = createVector(0, 0);
|
||||||
|
acceleration.add(this.gravity);
|
||||||
|
if (force) acceleration.add(force.div(this.mass));
|
||||||
|
// 计算时间差
|
||||||
|
const duration = deltaTime / 1000;
|
||||||
|
this.lifetime += duration;
|
||||||
|
// 计算速度差及位移
|
||||||
|
const deltaVelocity = acceleration.mult(duration);
|
||||||
|
const averageVelocity = deltaVelocity.copy().div(2).add(this.velocity);
|
||||||
|
const movement = averageVelocity.mult(duration);
|
||||||
|
// 更新速度及位置
|
||||||
|
this.velocity.add(deltaVelocity);
|
||||||
|
this.position.add(movement);
|
||||||
|
const report = {
|
||||||
|
time: this.lifetime.toFixed(3),
|
||||||
|
height: (height - this.position.y).toFixed(3),
|
||||||
|
velocity: this.velocity.mag().toFixed(3),
|
||||||
|
};
|
||||||
|
print(report);
|
||||||
|
}
|
||||||
|
|
||||||
|
show() {
|
||||||
|
noStroke();
|
||||||
|
fill(this.hue, this.saturation, this.brightness, this.alpha);
|
||||||
|
circle(this.position.x, this.position.y, this.size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Particles {
|
||||||
|
constructor() {}
|
||||||
|
show() {}
|
||||||
|
}
|
14
particle_demo.js
Normal file
14
particle_demo.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
let particle;
|
||||||
|
|
||||||
|
function setup() {
|
||||||
|
cursor(CROSS);
|
||||||
|
colorMode(HSB);
|
||||||
|
createCanvas(600, 600);
|
||||||
|
particle = new Particle(width / 2, height / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
function draw() {
|
||||||
|
background(64);
|
||||||
|
particle.move();
|
||||||
|
particle.show();
|
||||||
|
}
|
17
sketch-template.js
Normal file
17
sketch-template.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
function setup() {
|
||||||
|
cursor(CROSS);
|
||||||
|
createCanvas(600, 600);
|
||||||
|
}
|
||||||
|
|
||||||
|
function draw() {
|
||||||
|
background(64);
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawGrid() {
|
||||||
|
push();
|
||||||
|
stroke(0, 64);
|
||||||
|
strokeWeight(1);
|
||||||
|
for (let x = 0; x < width; x += 10) line(x, 0, x, height);
|
||||||
|
for (let y = 0; y < height; y += 10) line(0, y, width, y);
|
||||||
|
pop();
|
||||||
|
}
|
27
sketch.js
27
sketch.js
@ -1,8 +1,29 @@
|
|||||||
function setup() {
|
function setup() {
|
||||||
cursor(CROSS);
|
createCanvas(400, 400);
|
||||||
createCanvas(600, 600);
|
stroke("#FFFF00");
|
||||||
|
strokeWeight(8);
|
||||||
|
angleMode(DEGREES);
|
||||||
|
frameRate(60);
|
||||||
|
noCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
function draw() {
|
function draw() {
|
||||||
background(64);
|
background("skyblue");
|
||||||
|
// 移动原点坐标
|
||||||
|
push();
|
||||||
|
translate(mouseX, mouseY);
|
||||||
|
const a = 1 + (frameCount % 30);
|
||||||
|
// 画太阳
|
||||||
|
fill("#FFCC00");
|
||||||
|
circle(0, 0, 100);
|
||||||
|
noFill();
|
||||||
|
arc(-20, 0, 20, 20, -135, -45);
|
||||||
|
arc(20, 0, 20, 20, -135, -45);
|
||||||
|
arc(0, 10, 40, 40, 45, 135);
|
||||||
|
// 画阳光
|
||||||
|
for (let i = 0, n = 36; i < n; i++) {
|
||||||
|
line(0, -60 - a * 10, 0, -80 - a * 10);
|
||||||
|
rotate(360 / n);
|
||||||
|
}
|
||||||
|
pop();
|
||||||
}
|
}
|
||||||
|
120
vehicle.js
120
vehicle.js
@ -1,60 +1,3 @@
|
|||||||
let vehicle1;
|
|
||||||
let vehicle2;
|
|
||||||
|
|
||||||
function setup() {
|
|
||||||
cursor(CROSS);
|
|
||||||
createCanvas(600, 600);
|
|
||||||
vehicle1 = new Vehicle(300, 300, "#CCCCCC");
|
|
||||||
vehicle2 = new Vehicle(300, 300, "#CC3333");
|
|
||||||
vehicle2.velocity = randomVector(5);
|
|
||||||
}
|
|
||||||
|
|
||||||
function draw() {
|
|
||||||
// 追逐鼠标();
|
|
||||||
// 逃避鼠标();
|
|
||||||
// 小车追逐();
|
|
||||||
小车巡游();
|
|
||||||
}
|
|
||||||
|
|
||||||
function 追逐鼠标() {
|
|
||||||
background(64);
|
|
||||||
vehicle1.seek({ position: createVector(mouseX, mouseY) });
|
|
||||||
vehicle1.move();
|
|
||||||
vehicle1.turn();
|
|
||||||
vehicle1.drawPath();
|
|
||||||
vehicle1.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
function 逃避鼠标() {
|
|
||||||
background(64);
|
|
||||||
vehicle1.flee({ position: createVector(mouseX, mouseY) });
|
|
||||||
vehicle1.move();
|
|
||||||
vehicle1.turn();
|
|
||||||
vehicle1.drawPath();
|
|
||||||
vehicle1.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
function 小车追逐() {
|
|
||||||
background(64);
|
|
||||||
vehicle1.seek(vehicle2, 20);
|
|
||||||
vehicle2.move();
|
|
||||||
vehicle1.move();
|
|
||||||
if (vehicle2.turn()) vehicle2.velocity = randomVector(random(2, 5));
|
|
||||||
vehicle1.turn();
|
|
||||||
vehicle1.drawPath();
|
|
||||||
vehicle2.show("point");
|
|
||||||
vehicle1.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
function 小车巡游() {
|
|
||||||
background(64);
|
|
||||||
vehicle1.wander();
|
|
||||||
vehicle1.move();
|
|
||||||
vehicle1.turn();
|
|
||||||
vehicle1.drawPath();
|
|
||||||
vehicle1.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回可指定大小的随机二维向量
|
* 返回可指定大小的随机二维向量
|
||||||
* @param {number} magnitude 向量大小
|
* @param {number} magnitude 向量大小
|
||||||
@ -73,12 +16,12 @@ class Vehicle {
|
|||||||
this.velocity = createVector(0, 0);
|
this.velocity = createVector(0, 0);
|
||||||
this.heading = this.velocity.heading();
|
this.heading = this.velocity.heading();
|
||||||
this.acceleration = createVector(0, 0);
|
this.acceleration = createVector(0, 0);
|
||||||
this.maxVelocity = 5;
|
this.maxVelocity = 6;
|
||||||
this.maxAcceleration = 0.25;
|
this.maxAcceleration = 0.25;
|
||||||
}
|
}
|
||||||
|
|
||||||
seek(target, slowdownDistance = 100) {
|
seek(target, slowdownDistance = 100) {
|
||||||
const desired = p5.Vector.sub(target.position, this.position);
|
const desired = p5.Vector.sub(target, this.position);
|
||||||
const distance = desired.mag();
|
const distance = desired.mag();
|
||||||
const magnitude =
|
const magnitude =
|
||||||
slowdownDistance > 0 && distance <= slowdownDistance
|
slowdownDistance > 0 && distance <= slowdownDistance
|
||||||
@ -90,7 +33,7 @@ class Vehicle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
flee(target, fleeDistance = 100) {
|
flee(target, fleeDistance = 100) {
|
||||||
const desired = p5.Vector.sub(this.position, target.position);
|
const desired = p5.Vector.sub(this.position, target);
|
||||||
const distance = desired.mag();
|
const distance = desired.mag();
|
||||||
const magnitude =
|
const magnitude =
|
||||||
!fleeDistance || fleeDistance <= 0
|
!fleeDistance || fleeDistance <= 0
|
||||||
@ -127,6 +70,32 @@ class Vehicle {
|
|||||||
this.acceleration.add(steering);
|
this.acceleration.add(steering);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
follow(path, ahead = 50) {
|
||||||
|
// find future point of vehicle
|
||||||
|
const future = p5.Vector.add(
|
||||||
|
this.position,
|
||||||
|
this.velocity.copy().mult(ahead)
|
||||||
|
);
|
||||||
|
|
||||||
|
// noStroke();
|
||||||
|
// fill("#FF0000");
|
||||||
|
// circle(future.x, future.y, 5);
|
||||||
|
|
||||||
|
// find project point on the path
|
||||||
|
const v1 = p5.Vector.sub(future, path.start);
|
||||||
|
const v2 = p5.Vector.sub(path.end, path.start);
|
||||||
|
const project = path.start.copy().add(vectorProjection(v1, v2));
|
||||||
|
|
||||||
|
noStroke();
|
||||||
|
fill("#00FF00");
|
||||||
|
circle(project.x, project.y, 5);
|
||||||
|
|
||||||
|
// find the distance between project point and future point
|
||||||
|
const distance = future.dist(project);
|
||||||
|
// if the distance larger than path width then seek the project point
|
||||||
|
if (distance > path.width) this.seek(project, -1);
|
||||||
|
}
|
||||||
|
|
||||||
move() {
|
move() {
|
||||||
this.acceleration.limit(this.maxAcceleration);
|
this.acceleration.limit(this.maxAcceleration);
|
||||||
this.velocity.add(this.acceleration);
|
this.velocity.add(this.acceleration);
|
||||||
@ -174,12 +143,12 @@ class Vehicle {
|
|||||||
// return false;
|
// return false;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
drawPath(color = 128) {
|
drawPath(length = 1024) {
|
||||||
push();
|
push();
|
||||||
noFill();
|
noFill();
|
||||||
stroke(color);
|
stroke(255, 64);
|
||||||
strokeWeight(1);
|
strokeWeight(1);
|
||||||
if (this.path.length >= 10240) this.path.shift();
|
if (this.path.length >= length) this.path.shift();
|
||||||
beginShape();
|
beginShape();
|
||||||
this.path.forEach((v) => {
|
this.path.forEach((v) => {
|
||||||
if (!v) {
|
if (!v) {
|
||||||
@ -204,3 +173,28 @@ class Vehicle {
|
|||||||
pop();
|
pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Path {
|
||||||
|
constructor(x1, y1, x2, y2, width = 20) {
|
||||||
|
this.start = createVector(x1, y1);
|
||||||
|
this.end = createVector(x2, y2);
|
||||||
|
this.width = width;
|
||||||
|
}
|
||||||
|
|
||||||
|
show() {
|
||||||
|
push();
|
||||||
|
stroke(255, 64);
|
||||||
|
strokeWeight(this.width * 2);
|
||||||
|
line(this.start.x, this.start.y, this.end.x, this.end.y);
|
||||||
|
stroke(255);
|
||||||
|
strokeWeight(1);
|
||||||
|
line(this.start.x, this.start.y, this.end.x, this.end.y);
|
||||||
|
pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function vectorProjection(v1, v2) {
|
||||||
|
const v2n = v2.copy().normalize();
|
||||||
|
const sp = v1.dot(v2n);
|
||||||
|
return v2n.setMag(sp);
|
||||||
|
}
|
||||||
|
93
vehicle_demo.js
Normal file
93
vehicle_demo.js
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
let vehicle1;
|
||||||
|
let vehicle2;
|
||||||
|
let path;
|
||||||
|
|
||||||
|
function setup() {
|
||||||
|
cursor(CROSS);
|
||||||
|
createCanvas(600, 600);
|
||||||
|
vehicle1 = new Vehicle(300, 300, "#CCCCCC");
|
||||||
|
vehicle1.velocity = createVector(6, 0);
|
||||||
|
vehicle2 = new Vehicle(300, 300, "#CC3333");
|
||||||
|
vehicle2.velocity = randomVector(6);
|
||||||
|
path = new Path(0, 300, 600, 300, 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
function draw() {
|
||||||
|
// 追逐鼠标();
|
||||||
|
// 逃避鼠标();
|
||||||
|
// 小车追逐();
|
||||||
|
// 小车巡游();
|
||||||
|
小车巡线();
|
||||||
|
// 道路追逐();
|
||||||
|
}
|
||||||
|
|
||||||
|
function 追逐鼠标() {
|
||||||
|
background(64);
|
||||||
|
vehicle1.seek(createVector(mouseX, mouseY));
|
||||||
|
vehicle1.move();
|
||||||
|
vehicle1.turn();
|
||||||
|
vehicle1.drawPath();
|
||||||
|
vehicle1.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
function 逃避鼠标() {
|
||||||
|
background(64);
|
||||||
|
vehicle1.flee(createVector(mouseX, mouseY));
|
||||||
|
vehicle1.move();
|
||||||
|
vehicle1.turn();
|
||||||
|
vehicle1.drawPath();
|
||||||
|
vehicle1.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
function 小车追逐() {
|
||||||
|
background(64);
|
||||||
|
vehicle1.seek(vehicle2.position, 20);
|
||||||
|
vehicle2.move();
|
||||||
|
vehicle1.move();
|
||||||
|
if (vehicle2.turn()) vehicle2.velocity = randomVector(random(2, 5));
|
||||||
|
vehicle1.turn();
|
||||||
|
vehicle1.drawPath();
|
||||||
|
vehicle2.show("point");
|
||||||
|
vehicle1.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
function 小车巡游() {
|
||||||
|
background(64);
|
||||||
|
vehicle1.wander();
|
||||||
|
vehicle1.move();
|
||||||
|
vehicle1.turn();
|
||||||
|
vehicle1.drawPath();
|
||||||
|
vehicle1.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
function 小车巡线() {
|
||||||
|
background(0);
|
||||||
|
path.end.y = mouseY;
|
||||||
|
vehicle1.follow(path, 20);
|
||||||
|
vehicle1.move();
|
||||||
|
vehicle1.turn();
|
||||||
|
path.show();
|
||||||
|
vehicle1.drawPath();
|
||||||
|
vehicle1.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 未完成
|
||||||
|
*/
|
||||||
|
function 道路追逐() {
|
||||||
|
background(0);
|
||||||
|
// path.end.y = mouseY;
|
||||||
|
vehicle2.follow(path, 50);
|
||||||
|
vehicle1.seek(vehicle2.position, 100);
|
||||||
|
vehicle2.flee(vehicle1.position, 100);
|
||||||
|
|
||||||
|
vehicle2.move();
|
||||||
|
vehicle1.move();
|
||||||
|
vehicle2.turn();
|
||||||
|
vehicle1.turn();
|
||||||
|
path.show();
|
||||||
|
vehicle2.drawPath();
|
||||||
|
vehicle1.drawPath();
|
||||||
|
vehicle2.show();
|
||||||
|
vehicle1.show();
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user