przeksztalcenie 2d

0

Witam, chce dobrze zrozumiec obracanie,
mam obsluge suwaka:

void MyWindow::on_rotacja_sliderMoved(int position)
{
    obrot = M_PI * (position)/180.0;
    wywolywanie();
}

Obliczona ze wzoru macierz obrotu:

void MyWindow::Obrot(){
    MacierzObrot[0][0] = cos(obrot);
    MacierzObrot[0][1] = -sin(obrot);
    MacierzObrot[0][2] = (szer/2.0)*(1-cos(obrot))+(wys/2.0)*(sin(obrot));
    MacierzObrot[1][0] = sin(obrot);
    MacierzObrot[1][1] = cos(obrot);
    MacierzObrot[1][2] = (wys/2.0)*(1-cos(obrot))-(szer/2.0)*(sin(obrot));
    MacierzObrot[2][2] = 1;
}

Gdy przesuwam suwakiem obrazek się obraca czyli wywołuje się funkcja wywolywanie()

void MyWindow::wywolywanie(){
    int i,j;
    double a,b;
    int x,y,xn,yn;
    unsigned char *ptr,*org;
    czysc();
    ptr = img->bits();
    org = oryginal->bits();
    // czyscimy wartosci wszystkich macierzy
    reset();
    // liczymy macierz obrotu
    Obrot();
     wynik[0][0] = 1;
    wynik[1][1] = 1;
    wynik[2][2] = 1;
    Mnozenie(MacierzObrot);
    for(i=0; i<wys; i++)
    {
        for(j=0; j<szer; j++)
        {
            // obliczamy wartosci ktore bedziemy wyswietlac
            x = a = wynik[0][0] * i + wynik[0][1] * j + wynik[0][2];
            y = b = wynik[1][0] * i + wynik[1][1] * j + wynik[1][2];

            xn = x + 1;
            yn = y + 1;


            if(xn == wys)
                xn--;
            if(yn == szer)
                yn--;
            if(x >= 0 && y >= 0 && x < wys && y < szer){
                a = a - x;
                b = b - y;
                // interpolacja dla poziomu z dwoch pionow
                ptr[szer*4*i + 4*j] = round(Interpolacja(Interpolacja(org[szer*4*x + 4*y],org[szer*4*xn + 4*y],a),Interpolacja(org[szer*4*x + 4*yn],org[szer*4*xn + 4*yn],a),b));
                ptr[szer*4*i + 4*j + 1] = round(Interpolacja(Interpolacja(org[szer*4*x + 4*y + 1],org[szer*4*xn + 4*y + 1],a),Interpolacja(org[szer*4*x + 4*yn + 1],org[szer*4*xn + 4*yn + 1],a),b));
                ptr[szer*4*i + 4*j + 2] = round(Interpolacja(Interpolacja(org[szer*4*x + 4*y + 2],org[szer*4*xn + 4*y + 2],a),Interpolacja(org[szer*4*x + 4*yn + 2],org[szer*4*xn + 4*yn + 2],a),b));
            }
        }
    }

    update();
}
void MyWindow::Mnozenie(double dane[3][3]){
    int i,j,k;
    double s;
    for(i = 0; i < 3; i++){
        for(j = 0; j < 3; j++){
            s = 0;
            for(k = 0; k < 3; k++){
                s += wynik[i][k] * dane[k][j];
            }
            pomoc[i][j] = s;

        }
    }
    for(i = 0; i < 3; i++){
        for(j = 0; j < 3; j++){
            wynik[i][j] = pomoc[i][j];
        }
    }
}

I mam takie pytania jak:
Do czego jest potrzebna macierz

wynik[0][0] = 1;
 wynik[1][1] = 1;
 wynik[2][2] = 1;

jak działa mnożenie czy moglby mi ktos pokazac w jaki sposob jest to wymnazane? " Mnozenie(MacierzObrot);"
dodatkowo prosilbym o wytlumaczenie tego:

  x = a = wynik[0][0] * i + wynik[0][1] * j + wynik[0][2];
   y = b = wynik[1][0] * i + wynik[1][1] * j + wynik[1][2];

            xn = x + 1;
            yn = y + 1;
0

Mozna prosic mniej naukowym jezykiem? Chcialbym to zrozumiec na "chlopski rozum" a dopiero potem czytac naukową definicje..
rozumiem ze funkcja Mnozenie(MacierzObrot); wyglada w ten sposob? :
Macierz:

 [   cos(obrot)  -sin(obrot)   (szer/2.0)*(1-cos(obrot))+(wys/2.0)*(sin(obrot)) ]            
  [    sin(obrot)   cos(obrot)    (wys/2.0)*(1-cos(obrot))-(szer/2.0)*(sin(obrot)) ]       
  [    0                 0                    1                                    ]  
  

pomnozona jest przez ta macierz tak?

[1  0  0 ]
[0  1  0]
[0  0   1 ]
0

