2013-02-14 13 views
7

To zabija mnie przez ostatnie kilka dni. Nawet nie żartuję, ale bardzo mnie to stresuje, próbując go rozwiązać.Przesunięcie macierzy transformacji afinicznej

Obecnie próbuję użyć macierzy transformacji afinicznej do utworzenia rzutu izometrycznego w HTML5. Otrzymuję kafelek, który jest kwadratem obróconym o 45 stopni (zasadniczo kwadratowy diament na kwadratowym płótnie). Następnie skaluję jedną z osi "w zależności od tego, czy istnieje delta w kierunku x lub y. Następnie przekręcę oś o współczynnik, aby pasował. Następnie neguję początkowy obrót, obracając go z powrotem o -45 stopni.

Obecnie moja matryca afiniczne jest:

 // note: the difference in z is about 10 in this example, 
     //  so, xDiff is usually 40 
     var xDiff = 4 * (center.z - map[x+1][y].land.z); 
     var yDiff = 4 * (center.z - map[x][y+1].land.z); 

     var matrix = multiplyAll(
     // Rotation 
     [COS45, SIN45, 
     -SIN45, COS45], 

     // Scale in each respective axis 
     [(44+yDiff)/44, 0, 
     0, (44+xDiff)/44], 

     // Skew each axis 
     [1, -yDiff/(44+yDiff), 
     -xDiff/(44+xDiff), 1], 

     // Negate the rotation 
     [NCOS45, NSIN45, 
     -NSIN45, NCOS45] 
    ); 

Potem wyciągnąć go za pomocą:

 // the map has its own x & y values which directions are determined by the red x & y arrows in the picture 
     // pX & pY are the point relative to the canvas origin 
     var pX = x * 22 - y * 22 + 22; 
     var pY = y * 22 + x * 22 - 22 - (center.z * 4); 
     context.setTransform(matrix[0], matrix[1], 
          matrix[2], matrix[3], 

          300, 100); 

     //m_Context.drawImage(image, pX, pY); 
     drawDiamond(pX, pY, true); // draws a 44x44 diamond 

Projection test

Transformed plane

Jak widać, transformowane macierze są być rysowane w odniesieniu do transformacji ed osi X (myślę, że "nowa" oś X ma nachylenie YDiff/44). Nie wiem, jak narysować kształty, aby transformowany wynik był we właściwej pozycji. Wydaje mi się, że użycie pY = x * 22 - (yDiff/10); jest bliższe tej sytuacji, ale w zasadzie odgadłem to, podłączając losowe liczby.

tl; dr:

  • Przeprowadziłem transformację
  • Mam koordynować gdzie płytka powinna być (jeśli nie została przekształcona)
  • Jak obliczyć przesunięcie wymagane aby współrzędna przekształconego kafelka była taka sama jak w miejscu, w którym powinna być, gdyby nie została przekształcona?

PS: Dziwne diamenty na dnie można na razie zignorować, ponieważ mogą one correctly be created RAZ POTRZEBUJĘ, jak obliczyć przesunięcia.

+0

Nie rozumiem, czego potrzebujesz. Przeważnie masz transformacje liniowe, które nie mają przesunięć. Aby znaleźć pozycje w przekształconym układzie współrzędnych, nie możesz użyć ładnej siatki, którą już masz? –

+0

@luserdroog Siatka jest tworzona za pomocą tylko płytek, które nie są przekształcane, a więc możesz użyć ładnego równania, aby znaleźć lokalizację. –

+0

+1 za fajną grafikę – QED

Odpowiedz

4

Macierz przekształcenie afiniczne ([abcdef]) wyraża dwa równania

x' = ax + cy + e 
y' = bx + dy + f 

Tak, można użyć przesunięcia e i f ominąć części skalowania i pochylania (4x4 liniowy przekształcać osadzone w macierzy 2x3 lub 3x3).

Jest to często używane w programowaniu postscriptowym, w którym współrzędne używane do rysowania obiektu odnoszą się do źródła lokalnego lokalnego. Jeśli łączysz macierze, wykonaj skalowanie i pochylenie, a wartości e pozostaną niezmienione.

+0

Muszę poczekać 9 godzin zanim dam ci swoją nagrodę :( –

+0

Nie ma problemu Cieszę się, że mogłem pomóc –

+0

Równania powinny być 'x '= ax + cy + e' i' y' = bx + dy + f' , ponieważ macierz to | as | | bdf | | 0 0 1 | – cleong

Powiązane problemy