You are not logged in.
- Topics: Active | Unanswered
Announcement
Please create new topics on the new site at community.openstreetmap.org. We expect the migration of data will take a few weeks, you can follow its progress here.***
Pages: 1
#1 2015-07-13 16:51:29
- Cetusek
- Member
- From: Łódź
- Registered: 2014-06-10
- Posts: 135
Mapa 3D z mapy 2D
Chciałbym przekształcić "zwykłą, płaską" mapę, np. taką:

w postać mapy 3D, czyli, np. taką:

Czy zna ktoś algorym przeliczania współrzędnych ekranowych, aby coś takiego uzyskać? Na razie w opcji najprostszej zakładam, że wszystkie obiekty na mapie są płaskie.
Próbowałem to wygooglować, ale nie mogę znaleźć.
Chyba to ma związek z projekcją perspektywiczną.
Last edited by Cetusek (2015-07-13 16:52:30)
Offline
#2 2015-07-13 23:41:24
- RicoElectrico
- Moderator
- From: Trójmiasto
- Registered: 2012-07-01
- Posts: 1,850
Re: Mapa 3D z mapy 2D
Od razu skojarzyło mi się to ze SNES-owym Mode 7 ![]()
Może to Ci pomoże?
http://gamedev.stackexchange.com/questi … -in-pygame
Masz 2 sposoby na implementację tego efektu. Przed albo po rasteryzacji. Przed wymaga mniej obliczeń (przekształcasz tylko punkty), ale po daje Ci w gratisie perspektywę także dla grubości dróg (jak w widoku 3D który oferują od zawsze zwykłe samochodowe navi.)
Last edited by RicoElectrico (2015-07-13 23:43:59)
Offline
#3 2015-07-14 10:13:46
- Cetusek
- Member
- From: Łódź
- Registered: 2014-06-10
- Posts: 135
Re: Mapa 3D z mapy 2D
Spotkałem się już na wielu stronach z tego typu wzorami jak na tej stronie co podałeś:
sx = px / pz;
sy = py / pz;
Tylko problem w tym, że jak je stosuję to nic ciekawego mi nie wychodzi.
Wyobraźmy sobie szkolny układ współrzęcznych i cztery punkty: A = (-2, -5), B = (2, -5), C = (2, 5), D = (-2, 5). Ten prostokąt jest dla mnie drogą. Odcinki AD i BC stanowią jej krawężniki, a oś Y pas rozdzielający kierunki jazdy. W widoku 3D chciałbym uzyskać trapez: odcinek AB powinien się wydłużyć, a odcinek CD powinien się skrócić i obniżyć. Wszystko to powinno zależeć od punktu, w którym znajduje się oko oraz punktu w którym zbiegają sie linie perspektywy (to się chyba fachowo nazywa "vanishing point").
Jak moje punkty zastosowałem do tego pseudokodu ze strony, którą wskazałeś to dostałem:
A' = (-0,1333, 13,333), B' = (0,1333, 13,333), C' = (0,08, 8) D' = (-0,08, 8).
Jest to trapez, ale odwrócony i przesunięty do góry. Więc nie jest to tym, czego oczekuję. W ten sposób przeanalizowałem już kilka różnych stron i nic sensownego mi nie wychodzi ![]()
Last edited by Cetusek (2015-07-14 10:15:05)
Offline
#4 2015-07-14 10:27:56
- Dotevo
- Moderator
- From: Kobiernice/Wrocław Poland
- Registered: 2009-02-15
- Posts: 1,744
- Website
Re: Mapa 3D z mapy 2D
Wydaje mi się, że problem polega na tym, że nie chodzi tylko o rozciągnięcie/skurczenie względem osi X, ale również względem osi Y. Zrób sobie zdjęcie wmiarę płaskiego terenu zobaczysz wtedy, że pierwsze 100 px w osi Y zawiera np. 1m odległości, a kolejne 100px już kilka metrów. Poszukaj pod hasłem "perspective projection matrix". W przypadku podejścia typowo geometrycznego macierz perspektywy nie jest skomplikowana, niestety nie wiem jak będzie to wyglądać gdy się używa jakiejś projekcji geograficznej.
Offline
#5 2015-07-14 10:32:41
- balrog-kun
- Member
- From: Warsaw, Poland
- Registered: 2008-08-10
- Posts: 1,365
- Website
Re: Mapa 3D z mapy 2D
Przede wszystkim jesli to ma byc rzut z perspektywa to musisz ustalic gdzie jest kamera, niech bedzie w punkcie E. Kiedy chcesz przeksztalcic punkt to musisz sprawdzic czy jest przed kamera (np. Ay > Ey). Kamera musi miec nie-zerowa wysokosc jesli ma cokolwiek widziec... pz to odleglosc danego punktu od kamery w linii prostej, px to x punktu odjac x kamery, py to wysokosc punktu (0) odjac wysokosc kamery. Wtedy policz jeszcze raz A', B', C' i D' i powinno byc okej.
Moze lepiej nie kombinowac tylko zrobic to w OpenGL, nawet w aplikacji webowej mozesz go uzyc. Mozna nawet przkesztalcic zwykle kafelki OSM (czyli po rasteryzacji wedlug tego co pisze RicoElectrico) za pomoca shaderow bez dotykania 3D.
Last edited by balrog-kun (2015-07-14 10:37:05)
Offline
#6 2015-07-14 12:20:37
- Cetusek
- Member
- From: Łódź
- Registered: 2014-06-10
- Posts: 135
Re: Mapa 3D z mapy 2D
Zatem niech punkt E = (0, -8, 2) będzie kamerą. Załóżmy jeszcze, że punkt F będzie środkiem odcinka AB, czyli F = (0, -5), punkt G rzutem punktu E na płaszczyznę XY, czyli G = (0, -8). Stosując Twój przepis mamy:
- warunek Ay > Ey jest spełniony ponieważ -5 > -8.
- "pz to odleglosc danego punktu od kamery w linii prostej", czyli pz = sqrt((EF*EF + GF*GF) + EG*EG) = sqrt(17) = 4,123.
- "px to x punktu odjac x kamery", czyli -2 - 0 = -2.
- "py to wysokosc punktu (0) odjac wysokosc kamery", czyli 0 - 2 = -2.
Zatem otrzymujemy, że
sx = -2 / 4,123 = -0,485
sy = -2 / 4,123 = -0,485.
Czyli A' = (-0,485, -0,485). Z symetrii punkt B' = (0,485, -0,485). Długość A'B' = 0,97. Długość AB = 4.
Licząc analogicznie otrzymamy, że D' = (-0,15, -0,15) i C' = (-0,15, -0,15). Długość C'D' = 0,3. Długość CD = 4.
Zatem A'B' jest trzy razy dłuższy niż C'D' i A'B' "podjechał" do góry, a C'D "zjechał" na dół.
Muszę poeksperymentować z ustawieniem kamery. Zobaczymy co uzyskam.
Proszę o sprawdzenie, czy dobrze zrozumieałem formuły, które podałeś.
A propos OpenGL. Nie chcę stosować armaty na muchę. Policzenie powyższego, jak widzę, wymaga kilku prostych działań.
Offline
#7 2015-07-14 20:05:28
- Cetusek
- Member
- From: Łódź
- Registered: 2014-06-10
- Posts: 135
Re: Mapa 3D z mapy 2D
Efekt moich prób jest następujący. Działam na komputerze z rozdzielczością 1920 x 1080. Dane wejściowe do przeliczeń stanowią granice Polski, co w obrazie 2D wygląda następująco:
Wspórzędne każdego z wyświetlonych punktów przetwarzam za pomocą metody transform:
import java.awt.geom.Point2D;
public class Transformator {
double cameraX;
double cameraY;
double cameraZ;
public Transformator(int screenWidth, int screenHeight) {
cameraX = screenWidth / 2;
cameraY = screenHeight + 800;
cameraZ = 60;
}
private double getCameraToPointDistance(Point2D.Double point) {
double distance;
distance = (point.x - cameraX) * (point.x - cameraX)
+ (point.y - cameraY) * (point.y - cameraY);
distance = Math.sqrt(distance + cameraZ * cameraZ);
return distance;
}
public Point2D.Double transform(Point2D.Double screenPoint) {
double pz = getCameraToPointDistance(screenPoint);
double px = screenPoint.x - cameraX;
double py = cameraZ;
return new Point2D.Double(px / pz, py / pz);
}
}i otrzymuję w zasadzie kropkę ponieważ wszystkie punkty wyznaczają się jako (0, 0). Zacząłem wiec wprowadzać współczyniki w ostatniej linii wspomnianej metody. Przy takiej postaci tej linii:
return new Point2D.Double(cameraX + (2000 * px / pz), 10000 * py / pz);otrzymuję wynik:
Niby coś się spłaszczyło i rozciągnęło, ale nie wydaje mi się że to tak powinno wyglądac.
Help me!
Offline
#8 2015-07-15 00:11:16
- balrog-kun
- Member
- From: Warsaw, Poland
- Registered: 2008-08-10
- Posts: 1,365
- Website
Re: Mapa 3D z mapy 2D
Proszę o sprawdzenie, czy dobrze zrozumieałem formuły, które podałeś.
Chyba tak, tylko wynikowe wspolrzedne beda w ukladzie gdzie x=-1 to powiedzmy lewy brzeg ekranu, x=1 to prawy brzeg, y=-1 to dol, a y=1 to gora. Wiec trzeba to pomnozyc przez rozdzielczosc jaka bys chcial dostac, odpowiednio przesunac, odwrocic.
i otrzymuję w zasadzie kropkę ponieważ wszystkie punkty wyznaczają się jako (0, 0).
Wszystko zalezy w jakim zakresie masz dane wejsciowe. Mozna zrobic to tak jak masz w kodzie ale osobiscie nie mieszalbym rozmiaru ekranu do ustalenia pozycji kamery, a przeliczenie na wpolrzedne ekranowe zostawilbym na pozniej, gdzies tam, gdzie rysujesz linie. Kamere ustawilbym tak, zeby bylo widac wszystkie dane. Jesli x i y punktow sa w zakresie -10, 10 to ustaw kamere np. w (0, -15, 3).
Niby coś się spłaszczyło i rozciągnęło, ale nie wydaje mi się że to tak powinno wyglądac.
Dla mnie ok... jesli nie chcesz zeby horyzont byl w polowie ekranu to przyjmij np. y=0 za gore ekranu.
Offline
#9 2015-07-28 20:40:17
- Cetusek
- Member
- From: Łódź
- Registered: 2014-06-10
- Posts: 135
Re: Mapa 3D z mapy 2D
Moze lepiej nie kombinowac tylko zrobic to w OpenGL, nawet w aplikacji webowej mozesz go uzyc. Mozna nawet przkesztalcic zwykle kafelki OSM (czyli po rasteryzacji wedlug tego co pisze RicoElectrico) za pomoca shaderow bez dotykania 3D.
Żeby rozpoznać jeszcze ten temat. Możesz podać szczgóły w jaki sposób przekształcić kafelek za pomocą OpenGL?
Offline
#10 2015-07-30 10:16:58
- balrog-kun
- Member
- From: Warsaw, Poland
- Registered: 2008-08-10
- Posts: 1,365
- Website
Re: Mapa 3D z mapy 2D
Wsytarczy zaladowac widok mapy jako teksture dla odpowieniej wielkosc plaszczyzny i zrobic takie samo przeksztalcenie jak juz masz w jej pixel shaderze. Zamiast tego przeksztalcenia mozna tez manipulowac pozycja kamery i dostac taki sam wynik.
Offline
#11 2015-08-02 16:26:31
- Cetusek
- Member
- From: Łódź
- Registered: 2014-06-10
- Posts: 135
Re: Mapa 3D z mapy 2D
Może jakiś przykładzik z OpenGl?
IMHO kilogram przykładu jest lepszy niż tona teorii.
Offline
Pages: 1