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

```//中點畫線算法
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曲線
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);
}```