跟动画有关的数学和物理公式

角度与弧度互转

  1. radians=degrees*Math.PI/180
  2. degrees=radians*180/Math.PI

朝鼠标指针(或任意一点)旋转

  1. dx=mouse.x-object.x;
  2. dy=mouse.y-boject.y;
  3. object.rotation=Math.atan2(dy,dx)*180/Math.PI;

创建波

  1. (function(){
  2. window.requestAnimationFrame(drawFrame,canvas);
  3. value=center+Math.sin(angle)+range;
  4. angle+=speed;
  5. }());

创建圆形

  1. (function(){
  2. window.requestAnimationFrame(drawFrame,canvas);
  3. xposition=centerX + Math.cos(angle) * radius;
  4. yposition=center + Math.sin(angle) * radius;
  5. angle += speed;
  6. }());

创建椭圆

  1. (function(){
  2. window.requestAnimationFrame(drawFrame,canvas);
  3. xposition=centerX + Math.cos(angle) * radiusX;
  4. yposition=center + Math.sin(angle) * radiusY;
  5. angle += speed;
  6. }());

获得两点间的距离

  1. dx = x2 - x1;
  2. dy = y2 - y1;
  3. dist = Math.sqrt(dx * dx + dy * dy);

绘制一条穿越某个点的曲线

  1. x1 = xt * 2 - (x0 + x2) / 2;
  2. y1 = yt * 2 - (y0 + y2) / 2;
  3. context.moveTo(x0, y0);
  4. context.quadraticCurveTo(x1, y1, x2, y2);

将角速度分解为x、y轴上的速度向量

  1. vx = speed * Math.cos(angle);
  2. vy = speed * Math.sin(angle);

将角加速度(作用于物体上的力)分解为x、y轴上的加速度

  1. ax = force * Math.cos(angle);
  2. ay = force * Math.sin(agnle);

将加速度加入速度向量

  1. vx += ax;
  2. vy += ay;

将速度向量加入位置坐标

  1. object.x += vx;
  2. object.y += vy;

移除越界物体

  1. if(object.x - object.width /2 > right ||
  2. object.x + object.width /2 < left ||
  3. object.y - object.height /2 > bottom ||
  4. object.y + object.height /2 < top){
  5. }

重置越界物体

  1. if(object.x - object.width /2 > right ||
  2. object.x + object.width /2 < left ||
  3. object.y - object.height /2 > bottom ||
  4. object.y + object.height /2 < top){
  5. }

屏幕环绕越界物体

  1. if(object.x - object.width /2 > right){
  2. object.x = left - object.width / 2;
  3. }else if(object.x + object.width /2 < left){
  4. object.x = right + object.width /2;
  5. }
  6. if(object.y - object.height / 2 > bottom){
  7. object.y = top - object.height / 2;
  8. }else if(object.y + object.height / 2 < top){
  9. object.y = bottom + object.height /2;
  10. }

应用摩擦力(正确方法)

  1. speed = Math.sqrt(vx * vx + vy * vy);
  2. angle = Math.atan2(vy,vx);
  3. if(speed > friction){
  4. speed -= friction;
  5. }else{
  6. speed = 0;
  7. }
  8. vx = Math.cos(angle) * speed;
  9. vy = Math.sin(angle) * speed;

应用摩擦力(简便方法)

  1. vx *= friction;
  2. vy *= friction;

简单缓动

  1. object.x += (targetX - object.x) * easing;
  2. object.y += (targetY - object.y) * easing;

简单弹动

  1. vx += (targetX - object.x) * spring;
  2. vy += (targetY - object.y) * spring;
  3. object.x += (vx *= friction);
  4. object.y += (vy *= friction);

有偏移量的弹动

  1. var dx = object.x - fixedX,
  2. dy = object.y - fixedY,
  3. angle = Math.atan2(dy,dx),
  4. targetX = fixedX + Math.cos(angle) * springLength,
  5. targetY = fixedX + Math.sin(angle) * springLength;

基于距离的碰撞检测

  1. var dx = objectB.x - objectA.x,
  2. dy = objectB.y - objectB.y,
  3. dist = Math.sqrt(dx * dx + dy * dy);
  4. if(dist < objectA.radius + objectB.radius){
  5. }

多物理碰撞检测

  1. objects.forEach(function(objectA, i){
  2. for(var j = i + 1; j < objects.length; j++){
  3. var objectB = objects[j];
  4. //执行碰撞检测,在objectA和objectB之间。
  5. }
  6. });

坐标旋转

  1. x1 = x * Math.cos(rotation) - y * Math.sin(rotation);
  2. y1 = y * Math.cos(rotation) + x * Math.sin(rotation);

反向坐标旋转

  1. x1 = x * Math.cos(rotation) + y * Math.sin(rotation);
  2. y1 = y * Math.cos(rotation) - x * Math.sin(rotation);

动量守恒

  1. var vxTotal = vx0 -vx1;
  2. vx0 = ((ball0.mass -ball1.mass) * vx0 + 2 * ball1.mass * vx1) / (ball0.mass + ball1.mass);
  3. vx1 = vxTotal + vx0;

万有引力

  1. function gravitate(partA, partB){
  2. var dx = partB.x - partA.x;
  3. dy = partB.y - partA.y;
  4. distSQ = dx * dx + dy * dy;
  5. dist = Math.sqrt(distSQ);
  6. force = partA.mass * partB.mass / distSQ;
  7. ax = force * dx /dist;
  8. ay = force * dy / dist;
  9. partA.vx += ax / partA.mass;
  10. partA.vy += ax / partA.mass;
  11. partB.vx -= ax / partB.mass;
  12. partB.vy -= ax / partB.mass;
  13. }

余弦定理

  1. var A = Math.acos((b * b + c * c - a * a) / (2 * b * c));
  2. var B = Math.acos((a * a + c * c - b * b) / (2 * a * c));
  3. var C = Math.acos((a * a + b * b - c * c) / (2 * a * b));

基本透视图

  1. scale = fl / (fl + zpos);
  2. object.scaleX = object.scaleY = scale;
  3. object.alpha = scale;
  4. object.x = vanishingPointX + xpos * scale;
  5. object.y = vanishingPointY + ypos * scale;

Z排序

  1. function zSort(a, b){
  2. return (b.zpos - a.pos);
  3. }
  4. objects.sort(zsort);

坐标旋转

  1. x1 = xpos * cos(angleZ) - ypos * sin(angleZ);
  2. y1 = ypos * cos(angleZ) - xpos * sin(angleZ);
  3. x1 = xpos * cos(angleY) - zpos * sin(angleY);
  4. z1 = zpos * cos(angleY) + xpos * sin(angleY);
  5. y1 = ypos * cos(angleX) - zpos * sin(angleX);
  6. z1 = zpos * cos(angleX) + ypos * sin(angleX);

三维距离

  1. dist = Math.sqrt(dx * dx + dy * dy + dz * dz);

参考资料

原文: https://leohxj.gitbooks.io/front-end-database/content/animation/relative-math.html