Comment calculer la rotation en 2D en Javascript

Je ne suis pas si familier de la trigonométrie, mais je n'ai que deux points à faire pivoter en 2D:

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

Cx, CY = centre de rotation
x, y = courant x, y
nx, ny = nouvelles coordonnées

Comment calculer de nouveaux points dans un certain angle?

24
demandé sur Digerkam 2013-07-01 22:04:15

3 réponses

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];
}

Les deux premiers paramètres sont les coordonnées X et Y du point central (l'origine autour de laquelle le second point sera tourné). Les deux paramètres suivants sont les coordonnées du point que nous allons tourner. Le dernier paramètre est l'angle, en degrés.

Par exemple, nous allons prendre le point (2, 1) et le faire pivoter autour du point (1, 1) de 90 degrés dans le sens des aiguilles d'une montre.

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

Trois notes sur cette fonction:

  1. Pour rotation dans le sens horaire, Le Dernier le paramètre angle doit être positif. Pour la rotation dans le sens antihoraire (comme dans le diagramme que vous avez fourni), il devrait être négatif.

  2. Notez que même si vous fournissez des arguments qui devraient donner un point dont les coordonnées sont des nombres entiers-c'est-à-dire en tournant le point (5, 0) de 90 degrés sur l'origine (0, 0) , qui devrait donner (0, -5) - le comportement d'arrondi de JavaScript signifie que l'une ou l'autre coordonnée pourrait toujours être une valeur est encore un flotteur. Par exemple:

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

    Pour cette raison, les deux éléments du tableau résultant doivent être attendus en tant que flottant. Vous pouvez les convertir en entiers en utilisant Math.round(), Math.ceil(), ou Math.floor() au besoin.

  3. Enfin, notez que cette fonction suppose un système de coordonnées cartésiennes , ce qui signifie que les valeurs sur l'axe des ordonnées deviennent plus élevées à mesure que vous montez dans le plan de coordonnées. En HTML / CSS, l'axe Y est inversé - les valeurs sur l'axe Y deviennent plus élevées à mesure que vous vous déplacez en bas de la page.

74
répondu theftprevention 2015-09-10 20:29:25
  1. tout d'abord, traduisez le centre de rotation à l'origine
  2. Calculer les nouvelles coordonnées (nx, ny)
  3. Retour au centre de rotation d'origine

Étape 1

Vos nouveaux points sont

  1. centre: (0,0)
  2. point: (x-cx, y-cy)

Étape 2

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

Étape 3

Retour au centre de rotation d'origine:

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

Pour une explication plus approfondie, avec quelques diagrammes de fantaisie, je recommande de regarder this .

5
répondu jh314 2017-10-26 06:30:40

Ci-dessus la réponse acceptée ne fonctionne pas pour moi correctement, la rotation est inversée, voici la fonction de travail

/*
 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];
    }
0
répondu user889030 2018-04-03 13:40:29