2012-10-22 17 views
7

Domyślnie macierz obrotu używa punktu początkowego jako środka obrotu. Aby obrócić się wokół dowolnego punktu, musisz odjąć odległość do początku za pomocą macierzy translacji, obrócić, a następnie odłożyć z powrotem. Tyle tylko, że dla mnie to nie działa tak dobrze. Mam następujący kod (zakładamy, mój obiekt jest 100x100 z centrum w 50,50):Macierz obrotu o dowolnym punkcie

t = IDENTITY; 
t = translate(t, -50, -50); 
t = rotate(t, theta); 
t = translate(t, 50, 50); 

Niestety, jeśli zastosowanie tego macierzą transformacji t do mojego obiektu, obiekt jest ustawiony nieprawidłowo.

I zostały wdrożone szybko jsfiddle do wykazania mój problem: http://jsfiddle.net/9M3uy/67/

W JSFiddle czerwona obrócony kwadrat jest gdzie rotacja powinna skończyło się (dzięki uprzejmości wybudowany w transformacji pochodzenia CSS3 za), a niebieski obrócony kwadrat to miejsce, w którym kończy się moje obliczenie (zielony byłby oryginalnym nieobrotowym kwadratem).

Wszelkie pomysły? Czy po prostu nie rozumiem, w jaki sposób tłumaczę, obracam, tłumaczę z powrotem mechanikę lub czy robię coś okropnie nie tak?

+0

Nie widzę zielonego ... –

+0

Musisz używać przeglądarki Chrome lub Safari. Zaktualizowałem JSFiddle tak, aby zawierał niezbędne CSS dla wszystkich przeglądarek. – syazdani

+0

Tak! Ale wygląda na to, że znalazłeś odpowiedź! Przyszedłem za późno. –

Odpowiedz

2

Istnieją dwa problemy w kodzie:

  1. Matryca mnożenia odbywa się w odwrotnej kolejności niż prawdopodobnie zamierzasz. Wygląda na to, że chcesz rotate(t, theta) zwrócić macierz, która ma zastosowanie t, po której następuje rotacja, ale w rzeczywistości jest odwrotnie - obrót zostanie zastosowany przed t. Musisz odwrócić kolejność parametrów w wywołaniach matrixMultiply w rotate i translate.

  2. Parametry funkcji CSS matrix są w niewłaściwej kolejności. Powinno to być a11, a21, a12, a22, a13, a23. To, co przechodzisz, to a11, a12, a21, a22, a13, a23.

Oto fixed version.

+0

Oto zoptymalizowana wersja poprawionej wersji interjay. http://jsfiddle.net/orwellophile/hvvo9oh8/ – Orwellophile

0

Spróbuj najpierw wprowadzić "standardowe" mnożenie macierzy 3x3 dla przypadków 2d i dopiero po próbie optymalizacji elementów, które wynikają z pomnożenia przez zero. Trochę trudno jest sprawdzić, czy formuły są poprawne, gdy schemat indeksowania jest zdecydowanie zbyt nieortodoksyjny.

Macierz obrotu = [c -s 0; s c 0; 0 0 1]; Macierz tłumaczenia = [1 0 x; 0 1 y; 0 0 1];

Muszę założyć, że funkcja translacji css również przyjmuje wynik 3x3.

Zarówno mnożenie, jak i obracanie odbywa się poprzez pomnożenie wektorów (x, y, 1) przez odpowiednią macierz.

EDIT: Po błahy nieco, wydaje się, że zarówno macierz m powinny być tłumaczone, czy operatorzy mogą być zdefiniowane jako return MatMul([rot matrix],m) and return MatMul([trans matrix],m)

Edit2: Teraz widzę coś dziwnego: Przełożenie tylko + -50, + -50 i obracanie o ~ 10 stopni, róg nie pozostaje w środku czerwonego kwadratu. Ale nie rozumiem formatu matrycy css. Niestety ...

+0

Zaktualizowałem przykład, aby uzyskać pełne mnożenie 3x3: http://jsfiddle.net/9M3uy/5/. Transformacja css (myślę, że to, co miałeś na myśli), przyjmuje matrycę w postaci: 'matrix (a, b, c, d, tx, ty)' (Upuszcza trzeci rząd). – syazdani

+1

Musisz używać przeglądarki Chrome lub Safari (lub innej przeglądarki opartej na webkitach). Domyślnie początek transformacji w CSS znajduje się w centrum, a jeśli nic nie zmieniłeś w CSS, to matryca obliczona przez mój kod będzie działała, ale tylko dlatego, że przeglądarka wyśrodkowuje obrót dla ciebie. Jeśli spojrzysz na zaktualizowane skrzypce, w którym ustawię źródło na 0,0 dla wszystkich przeglądarek, zobaczysz, że sugerowana zmiana nie działa. – syazdani

Powiązane problemy