繁体   English   中英

如何在 Javascript 中计算 2D 中的旋转

[英]How to calculate rotation in 2D in Javascript

我不太熟悉三角学,但我只有两个点可以在 2D 中旋转:

                    *nx, ny
               .     -
          .           -
     .  angle          -
*cx,cy.................*x,y

cx, cy = 旋转中心
x,y = 当前 x,y
nx, ny = 新坐标

如何计算某个角度的新点?

function rotate(cx, cy, x, y, angle) {
    var radians = (Math.PI / 180) * angle,
        cos = Math.cos(radians),
        sin = Math.sin(radians),
        nx = (cos * (x - cx)) + (sin * (y - cy)) + cx,
        ny = (cos * (y - cy)) - (sin * (x - cx)) + cy;
    return [nx, ny];
}

前两个参数是中心点(第二个点将围绕其旋转的原点)的 X 和 Y 坐标。 接下来的两个参数是我们将要旋转的点的坐标。 最后一个参数是角度,以度为单位。

例如,我们将取点 (2, 1) 并将其绕点 (1, 1) 顺时针旋转 90 度。

rotate(1, 1, 2, 1, 90);
// > [1, 0]

关于这个函数的三个注意事项:

  1. 对于顺时针旋转,最后一个参数angle应为正。 对于逆时针旋转(如您提供的图表),它应该是负的。

  2. 请注意,即使您提供的参数应该产生坐标为整数的点 - 即将点 (5, 0) 围绕原点 (0, 0) 旋转 90 度,这应该产生 (0, -5) - - JavaScript 的舍入行为意味着任一坐标仍然可能是一个非常接近预期整数的值,但仍然是一个浮点数。 例如:

     rotate(0, 0, 5, 0, 90); // > [3.061616997868383e-16, -5]

    因此,结果数组的两个元素都应该是浮点数。 您可以根据需要使用Math.round()Math.ceil()Math.floor()将它们转换为整数。

  3. 最后,请注意,此函数采用笛卡尔坐标系,这意味着 Y 轴上的值随着您在坐标平面中“向上”而变高。 在 HTML/CSS 中,Y 轴是倒置的——当您向下移动页面时,Y 轴上的值会变高。

  1. 首先,将旋转中心平移到原点
  2. 计算新坐标 (nx, ny)
  3. 平移回原来的旋转中心

第 1 步

你的新积分是

  1. 中心:(0,0)
  2. 点:(x-cx,y-cy)

第2步

  1. nx = (x-cx)*cos(theta) - (y-cy)*sin(theta)
  2. ny = (y-cy)*cos(theta) + (x-cx)*sin(theta)

第 3 步

转换回原始旋转中心:

  1. nx = (x-cx)*cos(theta) - (y-cy)*sin(theta) + cx
  2. ny = (y-cy)*cos(theta) + (x-cx)*sin(theta) + cy

为了更深入的解释,有一些花哨的图表,我建议看这个

以上接受的答案对我来说不正确,旋转是反向的,这是工作功能

/*
 CX @ Origin X  
 CY @ Origin Y
 X  @ Point X to be rotated
 Y  @ Point Y to be rotated  
 anticlock_wise @ to rotate point in clockwise direction or anticlockwise , default clockwise 
 return @ {x,y}  
*/
function rotate(cx, cy, x, y, angle,anticlock_wise = false) {
    if(angle == 0){
        return {x:parseFloat(x), y:parseFloat(y)};
    }if(anticlock_wise){
        var radians = (Math.PI / 180) * angle;
    }else{
        var radians = (Math.PI / -180) * angle;
    }
    var cos = Math.cos(radians);
    var sin = Math.sin(radians);
    var nx = (cos * (x - cx)) + (sin * (y - cy)) + cx;
    var ny = (cos * (y - cy)) - (sin * (x - cx)) + cy;
    return {x:nx, y:ny};
 }

根据Wikipedia 上的极坐标系 artycle

x = r * cos(deg)
y = r * sin(deg)
  • r半径)等于Rotation CentreRotated Point之间的距离
  • deg)是以为单位的角度

我认为最好使用矩阵进行此类操作。

这是 gl-matrix 的示例(但您也可以使用 THREEJS 之类的东西)。

import * as glm from 'gl-matrix';
const rotateVector = (() => {
  
  const q = glm.quat.create();  
  // const m = glm.mat4.create(); // 2nd way

  return (v: glm.vec3, point: glm.vec3, axis: glm.vec3, angle: number) => {

      glm.quat.setAxisAngle(q, axis, angle);
      // glm.mat4.fromRotation(m, angle, axis); // 2nd way
      glm.vec3.sub(v, v, point);
      glm.vec3.transformQuat(v, v, q);
      // glm.vec3.transformMat4(v, v, m); // 2nd way
      glm.vec3.add(v, v, point);
      return v;
  }
})();

在 2D 情况下,您需要绕 z 轴旋转:

rotateVector([x, y, 0], [cX, cY, 0], [0, 0, 1], angleInRadians);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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