Nie, ta druga to macierz jednostkowa, jak ją mnożysz przez dowolną macierz 3x3 z jednej bądź drugiej strony i tak wyjdzie ta sama "dowolna".

0

W twoim przypadku jest złożenie obrotu o kąt phi względem osi Z oraz pochylenie trójwymiarowe [szer/2.0,wys/2.0] dla płaszczyzny XY.

2&space;\\&space;0&space;&&space;0&space;&&space;1&space;\end{bmatrix}

0

"Mozna prosic mniej naukowym jezykiem? Chcialbym to zrozumiec na "chlopski rozum" a dopiero potem czytac naukową definicje." Chyba bardziej na "chłopski rozum", jak w tym artykule już ciężko wytłumaczyć.
Mnożenie macierzy: https://pl.wikipedia.org/wiki/Mno%C5%BCenie_macierzy
Jakby funkcja Mnozenie brała dwie macierze i zwracał ich iloczyn, to by szło to zrozumieć.

0
void MyWindow::Obrot(){
   MacierzObrot[0][0] = cos(obrot);
   MacierzObrot[0][1] = -sin(obrot);
   MacierzObrot[0][2] = (szer/2.0)*(1-cos(obrot))+(wys/2.0)*(sin(obrot));
   MacierzObrot[1][0] = sin(obrot);
   MacierzObrot[1][1] = cos(obrot);
   MacierzObrot[1][2] = (wys/2.0)*(1-cos(obrot))-(szer/2.0)*(sin(obrot));
   MacierzObrot[2][2] = 1;
}

Ten kod jest nieczytelny. Bierze jakąś wartość obrot nie wiadomo skąd, zapisuje do jakiejś MacierzObrot nie wiadomo gdzie...
I co tu w ogóle robi jakieś szer/2.0?

Proponuję wzorować się na czymś zrobionym porządnie, jak GLM albo po prostu użyć tego na początek (nie, nie trzeba używać razem z OpenGL, to czysto matematyczna biblioteka).

2

Takie małe pytanie: co jest twoim celem?

  • nauczenie się przekształceń macierzowych i pisanie ich od zera?
  • wykonanie aplikacji która coś obraca?
  • coś innego?

W zależności od tego, odpowiedź na twoje pytanie będzie wyglądać zupełnie inaczej.

0

Chce nauczyć się przeksztalcen od podstaw gotowe skrypty są mi nie potrzebne, nie potrafię zrozumiec funkcji wywołanie..pobieram macierz obrotu już przekształcona i przemnozonna a potem znowu coś wymnazam nie potrafię zrozumiec jak wygląda proces mnożenia..

0

Wiem jak się mnoży macierze, chodzi mi o to jak przez jaka macierz jest mnożona macierz oborotu.?

1

podstawy macierzy do przekształceń 2d:
https://dybuksoft.pl/articles/matrix2d

Ogólnie o obliczeniach na macierzach:
https://dybuksoft.pl/articles/matrix

Przykład składania macierzy
https://dybuksoft.pl/articles/matrix2dSolar

1

Macierz obrotu mnożysz przez kolumnę:
x
y
z
dostajesz kolumnę:
x'
y'
z'
Ewentualnie jak masz kilka punktów to, mnożysz przez macierz:
x1 x2 x3 ... xN
y1 y2 y3 ... yN
z1 z2 z3 ... zN
dostajesz macierz:
x1' x2' x3' ... xN'
y1' y2' y3' ... yN'
z1' z2' z3' ... zN'

0

Okej dziękuję rozumiem, tylko dlaczego do przekątnych potem przypisuje 1? W sensie dlaczego ustawiam początkowe wartości?
wynik[0][0] = 1;
wynik[1][1] = 1;
wynik[2][2] = 1;

0
dcielak napisał(a):

Chce nauczyć się przeksztalcen od podstaw gotowe skrypty są mi nie potrzebne ...

Czy coś się zmieniło?

0

Dzięki niej konstruowana jest macierz translacji?

2
dcielak napisał(a):

Okej dziękuję rozumiem, tylko dlaczego do przekątnych potem przypisuje 1? W sensie dlaczego ustawiam początkowe wartości?
wynik[0][0] = 1;
wynik[1][1] = 1;
wynik[2][2] = 1;

Tak naprawdę macierz obrotu powinna być 2x2. Taka macierz pozwala na skalowanie i obracanie.
Jednak przy okazji chce się uzyskać inne efekty, więc powiększa się macierz do rozmiaru 3x3
Dodatkowy wiersz i kolumna pozwalają na dodatkowe transformacje, np przesunięcie.
Żeby jedna to mogło zadziałać, to wektor przez który mnoży się macierz musi mieć wymiar 3.
Macierz, która nic nie robi (macierz jednostkowa) ma na przekątnej jedynki a w pozostałych miejscach zera.
Stad masz taką formę wynik.

Tu jest to dość dobrze opisane https://doc.qt.io/qt-5/qmatrix.html

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