Fixed bezier drawing, improved performance

This commit is contained in:
Dawid Pietrykowski 2022-12-03 14:28:15 +01:00
parent 0b01f88ce5
commit e2d234479e
2 changed files with 47 additions and 36 deletions

View File

@ -106,27 +106,8 @@ void MyWindow::on_cleanButton_clicked()
// obszaru rysowania // obszaru rysowania
void MyWindow::czysc() void MyWindow::czysc()
{ {
// Wskaznik za pomoca, ktorego bedziemy modyfikowac obraz bezier_points.clear();
unsigned char *ptr; DrawBezier();
// Funkcja "bits()" zwraca wskaznik do pierwszego piksela danych
ptr = img->bits();
int i,j;
// Przechodzimy po wszystkich wierszach obrazu
for(i=0; i<wys; i++)
{
// Przechodzimy po pikselach danego wiersza
// W kazdym wierszu jest "szer" pikseli (tzn. 4 * "szer" bajtow)
for(j=0; j<szer; j++)
{
ptr[szer*4*i + 4*j]=0; // Skladowa BLUE
ptr[szer*4*i + 4*j + 1] = 0; // Skladowa GREEN
ptr[szer*4*i + 4*j + 2] = 0; // Skladowa RED
ptr[szer*4*i + 4*j + 3] = 255; // Skladowa RED
}
}
} }
@ -152,7 +133,6 @@ void MyWindow::mousePressEvent(QMouseEvent *event)
// draw_finished = false; // draw_finished = false;
// mode = event->button() == Qt::LeftButton ? Add : event->button() == Qt::RightButton ? Move : Move;
int id = -1; int id = -1;
switch(event->button()){ switch(event->button()){
case Qt::LeftButton: case Qt::LeftButton:
@ -239,7 +219,7 @@ int MyWindow::FindPoint(int x, int y, float radius){
float min_dist = FLT_MAX; float min_dist = FLT_MAX;
int min_id = -1; int min_id = -1;
for(int i = 0; i < bezier_points.size(); i++){ for(int i = 0; i < bezier_points.size(); i++){
float dist = src_point - (Point)(bezier_points[i]); float dist = (src_point - (Point)(bezier_points[i])).length();
if(dist < min_dist && dist < radius){ if(dist < min_dist && dist < radius){
min_id = i; min_id = i;
min_dist = dist; min_dist = dist;
@ -309,9 +289,6 @@ void MyWindow::DrawCircle(int x1, int y1, int x2, int y2){
UpdateTempImage(); UpdateTempImage();
unsigned char *ptr;
ptr = img_tmp->bits();
float R = sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2)); float R = sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2));
int q_last_x = R / sqrt(2) + 1; int q_last_x = R / sqrt(2) + 1;
@ -370,21 +347,41 @@ void MyWindow::DrawBezier(){
DrawPixel(img, bezier_points[i].x, bezier_points[i].y); DrawPixel(img, bezier_points[i].x, bezier_points[i].y);
} }
for(int i = 1; i < bezier_points.size(); i+=3){ for(int i = 1; i < bezier_points.size(); i+=3){
if(i + 3 <= bezier_points.size()){ if(i + 2 >= bezier_points.size())
for(int j = i; j < i + 3; j++){ break;
Point p1 = bezier_points[j-1]; Point p0 = bezier_points[i - 1];
Point p2 = bezier_points[j]; Point p1 = bezier_points[i];
Point p2 = bezier_points[i + 1];
Point p3 = bezier_points[i + 2];
DrawLine(p1.x, p1.y, p2.x, p2.y, img);
} Point last_point = p0;
for(int i = 1; i <= segment_count; i++){
float t = (float(i) / segment_count);
Point P =
p0 * (float)pow(1.0f - t, 3)
+ p1 * 3.0f * (float)pow(1.0f - t, 2) * t
+ p2 * 3.0f * (1.0f - t) * (float)pow(t, 2)
+ p3 * (float)pow(t, 3);
DrawLine(last_point.x, last_point.y, P.x, P.y, img);
last_point = P;
} }
} }
} }
void MyWindow::ClearImage(QImage *img){ void MyWindow::ClearImage(QImage *img){
unsigned char* empty_val = (unsigned char*)malloc(4);
empty_val[0] = 0;
empty_val[1] = 0;
empty_val[2] = 0;
empty_val[3] = 255;
unsigned char* ptr = img->bits();
for(int i = 0; i < img->width(); i++){ for(int i = 0; i < img->width(); i++){
for(int j = 0; j < img->height(); j++){ for(int j = 0; j < img->height(); j++){
DrawPixel(img, i, j, QColor(0,0,0)); memcpy(ptr + 4 * (i + j * img->width()), empty_val, 4);
} }
} }
} }

View File

@ -45,12 +45,26 @@ struct Point{
this->y=y; this->y=y;
} }
float operator-(const Point& other){ float length(){
float x = other.x - this->x;
float y = other.y - this->y;
float mag = std::sqrt(std::pow(x, 2) + std::pow(y, 2)); float mag = std::sqrt(std::pow(x, 2) + std::pow(y, 2));
return mag; return mag;
} }
Point operator-(const Point& other){
return Point(this->x - other.x, this->y - other.y);
// float x = other.x - this->x;
// float y = other.y - this->y;
// float mag = std::sqrt(std::pow(x, 2) + std::pow(y, 2));
// return mag;
}
Point operator*(const float mul){
return Point(this->x * mul, this->y * mul);
}
Point operator+(const Point& other){
return Point(this->x + other.x, this->y + other.y);
}
}; };
// MyWindow jest podklasa klasy QMainWindow. // MyWindow jest podklasa klasy QMainWindow.