74 lines
2.2 KiB
C++
74 lines
2.2 KiB
C++
#include <functional>
|
|
#include <algorithm>
|
|
#include <utility>
|
|
|
|
void WuDrawLine(float x0, float y0, float x1, float y1,
|
|
const std::function<void(int x, int y, float brightess)>& plot) {
|
|
auto ipart = [](float x) -> int {return int(std::floor(x));};
|
|
auto round = [](float x) -> float {return std::round(x);};
|
|
auto fpart = [](float x) -> float {return x - std::floor(x);};
|
|
auto rfpart = [=](float x) -> float {return 1 - fpart(x);};
|
|
|
|
const bool steep = abs(y1 - y0) > abs(x1 - x0);
|
|
if (steep) {
|
|
std::swap(x0,y0);
|
|
std::swap(x1,y1);
|
|
}
|
|
if (x0 > x1) {
|
|
std::swap(x0,x1);
|
|
std::swap(y0,y1);
|
|
}
|
|
|
|
const float dx = x1 - x0;
|
|
const float dy = y1 - y0;
|
|
const float gradient = (dx == 0) ? 1 : dy/dx;
|
|
|
|
int xpx11;
|
|
float intery;
|
|
{
|
|
const float xend = round(x0);
|
|
const float yend = y0 + gradient * (xend - x0);
|
|
const float xgap = rfpart(x0 + 0.5);
|
|
xpx11 = int(xend);
|
|
const int ypx11 = ipart(yend);
|
|
if (steep) {
|
|
plot(ypx11, xpx11, rfpart(yend) * xgap);
|
|
plot(ypx11 + 1, xpx11, fpart(yend) * xgap);
|
|
} else {
|
|
plot(xpx11, ypx11, rfpart(yend) * xgap);
|
|
plot(xpx11, ypx11 + 1, fpart(yend) * xgap);
|
|
}
|
|
intery = yend + gradient;
|
|
}
|
|
|
|
int xpx12;
|
|
{
|
|
const float xend = round(x1);
|
|
const float yend = y1 + gradient * (xend - x1);
|
|
const float xgap = rfpart(x1 + 0.5);
|
|
xpx12 = int(xend);
|
|
const int ypx12 = ipart(yend);
|
|
if (steep) {
|
|
plot(ypx12, xpx12, rfpart(yend) * xgap);
|
|
plot(ypx12 + 1, xpx12, fpart(yend) * xgap);
|
|
} else {
|
|
plot(xpx12, ypx12, rfpart(yend) * xgap);
|
|
plot(xpx12, ypx12 + 1, fpart(yend) * xgap);
|
|
}
|
|
}
|
|
|
|
if (steep) {
|
|
for (int x = xpx11 + 1; x < xpx12; x++) {
|
|
plot(ipart(intery), x, rfpart(intery));
|
|
plot(ipart(intery) + 1, x, fpart(intery));
|
|
intery += gradient;
|
|
}
|
|
} else {
|
|
for (int x = xpx11 + 1; x < xpx12; x++) {
|
|
plot(x, ipart(intery), rfpart(intery));
|
|
plot(x, ipart(intery) + 1, fpart(intery));
|
|
intery += gradient;
|
|
}
|
|
}
|
|
}
|