1

czy ktos poradzilby co zmienic w ponizszych wzorach, zeby punkt stawial sie poprawnie

obrot wokol osi x:

z1=cos(kat)*y-sin(kat)*z;
y1=sin(kat)*y+cos(kat)*z;
x1=x;

k=wspolczynik powiekszenia;

plot (x1/z1*k, y1/z1*k);

2

http://3.bp.blogspot.com/_GXn7fIpTaPs/SBdbbchghZI/AAAAAAAAAp0/FPtpQiP3SCA/s400/rotation+matrix.JPG

na pc uzywalo sie notacji maciezowej chocby ze wzgledow praktycznych - po wymnozeniu 3 rotacji skladowych dostajesz wynik ktory ma 9 mnozen, a mnozac osobno masz ich 12

rotajce masz ok, perspektywe...
x1*k/z1, y1*k/z1, pod warunkiem ze z jest skierowana w glab ekranu

przechodze na tumiwisizm

3 Ostatnio edytowany przez gorgh (2009-05-26 21:35:40)

nie wiem co jest grane,niby stosuje te wzory a punkty sie dziwnie rozjezdzaja :( zarzucam kod w C,moze ktos
sie dopatrzy bledu:

        static double xt[200]={0};
        static double yt[200]={0};
        static double zt[200]={0};
        static int index=0;

void kolo(int y,int z,int color,bool a){
     for (double kat=0; kat<10;kat+=0.3)
     {
           xx=40;     
           zz=(cos(kat)*y-sin(kat)*z);
           yy=(sin(kat)*y+cos(kat)*z);
           if(a){xt[index]=xx;yt[index]=yy;zt[index]=zz;index++;}
         };}
         
int main()
{
     double stx=320,sty=240;
     double k=3;
     double y=40,z=-40;
     kolo(y,z,0x00ff00,true);

     for (int t=0;t<index;t++)

     plot(xt[t]/zt[t]*k+stx,yt[t]/zt[t]*k+sty,0x0fffff);

     return 0;
     };

Jakby ktos pytal to jest kod atari przelozony na kod pc.

4

pracuj caly czas na floatach, ostatnie rzutowanie zrob na integer z zakresu, jesli bedzie ok to masz problem z precyzja

przechodze na tumiwisizm

5

1) Funkcje sin(), cos() przyjmują argumenty w radianach. Przyrosty kątowe 0.3 mogą być zbyt duże i dawać wrażenie chaotyczności.
2) Wsp. k powinien być pochodną rozmiarów okna obrazu oraz perspektywy. Tymczasowo powinieneś go zwiększyć.
3) Będą działy się różne paskudne rzeczy, jeżeli nie wykluczysz dzielenia przez 0, które jak najbardziej jest możliwe w tej sytuacji. Proponuję dodać odpowiednio duży offset do zz.

6 Ostatnio edytowany przez gorgh (2009-05-26 23:29:12)

Sprobowalem i z floatami i z offsetem do zz i nadal to samo:
(obrot kola wokol osi y)
http://img35.imageshack.us/img35/7440/wekt.png

7

gorgh napisał/a:

obrot wokol osi x:

z1=cos(kat)*y-sin(kat)*z;
y1=sin(kat)*y+cos(kat)*z;
x1=x;

Powinno być:

 z1=cos(kat)*z-sin(kat)*y;
 y1=sin(kat)*z+cos(kat)*y;
x1=x;

ewentualnie odwrotnie znaki przy sinach - będzie obrót w drugą stronę.

Najpierw mnóż przez k, a potem dziel przez zt[t] - wtedy xt[t] i zt[t] będą mogły być całkowite.
zt[t] powinny być dodatnie - tj. punkty są za ekranem, a nie przed. Możesz dodać przesunięcie po wykonaniu obrotu.

https://www.youtube.com/watch?v=jofNR_WkoCE

8 Ostatnio edytowany przez Marek Konopka (2009-05-27 10:31:06)

gorgh napisał/a:

Sprobowalem i z floatami i z offsetem do zz i nadal to samo:
(obrot kola wokol osi y)
http://img35.imageshack.us/img35/7440/wekt.png

Jeżeli pod pojęciem rozjeżdzania masz na myśli rosnące przerwy między punktami wzdłuż osi X, to wszystko jest w porządku. To skutek zaaplikowania perspektywy.

Ustaw offset z'ta na 150, a k na 554. Perspektywa będzie mniej "agresywna".

9

http://codebase64.org/doku.php?id=base:3d_rotation

*- TeBe/Madteam
3x Atari 130XE, SDX, CPU 65816, 2x VBXE, 2x IDE Plus rev. C

