Widok perspektywiczny w grafice 3D

Odpowiedz Nowy wątek
2011-01-03 22:01
Poszukiwacz prawdy
0

Mam problem z rzutem perspektywicznym w grafice 3D.
Mam jakąs bryłę w reprezentacji brzegowej, zbudowaną z trójkątów.
Na razie robię ten widok bez żadnego przycinania niewidocznych rzeczy :P

Mam dwa punkty na ekranie: kamerę i środek obrazu. Kamera - czyli skąd patrzymy, środek obrazu - czyli na co patrzymy.

Na początek robię przekształcenia, aby środek obrazu był w punkcie (0,0,0), a kamera na osi Z po ujemnej stronie.
Sprawdzam i po tych przekształceniach kamera ma faktycznie współrzędne (0,0,z) gdzie z<0.

Mam tę macierz przekształceń i teraz kazdy wierzchołek bryły mnożę przez tą macierz.
Następnie rzutuję perspektywicznie tą bryłę na grafikę 2D.
Czyli:

x *= (Math.abs(kam.z) / (Math.abs(kam.z)+bryla.wierzcholki[i].z));
y *= (Math.abs(kam.z) / (Math.abs(kam.z)+bryla.wierzcholki[i].z));

I rysuję bryłę, gdzie jej wierzchołki mają te współrzędne x,y.

Czy nie powinno być tak, że bryła jest teraz w całości widoczna, tzn. tak jakbysmy patrzyli z kamery?
Bo moja bryła jest w lewym górnym rogu, ponad połowa jest zakryta za panelem. I w dodatku jest strasznie mała.

A może trzeba potem jeszcze zrobić jakieś przekształcenia?

Z góry dziękuję za pomoc.

Pozostało 580 znaków

2011-01-03 23:19
0

Jakiego typu są zmienne?
double, czy int?
Jeżeli int, to pewnie problemem jest np. to, że dzielenie jest całkowitoliczbowe i Math.abs(kam.z) / (Math.abs(kam.z)+bryla.wierzcholki[i].z) dla bryla.wierzcholki[i].z > 0 jest zawsze równe 0.
Dodatkowo jeżeli Math.abs(kam.z) == -bryla.wierzcholki[i].z, to dzielisz przez 0


Registered Linux user #456405 | SCJP 6 | SCWCD 5 | SCBCD 5

Pozostało 580 znaków

2011-01-04 21:21
Poszukiwacz prawdy
0

Wszystkie zmienne są double.
Dopiero jak mam rysować to rzutuje współrzędne na int.

Zauwazyłem, że program mi się krzaczy, gdy kamera jest w środku bryły. Tzn. wyświetla coś, ale nie wiadomo co ;P
Da się na to jakoś zaradzić? :/

Pozostało 580 znaków

2011-01-05 00:10
0

To ja, Poszukiwacz prawdy :P Założyłem w końcu konto.

Perspektywę robię tak:
obr - współrzędne środka obrazu (czyli na co patrzymy)
kam - współrzędne kamery (czyli skąd patrzymy)

      Macierz mac = new Macierz();
//przesuwam srodek obrazu do punktu 0,0,0, żeby patrzeć się na poczatek układu współrzędnych
//kamerę przesuwam o tyle samo
        mac.translacja(-obr.x, -obr.y, -obr.z);
        obr = mac.pomnozPrzezPunkt(obr);
        kam = mac.pomnozPrzezPunkt(kam);

        //obracam kamerę wokół osi OY aby wyzerować x. z staje się ujemne.
        Macierz mac2 = new Macierz();
        mac2.obrotOY(Math.PI/2 + Math.atan2(kam.z, kam.x));
        kam = mac2.pomnozPrzezPunkt(kam);

//obracam kamerę wokół osi X aby wyzerować y. z jest dalej ujemne
        Macierz mac3 = new Macierz();
        mac3.obrotOX(Math.atan2(kam.y, kam.z)-Math.PI);
        kam = mac3.pomnozPrzezPunkt(kam);

        //składam jedna macierz przekształceń
        m = new Macierz();
        m.pomnozPrzezMacierz(mac.mac);
        m.pomnozPrzezMacierz(mac2.mac);
        m.pomnozPrzezMacierz(mac3.mac);

        //wyrównuję kierunek pionowy, ale nie wiem czy to jest potrzebne
                Punkt3D Pv = m.pomnozPrzezPunkt(new Punkt3D(0, 1, 0));
        Macierz mac4 = new Macierz();
        mac4.obrotOZ(Math.atan2(Pv.x, Pv.y));

//dokładam do macierzy przekształceń
        m.pomnozPrzezMacierz(mac4.mac);

//pobieram dane o wierzchołkach bryły i tworzę nowa bryłe, której zapiszę już te współrzędne pozmieniane do perspektywicznego
        Punkt3D[] wierzcholki = okno.bryla.wierzcholki;
        bryla = new Bryla();
        bryla.wierzcholki = new Punkt3D[wierzcholki.length];

        //przekształcam każdy wierzchołek bryły przez macierz przekształceń, żeby była ta bryła w takim samym umiejscowieniu w stosunku do kamery jak na początku
        for(int i=0; i<wierzcholki.length; i++) {
            bryla.wierzcholki[i] = m.pomnozPrzezPunkt(wierzcholki[i]);
                        //rzutuję perspektywicznie x i y. Potem jak rysuję na panelu to rysuję linie pomiędzy tymi punktami (x,y), aby wyświetlić bryłę
            bryla.wierzcholki[i].x *= (Math.abs(kam.z) / (Math.abs(kam.z)+bryla.wierzcholki[i].z));
            bryla.wierzcholki[i].y *= (Math.abs(kam.z) / (Math.abs(kam.z)+bryla.wierzcholki[i].z));
        }

Co jest źle? :/
Niby działa, bo coś wyświetla. Przy kuli nawet wygląda ona jak kula (zazwyczaj), ale już np. najprostszy sześcian wyglada bardziej jak cos ostrosłupopodobnego...

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0