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?
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:
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.-
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()
, lubMath.floor()
w razie potrzeby. 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.
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
- Najpierw Przetłumacz środek obrotu na początek
- Oblicz nowe współrzędne (nx, ny)
- Translate back to the original rotation center
Krok 1
Twoje nowe punkty to
- center: (0,0)
- punkt: (x-cx, y-cy)
Krok 2
- nx = (x-cx)*cos (theta) - (y-cy)*sin (theta)
- ny = (y-cy)*cos(theta) + (x-cx) * sin (theta)
Krok 3
Przetłumacz z powrotem do oryginalnego centrum obrotu:
- nx = (x-cx)*cos (theta) - (y-cy)*sin (theta) + cx
- ny = (y-cy)*cos(theta) + (x-cx) * sin (theta) + cy
Dla głębszego wyjaśnienia, z kilkoma fantazyjnymi diagramami, polecam spojrzeć na to .
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];
}
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