計算機圖形學幾個算法的關鍵代碼


一、中點畫線算法:

//中點畫線算法
void CMidPointLineView::MyMidLine(int x0, int y0, int x1, int y1)
{
	CClientDC dc(this);

	int a=0;
	int b=0;
	int d1=0;
	int d2=0;
	int d=0;
	int x=0;
	int y=0;
	
	a=y0-y1;
	b=x1-x0;
	d=2*a+b;
	d1=2*a;
	d2=2*a+2*b;
	x=x0;
	y=y0;
	
	dc.SetPixel(x,y,RGB(255,0,0));
	while(x<x1)
	{
		if(d<0)
		{
			x++;
			y++;
			d += d2;
		}
		else
		{
			x++;
			d += d1;
		}
		dc.SetPixel(x,y,RGB(255,0,0));
	}
}
效果圖如下:



二、中點畫圓算法:


//畫1/8圓弧
void CMidPointCircleView::MyMidCircle(int x0,int y0, int r)
{
	CClientDC dc(this);
	int x=0;
	int y=r;
	float d=1.25-r;
    CirclePoint(x0,y0,x,y);
	while(x<=y)
	{
		if(d<0)
		{
           d+=2*x+3;
		}
		else
		{
		d+=2*(x-y)+5;
		y--;
		}
		x++;
		CirclePoint(x0,y0,x,y);
	}
}
效果圖如下:


三、多邊形裁剪算法:


//直線窗口裁剪
int CPolygonCutView::DrawLine(float x1, float y1, float x2, float y2)

{
	CDC *pDC=GetDC();
	int code1,code2,code;
	float x,y;

	CPen redpen(PS_SOLID,1,RGB(255,0,0));//創建畫實線、線寬為2的紅色畫筆
	CPen *old=pDC->SelectObject(&redpen);

	encode(x1,y1,code1);
	encode(x2,y2,code2);
	while(code1!=0||code2!=0)
	{
		if(code1&code2)
			return 1;//線段在窗口外,返回
		code=code1;
		if(code1==0)code=code2;
		if(l&code)
		{
			x=left;
			y=y1+(y2-y1)*(left-x1)/(x2-x1);
		}
		else if(r&code)
		{
			x=right;
			y=y1+(y2-y1)*(right-x1)/(x2-x1);
		}
		else if(b&code)
		{
			y=bottom;
			x=x1+(x2-x1)*(bottom-y1)/(y2-y1);
		}
		else if(t&code)
		{
			y=top;
			x=x1+(x2-x1)*(top-y1)/(y2-y1);
		}
		if(code==code1)
		{
			x1=x;y1=y;encode(x,y,code1);
		}
		else
		{
			x2=x;y2=y;encode(x,y,code2);
		}
	}
	pDC->MoveTo(x1,y1);
	pDC->LineTo(x2,y2);

	ReleaseDC(pDC);

	return 1;
}

效果圖如下:


四、多邊形區域填充算法:


//掃描線填充算法
void CFieldFillView::ScanlineSeedfill(CDC *pDC, int x, int y, COLORREF boundaryvalue, COLORREF newvalue)
{
	int x0,xl,xr,y0,xid;
	int flag,xnextspan;
	stack<CPoint> s;//堆棧
	CPoint p;
	s.push(CPoint(x,y));//第一個種子入棧
	while (!s.empty())//堆棧不為空
	{
		p = s.top();
		s.pop();//取棧頂元素並彈棧
		pDC->SetPixel(p.x,p.y,newvalue);//繪制像素點為指定顏色
		x = p.x;y = p.y;
		x0 =x + 1;
		while (pDC->GetPixel(x0,y) != boundaryvalue)//填充右方元素
		{
			pDC->SetPixel(x0,y,newvalue);
			x0++;
		}
		xr = x0 -1;//最右邊像素
		x0 = x -1;
		while (pDC->GetPixel(x0,y) != boundaryvalue)//填充左方像素
		{
			pDC->SetPixel(x0,y,newvalue);
			x0--;
		}
		xl = x0 + 1;//最左邊像素
		//檢查上一條和下一條掃描線,若存在邊界且未填充的像素
		//則選取代表各連續區間的種子像素入棧
		y0 = y;
		for (int i=1;i>=-1;i-=2)
		{
			x0 = xr;
			y = y0 + i;//獲得上一行和下一行
			while (x0 >= xl)
			{
				flag = 0;
				while ((pDC->GetPixel(x0,y) != boundaryvalue)
					&& (pDC->GetPixel(x0,y) != newvalue) 
					&& (x0 > xl))
				{
					if (flag == 0)
					{
						flag = 1;
						xid = x0;
					}
					x0--;
				}
				if (flag == 1)
				{
					s.push(CPoint(xid,y));//新種子入棧
					flag = 0;
				}
				xnextspan = x0;
				while ((pDC->GetPixel(x0,y) == boundaryvalue)
					|| (pDC->GetPixel(x0,y) == newvalue)
					&& (x0 >= xl))
					x0--;
				if (xnextspan == x0) x0--;
			}
		}
	}
}

效果圖如下:




五、Bezier曲線生成算法:


//畫Bezier曲線
void CBezierView::OnBezier() 
{
	CDC*pDC=GetDC();
	RedrawWindow();
    CPen redpen(PS_SOLID,2,RGB(255,0,0));//創建畫筆
	CPen *old=pDC->SelectObject(&redpen);
	float x0=50,y0=80,x1=150,y1=250,x2=400,y2=130,x3=300,y3=70;
	float x,y,dt,t,n=30.0;
	int i ;
	dt=1/n;
	for(i=0;i<=n;i++)
	{
		t=i*dt;
		x=x0*(1-t)*(1-t)*(1-t)+x1*3*t*(1-t)*(1-t)+x2*3*t*t*(1-t)+x3*t*t*t;
        y=y0*(1-t)*(1-t)*(1-t)+y1*3*t*(1-t)*(1-t)+y2*3*t*t*(1-t)+y3*t*t*t;
		if(i==0)pDC->MoveTo(x,y);
		pDC->LineTo(x,y);
	}
    pDC->MoveTo(x0,y0);
	pDC->LineTo(x1,y1);
	pDC->LineTo(x2,y2);
	pDC->LineTo(x3,y3);

	pDC->SelectObject(old);
	ReleaseDC(pDC);
}

效果圖如下:





工程文件下載地址:http://www.kuaipan.cn/file/id_8128290032206914.htm











注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com