10

A czy te przerwy, to nie jest problem, że oś x i y nie są w tej samej fizycznej skali ?

11 Ostatnio edytowany przez gorgh (2009-05-29 12:42:25)

tego mi trzeba bylo,teraz punkt stawia sie poprawnie.Do perspektywy uzylem wzorow:
Focal=ogniskowa;
rzut=Focal/(z+Focal);
x1=x*rzut+srodek ekranuW;
y1=y*rzut+srodek ekranuH;

Swoja droga to ciekawe,ze jest kilka rodzajow wzorow na obroty i kilka na rzut perspektywiczny.
Jeszcze odnosnie obrotow:zastanawiam sie jak zrobic,zeby punkty obracaly sie nie wokol srodka ukladu wspolrzednych ale wokol dowolnej osi w przestrzeni,dysponuje ktos moze stosownym linkiem odnosnie tego problemu?

12

potrzebujesz cos co sie nazywa lokalny uklad wspolrzednych
czyli rotacja obiektu wedle lokalnego ukladu wspolrzednych, translacja do jego polozenia w globalnym ukladzie wspolrzednych i znow rotacja globalnego ukladu wspolrzednych
krocej - brakuje ci kamery ;)

przechodze na tumiwisizm

13 Ostatnio edytowany przez gorgh (2009-06-07 14:28:49)

