Przekształcenia 3d

0

Mam 3 zmienne przechowujące dane o obrocie statku(wokół każdej osi).
Z pliku wczytuje współrzędne środka statku(i obrotu) oraz współrzędne względem środka statku.
Na 4 sposoby próbowałem zrobić obracanie statku i nigdy nie działało tak jak powinno.
Czy ktoś może pomóc? Pisze grę w c w opengl z sfml.
Proszę, nie odsyłajcie mnie na inne strony bo ja nie ogarniam jeszcze do końca tego(nie umiem z tego skorzystać).

0

Dobra to teraz mam pytanie...

mam wzorki:

 
xx=cos((kat_z+kat(x,y))*M_PI/180)*sqrt(x*x+y*y);
yy=sin((kat_z+kat(x,y))*M_PI/180)*sqrt(x*x+y*y);
y=yy;
x=xx;

xx=cos((kat_y+kat(x,z))*M_PI/180)*sqrt(x*x+z*z);
zz=sin((kat_y+kat(x,z))*M_PI/180)*sqrt(x*x+z*z);
z=zz;
x=xx;

zz=cos((kat_x+kat(z,y))*M_PI/180)*sqrt(z*z+y*y);
yy=sin((kat_x+kat(z,y))*M_PI/180)*sqrt(z*z+y*y);
y=yy;
z=zz;

no i to działa normalnie kiedy stosuje tylko parę wzorów(2 wzory) jak mam więcej to normalnie działa tylko w tedy kiedy obracam wokół osi którą podałem jako ostatnią... czemu? coś zrobiłem źle? Jak przestawiam kolejnością wzory to inna oś działa...

0

Do każdej ze zmiennych zapisujesz 2 razy różne wyniki. Raz jeden, a potem nadpisujesz drugim.

0

w teorii wynik drugiej zmiany xx powinien wynosić x więc nie ogarniam błędu...

0

hmmmnnn teraz moge obracać wokół jednej osi ale wzory mam wpisane wszystkie(jak zwiększam 2 kąty to zaczyna świrować)

0

Proszę oto mój okrojony kod gry:


double kat(double xx,double yy)
{
    if (xx>0 && yy>0)
    {
        return sin(yy/(xx*xx+yy*yy));
    }
    else if (xx<0 && yy>0)
    {
        return 90+sin(xx/(xx*xx+yy*yy));
    }
    else if (xx<0 && yy<0)
    {
        return 180+sin(yy/(xx*xx+yy*yy));
    }
    else if (xx>0 && yy<0)
    {
        return 270+sin(xx/(xx*xx+yy*yy));
    }
    else if (xx==yy)
    {
        if (yy==0 && xx>0)
        {
            return 0;
        }
        else if (xx==0 && yy>0)
        {
            return 90;
        }
        else if (yy==0 && xx<0)
        {
            return 180;
        }
        else if (xx==0 && yy<0)
        {
            return 270;
        }
    }
}
double x,y,z;
void obliczenia_3d(int kat_x,int kat_y, int kat_z)
{
    double xx,yy,zz;


    zz=cos((kat_x+kat(z,y)+45)*M_PI/180)*sqrt(z*z+y*y);
    yy=sin((kat_x+kat(z,y)+45)*M_PI/180)*sqrt(z*z+y*y);
    y=yy;
    z=zz;

    xx=cos((kat_y+kat(x,z)+45)*M_PI/180)*sqrt(x*x+z*z);
    zz=sin((kat_y+kat(x,z)+45)*M_PI/180)*sqrt(x*x+z*z);
    z=zz;
    x=xx;

    xx=cos((kat_z+kat(x,y)+45)*M_PI/180)*sqrt(x*x+y*y);
    yy=sin((kat_z+kat(x,y)+45)*M_PI/180)*sqrt(x*x+y*y);
    y=yy;
    x=xx;
}

