计算机图形学中点画直线的算法

计算机图形学中点画直线的算法


一、中点画线法

中点画线法的建立基础是数值微分画线法(DDA),其作为改进算法,沿用了DDA算法的增量思想,针对影响DDA算法效率的两点:(1)采用了浮点加法(2)浮点数在显示输出时需要取整;进行了改进,即中点画线法直接采用了整数的加法、比较。

二、实现C代码

代码如下:

#include <windows.h>
#include <algorithm>

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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BridgeCloud

生活不易,多多支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值