diff --git a/QT/kolo/mywindow.cpp b/QT/kolo/mywindow.cpp index c82f9f3..98532b2 100644 --- a/QT/kolo/mywindow.cpp +++ b/QT/kolo/mywindow.cpp @@ -6,8 +6,13 @@ // z pliku XML "mywindow.ui" #include "ui_mywindow.h" -#include #include +#include +#include +#include +#include +#include // for float,double macros +#include #define PI 3.1415 @@ -32,6 +37,10 @@ MyWindow::MyWindow(QWidget *parent) : poczX = ui->rysujFrame->x(); poczY = ui->rysujFrame->y(); + segment_count = ui->segmentSlider->value(); + QString str(("Ilosc segmentow: " + std::to_string(segment_count)).c_str()); + ui->segmentLabel->setText(str); + // Tworzymy obiekt klasy QImage, o odpowiedniej szerokosci // i wysokosci. Ustawiamy format bitmapy na 32 bitowe RGB // (0xffRRGGBB). @@ -60,6 +69,14 @@ void MyWindow::on_exitButton_clicked() } +void MyWindow::on_segmentSlider_valueChanged(int val) +{ + segment_count = val; + QString str(("Ilosc segmentow: " + std::to_string(segment_count)).c_str()); + ui->segmentLabel->setText(str); +} + + // Funkcja "odmalowujaca" komponent void MyWindow::paintEvent(QPaintEvent*) { @@ -135,6 +152,8 @@ void MyWindow::mousePressEvent(QMouseEvent *event) draw_finished = false; + mode = event->button() == Qt::LeftButton ? Circle : event->button() == Qt::RightButton ? Ellipse : Other; + update(); } @@ -150,7 +169,7 @@ void MyWindow::mouseMoveEvent(QMouseEvent *event) x -= poczX; y -= poczY; - if(x >= szer || y >= wys || x < 0 || y < 0){ + if(x >= szer || y >= wys || x < 0 || y < 0 || draw_finished){ ApplyTempImage(); active_img = img; @@ -162,7 +181,11 @@ void MyWindow::mouseMoveEvent(QMouseEvent *event) return; } - DrawEllipse(startX, startY, x, y); + if(mode == Circle){ + DrawCircle(startX, startY, x, y); + }else if(mode == Ellipse){ + DrawEllipse(startX, startY, x, y); + } // Odswiezamy komponent update(); @@ -186,56 +209,54 @@ void MyWindow::ApplyTempImage(){ } void MyWindow::UpdateTempImage(){ - memcpy(img_tmp->bits(), img->bits(), szer * wys * 4); + memcpy(img_tmp->bits(), img->bits(), szer * wys * 4); } -void Rysuj(unsigned char* ptr, int szer, int wys, int x, int y){ +void DrawPixel(unsigned char* ptr, int szer, int wys, QColor color, int x, int y){ if(x >= szer || y >= wys || x < 0 || y < 0) return; - int kolor = 255; - ptr[szer*4*y + 4*x] = kolor; - ptr[szer*4*y + 4*x + 1] = kolor; - ptr[szer*4*y + 4*x + 2] = kolor; - ptr[szer*4*y + 4*x + 3] = 255; + ptr[szer*4*y + 4*x] = color.blue(); + ptr[szer*4*y + 4*x + 1] = color.green(); + ptr[szer*4*y + 4*x + 2] = color.red(); + ptr[szer*4*y + 4*x + 3] = color.alpha(); } void MyWindow::DrawLine(int x1, int y1, int x2, int y2, bool update_temp){ - - if(x2 >= szer || y2 >= wys || x2 < 0 || y2 < 0) - return; - - if(update_temp) UpdateTempImage(); + unsigned char* ptr = img_tmp->bits(); if(x1 > x2){ - int tmpX = x1; - int tmpY = y1; - x1 = x2; - y1 = y2; - x2 = tmpX; - y2 = tmpY; + std::swap(x1, x2); + std::swap(y1, y2); } - - - int kolor = 255; - unsigned char *ptr; - int y = y2; - ptr = img_tmp->bits(); float diff = x2 - x1; - float a = (y2 - y1) / diff; - for(int i = x1; i <= x2; i++){ - int x = i; - y = a * (i - x1) + y1; + float a = diff != 0 ? (y2 - y1) / diff : FLT_MAX; + QColor color(255, 255, 255, 255); - Rysuj(ptr, szer, wys, x, y); - // Ustawiamy kolor kliknietego piksela na bialy lub czarny -// ptr[szer*4*y + 4*x] = kolor; -// ptr[szer*4*y + 4*x + 1] = kolor; -// ptr[szer*4*y + 4*x + 2] = kolor; -// ptr[szer*4*y + 4*x + 3] = 255; + if(abs(a) < 0.5f){ + for(int x = x1; x <= x2; x++){ + int x_form = x - x1; + int y = a * x_form + y1; + + DrawPixel(ptr, szer, wys, color, x, y); + } + } + 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(ptr, szer, wys, color, x, y); + } } } @@ -252,13 +273,15 @@ void MyWindow::DrawCircle(int x1, int y1, int x2, int y2){ float R = sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2)); int q_last_x = R / sqrt(2) + 1; + QColor color(255, 255, 255, 255); + for(int x = 0; x <= q_last_x; x++){ float y = sqrt(pow(R, 2) - pow(x, 2)); for(int k = 0; k < 2; k++){ for(int i = 0; i < 2; i++){ for(int j = 0; j < 2; j++){ - Rysuj(ptr, szer, wys, x1 + x, y1 - y); + DrawPixel(ptr, szer, wys, color, x1 + x, y1 - y); y *= -1; } x *= -1; @@ -275,20 +298,14 @@ void MyWindow::DrawEllipse(int x1, int y1, int x2, int y2){ UpdateTempImage(); - int point_count = 60; - - unsigned char *ptr; - ptr = img_tmp->bits(); - - float last_x = 0; float last_y = 0; float Rx = abs(x2 - x1); float Ry = abs(y2 - y1); - for(int i = 0; i < point_count; i++){ - double angle = 2.0 * PI * (float(i) / point_count); + for(int i = 0; i <= segment_count; i++){ + double angle = 2.0 * PI * (float(i) / segment_count); float x = sin(angle) * Rx; float y = cos(angle) * Ry; diff --git a/QT/kolo/mywindow.h b/QT/kolo/mywindow.h index 578b045..871acdb 100644 --- a/QT/kolo/mywindow.h +++ b/QT/kolo/mywindow.h @@ -28,6 +28,8 @@ // klikniecia, ruch myszka itp. #include +enum Mode {Ellipse, Circle, Other}; + namespace Ui { class MyWindow; } @@ -59,6 +61,8 @@ private: // Do poszczegolnych elementow GUI odwolujemy sie za pomoca zmiennej "ui" Ui::MyWindow *ui; + Mode mode; + // Pole przechowujace obrazek QImage *img; // Pole przechowujace obrazek @@ -74,6 +78,7 @@ private: int poczY; int startX, startY; bool draw_finished; + int segment_count; // Deklaracje funkcji @@ -93,6 +98,7 @@ private: private slots: void on_cleanButton_clicked(); void on_exitButton_clicked(); + void on_segmentSlider_valueChanged(int val); void mousePressEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event); void mouseReleaseEvent(QMouseEvent *event); diff --git a/QT/kolo/mywindow.ui b/QT/kolo/mywindow.ui index f8e934b..330ffca 100644 --- a/QT/kolo/mywindow.ui +++ b/QT/kolo/mywindow.ui @@ -42,11 +42,11 @@ 630 10 241 - 191 + 271 - Wypełnianie + Opcje @@ -74,6 +74,70 @@ Wyjście + + + + 10 + 150 + 221 + 20 + + + + 4 + + + 100 + + + 10 + + + Qt::Horizontal + + + QSlider::TicksAbove + + + 10 + + + + + + 10 + 120 + 131 + 20 + + + + TextLabel + + + + + + 10 + 186 + 221 + 71 + + + + Przytrzymaj lewy przycisk myszy by utworzyć okrąg. +Przytrzymaj prawy przycisk myszy by utworzyć elipse. + + + Qt::PlainText + + + false + + + true + +