You are not logged in.

Announcement

*** NOTICE: forum.openstreetmap.org is being retired. Please request a category for your community in the new ones as soon as possible using this process, which will allow you to propose your community moderators.
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.***

#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ą:

map_2d.png?dl=0&raw=1

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

map_3d.png?dl=0&raw=1

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źć. sad 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 wink
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 sad

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:

Polska 2D

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:

Polska 3D

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

Cetusek wrote:

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.

Cetusek wrote:

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).

Polska 3D

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

balrog-kun wrote:

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

Board footer

Powered by FluxBB