2011-01-31 17 views
5

Ja nie uważam się za geniusza, jeśli chodzi o programowanie, a mój obecny problem mnie zafascynował.Obliczanie macierzy transformacji 2D z początkowej i wynikowej macierzy 2D

Znalazłem to pytanie Trying to derive a 2D transformation matrix using only the images który wydaje się przynajmniej częściowo odpowiedzieć na moje pytanie, ale obraz, który powinien pokazać rozwiązanie nie jest już dostępny: S

Pracuję w C# i nie przy użyciu WPF jako ani mój wejście lub wyjście musi być wyświetlane graficznie.

W moim programie mam 2 czworokąty, nazwijmy je czworokątem wejściowym i wyjściowym.

Czwórnik wejściowy ma współrzędne od (2,1), (2,3), (4,4), (3,1) od dołu po lewej zgodnie z ruchem wskazówek zegara.

Wyjściowe kwadraty mogą mieć dowolne współrzędne i zostaną ponownie wymienione w kolejności od dołu po lewej zgodnie z ruchem wskazówek zegara.

Biorąc pod uwagę te 8 współrzędnych par, czy możliwe jest obliczenie macierzy transformacji, którą mógłbym zastosować do dowolnej pary współrzędnych?

Nie jestem zbyt gorąca na Matrices, ale jestem gotów dowiedzieć się, czy wskazał we właściwym kierunku.

Wiele Dzięki

Josh

+1

Nie sądzę, że tutaj jest za dużo macierzyńskiego zaangażowania; pytasz o funkcję izomorficzną, aby rzutować pojedynczy punkt w kształcie czworoboku do punktu w drugim czworoboku. Nie powinno to być zbyt trudne ... musisz tylko ustalić, w jaki sposób punkty w pierwszym i drugim wielokątach są ze sobą odwzorowane. –

+0

Możesz również sprawdzić http://math.stackexchange.com/questions/13404/mapping-irregular-quadrilateral-to-a-rectangle –

Odpowiedz

2

Szybki google lub hop, pomiń google i znajdź go pod adresem this. Myślę, że to na pewno rozwiąże twój problem.

Jak wspomniałem w komentarzu, prosisz, aby funkcja izomorficzna wyświetlała pojedynczy punkt w kształcie czworoboku do punktu w drugim czworoboku. Zamiast pracować ręcznie, znalazłem poniższy algorytm.

zamieszczaniu algorytm tu dla potomnych:

Let P00, P10, P11, P01 i być wierzchołki pierwszego czworokąta wymienionych w przeciwnym kolejności.

Niech q00, q10, q11 i q01 będą wierzchołkami drugiego czworokąta wymienionego w w kolejności przeciwnej do ruchu wskazówek zegara.

zdefiniować P10 = P10-P00, P11, P11, P00 =, = P01 P01, P00, Q10 = Q10-Q00, Q11 = Q11-Q00 i Q01 = Q01, Q00.

Obliczyć aib tak, aby Q11 = aQ10 + bQ01.

Jest to zestaw dwóch równań liniowych w dwóch niewiadomych.

Podobnie należy obliczyć cid, aby P11 = cP10 + dP01.

Okazuje się, że a> = 0, b> = 0, a + b> 1 c> = 0, D> = 0, a c + d> 1.

Każdy punkt P w czworobok może być zapisany jako jako p = (1-xy) p00 + xp10 + yp01 gdzie x = 0, y = 0, (1 - d) x + c (y - 1) = 0 i d (x - 1) + (1 - c) y = 0.

Każdy punkt q w czworoboku może być zapisany jako q = (1-uv) q00 + uq10 + vq01 gdzie u = 0, v = 0, (1 - b) u + a (v -1) = 0 i b (u - 1) + (1 - a) v = 0.

Mapowanie perspektywiczne dotyczące (u, v) do (x, y) to u = m0x n0 + n1x + n2y i v = m1y n0 + n1x + n2y gdzie m0 = reklama (1 - c - d), m1 = bc (1 - c - d), n0 = cd (1 - a - b), n1 = d (a - c + bc - ad), a n2 = c (b - d - bc + ad).

skutecznie p-czworoboku jest mapowany do „standardowej” jeden, < (0, 0), (1, 0) (0, 1), (C, D)>

i Q -podobny jest mapowany na < (0, 0), (1, 0), (0, 1), (a, b)>.

Mapowanie (x, y) do (u, v) dotyczy tych dwóch.

Można sprawdzić,

• (x, y) = (0, 0), jest mapowany (u, v) = (0, 0)

