Nadesłany przez Andrzej Borucki, 26 stycznia 2012 22:19
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.Pobierz pełne rozwiązanie.
Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.
window.cpp:
/**************************************************************************** Andrzej Borucki www.algorytm.org Algorytm kreslenia odcinkow ****************************************************************************/ #include <QtGui> #include <windows.h> #include "window.h" Window::Window() : QWidget() { label = new QLabel(tr("Image")); QGridLayout *layout = new QGridLayout; btn1 = new QPushButton("std"); btn2 = new QPushButton("bresenham"); layout->addWidget(btn1, 0, 1); layout->addWidget(btn2, 1, 1); layout->addWidget(label, 0, 0); setLayout(layout); connect( btn1, SIGNAL(clicked()), SLOT(draw_clicked()) ); connect( btn2, SIGNAL(clicked()), SLOT(bresenham_clicked()) ); } void bresenham(int x1, int y1, int x2, int y2, int color, uchar * bits, int bytesPerLine) { int d, dx, dy, ai, bi, xi, yi; int pxi, pyi; int x = x1, y = y1; // determining the direction of drawing if (x1 < x2) { xi = 1; pxi = 4; dx = x2 - x1; } else { xi = -1; pxi = -4; dx = x1 - x2; } // determining the direction of drawing if (y1 < y2) { yi = 1; pyi = bytesPerLine; dy = y2 - y1; } else { yi = -1; pyi = -bytesPerLine; dy = y1 - y2; } // first pixel //SetPixel(x, y, color); uchar* p = bits + y * bytesPerLine + x * 4; *((int*)p) = color; // the leading axis OX if (dx > dy) { ai = (dy - dx) * 2; bi = dy * 2; d = bi - dx; // loop for x while (x != x2) { // factor test if (d >= 0) { x += xi; p += pxi; y += yi; p += pyi; d += ai; } else { d += bi; x += xi; p += pxi; } //SetPixel(x, y, color); *((int*)p) = color; } } // the leading axis OY else { ai = (dx - dy) * 2; bi = dx * 2; d = bi - dy; // loop for y while (y != y2) { // factor test if (d >= 0) { x += xi; p += pxi; y += yi; p += pyi; d += ai; } else { d += bi; y += yi; p += pyi; } //SetPixel(x, y, color); *((int*)p) = color; } } } void Window::draw_clicked() { btn1->setEnabled(false); QImage myImage(100,100,QImage::Format_RGB32); QPainter p; p.begin(&myImage); p.setPen(QPen(QColor(Qt::color1))); p.setBrush(QBrush(QColor(Qt::color0), Qt::NoBrush)); LARGE_INTEGER n1,n2,f; QueryPerformanceCounter(&n1); for(int i=0; i<1000*1000; i++) p.drawLine(rand()%100, rand()%100, rand()%100, rand()%100); QueryPerformanceCounter(&n2); p.end(); btn1->setEnabled(true); label->setPixmap(QPixmap::fromImage(myImage)); QueryPerformanceFrequency(&f); QMessageBox msgBox; msgBox.setText("time "+QString::number(double(n2.QuadPart-n1.QuadPart)/f.QuadPart)); msgBox.exec(); } void Window::bresenham_clicked() { QImage myImage(100,100,QImage::Format_RGB32); uchar * bits = myImage.bits(); LARGE_INTEGER n1,n2,f; QueryPerformanceCounter(&n1); for(int i=0; i<1000*1000; i++) bresenham(rand()%100, rand()%100, rand()%100, rand()%100, 255, bits, myImage.bytesPerLine()); QueryPerformanceCounter(&n2); label->setPixmap(QPixmap::fromImage(myImage)); QueryPerformanceFrequency(&f); QMessageBox msgBox; msgBox.setText("time "+QString::number(double(n2.QuadPart-n1.QuadPart)/f.QuadPart)); msgBox.exec(); }
Po przejrzeniu algorytmów rysujących linie proste w grafice komputerowej wychodzi prosty wniosek. Sergiej Savchenko prześcignął Naszych algorytmików o duży krok. Jego algorytm rysowania linii prostej jest kilka razy szybszy od tych, co prezentowane są na tym portalu. Może ktoś by się dowiedział od zespołu twórców kart graficznych firmy NVidia jak się takie algorytmy tworzy? :)
Roman