Jak przekonwertować między dwoma różnymi układami współrzędnych 2D?

10

Próbuję przekonwertować współrzędną z jednego układu współrzędnych na inny, aby móc narysować ją na obrazie.

Zasadniczo docelowy układ współrzędnych jest następujący:

X range: 0 to 1066
Y range: 0 to 1600

(tylko standardowy obraz, na który rysuję, o wielkości 1066 x 1600)

Pozycja, którą próbuję narysować na obrazie, ma dokładnie ten sam rozmiar, ale układ współrzędnych jest inny. Rozpiętość wszystkich współrzędnych to 1066 x 1600.

Ale współrzędnym przykładem byłoby:

(111.33f, 1408.41f)
(-212.87f, 1225.16f)

Zakres tego układu współrzędnych wynosi:

X range: -533.333 to 533.333
Y range: 533.333 to 2133.333

Wydaje mi się, że to BARDZO prosta matematyka, ale z jakiegoś powodu tego nie rozumiem.

Jak przekonwertować podane współrzędne na pierwszy układ współrzędnych?

Geesu
źródło
3
Jeśli dwa układy współrzędnych mają te same wektory podstawowe, możesz po prostu użyć współczynnika skalowania. Jeśli nie mają tych samych wektorów bazowych, konieczna jest zmiana bazy .
thalador

Odpowiedzi:

7

Możesz znormalizować pierwszą wartość, da to wartość z zakresu [0,1]. Można to traktować jako procent X, procent odwzorowany na wartość między wartością minimalną i maksymalną. Następnie możesz dowiedzieć się, gdzie procent ten należy do docelowego układu współrzędnych, sprawdzając, jaką wartość stanowi procent X w układzie docelowym. Użyję kodu Java jako języka przykładowego, ale jestem pewien, że pojęcia są wystarczająco jasne, aby tłumaczyć na dowolny język.

Więc znormalizuj:

public static float normalize(float value, float min, float max) {
    return Math.abs((value - min) / (max - min));
}

Korzystając z przykładu, wpisz:

xPercent = normalize(x,0,1066);

Następnie znajdź, gdzie leży w systemie docelowym. Z czymś takim

destX = xPercent*(Math.abs(max-min)) + min;

Lub użyć swoich wartości:

destX = xPercent*(Math.abs(533.33--533.33)) + -533.33;

Na przykład przy wartości x 1000 zamapowałbyś ją na docelowym układzie współrzędnych 467.29.

Alternatywnie , jeśli układy współrzędnych będą zawsze takie same, możesz wstępnie obliczyć stosunek między nimi.

Więc:

xRatio = (Math.abs(srcMax-srcMin))/(Math.abs(destMax-destMin));

destX = x*xRatio+destMin;
MichaelHouse
źródło
Dlaczego Java (C #)? Nie poprosił o kod Java :)
kravemir
6
To dać przykład. Nie trzeba go używać w obecnej postaci, a koncepcja jest wystarczająco jasna.
MichaelHouse
Ale jeśli to zrobię: destX = xPercent * (Math.abs (533.33--533.33)) + -533.33; Zawsze otrzymuję wartość ujemną, a wynikowy układ współrzędnych wynosi tylko od 0-1066, czy powinienem zamieniać wszystkie współrzędne?
Geesu
Zamieniłem je i wciąż otrzymuję dump.tanaris4.com/sota.png, tak jak w innym poście, może mam inny problem (związany z C # i rysowaniem). Dzięki chłopaki!
Geesu
Rozumiem, z jakiegoś powodu musiałem zrobić xPercent = 1.0f - xPercent
Geesu
4

To prosta matematyka:

res = ( src - src_min ) / ( src_max - src_min ) * ( res_max - res_min ) + res_min

src - źródłowy układ współrzędnych

res - system koordynacji wyników

Edycja - wyjaśnienie matematyki

( src - src_min ) / ( src_max - src_min )przekłada go na układ współrzędnych zaczynający się od zera o równej długości źródłowego układu współrzędnych (0.0, src_max - src_min ). Następnie skaluje wartość do układu współrzędnych(0.0, 1.0) .

* ( res_max - res_min ) wartość ta jest skalowana do układu współrzędnych rozpoczynającego się od zera z długością układu koordynacji wyników (0.0, dst_max - dst_min)

+ res_min tłumaczy wartość na wynikowy układ współrzędnych (dst_min, dst_max)

kravemir
źródło
Też tak myślałem, ale nie wyświetla się poprawnie: dump.tanaris4.com/sota.png Końcowa współrzędna powinna trafić tam, gdzie biały okrąg znajduje się na dole
Geesu
1
To wcale nie wyjaśnia ich matematyki, dlaczego nie? :)
MichaelHouse
@ Byte56 Dla mnie jest to formuła wystarczająca do zrozumienia czegoś, szczególnie jeśli używa tylko operacji arytmetycznych, ale dodałem wyjaśnienie dla osób, które będą tego potrzebować :)
kravemir
1
@Geesu Prawdopodobnie robisz coś innego (renderowanie matryc?).
kravemir
2
Dzięki za aktualizację. Ogólnie myślę, że lepiej jest udzielić odpowiedzi, która próbuje wyjaśnić, dlaczego. W przeciwnym razie po prostu dajesz odpowiedź na to pytanie, zamiast jak rozwiązać to pytanie i podobne problemy. To coś w stylu „daj człowiekowi rybę, naucz mężczyznę łowić ryby”.
MichaelHouse
3