• (x, y) = (1, 0), jest mapowany (u, v) = (1, 0)

• (x, y) = (0, 1) jest mapowany (u, v) = (0, 1)

• (x, y) = (C, d) jest mapowany (u, v) = (a, b)

mi da kolejna odpowiedź opisująca, jak rozwiązałbym ten przykład w komentarzach - ta odpowiedź jest zbyt długa.

+0

To jest Brilliant Kirk, wielkie dzięki za podzielenie się swoją wiedzą. –

+0

Świetne rzeczy, Kirk. –

+0

Ok chłopaki, zaimplementowałem to w kodzie najlepiej jak potrafię i nie działa to dla mnie. Obecnie używam przykładowej aplikacji, w której ręcznie definiuję wszystkie współrzędne i używam prostych transformacji, nie otrzymuję potrzebnych wyników. Jeśli na przykład używam kwadratu 10 x 10 od 0,0 dla początkowego i kwadratu 20 x 20 również od 0,0, gdy wprowadzam współrzędne 5,5 jako X i Y dla pierwszego, powinienem otrzymać 10, 10 za wypadkową, w tej chwili otrzymuję 5,5. Kiedy to robię, wartości A, B, C, D wynoszą 1, gdy czuję, że nie powinny być. Czy ktoś wie, gdzie popełniłem błąd? –

2

Tytuł pytanie jest mylące, ponieważ oznacza to, że masz początkowe i końcowe matryce. To, co naprawdę masz, to dwa zestawy punktów: punkty początkowe i punkty końcowe.

Po pierwsze, jak wspomniano, jest to możliwe, aby obliczyć się macierz transformacji, ale niekoniecznie matryca transformacja. Dla każdej konkretnej transformacji istnieje wiele (nieskończonych?) Sposobów, aby to osiągnąć.

Należy pamiętać, że poniższe informacje to tylko niektóre z nich. Tak naprawdę tego nie zrobiłem. Zakładam, że masz dwa zestawy punktów: A i B i wiesz na pewno, że B jest wynikiem zastosowania pewnej transformacji do A.

Problem jest banalny, jeśli jedyną dozwoloną transformacją jest tłumaczenie. W takim przypadku możesz po prostu wziąć odległość między dolnymi lewymi punktami. Oznacza to, że jeśli oryginalne punkty to A[0] do A[3], a nowe punkty to B[0] do B[3], transformacja jest po prostu translacją X, Y: ((B[0].X - A[0].X), (B[0].Y - A[0].Y)).

Jeśli dozwolone jest skalowanie, możesz obliczyć tłumaczenie, a następnie skalowanie. Chociaż, aby uprościć, najpierw będziesz chciał przetłumaczyć na pochodzenie. W rzeczywistości większość tego staje się prostsza, jeśli najpierw przetłumaczysz na pochodzenie.

Jeśli obrót jest dozwolony, sprawy stają się nieco trudniejsze. Biorąc pod uwagę czworoboki, najpierw musisz obrócić przedmiot, aby punkty były w tej samej orientacji co oryginał. Będzie to wymagało obliczenia odległości między punktami i skorzystania ze współczynników, aby określić, który punkt znajduje się w lewym dolnym rogu. Następnie obróć w odpowiednie miejsce.

Sprawa rotacji, skalowania i tłumaczenia powinna być prosta do rozwiązania.

Ścinanie jest nieco bardziej skomplikowane. Powinieneś być w stanie wykryć wykrywanie, ale nie mam pojęcia, jak wykryć ilość ścinania. Myślę jednak, że jeśli rozwiążesz przypadek obracania/skalowania/translacji, wówczas rozwiązanie ścinania stanie się co najmniej bardziej oczywiste.

+0

Podoba mi się pierwsza połowa Twojej odpowiedzi. Moje odczytanie pytania polegało na tym, że drugi zbiór współrzędnych może być * dowolnym * zbiorem współrzędnych; obrócone, skalowane, strzyżone są wszystkie na stole. Nie będzie żadnego "prawdziwego" obrotu (więcej niż 90 stopni), ponieważ są to tylko dwa czworoboki zdefiniowane przez lewy dolny róg. –

+0

@Kirk: Możesz chcieć sprawdzić znaczenie "czworoboku". To tylko 4-stronny kształt. Więc * może * być prawdziwym obrotem. –

+0

