我对三角学并不是很熟悉,但我只需要在二维平面上旋转两个点:
*nx, ny
. -
. -
. angle -
*cx,cy.................*x,y
cx,cy是旋转中心
x,y是当前坐标
nx,ny是新坐标
如何计算在给定角度下的新点?
我对三角学并不是很熟悉,但我只需要在二维平面上旋转两个点:
*nx, ny
. -
. -
. angle -
*cx,cy.................*x,y
cx,cy是旋转中心
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)为例,以顺时针90度旋转它围绕点(1,1)旋转。
rotate(1, 1, 2, 1, 90);
// > [1, 0]
关于这个函数有三点需要注意:
对于顺时针旋转,最后一个参数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轴上的值随着向页面下方移动而变大。
angle
)设置为0
时,我总是得到一个包含第3个和第4个参数([x,y]
)未修改的数组。您看到了不同的东西吗? - theftpreventionnx = (cos * (x - cx)) - (sin * (y - cy)) + cx, ny = (cos * (y - cy)) + (sin * (x - cx)) + cy;
- prateekj_ahead步骤1
您的新点为
步骤2
步骤3
将其平移回原始的旋转中心:
想要了解更深入的解释和一些精美的图表,请参考这个链接.
上面接受的答案对我来说并不正确,旋转是相反的,这里是可行的函数
/*
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};
}
我认为对于这样的操作,使用矩阵更好。
以下是使用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;
}
})();
rotateVector([x, y, 0], [cX, cY, 0], [0, 0, 1], angleInRadians);