计算机图形学几个算法的关键C++代码

jopen 12年前

一、中点画线算法:

//中点画线算法  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));   }  }
效果图如下:

计算机图形学几个算法的关键C++代码

 

二、中点画圆算法:


//画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);   }  }
效果图如下:

计算机图形学几个算法的关键C++代码

 

三、多边形裁剪算法:


//直线窗口裁剪  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;  }

效果图如下:

计算机图形学几个算法的关键C++代码

 

四、多边形区域填充算法:


//扫描线填充算法  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--;     }    }   }  }

效果图如下:

计算机图形学几个算法的关键C++代码

 

 

五、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);  }

效果图如下:

计算机图形学几个算法的关键C++代码

 

 

 

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