typedef struct punkt
{
    double x,y,z;
    int last;
}punkt;
typedef struct obiekt
{
    double r_x,r_y,r_z,x,y,z;
    struct punkt wektor[100];
}obiekt;
int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int nCmdShow)
{
    WNDCLASSEX wcex;
    HWND hwnd;
    HDC hDC;
    HGLRC hRC;
    MSG msg;
    BOOL bQuit = FALSE;
    float theta = 0.0f;

    /* register window class */
    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style = CS_OWNDC;
    wcex.lpfnWndProc = WindowProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
    wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    wcex.lpszMenuName = NULL;
    wcex.lpszClassName = "GLSample";
    wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);;


    if (!RegisterClassEx(&wcex))
        return 0;

    /* create main window */
    hwnd = CreateWindowEx(0,
                          "GLSample",
                          "OpenGL Sample",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT,
                          CW_USEDEFAULT,
                          800,
                          800,
                          NULL,
                          NULL,
                          hInstance,
                          NULL);

    ShowWindow(hwnd, nCmdShow);

    /* enable OpenGL for the window */
    EnableOpenGL(hwnd, &hDC, &hRC);

    /* program main loop */
    int i=0,a=0,c,d,e;
    struct obiekt statek[2];
    FILE *plik;
    char *mode="r";
    plik=fopen("statek.model", mode);
    if (plik == NULL) {
        fprintf(stderr, "Can't open input file in.list!\n");
        exit(1);
    }
    if (fscanf(plik,"%i %i %i",&c,&d,&e) != EOF)
    {
        statek[0].x=c;
        statek[0].y=d;
        statek[0].z=e;
        while (fscanf(plik,"%i %i %i",&c,&d,&e) != EOF)
        {
            statek[0].wektor[i].last=0;
            statek[0].wektor[i].x=c;
            statek[0].wektor[i].y=d;
            statek[0].wektor[i].z=e;
            i=i+1;
        }
    }
    statek[0].wektor[i].last=1;
    fclose(plik);
    statek[0].r_x=0;
    statek[0].r_y=0;
    statek[0].r_z=0;
    while (!bQuit)
    {
        /* check for messages */
        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            /* handle or dispatch messages */
            if (msg.message == WM_QUIT)
            {
                bQuit = TRUE;
            }
            else
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }
        else
        {
            /* OpenGL animation code goes here */

            glClearColor(0.0f, 0.5f, 0.5f, 0.0f);
            glClear(GL_COLOR_BUFFER_BIT);
            i=3;
            while(statek[0].wektor[i-3].last==0)
            {
                glPushMatrix();
                glBegin(GL_POLYGON);

                x=statek[0].wektor[i].x;
                y=statek[0].wektor[i].y;
                z=statek[0].wektor[i].z;
                obliczenia_3d(statek[0].r_x,statek[0].r_y,statek[0].r_z);
                glColor3f(1.0f, 0.5f, 0.0f); glVertex3f(x/1000,y/1000,z/1000);

                x=statek[0].wektor[i-1].x;
                y=statek[0].wektor[i-1].y;
                z=statek[0].wektor[i-1].z;
                obliczenia_3d(statek[0].r_x,statek[0].r_y,statek[0].r_z);
                glColor3f(1.0f, 0.5f, 0.0f); glVertex3f(x/1000,y/1000,z/1000);

                x=statek[0].wektor[i-2].x;
                y=statek[0].wektor[i-2].y;
                z=statek[0].wektor[i-2].z;
                obliczenia_3d(statek[0].r_x,statek[0].r_y,statek[0].r_z);
                glColor3f(1.0f, 0.5f, 0.0f); glVertex3f(x/1000,y/1000,z/1000);

                x=statek[0].wektor[i-3].x;
                y=statek[0].wektor[i-3].y;
                z=statek[0].wektor[i-3].z;
                obliczenia_3d(statek[0].r_x,statek[0].r_y,statek[0].r_z);
                glColor3f(1.0f, 0.5f, 0.0f); glVertex3f(x/1000,y/1000,z/1000);

                glEnd();

                glBegin(GL_LINE_LOOP);

                x=statek[0].wektor[i].x;
                y=statek[0].wektor[i].y;
                z=statek[0].wektor[i].z;
                obliczenia_3d(statek[0].r_x,statek[0].r_y,statek[0].r_z);

                glColor3f(0.0f, 0.0f, 0.0f); glVertex3f(x/1000,y/1000,z/1000);

                x=statek[0].wektor[i-1].x;
                y=statek[0].wektor[i-1].y;
                z=statek[0].wektor[i-1].z;
                obliczenia_3d(statek[0].r_x,statek[0].r_y,statek[0].r_z);

                glColor3f(0.0f, 0.0f, 0.0f); glVertex3f(x/1000,y/1000,z/1000);

                x=statek[0].wektor[i-2].x;
                y=statek[0].wektor[i-2].y;
                z=statek[0].wektor[i-2].z;
                obliczenia_3d(statek[0].r_x,statek[0].r_y,statek[0].r_z);

                glColor3f(0.0f, 0.0f, 0.0f); glVertex3f(x/1000,y/1000,z/1000);

                x=statek[0].wektor[i-3].x;
                y=statek[0].wektor[i-3].y;
                z=statek[0].wektor[i-3].z;
                obliczenia_3d(statek[0].r_x,statek[0].r_y,statek[0].r_z);

                glColor3f(0.0f, 0.0f, 0.0f); glVertex3f(x/1000,y/1000,z/1000);

                glEnd();
                glPopMatrix();
                i=i+4;
            }

            SwapBuffers(hDC);
            //statek[0].r_x+=1;
            statek[0].r_z+=1;
            Sleep (1);
        }
    }

    /* shutdown OpenGL */
    DisableOpenGL(hwnd, hDC, hRC);

    /* destroy the window explicitly */
    DestroyWindow(hwnd);

    return msg.wParam;
}
 