to ja jeszcze w sprawie kamery...
do przeksztalcen wspolrzednych swiata do wspolrzednych kamery sprobowalem zastosowac ta macierz(na samym dole stronki) ale zamiast np. przesuniecia kamery wzdloz osi x program obraca mi punkty wokol poczatku ukladu wspolrzednych swiata, tak jakby tam stala kamera. Moze znalazby sie ktos obeznany z tematem i udzielil rady jak krok po kroku stworzyc tak`ową kamere?

14

no ale na dole masz iloczyn skalarny tego gdzie sie znajduje kamera (punkt s), wektorki p g k to uklad ortonormalny kamery (uklad loklany)
wiec jak ty masz tam same 1 to co ma sie stac?

jesli chcesz moge wyslac engine ale w asmie x86

przechodze na tumiwisizm

15

niby wszystko podstawiam dobrze pod wzor...najpierw licze sobie wektory,co by byly prostopadle do siebie,normalizuje,potem okreslam przesuniecie kamery,podstawiam to wszystko do macierzy i nic.
za engine dzieki,ale nie rozczytam.

16

odświeżam temat: po dłuższym czasie wróciłem do tematu, kamera działa, obraca się , problem tylko z kolejnością obrotów, jak najpierw obracam wokół osi Z kamery to osie X i Y dziwnie się zachowują (obracają się względem osi X i Y świata) gdy robie odwrotnie to obrót Z zamiast kręcić się wokół punktu w środku widoku kamery obraca się względem osi Z świata.
Czy któryś z szanownych kolegów programistów wie czym może być to spowodowane?
pozdrawiam,
Gorgh

17

Gimbal lock?

18

to pomoże?

19

Przesuń najpierw świat, tak, aby kamera była w (0, 0, 0).

https://www.youtube.com/watch?v=jofNR_WkoCE

20

kamera jest w 0,0,0 bo najpierw obracam wektory kamery a potem podstawiam je do macierzy kamery (obrotu i translacji) przez którą mnożę wszystkie wierzchołki. Albo coś pokićkałem, albo coś jest nie tak z tymi obrotami i trza użyć czegoś bardziej skomplikowanego, w razie czego dołączam  filmik pokazujący co jest nie tak (WMPlayer),
pozdrawiam z pola bitwy,
gorgh

Post's attachments

java.wmv 265.79 kb, liczba pobrań: 15 (od 2011-07-05) 

Tylko zalogowani mogą pobierać załączniki.

21

Może spróbuj skrótowo opisać algorytm jakiego faktycznie używasz: Opisz jak przeliczasz każdy z wejściowych puntków (x,y,z), aby otrzymać końcową pozycję na ekranie (przez co mnożysz, jakim wzorem, punkt po punkcie) bo rozłożenie punktów jest tak nierównomierne, że mi to wygląda na błąd w zastosowanej formule.

22 Ostatnio edytowany przez gorgh (2011-07-05 13:34:34)

laoo/ng napisał/a:

Może spróbuj skrótowo opisać algorytm jakiego faktycznie używasz: Opisz jak przeliczasz każdy z wejściowych puntków (x,y,z), aby otrzymać końcową pozycję na ekranie (przez co mnożysz, jakim wzorem, punkt po punkcie) bo rozłożenie punktów jest tak nierównomierne, że mi to wygląda na błąd w zastosowanej formule.

Załączam kod w Javie z komentarzami, który wysłałem do jednego z koderów z którym również koresponduje w tej sprawie (mam nadzieje, że się nie obrazi) :

// początkowe wartości wektorów kamery- up, front, right, wektory
jednostkowe
//(camz,camx,camy to obiekty klasy wektor z polem float x[4]);
                 camz.x[0]=0;camz.x[1]=0;camz.x[2]=1.0f;camz.x[3]=1;
                 camx.x[0]=1.0f;camx.x[1]=0;camx.x[2]=0;camx.x[3]=1;
                 camy.x[0]=0;camy.x[1]=1.0f;camy.x[2]=0;camy.x[3]=1;


 // obroty na poszczegolnych osiach 3 wektorow kamery ,wartosci obrotow
 wziete z wejscia
// oś y obraca wokoł osi Z kamery, jakoś tak mi się poprzestawiało, w
kazdym badz razie
//najpierw obracam osie x i y a na koncu z- wynikiem jest bledne obracanie
wokol osi Z
// gdy obrot jest najpierw wokol osi Z blad dotyczy pozostalych dwóch osi

             obrocx(camz,osx*3.14f/180);
             obrocx(camx,osx*3.14f/180);               
            obrocx(camy,osx*3.14f/180);
 
             obrocz(camz,osz*3.14f/180);
             obrocz(camx,osz*3.14f/180);               
               obrocz(camy,osz*3.14f/180); 

            obrocy(camz,osy*3.14f/180);
            obrocy(camx,osy*3.14f/180);               
              obrocy(camy,osy*3.14f/180);   

// przygotowanie macierzy (wstawienie 1.0 w kilka pól)
                mtxbase(mbase);
//normalizowanie wektorów (na wszelki wypadek)

                wersor(camz);
                wersor(camx);
                wersor(camy);

// ustalanie pozycji kamery

                 campoz.x[0]=pozx;campoz.x[1]=pozy;campoz.x[2]=pozz;campoz.x[3]=1;



//przygotowanie macierzy projekcji-wszystkie punkty świata mnożone są
przez tą macierz
//campoz służy do translacji, pozostałe wektory, jako normalne służą
do ustalenia obrotu
// poszczególne pola macierzy :plik JPG w załączniku


                 makeview(mbase,camx,camy,camz,campoz);

[edit] W załączonej macierzy brakuje translacji (pola 3,7,11)
[edit 2] punkty są rzucone na chybił trafił, to raczej nie wiąże się z samym problemem

Post's attachments

macierz projekcji.jpg 63.56 kb, nikt jeszcze nie pobierał tego pliku. 

Tylko zalogowani mogą pobierać załączniki.

23 Ostatnio edytowany przez laoo/ng (2011-07-06 07:45:13)

Twoje podejście jest odrobinę "niekanoniczne". A jak robi się coś niestandardowo, to łatwiej o błędy. Ja stosuję się do metody używanej w direct3d i jedyne problemy jakie miewam, to czy transponować ostateczną macierz, czy nie (bo zwykle nie pamiętam jak ostatecznie ma być).
Jedyne co mogę zaproponować, to:
1. Porzuć tę metodę, którą teraz używasz, bo taniej jest napisać to dobrze od nowa, niż szukać błędu.
2. Przeczytaj w tutorialu z dokumentacji do direct3d 9: Transforms oraz podstrony World, View oraz Projection. Dowiedz się też, co to jest Viewing Frustum.
3. Znajdź / napisz klasę macierzy oraz funkcje tworzenia osobnych macierzy do rotacji w każdej z osi, translacji, skalowania i perspektywy oraz metodę mnożenia macierzy przez siebie i mnożenia wektora przez macierz tak, jak jest to w tym tutorialu.
4. Twórz macierze, mnóż i voilà (ewentualnie przetransponuj końcową macierz jak nie wyjdzie ;)).

24

Ciężko będzie pomóc, bo pokazałeś tylko wycinek kodu. Pozostaje zgadywać: np. czy odrzucasz punkty niewidoczne w kamerze?

https://www.youtube.com/watch?v=jofNR_WkoCE

25

@Fox:załączam całość źródeł, nie jest tego wiele. Punktów niewidocznych nie stawiam.
@Laoo: dzięki za rady, chyba najrozsądniej będzie tak zrobić.

Post's attachments

src.rar 5.03 kb, liczba pobrań: 4 (od 2011-07-06) 

Tylko zalogowani mogą pobierać załączniki.