Cómo calcular la rotación en 2D en Javascript
rotation trigonometry (3)
- Primero, traduce el centro de rotación al origen.
- Calcular las nuevas coordenadas (nx, ny)
- Traducir de nuevo al centro de rotación original
Paso 1
Tus nuevos puntos son
- centro: (0,0)
- punto: (x-cx, y-cy)
Paso 2
- nx = (x-cx) * cos (theta) - (y-cy) * sin (theta)
- ny = (y-cy) * cos (theta) + (x-cx) * sin (theta)
Paso 3
Traducir de nuevo al centro de rotación original:
- nx = (x-cx) * cos (theta) - (y-cy) * sin (theta) + cx
- ny = (y-cy) * cos (theta) + (x-cx) * sin (theta) + cy
Para una explicación más profunda, con algunos diagramas de fantasía, recomiendo mirar this .
No soy trigonometría tan familiar, pero solo tengo dos puntos para rotar en 2D:
*nx, ny
. -
. -
. angle -
*cx,cy.................*x,y
cx, cy = centro de rotación
x, y = corriente x, y
nx, ny = nuevas coordenadas
¿Cómo calcular nuevos puntos en un ángulo determinado?
La respuesta aceptada anteriormente no funciona correctamente, la rotación se invierte, aquí está la función de trabajo
/*
CX @ Origin X
CY @ Origin Y
X @ Point X to be rotated
Y @ Point Y to be rotated
*/
function rotate(CX, CY, X, Y, angle) {
var rad = angle * Math.PI / 180.0;
var nx = Math.cos(rad) * (X-CX) - Math.sin(rad) * (Y-CY) + CX;
var ny = Math.sin(rad) * (X-CX) + Math.cos(rad) * (Y-CY) + CY;
return [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];
}
Los primeros dos parámetros son las coordenadas X e Y del punto central (el origen alrededor del cual se girará el segundo punto). Los siguientes dos parámetros son las coordenadas del punto que estaremos girando. El último parámetro es el ángulo, en grados.
Como ejemplo, tomaremos el punto (2, 1) y lo giraremos alrededor de 90 grados en el sentido de las agujas del reloj alrededor del punto (1, 1).
rotate(1, 1, 2, 1, 90);
// > [1, 0]
Tres notas sobre esta función:
En el sentido de las agujas del reloj, el
angle
del último parámetro debe ser positivo. Para la rotación en sentido contrario a las agujas del reloj (como en el diagrama que proporcionó), debe ser negativo.Tenga en cuenta que incluso si proporciona argumentos que deberían producir un punto cuyas coordenadas son números enteros, es decir, girar el punto (5, 0) en 90 grados sobre el origen (0, 0), que debería producir (0, -5) - - El comportamiento de redondeo de JavaScript significa que cualquiera de las coordenadas podría ser un valor que se aproxima frustrantemente al número entero esperado, pero aún es un valor flotante. Por ejemplo:
rotate(0, 0, 5, 0, 90); // > [3.061616997868383e-16, -5]
Por esta razón, ambos elementos de la matriz resultante deben esperarse como un flotador. Puede convertirlos a enteros utilizando
Math.round()
,Math.ceil()
oMath.floor()
según sea necesario.Finalmente, tenga en cuenta que esta función asume un sistema de coordenadas cartesianas , lo que significa que los valores en el eje Y se vuelven más altos a medida que sube "arriba" en el plano de coordenadas. En HTML / CSS, el eje Y está invertido: los valores en el eje Y se vuelven más altos a medida que se desplaza hacia abajo en la página .