《計算機圖形學》第四版練習題——BresenHam算法適配所有斜率情況

  閱讀《計算機圖形學》接觸到bresenham畫線算法,該算法的核心是用精確的化簡後結果衡量每次遞增單元格後另一個方向要不要相應遞增,書中列舉了斜率m絕對值小於1的情況算法,本文完善書中代碼使之適配所有斜率情況。

代碼如下:

#include <stdlib.h>
#include <math.h>
#include <Windows.h>

void drawpixel(int x, int y){
	HDC hdc = GetWindowDC(GetDesktopWindow());
	SetPixel(hdc, x, y, RGB(255, 0, 0));
	
}

void lineBres(int x0, int y0, int xEnd, int yEnd){
	int dx = abs(xEnd - x0);
	int dy = abs(yEnd - y0);
	int x, y;
	if (dx == 0)
	{
		int interval = (yEnd > y0) ? 1 : -1;
		x = x0, y = y0;
		drawpixel(x, y);
		while (y != yEnd)
		{
			y += interval;
			drawpixel(x, y);
		}
	}
	else if (dy == 0)
	{
		int interval = (xEnd > x0) ? 1 : -1;
		x = x0, y = y0;
		drawpixel(x, y);
		while (x != xEnd)
		{
			x += interval;
			drawpixel(x, y);
		}
	}
	else
	{

		
		bool klower1 = (dy <= dx);

		if (klower1)
		{
			int p = 2 * dy - dx;
			int twody = 2 * dy;
			int twodyminusdx = 2 * (dy - dx);

			if (xEnd < x0)
			{
				//交換首尾
				x0 = xEnd - x0;
				xEnd = xEnd - x0;
				x0 = xEnd + x0;
				y0 = yEnd - y0;
				yEnd = yEnd - y0;
				y0 = yEnd + y0;				
			}			
			x = x0;
			y = y0;
			drawpixel(x, y);
			while (x < xEnd)
			{
				x++;
				if (p < 0)
				{
					drawpixel(x, y);
					p += twody;
				}
				else
				{
					y += (yEnd > y0) ? 1 : -1;
					drawpixel(x, y);
					p += twodyminusdx;
				}
			}
		}
		else
		{
			int p = 2 * dx - dy;
			int twodx = 2 * dx;
			int twodxminusdy = 2 * (dx - dy);
			if (yEnd < y0)
			{
				//交換首尾
				x0 = xEnd - x0;
				xEnd = xEnd - x0;
				x0 = xEnd + x0;
				y0 = yEnd - y0;
				yEnd = yEnd - y0;
				y0 = yEnd + y0;
			}		
			x = x0;
			y = y0;
			drawpixel(x, y);
			while (y < yEnd)
			{
				y++;
				if (p < 0)
				{
					drawpixel(x, y);
					p += twodx;
				}
				else
				{
					x += (xEnd > x0) ? 1 : -1;
					drawpixel(x, y);
					p += twodxminusdy;
				}
			}
		}
	}
}

void main(){
	//dy==0
	lineBres(20, 10, 300, 10);
	lineBres(300, 10, 20, 10);
	//dx==0
	lineBres(20, 10, 20, 300);
	lineBres(20, 300, 20, 10);
	//m<1
	lineBres(20, 10, 300, 40);
	lineBres(300, 40, 20, 10);
	lineBres(20, 40, 300, 10);
	lineBres(300, 10, 20, 40);
	//m>1
	lineBres(20, 10, 300, 600);
	lineBres(300, 600, 20, 10);
	lineBres(20, 600, 300, 10);
	lineBres(300, 10, 20, 600);
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章