Nadesłany przez Andrzej Borucki, 27 stycznia 2012 01:18
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 elips ****************************************************************************/ #include <QtGui> #include <windows.h> #include "window.h" Window::Window() : QWidget() { label = new QLabel(tr("Image")); QFormLayout *layout = new QFormLayout; btnDraw = new QPushButton("bresenham"); editCx = new QLineEdit("100"); editCy = new QLineEdit("100"); editRx = new QLineEdit("100"); editRy = new QLineEdit("100"); layout->addRow(btnDraw); layout->addRow(label); layout->addRow("Center X",editCx); layout->addRow("Center Y",editCy); layout->addRow("RadiusX",editRx); layout->addRow("RadiusY",editRy); setLayout(layout); connect( btnDraw, SIGNAL(clicked()), SLOT(bresenham_clicked()) ); } int W,H; uchar *bits; int bytesPerLine; void SetPixel(int x, int y, int color) { if ((x >= 0) && (y >= 0) && (x < W) && (y < H)) { uchar* p = bits + y * bytesPerLine + x * 4; *((int*)p) = color; } } void ElipsePoints(int x, int y, int x0, int y0, int color) { SetPixel(x + x0, y + y0, color); SetPixel(x + x0, -y + y0, color); SetPixel(-x + x0, -y + y0, color); SetPixel(-x + x0, y + y0, color); } void bresenham_ellipse(int x0, int y0, int radius_a, int radius_b, int color) { int x, y, limit; long d; int radius_a2, radius_b2; if ((radius_a == 0) && (radius_b == 0)) { SetPixel(x0, y0, color); return; } radius_a2 = radius_a * radius_a; radius_b2 = radius_b * radius_b; if (radius_b2 == 0) d = 0; else d = 4 * radius_b2 - 4 * radius_b * radius_a2 + radius_a2; limit = (int)(((double)radius_a2 * radius_a2) / (radius_a2 + radius_b2)+0.5); x = 0; y = radius_b; while (x * x < limit) { ElipsePoints(x, y, x0, y0, color); if (d > 0) { d += 8 * (long)radius_b2 * x + 12 * radius_b2 - 8 * (long)radius_a2 * y + 8 * radius_a2; x++; y--; } else { if (radius_b2 > 1) d += 7 * (long)radius_b2 * x + 12 * radius_b2; else if ((x + 2) * (x + 2) >= limit) y --; x++; } } //second part int aux = radius_a; radius_a = radius_b; radius_b = aux; radius_a2 = radius_a * radius_a; radius_b2 = radius_b * radius_b; if (radius_b == 0) d = 0; else d = 4 * radius_b2 - 4 * radius_b * radius_a2 + radius_a2; limit = (int)(((double)radius_a2 * radius_a2) / (radius_a2 + radius_b2) + 0.5); x = 0; y = radius_b; while (x * x < limit) { ElipsePoints(y, x, x0, y0, color); if (d > 0) { d += 8 * (long)radius_b2 * x + 12 * radius_b2 - 8 * (long)radius_a2 * y + 8 * radius_a2; x++; y--; } else { if (radius_b2 > 1) d += 8 * (long)radius_b2 * x + 12 * radius_b2; else if ((x + 2) * (x + 2) >= limit) y--; x++; } } } void Window::bresenham_clicked() { QImage myImage(200,200,QImage::Format_RGB32); bits = myImage.bits(); bytesPerLine = myImage.bytesPerLine(); W = myImage.width(); H = myImage.height(); bresenham_ellipse(editCx->text().toInt(), editCy->text().toInt(), editRx->text().toInt(), editRy->text().toInt(), 255); label->setPixmap(QPixmap::fromImage(myImage)); }