1.先看预览
circleShake.gifcircleSport.gif
2.随机运动分析
随机运动比较很好计算,从-speed 到speed之间随机获取一个当前速度,来控制粒子的x,y坐标就可以了。
代码demo
let speedX = window.random(-this.speed, this.speed);
let speedY = window.random(-this.speed, this.speed);
this.x += speedX;
this.y += speedY;
3.反弹运动分析
我门先来看看向量问题:
image.png
有向量OB与向量OA,求向量OB关于向量OA的对称向量OB1
image.png
为了限制粒子在圆内,需要将超出圆范围的粒子重新计算x,y坐标,并与圆心链接组成对称向量,计算对称向量与向量(1,0)之间的角度
image.png
let f = Math.acos((particle.x - this.cx) / Math.sqrt(Math.pow(particle.x - this.cx, 2)+ Math.pow(particle.y - this.cy, 2)));
粒子初始化时,会随机给出粒子的方向弧度,范围是[0,2PI),粒子就会沿着初始化的方向一致运动,一直到碰到圆,那么对于粒子来说,向量就是
const vectorI = {x: Math.cos(particle.vector), y: Math.sin(particle.vector)};
对称向量就是半径的那条直线
const vectorN = {x: particle.x - this.cx, y: -particle.y + this.cy};
按照公式计算两个向量之间的点乘
const iDotN = vectorI.x * vectorN.x + vectorI.y * vectorN.y;
那么前面的系数就是
const q = 2 * iDotN / (Math.pow(vectorN.x, 2) + Math.pow(vectorN.y, 2));
接下里就是计算OB1了,前面加了一个负号,那就是我们计算的反弹向量
const vectorM = {x: -(q * vectorN.x - vectorI.x), y: -(q * vectorN.y - vectorI.y)};
image.png
计算反弹向量与水平线弧度
let theta = Math.acos(vectorM.x / Math.sqrt(Math.pow(vectorM.x, 2) + Math.pow(vectorM.y, 2)));
if (vectorM.y < 0) {
theta = 2 * Math.PI - theta;
}
theta就是粒子运动的新方向
Demo
3.扩展
我们将圆变成矩形
rectShake.gif
rectSport.gif
代码:github
网友评论