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

时间:2013-07-01 18:04:16

标签: javascript rotation trigonometry

我不是那么熟悉的三角函数,但我在2D中只有两个点可以旋转:

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

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

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

5 个答案:

答案 0 :(得分:78)

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]
    

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

  3. 最后,请注意此函数假定为Cartesian coordinate system,这意味着当您在坐标平面中“向上”时,Y轴上的值会变得更高。在HTML / CSS中,Y轴被反转 - 当您向向下移动时,Y轴上的值会变得更高。

答案 1 :(得分:5)

  1. 首先,将旋转中心转换为原点
  2. 计算新坐标(nx,ny)
  3. 翻译回原始轮换中心
  4. 第1步

    您的新观点

    1. center:(0,0)
    2. 点:(x-cx,y-cy)
    3. 第2步

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

        翻译回原始旋转中心:

        1. nx =(x-cx)* cos(theta) - (y-cy)* sin(theta)+ cx
        2. ny =(y-cy)* cos(theta)+(x-cx)* sin(theta)+ cy
        3. 有关更深入的解释,我想建议this

答案 2 :(得分:2)

根据Polar coordinate system artycle on Wikipedia

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

答案 3 :(得分:1)

以上接受的答案对我不起作用,轮换是相反的,这里是工作函数

/*
 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:parseInt(x), y:parseInt(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};
 }

答案 4 :(得分:1)

我认为最好将矩阵用于此类操作。

以下是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);