tBane Temat założony przez niniejszego użytkownika |
[C++] Silnik Graficzny z wykorzystaniem matematyki niższej - czyli jak ominąć macierze » 2023-07-29 19:01:24 Prosto, krótko i na temat. Wymyśliłem funkcje na rotacje (x), (y), (z). Potrzebuje rotacji (x,y,z).. Korzystałem z algorytmu rysowania zegara analogowego. Rotacja miała działac nastepujaca: -pobierz obecny kat nachylenia wierzchołka do centrum modelu -oblicz długość odcinka od wierzcholka do centrum modelu -dodaj wektor rotacji do wierzholka z użyciem funkcji trygonometrycznych dla sumy kątów ( obecny kat + nowy kat) Rotacje działają pojedynczo ale "razem" nie działają (Jak ustawiasz kat tylko dla jednej osi a pozostałe rotacje "zakomentujesz" algorytm działa), zanikają lub niweluja się. Mój zbyt prosty umysł nie potrafi tego przetworzyc. Zalozenia1. os Z rośnie od ekranu wgląb, os Y rośnie w górę, os X rośnie w prawo. Punkt 0 dla wszystkich osi to centrum ekranu. 2. Delta Z (dz) to stała 2.f do "stymulowanie 3D" x=x+(z*/dz) ; y=y+(z/dx). Wtedy wydaje się jakby model był pod kątem przechylony pod kątem 45stopni w osi X i 45stopni wokół osi y. (osobiście nazywam to rzutem "3 do 2D") 3. V - vertice, R - rotate vertice, P - projected vertice Oto mój kod class trit { public: float v1x, v1y, v1z, v2x, v2y, v2z, v3x, v3y, v3z; float r, g, b, a; trit * next; float r1x, r1y, r1z, r2x, r2y, r2z, r3x, r3y, r3z; float p1x, p1y, p2x, p2y, p3x, p3y; float cx, cy, cz; trit( float, float, float, float, float, float, float, float, float, float, float, float, float ); trit( trit * ); ~trit(); };
Triangle * t = New triangle( - 100, - 50, 0, 100, - 50, 0, 0, 50, 0 ); float toDegrees = 180.f / M_PI; float toRads = M_PI / 180.f; float dz = 2.f; float deg1z, deg2z, deg3z; float deg1y, deg2y, deg3y; float deg1x, deg2x, deg3x;
float len1, len2, len3; float fullAnglez1, fullAnglez2, fullAnglez3; float fullAngley1, fullAngley2, fullAngley3; float fullAnglex1, fullAnglex2, fullAnglex3;
deg1z = atan2( cy - t->v1y, cx - t->v1x ) * toDegrees; deg2z = atan2( cy - t->v2y, cx - t->v2x ) * toDegrees; deg3z = atan2( cy - t->v3y, cx - t->v3x ) * toDegrees;
fullAnglez1 =( deg1z + anglez ) * toRads; fullAnglez2 =( deg2z + anglez ) * toRads; fullAnglez3 =( deg3z + anglez ) * toRads;
len1 = sqrt( pow( cx - t->v1x, 2 ) + pow( cy - t->v1y, 2 ) + pow( cz - t->v1z, 2 ) ); len2 = sqrt( pow( cx - t->v2x, 2 ) + pow( cy - t->v2y, 2 ) + pow( cz - t->v2z, 2 ) ); len3 = sqrt( pow( cx - t->v3x, 2 ) + pow( cy - t->v3y, 2 ) + pow( cz - t->v3z, 2 ) );
t->r1x = cx + len1 * sin( fullAnglez1 ); t->r1y = cy + len1 * cos( fullAnglez1 ); t->r1z = t->v1z;
t->r2x = cx + len2 * sin( fullAnglez2 ); t->r2y = cy + len2 * cos( fullAnglez2 ); t->r2z = t->v2z;
t->r3x = cx + len3 * sin( fullAnglez3 ); t->r3y = cy + len3 * cos( fullAnglez3 ); t->r3z = t->v3z; deg1y = atan2( cz - t->v1z, cx - t->v1x ) * toDegrees; deg2y = atan2( cz - t->v2z, cx - t->v2x ) * toDegrees; deg3y = atan2( cz - t->v3z, cx - t->v3x ) * toDegrees;
fullAngley1 =( deg1y + angley ) * toRads; fullAngley2 =( deg2y + angley ) * toRads; fullAngley3 =( deg3y + angley ) * toRads;
len1 = sqrt( pow( cx - t->v1x, 2 ) + pow( cy - t->v1y, 2 ) + pow( cz - t->v1z, 2 ) ); len2 = sqrt( pow( cx - t->v2x, 2 ) + pow( cy - t->v2y, 2 ) + pow( cz - t->v2z, 2 ) ); len3 = sqrt( pow( cx - t->v3x, 2 ) + pow( cy - t->v3y, 2 ) + pow( cz - t->v3z, 2 ) );
t->r1x = t->r1x - len1 * cos( fullAngley1 ); t->r1y = t->r1y; t->r1z = t->r1z + len1 * sin( fullAngley1 );
t->r2x = t->r2x - len2 * cos( fullAngley2 ); t->r2y = t->r2y; t->r2z = t->r2z + len2 * sin( fullAngley2 );
t->r3x = t->r3x - len3 * cos( fullAngley3 ); t->r3y = t->r3y; t->r3z = t->r3z + len3 * sin( fullAngley3 );
deg1x = atan2( cy - t->r1y, cz - t->r1z ) * toDegrees; deg2x = atan2( cy - t->r2y, cz - t->r2z ) * toDegrees; deg3x = atan2( cy - t->r3y, cz - t->r3z ) * toDegrees;
fullAnglex1 =( deg1x + anglex ) * toRads; fullAnglex2 =( deg2x + anglex ) * toRads; fullAnglex3 =( deg3x + anglex ) * toRads;
len1 = sqrt( pow( cx - t->r1x, 2 ) + pow( cy - t->r1y, 2 ) + pow( cz - t->r1z, 2 ) ); len2 = sqrt( pow( cx - t->r2x, 2 ) + pow( cy - t->r2y, 2 ) + pow( cz - t->r2z, 2 ) ); len3 = sqrt( pow( cx - t->r3x, 2 ) + pow( cy - t->r3y, 2 ) + pow( cz - t->r3z, 2 ) );
t->r1x = t->r1x; t->r1y = t->r1y + len1 * sin( fullAnglex1 ); t->r1z = t->r1z + len1 * cos( fullAnglex1 );
t->r2x = t->r2x; t->r2y = t->r2y + len2 * sin( fullAnglex2 ); t->r2z = t->r2z + len2 * cos( fullAnglex2 );
t->r3x = t->r3x; t->r3y = t->r3y + len3 * sin( fullAnglex3 ); t->r3z = t->r3z + len3 * cos( fullAnglex3 );
t->cx =( t->r1x + t->r2x + t->r3x ) / 3.f; t->cy =( t->r1y + t->r2y + t->r3y ) / 3.f; t->cz =( t->r1z + t->r2z + t->r3z ) / 3.f;
t->p1x = t->r1x; t->p1y = t->r1y; t->p2x = t->r2x; t->p2y = t->r2y; t->p3x = t->r3x; t->p3y = t->r3y;
|
|
DejaVu |
» 2023-07-29 19:30:46 Strzelałbym, że nie zapisujesz wyniku i... transformujesz oryginalne współrzędne, a nie po wykonaniu pierwszej rotacji. No ale mogę być w błędzie, bo kojarzę, że z 10+ lat temu miałem podobny problem :) |
|
tBane Temat założony przez niniejszego użytkownika |
» 2023-07-29 19:40:36 Done. Ale nadal nie działa, algorytm metamorfozuje mój szesciokat jak w jakimś 4 wymiarze .. Po rotacji dla osi z operuje na rotowanych już wierzcholkach i się psuje wszystko.. Nie wiem czy dobrze rozumuję, lecz myślę że może tu chodzić o to, że rotacja y względem rotacji z jest "przestawiona" o 90 stopni w osii.. Próbowałem dodawać i odejmować kąty dodatkowe (90 stopni) i nic to nie dało. for( trit * t = mesh; t != NULL; t = t->next ) { deg1z = atan2( cy - t->v1y, cx - t->v1x ) * toDegrees; deg2z = atan2( cy - t->v2y, cx - t->v2x ) * toDegrees; deg3z = atan2( cy - t->v3y, cx - t->v3x ) * toDegrees; fullAnglez1 =( deg1z + anglez ) * toRads; fullAnglez2 =( deg2z + anglez ) * toRads; fullAnglez3 =( deg3z + anglez ) * toRads; len1 = sqrt( pow( cx - t->v1x, 2 ) + pow( cy - t->v1y, 2 ) + pow( cz - t->v1z, 2 ) ); len2 = sqrt( pow( cx - t->v2x, 2 ) + pow( cy - t->v2y, 2 ) + pow( cz - t->v2z, 2 ) ); len3 = sqrt( pow( cx - t->v3x, 2 ) + pow( cy - t->v3y, 2 ) + pow( cz - t->v3z, 2 ) ); t->r1x = cx + len1 * sin( fullAnglez1 ); t->r1y = cy + len1 * cos( fullAnglez1 ); t->r1z = t->v1z; t->r2x = cx + len2 * sin( fullAnglez2 ); t->r2y = cy + len2 * cos( fullAnglez2 ); t->r2z = t->v2z; t->r3x = cx + len3 * sin( fullAnglez3 ); t->r3y = cy + len3 * cos( fullAnglez3 ); t->r3z = t->v3z; deg1y = atan2( cz - t->r1z, cx - t->r1x ) * toDegrees; deg2y = atan2( cz - t->r2z, cx - t->r2x ) * toDegrees; deg3y = atan2( cz - t->r3z, cx - t->r3x ) * toDegrees; fullAngley1 =( deg1y + angley ) * toRads; fullAngley2 =( deg2y + angley ) * toRads; fullAngley3 =( deg3y + angley ) * toRads; len1 = sqrt( pow( cx - t->r1x, 2 ) + pow( cy - t->r1y, 2 ) + pow( cz - t->r1z, 2 ) ); len2 = sqrt( pow( cx - t->r2x, 2 ) + pow( cy - t->r2y, 2 ) + pow( cz - t->r2z, 2 ) ); len3 = sqrt( pow( cx - t->r3x, 2 ) + pow( cy - t->r3y, 2 ) + pow( cz - t->r3z, 2 ) ); t->r1x = t->r1x - len1 * cos( fullAngley1 ); t->r1y = t->r1y; t->r1z = t->r1z + len1 * sin( fullAngley1 ); t->r2x = t->r2x - len2 * cos( fullAngley2 ); t->r2y = t->r2y; t->r2z = t->r2z + len2 * sin( fullAngley2 ); t->r3x = t->r3x - len3 * cos( fullAngley3 ); t->r3y = t->r3y; t->r3z = t->r3z + len3 * sin( fullAngley3 ); deg1x = atan2( cy - t->r1y, cz - t->r1z ) * toDegrees; deg2x = atan2( cy - t->r2y, cz - t->r2z ) * toDegrees; deg3x = atan2( cy - t->r3y, cz - t->r3z ) * toDegrees; fullAnglex1 =( deg1x + anglex ) * toRads; fullAnglex2 =( deg2x + anglex ) * toRads; fullAnglex3 =( deg3x + anglex ) * toRads; len1 = sqrt( pow( cx - t->r1x, 2 ) + pow( cy - t->r1y, 2 ) + pow( cz - t->r1z, 2 ) ); len2 = sqrt( pow( cx - t->r2x, 2 ) + pow( cy - t->r2y, 2 ) + pow( cz - t->r2z, 2 ) ); len3 = sqrt( pow( cx - t->r3x, 2 ) + pow( cy - t->r3y, 2 ) + pow( cz - t->r3z, 2 ) ); t->r1x = t->r1x; t->r1y = t->r1y + len1 * sin( fullAnglex1 ); t->r1z = t->r1z + len1 * cos( fullAnglex1 ); t->r2x = t->r2x; t->r2y = t->r2y + len2 * sin( fullAnglex2 ); t->r2z = t->r2z + len2 * cos( fullAnglex2 ); t->r3x = t->r3x; t->r3y = t->r3y + len3 * sin( fullAnglex3 ); t->r3z = t->r3z + len3 * cos( fullAnglex3 ); t->cx =( t->r1x + t->r2x + t->r3x ) / 3.f; t->cy =( t->r1y + t->r2y + t->r3y ) / 3.f; t->cz =( t->r1z + t->r2z + t->r3z ) / 3.f; t->p1x = t->r1x; t->p1y = t->r1y; t->p2x = t->r2x; t->p2y = t->r2y; t->p3x = t->r3x; t->p3y = t->r3y; }
|
|
pekfos |
» 2023-07-30 23:27:18 A czemu nie macierze? Skoro masz "zbyt prosty umysł", to najprościej byłoby skorzystać ze wzoru. |
|
tBane Temat założony przez niniejszego użytkownika |
» 2023-07-30 23:31:46 Bo chciałem "po swojemu" napisać :-) Kiedyś ktoś na tym forum uczył mnie jak za pomocą sin() i cos() rysować tarcze zegara analogowego i rotowac wskazówki :-) poszedłem o krok dalej.. I przypadkiem zaświtała mi w głowie 3-wymiarowa rotacja. Niby algorytm działa, ale tylko pojedynczo-choć ja uważam, że powinien działać. Nie wiem gdzie robię błąd i dlatego stoję w miejscu. A chcę napisać grę w której są aż 2 rotacje :D ( proszę. Tylko bez macierzy) |
|
pekfos |
» 2023-07-30 23:44:16 Ale wiesz że macierz to tylko sposób na zwięzłe zapisanie współczynników do szeregu mnożeń i dodawań? Można by rozpisać mnożenie macierzy obrotu przez wektor, ale średnio widzę w tym sens. Twoje rozwiązanie już jest bardziej skomplikowane i używa cięższych operacji. W twoim spaghetti w pierwszej kolejności bym patrzył czy w tej masie zmiennych nie ma błędów. Kod wygląda jak nakopiowany, więc nie zaktualizowanie zmiennej jest prawdopodobną pomyłką. Inna sprawa że nie powinieneś pisać tak kodu. |
|
tBane Temat założony przez niniejszego użytkownika |
» 2023-07-30 23:51:11 Dla mnie wydaje się czytelny. Widać kiedy zaczynają się obliczenia dla konkretnej rotacji. Dla każdej rotacji pobieramy kąt obecny, dodajemy do niego nowy kąt, ten kat wykorzystujemy w funkcji trygonometryczne, którą "skalujemy" odcinek cx-v1x, cx-v1x... cy-v1y.. etc.
To jest czytelne.
Dlaczego nie powinienem tak pisać kodu? I czy widzisz tu jakiś błąd logiczny? |
|
pekfos |
» 2023-07-31 00:04:45 To jest czytelne. Dlaczego nie powinienem tak pisać kodu? Może i jest czytelne. Dla ciebie, teraz. Czemu rotacje nie są wydzielone do funkcji? Powiedzmy 3 różnych, gdzie teraz są wszystkie wrzucone na kupę i kopiując kod trudziłeś się by każdy kod miał swoje unikalne zmienne, chociaż można było używać ponownie niektórych? Czemu wszystko jest rozbite na floaty, zamiast mieć strukturę z punktem? Nie ma różnicy w wydajności, co sugeruje twój komentarz, a znacznie upraszcza kod. Twierdzisz że kod jest czytelny, ale nie możesz znaleźć w nim błędu. Teraz jakbym ja miał w nim szukać błędu, to muszę zaczynać od największych bzdur, jak nieaktualna nazwa zmiennej. Czytelny kod nie ma tylu bzdur do sprawdzania. |
|
« 1 » 2 3 4 5 6 |