To naprawdę nie fair zakładać, że nie znam znaczenia czworoboku, prawda? Chodzi mi o to, że dla 2 czworokąta, oba zdefiniowały * wyłącznie * na 4 współrzędne, i gdzie współrzędne są uporządkowane zgodnie z ruchem wskazówek zegara od "dolnego lewego", jak można określić dowolny "obrót"? Jeśli wiesz, który zakątek z Q1 zamapowany do którego rogu w Q2, a następnie przyznane, możesz mieć "obrót", ale gdy nie masz dostępnych informacji, obrót jest nieistotnym pojęciem. –

1

Aby rozwiązać przykładowy przypadek - przeniesienie punktu (5,5) z kwadratu (0,0) - (10,10) na kwadrat (0,0) - (20,20) - jesteś na właściwy tor, ale albo za szybko się zatrzymał, albo zgubił. Algorytm nie jest najprostszy, ale jest całkiem użyteczny, gdy zrozumiesz, dokąd zmierzasz.

W przypadku "kwadratów" prostopadłych do osi x & y następnie tak a = b = c = d = 1.

Nazwijmy punkty twojego quada p1, p2, p3 i p4. Teraz pomyśl o a jako opisującej zależność pomiędzy p2 i p3 (względem p1), a b jako opisującej podobną zależność między p4 i p3 (w stosunku do p1). Bardzo upraszczając, chcesz poćwiczyć a i b gdzie

  • współrzędna x p1 + a * length of side p1-p2 = współrzędna x P3 i
  • współrzędną y = p1 + b * length of side p1-p4 współrzędna y P3.

czyli zaczynając od dołu po lewej, jak wiele wiele dolne krawędzie muszę dodać, aby dostać się współrzędna x w prawym górnym rogu, a podobnie do współrzędna y. Chociaż jest to kęs, gdy masz do czynienia z kwadratem, poprawny wynik tutaj jest zdecydowanie 1 i 1. Kiedy odejdziesz od prostopadłych kwadratów, nie jest to takie proste, ale łatwo je sobie wyobrazić.

Kiedy można rozwiązać ten

  • p =(1-x-y)p00 + xp10 + yp01, gdzie
  • x >= 0
  • y >= 0
  • (1 - d)x + c(y - 1) = 0
  • d(x - 1)+(1 - c)y = 0

używając punktu (5,5) otrzymasz wartość x = 1/2, y = 1/2. Zauważ, że nie są to współrzędne X i Y twojego punktu. Zamiast tego reprezentują one punkt, w którym ma się znajdować punkt, jeśli czworobok został rzutowany na kwadrat (1,1). W tym przypadku oznacza to, że twój punkt jest ustawiony na 1/2 szerokości (poziomo) i 1/2 w górę (pionowo) na wielokącie - to znaczy na środku.

Podłączyć wartości a,b,c,d,x i y do dużego równania (po łączu zamiast próbować go przeczytać tutaj!), dostaniesz również (u, v) = (1/2, 1/2), gdzie u & v reprezentuje to samo pojęcie powyżej, ale w drugim kwadracie. Jest to poprawne, ponieważ wynikowy punkt powinien znajdować się pośrodku drugiego wielokąta.

Wreszcie, kiedy podłączyć u, v do równania

  • q =(1-u-v)q00 + uq10 + vq01

dostaniesz punkt q = (10,10), co jest zgodne z oczekiwaniami.

Nie wiem, czy nie myślałem o rozwiązaniu równoczesnych równań w kodzie, jestem pewien, że jest sposób, ale może nie jest to proste, ale niestety będę musiał zostawić to tobie. Właśnie zrobiłem to na kartce papieru i wszystko się udało; jednak moja matematyka jest trochę zardzewiała, aby zrobić coś więcej niż banalny przykład.

+0

Cześć Kirk, myślę, że zgubiłem się i zatrzymałem wcześnie z powodu tego faktu. Zobaczę, jak wprowadzić ten kod później, gdy mój mózg będzie pracował lepiej. –

+0

@Josh Zalecam, abyś najpierw przejrzał go na papierze, żebyś zobaczył, jak to działa; następnie spróbuj wdrożyć go w kodzie. –

+0

Dzięki za sugestię, przeprowadziłem to szybko na papierze z kilkoma różnymi scenariuszami i wydawało się, że działa dobrze. Zaimplementowałem to w kodzie i wydaje mi się, że wszystko działa dla mnie w tych samych scenariuszach, ale kod wydaje się przewracać z bardziej złożonymi zmianami parametrów wejściowych i wyjściowych. Zamierzam spojrzeć na to jeszcze za kilka dni, kiedy mój umysł będzie trochę świeższy i odejdę stamtąd. Znów na zdrowie. –

Powiązane problemy