mam nadzieję, że pomoże

0

Człowieku, poczytaj może o tym https://www.opengl.org/sdk/docs/man2/xhtml/glTranslate.xml
zamiast wyważać otwarte drzwi.

0

ta tylko jak potem wyjąć te dane z matrixa? bo oprócz wyświetlania modelu chce zrobić kolizje pojazdów a do tego potrzebuje wzoru...

0

Wzoru Pitagorasa na odległość, tego też nie znasz?

0

czyli dlaczego? działa do momentu "środkowego kąta"(przeskakuje nagle o dużą odległość zamiast płynnie sie obrucić) osi x i y... jakieś pomysły na poprawę kodu?

0

o i mała poprawka poprzednich wzorów:

    zz=cos((kat_x+kat(z,y)+45)*M_PI/180)*sqrt(z*z+y*y);
    yy=sin((kat_x+kat(z,y)+45)*M_PI/180)*sqrt(z*z+y*y);
    y=yy;
    z=zz;

    xx=sin((kat_y+kat(z,x)+45)*M_PI/180)*sqrt(x*x+z*z);
    zz=cos((kat_y+kat(z,x)+45)*M_PI/180)*sqrt(x*x+z*z);
    z=zz;
    x=xx;

    xx=cos((kat_z+kat(x,y)+45)*M_PI/180)*sqrt(x*x+y*y);
    yy=sin((kat_z+kat(x,y)+45)*M_PI/180)*sqrt(x*x+y*y);
    y=yy;
    x=xx; 
0

Twój kod jest równoważny z tym.

    
    z=cos((kat_y+kat(z,x)+45)*M_PI/180)*sqrt(x*x+z*z);
    x=cos((kat_z+kat(x,y)+45)*M_PI/180)*sqrt(x*x+y*y);
    y=sin((kat_z+kat(x,y)+45)*M_PI/180)*sqrt(x*x+y*y);

a to nie wygląda poprawnie

http://en.wikipedia.org/wiki/Rotation_matrix#In_three_dimensions

0

dzięki właśnie zrozumiałem jak zamienić to na wzór... zaraz zobaczę czy działa

0

wyszło mi coś takiego

    x=1*x;
    y=(cos(kat_x*M_PI/180)+sin(kat_x*M_PI/180))*y;
    z=(cos(kat_x*M_PI/180)-sin(kat_x*M_PI/180))*z;

    x=(cos(kat_y*M_PI/180)-sin(kat_y*M_PI/180))*x;
    y=1*y;
    z=(sin(kat_y*M_PI/180)+cos(kat_y*M_PI/180))*z;

    x=(cos(kat_z*M_PI/180)+sin(kat_z*M_PI/180))*x;
    y=(cos(kat_z*M_PI/180)-sin(kat_z*M_PI/180))*y;
    z=1*z;
 

i dalej źle... gdzie mam błąd?
Mnie się wydaje, że muszę pokombinować z kątami, tak, żeby x y i z było dodatnie

0

Jak się nie pomyliłem przy wpisywaniu to:
R = Rx(α)Ry(β)Rz(γ) = http://www.wolframalpha.com/input/?i={{1%2C+0%2C+0}%2C+{0%2C+cos%28%CE%B1%29%2C+-sin%28%CE%B1%29}%2C+{0%2C+sin%28%CE%B1%29%2C+cos%28%CE%B1%29}}.{{cos%28%CE%B2%29%2C0%2Csin%28%CE%B2%29}%2C+{0%2C+1%2C+0}%2C+{-sin%28%CE%B2%29%2C+0%2C+cos%28%CE%B2%29}}.{{cos%28%CE%B3%29%2C+-sin%28%CE%B3%29%2C+0}%2C+{sin%28%CE%B3%29%2Ccos%28%CE%B3%29%2C0}%2C+{0%2C0%2C1}}

