Thread View: pl.comp.grafika.grafika3d
1 messages
1 total messages
Started by Wojciech "Spook" Sura
Tue, 05 Aug 2008 17:17
[OpenGL, 3D] przekształcenie 2D do 3D
Author: Wojciech "Spook" Sura
Date: Tue, 05 Aug 2008 17:17
Date: Tue, 05 Aug 2008 17:17
102 lines
6517 bytes
6517 bytes
Witam! Crosspost na pl.comp.grafika.grafika3d; pl.sci.matematyka i pl.comp.lang.delphi. Followup-to na pl.comp.lang.delphi Piszę program wykonujący pewne wizualizacje 3D. Wyświetla on na scenie widgety umożliwiające przekształcanie jej zawartości, a są one w postaci (mniej więcej) scrollbara (paska przewijania). Ogólny problem polega na tym, że użytkownik przeciąga suwak scrollbara na płaskim, dwuwymiarowym ekranie, ale przesunięcie następuje w przestrzeni trójwymiarowej, a ja nie umiem znaleźć sprytnego sposobu na wykonanie jakiejś transformacji 2D->3D by powiązać kliknięte przez usera miejsce z pewnym miejscem na trójwymiarowej scenie. Teraz bardziej formalnie. Na scenie dany jest pewien odcinek, wyznaczony - powiedzmy - punktem zaczepienia P3D i pewnym wektorem V3D. Jest on wizualizowany na odcinek na płaskim ekranie, który możemy opisać punktem zaczepienia P2D i pewnym wektorem V2D. Przekształcenie [punktu] w tą stronę realizowane jest pewnym iloczynem macierzy: I * P * R * R * T (x), gdzie: I - macierz jednostkowa (4x4 !) P - macierz perspektywy, która jest opisana na stronie: http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/frustum.html [1] R - pewne macierze rotacji T - pewna macierz translacji. Poszczególne macierze nie grają chyba specjalnej roli - dosyć, że mogę dobrać się bez problemów do każdej z osobna, mam kąty rotacji, mam wektor translacji, mam współrzędne perspektywy i tak dalej. Mam też wynikową macierz. Wynik (x1, y1) nałożenia na macierz wektora (x, y, z, 1) (pozostałe współrzędne są porzucane) jest liniowo skalowany na współrzędne ekranowe (wynikowe współrzędne są w zakresie od -1 do 1) i tak wyświetlany. Problem polega na tym, że mam dany pewien punkt (x1, y1) ekranowy (dla uproszczenia przyjmijmy, że zawsze należy on do "ekranowego" odcinka) i chciałbym przekształcić go teraz na punkt trójwymiarowy (x, y, z) leżący na trójwymiarowym odcinku w odpowiednim miejscu. Teoretycznie mógłbym próbować walczyć z macierzą odwrotną, ale nie mam niestety wartości z1 (będącej, de facto, odległością punktu na scenie od obserwatora), więc nie jestem w stanie wykonać przekształcenia odwrotnego. Myślałem o liniowym przenoszeniu pozycji myszy na odcinku z 2D do 3D, ale niestety nie jest to rozwiązanie najlepsze. Wyobraźmy sobie bowiem odcinek, którego lewa strona jest gdzieś daleko, prawa zaś blisko. Jeśli będę przesuwał liniowo mysz z lewej na prawą stronę, mysz będzie przesuwała się tak: a b c d e f -------------------------- Ale "marker" na trójwymiarowym odcinku zwizualizowany w dwóch wymiarach, a z uwagi na perspektywę, mniej więcej tak: ab c d e f -------------------------- Jak widać, funkcja f(x), gdzie x jest pozycją myszy na ekranowym odcinku, zaś jej wynikiem jest taka pozycja na trójwymiarowym odcinku, która po wizualizacji pokrywa się z pozycją myszy, nie jest liniowa. Niestety jednak nie mam pojęcia, jaka jest to funkcja - nawet nie mam żadnych pomysłów, intuicji. Fragment kwadratowej? Wykładniczej? Ale skąd się wzięła i jak obliczyć jej współczynniki? Pomysł niestety upadł. Pojawił się inny - aby próbować obliczyć oś widoku odpowiadającą pozycji myszy (przeciwobraz miejsca w którym znajduje się mysz - jak wiadomo, będzie to prosta) i stamtąd próbować powiązać ją z odcinkiem, ale właściwie nie mam pomysłu co dalej. Kombinowałem z próbą obliczenia jakiejś płaszczyzny w którą wbije się owa prosta, a następnie rzutowanie miejsca trafienia na docelowy odcinek, ale i tu było sporo problemów. Właściwie pomysły już mi się skończyły. Czy ktoś wie może jak rozwiązać ten problem? Pozdrawiam -- Spook. [1] Obszar widoku opisywany jest następująco: * Obserwator jest w punkcie (0,0,0) * Obszar, który jest renderowany ma postać ściętego ostrosłupa o podstawie prostokąta; * Jego mniejsza podstawa (ta ścięta) jest opisana wartościami top, left, bottom i right, a znajduje się w odległości [z]near od obserwatora * Większa podstawa jest odległa o [z]far od obserwatora (wraz z wierzchołkiem w (0,0,0) wystarczy to do jednoznacznego wyznaczenia ostrosłupa widoku) * Ekranem jest mniejsza podstawa. -- ! ._______. Warning: Lucida Console sig! //) ! ! || spk || www.spook.freshsite.pl / _ """*! ! ||_____|| spook at op.pl / ' | ""! ! | ___ | tlen: spoko_ws gg:1290136 /. __/"\ '! ! |_|[]_|_| May the SOURCE be with you! \/) \ !
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads