如何在 Javascript 中计算 2D 中的旋转
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17410809/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to calculate rotation in 2D in Javascript
提问by Digerkam
I am not so familiar trigonometry, but I have only two points to rotate in 2D:
我不太熟悉三角学,但我只有两个点可以在 2D 中旋转:
*nx, ny
. -
. -
. angle -
*cx,cy.................*x,y
cx, cy = rotation center
x,y = current x,y
nx, ny = new coordinates
cx, cy = 旋转中心
x,y = 当前 x,y
nx, ny = 新坐标
How to calculate new points in a certain angle?
如何计算某个角度的新点?
回答by theftprevention
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];
}
The first two parameters are the X and Y coordinates of the central point (the origin around which the second point will be rotated). The next two parameters are the coordinates of the point that we'll be rotating. The last parameter is the angle, in degrees.
前两个参数是中心点(第二个点将围绕其旋转的原点)的 X 和 Y 坐标。接下来的两个参数是我们将要旋转的点的坐标。最后一个参数是角度,以度为单位。
As an example, we'll take the point (2, 1) and rotate it around the point (1, 1) by 90 degrees clockwise.
例如,我们将取点 (2, 1) 并将其绕点 (1, 1) 顺时针旋转 90 度。
rotate(1, 1, 2, 1, 90);
// > [1, 0]
Three notes about this function:
关于这个函数的三个注意事项:
For clockwise rotation, the last parameter
angle
should be positive. For counterclockwise rotation (like in the diagram you provided), it should be negative.Note that even if you provide arguments that should yield a point whose coordinates are whole numbers -- i.e. rotating the point (5, 0) by 90 degrees about the origin (0, 0), which should yield (0, -5) -- JavaScript's rounding behavior means that either coordinate could still be a value that's frustratingly close to the expected whole number, but is still a float. For example:
rotate(0, 0, 5, 0, 90); // > [3.061616997868383e-16, -5]
For this reason, both elements of the resulting array should be expected as a float. You can convert them to integers using
Math.round()
,Math.ceil()
, orMath.floor()
as needed.Finally, note that this function assumes a Cartesian coordinate system, meaning that values on the Y axis become higher as you go "up" in the coordinate plane. In HTML / CSS, the Y axis is inverted -- values on the Y axis become higher as you move down the page.
对于顺时针旋转,最后一个参数
angle
应为正。对于逆时针旋转(如您提供的图表),它应该是负的。请注意,即使您提供的参数应该产生坐标为整数的点 - 即将点 (5, 0) 绕原点 (0, 0) 旋转 90 度,这应该产生 (0, -5) - - JavaScript 的舍入行为意味着任一坐标仍然可能是一个非常接近预期整数的值,但仍然是一个浮点数。例如:
rotate(0, 0, 5, 0, 90); // > [3.061616997868383e-16, -5]
因此,结果数组的两个元素都应该是浮点数。您可以使用它们转换为整数
Math.round()
,Math.ceil()
或Math.floor()
需要。最后,请注意,此函数采用笛卡尔坐标系,这意味着当您在坐标平面中“向上”时,Y 轴上的值会变得更高。在 HTML/CSS 中,Y 轴是倒置的——当您向下移动页面时,Y 轴上的值会变高。
回答by jh314
- First, translate the rotation center to the origin
- Calculate the new coordinates (nx, ny)
- Translate back to the original rotation center
- 首先,将旋转中心平移到原点
- 计算新坐标 (nx, ny)
- 平移回原来的旋转中心
Step 1
步骤1
Your new points are
你的新积分是
- center: (0,0)
- point: (x-cx, y-cy)
- 中心:(0,0)
- 点:(x-cx,y-cy)
Step 2
第2步
- nx = (x-cx)*cos(theta) - (y-cy)*sin(theta)
- ny = (y-cy)*cos(theta) + (x-cx)*sin(theta)
- nx = (x-cx)*cos(theta) - (y-cy)*sin(theta)
- ny = (y-cy)*cos(theta) + (x-cx)*sin(theta)
Step 3
第 3 步
Translate back to original rotation center:
转换回原始旋转中心:
- nx = (x-cx)*cos(theta) - (y-cy)*sin(theta) + cx
- ny = (y-cy)*cos(theta) + (x-cx)*sin(theta) + cy
- nx = (x-cx)*cos(theta) - (y-cy)*sin(theta) + cx
- ny = (y-cy)*cos(theta) + (x-cx)*sin(theta) + cy
For deeper explanation, with some fancy diagrams, I recommend looking at this.
为了更深入的解释,有一些花哨的图表,我建议看这个。
回答by user889030
above accepted answer not work for me correctly, rotation are reversed , here is working function
以上接受的答案对我来说不正确,旋转是反向的,这是工作功能
/*
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};
}