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));
}

