中点画线法的建立基础是数值微分画线法(DDA),其作为改进算法,沿用了DDA算法的增量思想,针对影响DDA算法效率的两点:(1)采用了浮点加法(2)浮点数在显示输出时需要取整;进行了改进,即中点画线法直接采用了整数的加法、比较。
代码如下:
#include
#include
#define SWAP(a, b) \
(a)=(a)^(b); \
(b)=(a)^(b); \
(a)=(a)^(b)
void DrawLine(HDC hdc, LONG x0, LONG y0, LONG x1, LONG y1) {
bool fx = false, fy = false;
if (x0 > x1) { SWAP(x0, x1); fx = true; }
if (y0 > y1) { SWAP(y0, y1); fy = true; }
double m = (y1 - y0) * 1.0f / (x1 - x0);
if (m > 1) {
m = 1 / m;
auto x = fx ? x1 : x0;
double s = x;
for (auto y = y0; y <= y1; ++y) {
SetPixel(hdc, x, y, RGB(0,0, 0));
s += (fx ? -m : m);
if (abs(s - x) >= 1) x += (fx ? -1 : 1);
}
} else {
auto y = fy ? y1 : y0;
double s = y;
for (auto x = x0; x <= x1; ++x) {
SetPixel(hdc, x, y, RGB(0, 0, 0));
s += (fy ? -m : m);
if (abs(s - y) >= 1) y += (fy ? -1 : 1);
}
}
}
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
HDC hdc;
PAINTSTRUCT ps;
switch (msg) {
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
DrawLine(hdc, 10, 10, 200, 100);
DrawLine(hdc, 10, 200, 200, 100);
DrawLine(hdc, 10, 10, 100, 200);
DrawLine(hdc, 10, 200, 100, 200);
EndPaint(hwnd, &ps);
return 0;
case WM_DESTROY:
ExitProcess(0);
return 0;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) {
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
WNDCLASS wc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
wc.hIcon = LoadIcon(nullptr, IDI_APPLICATION);
wc.hInstance = hInstance;
wc.lpfnWndProc = WndProc;
wc.lpszClassName = TEXT("WndClass");
wc.lpszMenuName = nullptr;
wc.style = CS_HREDRAW | CS_VREDRAW;
if (!RegisterClass(&wc)) {
MessageBox(nullptr, TEXT("注册窗口类失败!"), nullptr, MB_ICONERROR);
return ERROR;
}
HWND hwnd = CreateWindow(TEXT("WndClass"), TEXT("Bresenham2.0"),
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 400, 400,
nullptr, nullptr, hInstance, nullptr);
ShowWindow(hwnd, nShowCmd);
UpdateWindow(hwnd);
MSG msg;
while (GetMessage(&msg, nullptr, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}