{{x'},{y'},{z'}} = R*{{x},{y},{z}} = http://www.wolframalpha.com/input/?i={{1%2C+0%2C+0}%2C+{0%2C+cos%28%CE%B1%29%2C+-sin%28%CE%B1%29}%2C+{0%2C+sin%28%CE%B1%29%2C+cos%28%CE%B1%29}}.{{cos%28%CE%B2%29%2C0%2Csin%28%CE%B2%29}%2C+{0%2C+1%2C+0}%2C+{-sin%28%CE%B2%29%2C+0%2C+cos%28%CE%B2%29}}.{{cos%28%CE%B3%29%2C+-sin%28%CE%B3%29%2C+0}%2C+{sin%28%CE%B3%29%2Ccos%28%CE%B3%29%2C0}%2C+{0%2C0%2C1}}.{{x}%2C{y}%2C{z}}

@_13th_Dragon chodziło ci o zapis tutaj czy na WA?
tutaj poprawiłem

#edit
może to jeszcze będzie pomocne
http://www.wolframalpha.com/input/?i=three+dimensional+rotation

0

może ktoś mi wzór poprawny pokazać z c bo ja się poddaje... nie wiem jak to zrobić

0

Nie kombinuj poprawnych wzorów tylko użyj mnożenia macierzy.

0

...aaa dobra... i tak nie mam pomysłu...

0

Link na mnożenie macierzy dostałeś, jakiego pomysłu chcesz.
Jedynego pomysłu którego jeszcze nie podałem, to - wynajmij fachowca, ponieważ sam to się nie nadajesz.

0

jaka jest różnica pomiędzy

    macierz[0][0]=1;
    macierz[0][1]=0;
    macierz[0][2]=0;
    macierz[1][0]=0;
    macierz[1][1]=cos(kat_x);
    macierz[1][2]=sin(kat_x);
    macierz[2][0]=0;
    macierz[2][1]=-sin(kat_x);
    macierz[2][2]=cos(kat_x);
    x=macierz[0][0]*x+macierz[0][1]*x+macierz[0][2]*x;
    y=macierz[1][0]*y+macierz[1][1]*y+macierz[1][2]*y;
    z=macierz[2][0]*z+macierz[2][1]*z+macierz[2][2]*z; 

a

x=1*x;
y=(cos(kat_x)+sin(kat_x))*y;
z=(cos(kat_x)-sin(kat_x))*z; 

bo nie rozumiem

0

oooo pomyliłem wiersze z kolumnami :(

0
Niikelion napisał(a):

jaka jest różnica ...
Jak robisz tylko jeden obrót to nie ma różnicy.
Zaś jak robisz obrót wzdłuż 3ch osi naraz należy przemnożyć trzy macierze.

0

ok działa, dziękuję wszystkim za pomoc.

    double xx,yy,zz;
    xx=cos(kat_y*M_PI/180)*x+sin(kat_y*M_PI/180)*z;
    zz=-sin(kat_y*M_PI/180)*x+cos(kat_y*M_PI/180)*z;
    x=xx;
    z=zz;

    yy=cos(kat_x*M_PI/180)*y-sin(kat_x*M_PI/180)*z;
    zz=sin(kat_x*M_PI/180)*y+cos(kat_x*M_PI/180)*z;
    y=yy;
    z=zz;

    xx=cos(kat_z*M_PI/180)*x-sin(kat_z*M_PI/180)*y;
    yy=sin(kat_z*M_PI/180)*x+cos(kat_z*M_PI/180)*y;
    x=xx;
    y=yy; 

jeszcze tylko perspektywa i silnik 3d gotowy

0

Robienie silnika 3d za pomocą silnika 3d - ja wymiękam.

0

... 3d jako 2d...

0

o i jeszcze jeden kłopot tak przy okazji... wczytałem 6 ścian (sześcian) i wyświetlam je... niestety nie wszystkie wyświetlają się w odpowiedniej kolejności... muszę je sobie posortować czy jest jakaś funkcja, której nie znam

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