Jak obliczyć obrót w 2D w Javascript

Nie znam się na trygonometrii, ale mam tylko dwa punkty do obracania w 2D:

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

Cx, cy = rotation center
x, y = current X, y
NX, ny = New coordinates

Jak obliczyć nowe punkty pod określonym kątem?

Author: Digerkam, 2013-07-01

3 answers

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

Pierwsze dwa parametry to współrzędne x I Y punktu centralnego (początek, wokół którego obraca się drugi punkt). Następne dwa parametry to współrzędne punktu, który będziemy obracać. Ostatnim parametrem jest kąt, w stopniach.

Jako przykład weźmiemy punkt (2, 1) i obrócimy go wokół punktu (1, 1) o 90 stopni zgodnie z ruchem wskazówek zegara.
rotate(1, 1, 2, 1, 90);
// > [1, 0]

Trzy uwagi o tej funkcji:

  1. Do obrotu zgodnie z ruchem wskazówek zegara, ostatni parametr angle powinien być dodatni. W przypadku obrotu w kierunku przeciwnym do ruchu wskazówek zegara (jak na podanym diagramie), powinien on być ujemny.

  2. Zauważ, że nawet jeśli podasz argumenty, które powinny dawać punkt, którego współrzędne są liczbami całkowitymi - tzn. obracając punkt (5, 0) o 90 stopni o początek (0, 0), który powinien dawać (0, -5) -- zachowanie zaokrąglania JavaScript oznacza, że obie współrzędne mogą być wartością frustrująco zbliżoną do oczekiwanej liczby całkowitej, ale nadal jest pływakiem. Na przykład:

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

    Z tego powodu oba elementy tablicy wynikowej powinny być oczekiwane jako float. Możesz przekonwertować je na liczby całkowite za pomocą Math.round(), Math.ceil(), lub Math.floor() w razie potrzeby.

  3. Na koniec zauważ, że ta funkcja zakłada kartezjański układ współrzędnych , co oznacza, że wartości na osi Y stają się wyższe, gdy idziesz "w górę" na płaszczyźnie współrzędnych. W HTML / CSS oś Y jest odwrócona - wartości na osi Y stają się wyższe w miarę poruszania się W Dół strony.

 74
Author: theftprevention,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-10 20:29:25
  1. Najpierw Przetłumacz środek obrotu na początek
  2. Oblicz nowe współrzędne (nx, ny)
  3. Translate back to the original rotation center

Krok 1

Twoje nowe punkty to

  1. center: (0,0)
  2. punkt: (x-cx, y-cy)

Krok 2

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

Krok 3

Przetłumacz z powrotem do oryginalnego centrum obrotu:

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

Dla głębszego wyjaśnienia, z kilkoma fantazyjnymi diagramami, polecam spojrzeć na to .

 5
Author: jh314,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-26 06:30:40

Powyżej zaakceptowana odpowiedź nie działa dla mnie poprawnie, obroty są odwrócone, tutaj działa funkcja

/*
 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
Author: user889030,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-03 13:40:29