Podstawowe równanie transformacji współrzędnych 2D (w algebrze, bez uwzględnienia obrotu) to:

TargetCoordinate = TranslateFactor + ScalingFactor*SourceCoordinate

otrzymuje dwa punkty w TargetCoordinate (T1, T2), które odpowiadają dwóm punktom w SourceCoordinate (S1, S2) TranslateFactori ScalingFactorsą przyznawane poprzez rozwiązanie:

T1 = TranslateFactor + ScalingFactor*S1
T2 = TranslateFactor + ScalingFactor*S2

które wynikają:

TranslateFactor = (T2*S1 - T1*S2) / (S1 - S2)
ScalingFactor   = (T2 - T1) / (S2 - S1)

W twoim przypadku dla współrzędnej x

S1 = 0    -> T1 = -533.333
S2 = 1066 -> T2 = 53.333

A zatem,

TranslateFactor = -533.333
ScalingFactor   = 1.000625
=> TargetCoordinate = (-533.333) + (1.000625)*SourceCoordinate

Współrzędna y postępuj zgodnie z tą samą procedurą

tkokasih
źródło
S1 i S2 nie mogą mieć tej samej współrzędnej x / y, która prowadzi do podziału przez zero.
zwcloud,
0

Dokonując kilku założeń:

  • Jesteś (ostatecznie) zainteresowany impementacją matrycy, dla wygody i mocy; i
  • Znasz homogeniczne współrzędne.

Następnie pojawia się pytanie: jaka jest homogeniczna macierz transformacji dla mojej zmiany podstawy?

Aby odpowiedzieć na to pytanie, najpierw potrzebujemy odpowiedzi na trzy dodatkowe pytania:

  1. Skąd się wzięło moje pochodzenie?
  2. Co się stało z moją osią X? Niech (M11, M12) będą współrzędnymi punktu
  3. Co się stało z moją osią Y?

Zdefiniuj odpowiedzi na te trzy pytania w następujący sposób:

  1. (M31, M32) to współrzędne nowego źródła w oryginalnym układzie współrzędnych.
  2. (M11, M12) są współrzędnymi nowego wektora x jednostki w oryginalnym układzie współrzędnych.
  3. (M21, M22) to współrzędne nowego wektora y jednostki w oryginalnym układzie współrzędnych.

Zatem jednorodna macierz transformacji jest:

( M11, M12,  0 )
( M21, M22,  0 )
( M31, M32,  1 )

Moja konwencja polega na tym, że punkty są reprezentowane przez wektory rzędowe, co jest normalną konwencją grafiki komputerowej; matematycy i fizycy często używają przeciwieństwa.

Pieter Geerkens
źródło
Układ współrzędnych można opisać za pomocą takiej macierzy: M11 = Xaxis.X, M12 = Xaxis.Y, M21 = Yaxis.X, M22 = Yaxis.Y, M31 = origin.X, M32 = origin.Y. Biorąc pod uwagę macierz układu współrzędnych A i macierz układu współrzędnych B, P * A * Odwrotna (B), gdzie P jest reprezentacją punktu jako współrzędnych w A, daje reprezentację punktu jako współrzędnych w B.
Jim Balter