diff --git a/QT/3d-cube/mywindow.cpp b/QT/3d-cube/mywindow.cpp index 4b2ad0b..6a27aab 100644 --- a/QT/3d-cube/mywindow.cpp +++ b/QT/3d-cube/mywindow.cpp @@ -18,6 +18,8 @@ #define PI 3.1415 +const int VIEW_SIZE = 4.0f; + std::vector matrixMul(std::vector p, std::vector m) { std::vector res(3); @@ -32,6 +34,16 @@ std::vector matrixMul(std::vector p, std::vector m) return res; } + +std::vector MyWindow::GetXY(Point p, std::vector m) +{ + std::vector res(3); + res[0] = ((p.x + VIEW_SIZE / 2.0f) / VIEW_SIZE * szer ); + res[1] = ((p.y + VIEW_SIZE / 2.0f) / VIEW_SIZE * wys); + + return res; +} + std::vector matrixMul3x3(std::vector m1, std::vector m2) { std::vector res(9, 0); @@ -48,6 +60,21 @@ std::vector matrixMul3x3(std::vector m1, std::vector m2) return res; } +std::vector matrixMul4x4(std::vector m1, std::vector m2) +{ + std::vector res(16, 0); + for(int i = 0; i < 4; i++) + { + for(int j = 0; j < 4; j++) + { + for(int k = 0; k < 4; k++) + { + res[i * 4 + j] += m1[i * 4 + k] * m2[k * 4 + j]; + } + } + } + return res; +} // Definicja konstruktora, wywolujemy najpierw // konstruktor klasy nadrzednej, nastepnie tworzymy // obiekt klasy Ui_MyWindow reprezentujacy GUI @@ -81,6 +108,17 @@ MyWindow::MyWindow(QWidget *parent) : translation_vec.push_back(0); translation_vec.push_back(0); +// points[0] = Point(-1.0f, -1.0f, 0.0f); +// points[1] = Point(1.0f, -1.0f, 0.0f); +// points[2] = Point(1.0f, 1.0f, 0.0f); +// points[3] = Point(-1.0f, 1.0f, 0.0f); + +// points[4] = Point(-1.0f, -1.0f, 0.0f); +// points[5] = Point(1.0f, -1.0f, 0.0f); +// points[6] = Point(1.0f, 1.0f, 0.0f); +// points[7] = Point(-1.0f, 1.0f, 0.0f); + + scale_vec.push_back(1.0f); scale_vec.push_back(1.0f); @@ -142,59 +180,73 @@ void MyWindow::UpdateImage(){ float cosa = cos(rotation_angle * 0.01745329252f); std::vector translate_mat = { - 1, 0, translation_vec[0], - 0, 1, translation_vec[1], - 0, 0, 1, + 1, 0, 0, translation_vec[0], + 0, 1, 0, translation_vec[1], + 0, 0, 1, 0, + 0, 0, 0, 1, }; std::vector scale_mat = { - scale_vec[0], 0, 0, - 0, scale_vec[1], 0, - 0, 0, 1, + scale_vec[0], 0, 0, 0, + 0, scale_vec[1], 0, 0, + 0, 0, scale_vec[1], 0, + 0, 0, 0, 1, }; - std::vector rotation_mat = { - cosa, -sina, 0, - sina, cosa, 0, - 0, 0, 1, + std::vector rotation_mat_x = { + 1, 0, 0, 0, + 0, cosa, -sina, 0, + 0, sina, cosa, 0, + 0, 0, 0, 1 }; - std::vector shx_mat = { - 1, sh_vec[0], 0, - 0, 1, 0, - 0, 0, 1, + std::vector rotation_mat_y = { + cosa, 0, sina, 0, + 0, 1, 0, 0, + -sina, 0, cosa, 0, + 0, 0, 0, 1 }; - - std::vector shy_mat = { - 1, 0, 0, - sh_vec[1], 1, 0, - 0, 0, 1, + std::vector rotation_mat_z = { + cosa, -sina, 0, 0, + sina, cosa, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 }; - std::vector tansform_mat = matrixMul3x3(matrixMul3x3(matrixMul3x3(matrixMul3x3( - scale_mat, - rotation_mat), - shx_mat), - shy_mat), - translate_mat); + std::vector sh_mat = { + 1, 0, sh_vec[0], 0, + 0, 1, sh_vec[1], 0, + 0, 0, 1, 0, + 0, 0, 0, 1, + }; - for(int x = 0; x < szer; x++) - for(int y = 0; y < wys; y++){ - float xw = (float) x / (float)szer; - float yh = (float) y / (float) wys; - xw -= 0.5f; - yh -= 0.5f; - std::vector P1 = {xw, yh, 1}; - std::vector P2 = matrixMul(P1, tansform_mat); - P2[0] += 0.5f; - P2[1] += 0.5f; - DrawPixel(img, x, y, GetInterpolatedColor(P2[0], P2[1])); - } + std::vector tansform_mat = + matrixMul4x4( + matrixMul4x4( + matrixMul4x4( + matrixMul4x4( + matrixMul4x4( + scale_mat, + rotation_mat_x), + rotation_mat_y), + rotation_mat_z), + sh_mat), + translate_mat); + + for(int i = 1; i < 8; i++){ + Point P1 = points[i-1]; + Point P2 = points[i]; + std::vector p1_vec = GetXY(P1, std::vector{}); + std::vector p2_vec = GetXY(P2, std::vector{}); + DrawLine(p1_vec[0], p1_vec[1], p2_vec[0], p2_vec[1], img); + } update(); } + + QColor MyWindow::GetPixel(QImage* img, int x, int y){ QColor res; int width = img->width(); @@ -275,6 +327,40 @@ void MyWindow::paintEvent(QPaintEvent*) p.drawImage(poczX,poczY,*img); } +void MyWindow::DrawLine(int x1, int y1, int x2, int y2, QImage *img){ + if(x1 > x2){ + std::swap(x1, x2); + std::swap(y1, y2); + } + float diff = x2 - x1; + float a = diff != 0 ? (y2 - y1) / diff : FLT_MAX; + + QColor color(255, 255, 255, 255); + + if(abs(a) < 1.0f){ + for(int x = x1; x <= x2; x++){ + int x_form = x - x1; + int y = a * x_form + y1; + + DrawPixel(img, x, y, color); + } + } + else{ + if(y1 > y2){ + std::swap(x1, x2); + std::swap(y1, y2); + } + float diff = x2 - x1; + float a = diff != 0 ? (y2 - y1) / diff : FLT_MAX; + for(int y = y1; y <= y2; y++){ + int y_form = y - y1; + int x = ((float)(y_form) / a) + x1; + + DrawPixel(img, x, y, color); + } + } +} + void MyWindow::DrawPixel(QImage* img, int x, int y, QColor color){ if(x >= szer || y >= wys || x < 0 || y < 0) diff --git a/QT/3d-cube/mywindow.h b/QT/3d-cube/mywindow.h index 09395af..1221b0d 100644 --- a/QT/3d-cube/mywindow.h +++ b/QT/3d-cube/mywindow.h @@ -31,6 +31,33 @@ #include #include // for float,double macros +struct Point{ + float x, y, z; + + Point(int x, int y, int z){ + this->x=x; + this->y=y; + this->z=z; + } + + float length(){ + float mag = std::sqrt(std::pow(x, 2) + std::pow(y, 2) + std::pow(z, 2)); + return mag; + } + + Point operator-(const Point& other){ + return Point(this->x - other.x, this->y - other.y, this->z - other.z); + } + + Point operator*(const float mul){ + return Point(this->x * mul, this->y * mul, this->z * mul); + } + + Point operator+(const Point& other){ + return Point(this->x + other.x, this->y + other.y, this->z + other.z); + } +}; + enum Mode {Line, Circle, Fill}; namespace Ui { @@ -88,7 +115,16 @@ private: int segment_count; float rotation_angle; - Point[8] points; + Point points[8] = { + Point(-1.0f, -1.0f, 0.0f), + Point(1.0f, -1.0f, 0.0f), + Point(1.0f, 1.0f, 0.0f), + Point(-1.0f, 1.0f, 0.0f), + Point(-1.0f, -1.0f, 0.0f), + Point(1.0f, -1.0f, 0.0f), + Point(1.0f, 1.0f, 0.0f), + Point(-1.0f, 1.0f, 0.0f), + }; std::vector scale_vec; std::vector translation_vec; std::vector sh_vec; @@ -113,10 +149,12 @@ private: void DrawS(float s); void DrawV(float v); + void DrawLine(int x1, int y1, int x2, int y2, QImage *img); QColor GetPixel(QImage* img, int x, int y); void DrawPixel(QImage* img, int x, int y, QColor color); QColor GetInterpolatedColor(float x, float y); void UpdateImage(); + std::vector GetXY(Point p, std::vector m); // Deklaracje slotow, czyli funkcji wywolywanych // po wystapieniu zdarzen zwiazanych z GUI