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ć).
A tych 4-ch sposobów już nie możesz pokazać, czy dobrze rozumiem?
http://pl.wikipedia.org/wiki/Elementarne_macierze_transformacji
http://pl.wikipedia.org/wiki/Mno%C5%BCenie_macierzy
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...
Do każdej ze zmiennych zapisujesz 2 razy różne wyniki. Raz jeden, a potem nadpisujesz drugim.
w teorii wynik drugiej zmiany xx powinien wynosić x więc nie ogarniam błędu...
hmmmnnn teraz moge obracać wokół jednej osi ale wzory mam wpisane wszystkie(jak zwiększam 2 kąty to zaczyna świrować)
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
Człowieku, poczytaj może o tym https://www.opengl.org/sdk/docs/man2/xhtml/glTranslate.xml
zamiast wyważać otwarte drzwi.
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...
Wzoru Pitagorasa na odległość, tego też nie znasz?
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?
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;
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
dzięki właśnie zrozumiałem jak zamienić to na wzór... zaraz zobaczę czy działa
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
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
może ktoś mi wzór poprawny pokazać z c bo ja się poddaje... nie wiem jak to zrobić
Nie kombinuj poprawnych wzorów
tylko użyj mnożenia macierzy.
...aaa dobra... i tak nie mam pomysłu...
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.
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
oooo pomyliłem wiersze z kolumnami :(
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.
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
Robienie silnika 3d za pomocą silnika 3d - ja wymiękam.
... 3d jako 2d...
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