计算机图形学常见简单算法整理

直线段的扫描转换算法(3)

1.DDA画直线算法

void CLine_ScanView::DDALine(int x1, int y1, int x2, int y2, int color)

{

    int dx,dy,epsl,k;

    float x=10,y=10,xIncre,yIncre;

    dx = x2-x1;

    dy = y2-y1;

    k = dy/dx;

    y = y1;

    if(abs(dx)>abs(dy))

        epsl = abs(dx);

    else

        epsl = abs(dy);

    xIncre = (float)dx/(float)epsl;

    yIncre = (float)dy/(float)epsl;

    CClientDC dc(this);

    for(k=0;k<=epsl;k++){

        dc.SetPixel((int) x,(int) y,color);

        x += xIncre;

        y += yIncre;

}   }

2.MidBresenham画直线算法

void CLine_ScanView::MidBresenhamLine(int x1, int y1, int x2, int y2, int color)

{

    int dx,dy,d,UpIncre,DownIncre,x,y;

    if(x1>x2){

        x=x2;x2=x1;x1=x;

        y=y2;y2=y1;y1=y;

    }

    x=x1;

    y=y1;

    dx=x2-x1;

    dy=y2-y1;

    d=dx-2*dy;

    CClientDC dc(this);

    UpIncre=2*dx-2*dy;

    DownIncre=-2*dy;

    while(x<=x2){

        dc.SetPixel(x,y,color);

        x++;

        if(d<0){

            y++;

            d += UpIncre;

    }

        else

            d += DownIncre;

    }  }

3.Bresenham画直线算法

void CLine_ScanView::BresenhamLine(int x1, int y1, int x2, int y2, int color)

{

    int x,y,dx,dy,e;

    dx = x2-x1;

    dy = y2-y1;

    e = -dx;

    x = x1;

    y = y1;

    CClientDC dc(this);

    while(x<=x2){

        dc.SetPixel(x,y,color);

        x++;

        e = e+2*dy;

        if(e>0){

            y++;

            e=e-2*dx;

        }

    }    }

圆的扫描转换算法(2/椭圆1)

1. 中点画圆算法

void CLine_ScanView::MidBresenhamCircle(int r, int color)

{

    int x = 0;

    int y = r;

    int d = 1-r;

    int x0 = 100;

    int y0 = 100;

    CDC *pDC = GetDC();

    while(x<=y){

        pDC->SetPixel(x+x0,y+y0,color);

        pDC->SetPixel(-x+x0,y+y0,color);

        pDC->SetPixel(-x+x0,-y+y0,color);

        pDC->SetPixel(x+x0,-y+y0,color);

        pDC->SetPixel(y+x0,x+y0,color);

        pDC->SetPixel(-y+x0,x+y0,color);

        pDC->SetPixel(-y+x0,-x+y0,color);

        pDC->SetPixel(y+x0,-x+y0,color);

        if(d<0)  d+=2*x+3;

        else{ d+=2*(x-y)+5; y--; }

        x++;

    }  }

2.Breshnham画圆算法

circle (xc, yc, radius, c)

int xc, yc, radius, c;

{

int x, y, p;

x=0;

y=radius;

p=3-2*radius;

while (x<y)

{

  plot_circle_points(xc, yc, x, y, c);

  if (p<0) p=p+4*x+6;

  else{ p=p+4*(x-y)+10; y-=1; }

  x+=1;                

}

if (x= =y)

plot_circle_points(xc, yc, x, y, c);

}

plot_circle_points(xc, yc, x, y, c)

int xc, yc, x, y, c;

{

set_pixel(xc+x, yc+y, c);

set_pixel(xc+x, yc+y, c);

set_pixel(xc+x, yc-y, c);

set_pixel(xc-x, yc-y, c);

set_pixel(xc+y, yc+x, c);

set_pixel(xc-y, yc+x, c);

set_pixel(xc+y, yc-x, c);

set_pixel(xc-y, yc-x, c);

}

3.中点画椭圆算法

MidpointEllipe(a,b, color)

    int a,b,color;

    {  int x,y;  float d1,d2;

        x = 0; y = b;

        d1 = b*b +a*a*(-b+0.25);

       ellipesputpixel(x,y,color);

       while( b*b*(x+1) < a*a*(y-0.5))  生成上半部分椭圆

       {     {  if (d1<0)

            d1 +=b*b*(2*x+3); x++;  }

            else  {  d1 +=(b*b*(2*x+3)+a*a*(-2*y+2))

                x++;  y--;  }

        ellipesputpixel(x,y,color);

    }//上部分

        d2 = b*b*(x+0.5)*(x+0.5)+a*a*(y-1)*(y-1)-a*a*b*b;

        while(y >0)   生成下半部分椭圆

      {  if (d2 <0) { d2 +=b*b*(2*x+2)+a*a*(-2*y+3);

              x++;  y--;}

          else  {d2 += a*a*(-2*y+3);  y--; }

       ellipesputpixel(x,y,color); }

Void ellipespixel(int x,int y,int color)

{

        putpixel(x,y,color)

        putpixel(-x,y,color)

        putpixel(x,-y,color)

        putpixel(-x,-y,color)

}

 

填充算法(3)

1.种子填充算法——递归算法可实现如下:

void FloodFill4(int x,int y,int oldColor,int newColor)

{  if(GetPixel(x,y) == oldColor)

  { PutPixel(x,y,newColor);

    FloodFill4(x,y+1,oldColor,newColor);

    FloodFill4(x,y-1,oldColor,newColor);

    FloodFill4(x-1,y,oldColor,newColor);

   FloodFill4(x+1,y,oldColor,newColor);

   }

}

2.多边形的4种子填充算法——边界表示的4连通区域

void CLine_ScanView::BoundaryFill4(int x, int y, int boundarycolor, int newcolor)

{

    CDC* pDC = GetDC();

    CPen pen;

    pen.CreatePen(PS_SOLID,2,RGB(0,255,0));

    pDC->SelectObject(&pen);

    int a[4][2] = {200,100,180,120,220,120,200,100};

    pDC->MoveTo(a[0][0],a[0][1]);

    for(int i=0;i<4;i++) {

        pDC->LineTo(a[i][0],a[i][1]);

    }

    int color = pDC->GetPixel(x,y);

    if(color!=newcolor&&color!=boundarycolor){

        pDC->SetPixel(x,y,newcolor);

        BoundaryFill4(x,y+1,boundarycolor,newcolor);

        BoundaryFill4(x,y-1,boundarycolor,newcolor);

        BoundaryFill4(x+1,y,boundarycolor,newcolor);

        BoundaryFill4(x-1,y,boundarycolor,newcolor);

    }

}

3.多边形的8种子填充算法——边界表示的4连通区域

void CLine_ScanView::BoundaryFill8(int x, int y, int boundarycolor, int newcolor)

{

    CDC* pDC = GetDC();

    CPen pen;

    pen.CreatePen(PS_SOLID,2,RGB(0,255,0));

    pDC->SelectObject(&pen);

    int a[4][2] = {200,100,180,120,220,120,200,100};

    pDC->MoveTo(a[0][0],a[0][1]);

    for(int i=0;i<4;i++) {

        pDC->LineTo(a[i][0],a[i][1]);

    }

    int color = pDC->GetPixel(x,y);

    if(color!=newcolor&&color!=boundarycolor){

        pDC->SetPixel(x,y,newcolor);

        BoundaryFill8(x,y+1,boundarycolor,newcolor);

        BoundaryFill8(x+1,y+1,boundarycolor,newcolor);

        BoundaryFill8(x,y-1,boundarycolor,newcolor);

        BoundaryFill8(x-1,y-1,boundarycolor,newcolor);

        BoundaryFill8(x+1,y,boundarycolor,newcolor);

        BoundaryFill8(x+1,y-1,boundarycolor,newcolor);

        BoundaryFill8(x-1,y,boundarycolor,newcolor);

        BoundaryFill8(x-1,y+1,boundarycolor,newcolor);

    }

}

二维变换(5)

1.二维变换的比例变换响应函数

void CLine_ScanView::OnTwoProportion()

{

    // TODO: 在此添加命令处理程序代码

    CClientDC dc(this);

    CPen pen1;

    pen1.CreatePen(PS_SOLID,2,RGB(255,10,255)); 

    int a[11][2]={100,105,90,135,60,135,85,155,75,185,100,165,125,185,115,155,140,135,110,135,100,105};

    dc.SelectObject(&pen1);

    dc.MoveTo (a[0][0],a[0][1]);

    for(int i=0;i<11;i++) { 

        dc.LineTo (a[i][0],a[i][1]);

    }  

    double sx=0.5,sy=0.5; 

    dc.MoveTo (a[0][0]*sx,a[0][1]*sy);

    for(int i=0;i<11;i++) { 

        dc.LineTo (a[i][0]*sx,a[i][1]*sy);

        Sleep(5);

    }

    pen1.DeleteObject();

}

2.二维变换的旋转变换响应函数

void CLine_ScanView::OnTwoRotating()

{

    // TODO: 在此添加命令处理程序代码

    CClientDC dc(this);

    CPen pen1;

    pen1.CreatePen(PS_SOLID,2,RGB(255,10,255));

    int  a[11][2]={100,105,90,135,60,135,85,155,75,185,100,165,125,185,115,155,140,135,110,135,100,105};

    dc.SelectObject(&pen1);

    dc.MoveTo (a[0][0],a[0][1]);

    for(int i=0;i<11;i++) { 

        dc.LineTo (a[i][0],a[i][1]);

    }

    int t = 600;

    dc.MoveTo (a[0][0]*cos((t/6)*1.0)-a[0][1]*sin((t/6)*1.0),//一个点

        a[0][0]*sin((t/6)*1.0)+a[0][1]*cos((t/6)*1.0));

    for(int i=0;i<11;i++) { 

        dc.LineTo (a[i][0]*cos((t/6)*1.0)-a[i][1]*sin((t/6)*1.0),//一个点

            a[i][0]*sin((t/6)*1.0)+a[i][1]*cos((t/6)*1.0));

    } 

    pen1.DeleteObject();

}

3.二维变换的错切变换响应函数

void CLine_ScanView::OnTwoShear()

{

    // TODO: 在此添加命令处理程序代码

    CClientDC dc(this);

    CPen pen1;

    pen1.CreatePen(PS_SOLID,2,RGB(255,10,255));

    int  a[11][2]={100,105,90,135,60,135,85,155,75,185,100,165,125,185,115,155,140,135,110,135,100,105};

    dc.SelectObject(&pen1);

    dc.MoveTo (a[0][0],a[0][1]);

    for(int i=0;i<11;i++) { 

        dc.LineTo (a[i][0],a[i][1]);

    }

    double c=2,d=1.5,u=50;

    dc.MoveTo (a[0][0]+c*a[0][1],a[0][1]-u);

    for(int i=0;i<11;i++) { 

        dc.LineTo (a[i][0]+c*a[i][1],a[i][1]-u);

    }

    int s=170,h=200;

    dc.MoveTo (a[0][0]+s,d*a[0][0]+a[0][1]-h);

    for(int i=0;i<11;i++) {

        dc.LineTo (a[i][0]+s,d*a[i][0]+a[i][1]-h);

    } 

    pen1.DeleteObject();

}

4.二维变换的对称变换响应函数

void CLine_ScanView::OnTwoSymmetry()

{

    // TODO: 在此添加命令处理程序代码

    CClientDC dc(this);

    CPen pen1;

    pen1.CreatePen(PS_SOLID,2,RGB(255,10,255)); 

    int  a[11][2]={100,105,90,135,60,135,85,155,75,185,100,165,125,185,115,155,140,135,110,135,100,105};

    dc.SelectObject(&pen1);

    dc.MoveTo (a[0][0],a[0][1]);

    for(int i=0;i<11;i++) { 

        dc.LineTo (a[i][0],a[i][1]);

    }

    int m=0,b=200;

    dc.MoveTo (a[0][0]*(1-m*m)/(1+m*m)+2*(a[0][1]-b)*m/(1+m*m),//一个点

        a[0][0]*(2*m)/(1+m*m)+(a[0][1]-b)*(m*m-1)/(1+m*m)+b);

    for(int i=0;i<11;i++) { 

        dc.LineTo (a[i][0]*(1-m*m)/(1+m*m)+2*(a[i][1]-b)*m/(1+m*m), a[i][0]*(2*m)/(1+m*m)+(a[i][1]-b)*(m*m-1)/(1+m*m)+b);

    }  

    pen1.DeleteObject(); 

}

5.二维变换的平移变换响应函数

void CLine_ScanView::OnTwoTranslation()

{

    // TODO: 在此添加命令处理程序代码

    CClientDC dc(this);

    CPen pen1;

    pen1.CreatePen(PS_SOLID,2,RGB(255,10,255));

    int  a[11][2]={100,105,90,135,60,135,85,155,75,185,100,165,125,185,115,155,140,135,110,135,100,105};

    dc.SelectObject(&pen1);

    dc.MoveTo (a[0][0],a[0][1]);

    for(int i=0;i<11;i++) { 

        dc.LineTo (a[i][0],a[i][1]);

    } 

    int tx=120,ty=100; 

    dc.MoveTo (a[0][0]+tx,a[0][1]+ty);

    for(int i=0;i<11;i++) { 

        dc.LineTo (a[i][0]+tx,a[i][1]+ty);

    }  

    pen1.DeleteObject();

}

三维变换(5)

1.三维变换的比例变换响应函数

void CLine_ScanView::OnThreeProportion()

{

    // TODO: 在此添加命令处理程序代码

    CClientDC dc(this);

    CPen pen1,pen2;

    pen1.CreatePen(PS_SOLID,2,RGB(0,0,0));

    pen2.CreatePen(PS_SOLID,2,RGB(0,255,0));

    int a[4][4] = {100,150,0,1,50,200,0,1,150,200,0,1,100,150,0,1};

    dc.SelectObject(&pen1);

    dc.MoveTo (a[0][0],a[0][1]);

    for(int i=0;i<4;i++){

        dc.LineTo(a[i][0],a[i][1]);

    }

    int b[4][4] = {2,0,0,0,0,2,0,0,0,0,2,0,0,0,0,1};

    int c[4][4];

    for(int i=0;i<4;i++){

        for(int j=0;j<4;j++){

            c[i][j] = 0;

        }

    }

    for(int i=0;i<4;i++){

        for(int j=0;j<4;j++){

            for(int k=0;k<4;k++){

                c[i][j]=c[i][j]+a[i][k]*b[k][j];

            }

        }

    }

    dc.SelectObject(&pen2);

    dc.MoveTo(c[0][0],c[0][1]);

    for(int i=0;i<4;i++){

        dc.LineTo(c[i][0],c[i][1]);

    }

    pen1.DeleteObject();

    pen2.DeleteObject();

}

2.三维变换的旋转变换响应函数

void CLine_ScanView::OnThreeRotating()

{

    // TODO: 在此添加命令处理程序代码

    CClientDC dc(this);

    CPen pen1,pen2;

    pen1.CreatePen(PS_SOLID,2,RGB(0,0,0));

    pen2.CreatePen(PS_SOLID,2,RGB(255,0,0));

    int a[4][4] = {100,150,0,1,50,200,0,1,150,200,0,1,100,150,0,1};

    dc.SelectObject(&pen1);

    dc.MoveTo (a[0][0],a[0][1]);

    for(int i=0;i<4;i++) { 

        dc.LineTo (a[i][0],a[i][1]);

    }

    int t = 600;

    dc.SelectObject(&pen2);

    dc.MoveTo (a[0][0]*cos((t/6)*1.0)-a[0][1]*sin((t/6)*1.0),//一个点

        a[0][0]*sin((t/6)*1.0)+a[0][1]*cos((t/6)*1.0));

    for(int i=0;i<4;i++) { 

        dc.LineTo (a[i][0]*cos((t/6)*1.0)-a[i][1]*sin((t/6)*1.0),//一个点

            a[i][0]*sin((t/6)*1.0)+a[i][1]*cos((t/6)*1.0));

    } 

    pen1.DeleteObject();

    pen2.DeleteObject();

}

3.三维变换的错切变换响应函数

void CLine_ScanView::OnThreeShear()

{

    // TODO: 在此添加命令处理程序代码

    CClientDC dc(this);

    CPen pen1,pen2;

    pen1.CreatePen(PS_SOLID,2,RGB(0,0,0));

    pen2.CreatePen(PS_SOLID,2,RGB(255,255,0));

    int a[4][4] = {100,150,0,1,50,200,0,1,150,200,0,1,100,150,0,1};

    dc.SelectObject(&pen1);

    dc.MoveTo (a[0][0],a[0][1]);

    for(int i=0;i<4;i++){

        dc.LineTo(a[i][0],a[i][1]);

    }

    int b[4][4] = {1,2,0,0,1.5,1,0,0,0,0,1,0,0,0,0,1};

    int c[4][4];

    for(int i=0;i<4;i++){

        for(int j=0;j<4;j++){

            c[i][j] = 0;

        }

    }

    for(int i=0;i<4;i++){

        for(int j=0;j<4;j++){

            for(int k=0;k<4;k++){

                c[i][j]=c[i][j]+a[i][k]*b[k][j];

            }

        }

    }

    dc.SelectObject(&pen2);

    dc.MoveTo(c[0][0],c[0][1]);

    for(int i=0;i<4;i++){

        dc.LineTo(c[i][0],c[i][1]);

    }

    pen1.DeleteObject();

    pen2.DeleteObject();

}

4.三维变换的对称变换响应函数

void CLine_ScanView::OnThreeSymmetry()

{

    // TODO: 在此添加命令处理程序代码

    CClientDC dc(this);

    CPen pen1,pen2;

    pen1.CreatePen(PS_SOLID,2,RGB(0,0,0));

    pen2.CreatePen(PS_SOLID,2,RGB(0,255,255));

    int a[4][4] = {100,150,0,1,50,200,0,1,150,200,0,1,100,150,0,1};

    dc.SelectObject(&pen1);

    dc.MoveTo (a[0][0],a[0][1]);

    for(int i=0;i<4;i++){

        dc.LineTo(a[i][0],a[i][1]);

    }

    int b[4][4] = {0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,1};  //沿y=x对称

    int c[4][4];

    for(int i=0;i<4;i++){

        for(int j=0;j<4;j++){

            c[i][j] = 0;

        }

    }

    for(int i=0;i<4;i++){

        for(int j=0;j<4;j++){

            for(int k=0;k<4;k++){

                c[i][j]=c[i][j]+a[i][k]*b[k][j];

            }

        }

    }

    dc.SelectObject(&pen2);

    dc.MoveTo(c[0][0],c[0][1]);

    for(int i=0;i<4;i++){

        dc.LineTo(c[i][0],c[i][1]);

    }

    pen1.DeleteObject();

    pen2.DeleteObject();

}

5.三维变换的平移变换响应函数

void CLine_ScanView::OnThreeTranslation()

{

    // TODO: 在此添加命令处理程序代码

    CClientDC dc(this);

    CPen pen1,pen2;

    pen1.CreatePen(PS_SOLID,2,RGB(0,0,0));

    pen2.CreatePen(PS_SOLID,2,RGB(0,0,255));

    int a[4][4] = {100,150,0,1,50,200,0,1,150,200,0,1,100,150,0,1};

    dc.SelectObject(&pen1);

    dc.MoveTo (a[0][0],a[0][1]);

    for(int i=0;i<4;i++){

        dc.LineTo(a[i][0],a[i][1]);

    }

    int b[4][4] = {1,0,0,0,0,1,0,0,0,0,1,0,100,100,0,1};

    int c[4][4];

    for(int i=0;i<4;i++){

        for(int j=0;j<4;j++){

            c[i][j] = 0;

        }

    }

    for(int i=0;i<4;i++){

        for(int j=0;j<4;j++){

            for(int k=0;k<4;k++){

                c[i][j]=c[i][j]+a[i][k]*b[k][j];

            }

        }

    }

    dc.SelectObject(&pen2);

    dc.MoveTo(c[0][0],c[0][1]);

    for(int i=0;i<4;i++){

        dc.LineTo(c[i][0],c[i][1]);

    }

    pen1.DeleteObject();

    pen2.DeleteObject();

}

 

编码裁剪(Cohen-Sutherland)法裁剪

// 直线段CS裁剪算法的响应函数

void CLine_ScanView::OnLineCs()

{

         // TODO: 在此添加命令处理程序代码

         Line_Cut lc;

         lc.DoModal();

         int min_clip_x = 100 ,min_clip_y = 100 ,max_clip_x = 300,max_clip_y=300 ; 

         CClientDC dc(this);

        

         dc.MoveTo(min_clip_x,min_clip_y);

         dc.LineTo(min_clip_x,max_clip_y);

         dc.MoveTo(min_clip_x,max_clip_y );

         dc.LineTo(max_clip_x,max_clip_y);

         dc.MoveTo(max_clip_x,max_clip_y );

         dc.LineTo(max_clip_x,min_clip_y);

         dc.MoveTo(max_clip_x,min_clip_y );

         dc.LineTo(min_clip_x,min_clip_y);

         if(CutLine(lc.x0,lc.y0,lc.x1,lc.y1)){

                   dc.MoveTo(lc.x0,lc.y0 );

             dc.LineTo(lc.x1,lc.y1);

         }

}

// 直线段的CS裁剪算法

int CLine_ScanView::CutLine(int& x0, int& y0, int& x1, int& y1)

{

         #define CLIP_CODE_C 0x0000 

         #define CLIP_CODE_N 0x0008 

         #define CLIP_CODE_S 0x0004 

         #define CLIP_CODE_E 0x0002 

         #define CLIP_CODE_W 0x0001 

 

         #define CLIP_CODE_NE 0x000a 

         #define CLIP_CODE_SE 0x0006 

         #define CLIP_CODE_NW 0x0009 

         #define CLIP_CODE_SW 0x0005 

    int xc0 = x0 ,yc0 = y0 , xc1=x1 , yc1=y1 ; 

    int min_clip_x = 100 ,min_clip_y = 100 ,max_clip_x = 300,max_clip_y=300 ; 

    int p0_code = 0 ,p1_code = 0 ; 

 

    //确定各个顶点所在的位置代码 

    if(y0<min_clip_y) 

        p0_code|=CLIP_CODE_N; 

    else if(y0>max_clip_y) 

        p0_code|=CLIP_CODE_S; 

 

    if(x0<min_clip_x) 

        p0_code|=CLIP_CODE_W; 

    else if(x0>max_clip_x) 

        p0_code|=CLIP_CODE_E; 

 

    if(y1<min_clip_y) 

        p1_code|=CLIP_CODE_N; 

    else if(y1>max_clip_y) 

        p1_code|=CLIP_CODE_S; 

 

    if(x1<min_clip_x) 

        p1_code|=CLIP_CODE_W; 

    else if(x1>max_clip_x) 

        p1_code|=CLIP_CODE_E; 

 

    //先检测一些简单的情况 

    if(p0_code&p1_code) //有相同的位置代码,表示在裁剪区外部 

        return 0 ; 

    if(p0_code==0&&p1_code==0) //表示两个点都在裁剪区内,不需要裁剪 

        return 1 ; 

 

    //判断第一个点的位置代码 

    switch(p0_code) 

    { 

    case CLIP_CODE_C: 

        break; 

    case CLIP_CODE_N: 

        { 

            yc0 = min_clip_y ; 

            xc0 = x0 + 0.5 + (yc0-y0)*(x1-x0)/(y1-y0); 

            break ; 

        } 

    case CLIP_CODE_S: 

        { 

            yc0 = max_clip_y; 

            xc0 = x0 + 0.5 + (yc0-y0)*(x1-x0)/(y1-y0); 

            break ; 

        } 

    case CLIP_CODE_W: 

        { 

            xc0=min_clip_x; 

            yc0=y0+0.5+(xc0-x0)*(y1-y0)/(x1-x0); 

            break; 

        } 

    case CLIP_CODE_E: 

        { 

            xc0=max_clip_x; 

            yc0=y0+0.5+(xc0-x0)*(y1-y0)/(x1-x0); 

            break; 

        } 

    case CLIP_CODE_NE: 

        { 

            yc0 = min_clip_y; 

            xc0 = x0 + 0.5 + (yc0-y0)*(x1-x0)/(y1-y0); 

 

            if(xc0<min_clip_x||xc0>max_clip_x) 

            { 

                xc0=max_clip_x; 

                yc0=y0+0.5+(xc0-x0)*(y1-y0)/(x1-x0); 

            } 

            break; 

        } 

    case CLIP_CODE_SE: 

        { 

            yc0 = max_clip_y; 

            xc0 = x0 + 0.5 + (yc0-y0)*(x1-x0)/(y1-y0); 

 

            if(xc0<min_clip_x||xc0>max_clip_x) 

            { 

                xc0=max_clip_x; 

                yc0=y0+0.5+(xc0-x0)*(y1-y0)/(x1-x0); 

            } 

            break; 

        } 

    case CLIP_CODE_NW: 

        { 

            yc0=min_clip_y; 

            xc0 = x0 + 0.5 + (yc0-y0)*(x1-x0)/(y1-y0); 

 

            if(xc0<min_clip_x||xc0>max_clip_x) 

            { 

                xc0=min_clip_x; 

                yc0=y0+0.5+(xc0-x0)*(y1-y0)/(x1-x0); 

            } 

            break; 

        } 

    case CLIP_CODE_SW: 

        { 

            yc0=max_clip_y; 

            xc0 = x0 + 0.5 + (yc0-y0)*(x1-x0)/(y1-y0); 

 

            if(xc0<min_clip_x||xc0>max_clip_x) 

            { 

                xc0=min_clip_x; 

                yc0=y0+0.5+(xc0-x0)*(y1-y0)/(x1-x0); 

            } 

            break; 

        } 

    default: 

        break; 

    } // end switch(p0_code) 

 

    //判断第二个点的位置代码 

    switch(p1_code) 

    { 

    case CLIP_CODE_C: 

        break; 

    case CLIP_CODE_N: 

        { 

            yc1 = min_clip_y ; 

            xc1 = x1 + 0.5 + (yc1-y1)*(x1-x0)/(y1-y0); 

            break ; 

        } 

    case CLIP_CODE_S: 

        { 

            yc1 = max_clip_y; 

            xc1 = x1 + 0.5 + (yc1-y1)*(x1-x0)/(y1-y0); 

            break ; 

        } 

    case CLIP_CODE_W: 

        { 

            xc1=min_clip_x; 

            yc1=y1+0.5+(xc1-x1)*(y1-y0)/(x1-x0); 

            break; 

        } 

    case CLIP_CODE_E: 

        { 

            xc1=max_clip_x; 

            yc1=y1+0.5+(xc1-x1)*(y1-y0)/(x1-x0); 

            break; 

        } 

    case CLIP_CODE_NE: 

        { 

            yc1 = min_clip_y; 

            xc1 = x1 + 0.5 + (yc1-y1)*(x1-x0)/(y1-y0); 

 

            if(xc1<min_clip_x||xc1>max_clip_x) 

            { 

                xc1=max_clip_x; 

                yc1=y1+0.5+(xc1-x1)*(y1-y0)/(x1-x0); 

            } 

            break; 

        } 

    case CLIP_CODE_SE: 

        { 

            yc1 = max_clip_y; 

            xc1 = x1 + 0.5 + (yc1-y1)*(x1-x0)/(y1-y0); 

 

            if(xc1<min_clip_x||xc1>max_clip_x) 

            { 

                xc1=max_clip_x; 

                yc1=y1+0.5+(xc1-x1)*(y1-y0)/(x1-x0); 

            } 

            break; 

        } 

    case CLIP_CODE_NW: 

        { 

            yc1=min_clip_y; 

            xc1 = x1 + 0.5 + (yc1-y1)*(x1-x0)/(y1-y0); 

 

            if(xc1<min_clip_x||xc1>max_clip_x) 

            { 

                xc1=min_clip_x; 

                yc1=y1+0.5+(xc1-x1)*(y1-y0)/(x1-x0); 

            } 

            break; 

        } 

    case CLIP_CODE_SW: 

        { 

            yc1=max_clip_y; 

            xc1 = x1 + 0.5 + (yc1-y1)*(x1-x0)/(y1-y0); 

 

            if(xc1<min_clip_x||xc1>max_clip_x) 

            { 

                xc1=min_clip_x; 

                yc1=y1+0.5+(xc1-x1)*(y1-y0)/(x1-x0); 

            } 

            break; 

        } 

    default: 

        break; 

    } // end switch(p1_code) 

 

    //进行最后的检测 

    if(xc0>max_clip_x||xc0<min_clip_x|| 

        yc0>max_clip_y||yc0<min_clip_y|| 

        xc1>max_clip_x||xc1<min_clip_x|| 

        yc1>max_clip_y||yc1<min_clip_y) 

    { 

        //表示全部在裁剪区外部 

        return 0 ; 

    } 

 

    //将裁减后的数据返回 

    x0 = xc0 ; 

    x1 = xc1 ; 

    y0 = yc0 ; 

    y1 = yc1 ; 

 

    return 1 ;

}

 

// 直线段中点分割算法的响应函数

void CLine_ScanView::OnLineMidpoint()

{

         // TODO: 在此添加命令处理程序代码

         int x0,y0,x1,y1;

         CClientDC dc(this);

         int min_clip_x = 100 ,min_clip_y = 100 ,max_clip_x = 300,max_clip_y=300 ;

         dc.MoveTo(min_clip_x,min_clip_y);

         dc.LineTo(min_clip_x,max_clip_y);

         dc.MoveTo(min_clip_x,max_clip_y );

         dc.LineTo(max_clip_x,max_clip_y);

         dc.MoveTo(max_clip_x,max_clip_y );

         dc.LineTo(max_clip_x,min_clip_y);

         dc.MoveTo(max_clip_x,min_clip_y );

         dc.LineTo(min_clip_x,min_clip_y);

 

         x0=120;y0=90;x1=310,y1=310;

    Mid_CutLine(x0,y0,x1,y1);

}

 

// 直线段的中点分割算法

void CLine_ScanView::Mid_CutLine(int x0, int y0, int x1, int y1)

{

         #define CLIP_CODE_C 0x0000 

         #define CLIP_CODE_N 0x0008 

         #define CLIP_CODE_S 0x0004 

         #define CLIP_CODE_E 0x0002 

         #define CLIP_CODE_W 0x0001 

 

         #define CLIP_CODE_NE 0x000a 

         #define CLIP_CODE_SE 0x0006 

         #define CLIP_CODE_NW 0x0009 

         #define CLIP_CODE_SW 0x0005 

 

         int min_clip_x = 100 ,min_clip_y = 100 ,max_clip_x = 300,max_clip_y=300 ;

         int p0_code = 0 ,p1_code = 0 ; 

 

    //确定各个顶点所在的位置代码 

    if(y0<min_clip_y) 

        p0_code|=CLIP_CODE_N; 

    else if(y0>max_clip_y) 

        p0_code|=CLIP_CODE_S; 

 

    if(x0<min_clip_x) 

        p0_code|=CLIP_CODE_W; 

    else if(x0>max_clip_x) 

        p0_code|=CLIP_CODE_E; 

 

    if(y1<min_clip_y) 

        p1_code|=CLIP_CODE_N; 

    else if(y1>max_clip_y) 

        p1_code|=CLIP_CODE_S; 

 

    if(x1<min_clip_x) 

        p1_code|=CLIP_CODE_W; 

    else if(x1>max_clip_x) 

        p1_code|=CLIP_CODE_E; 

 

    //先检测一些简单的情况 

    if(p0_code&p1_code) //有相同的位置代码,表示在裁剪区外部 

         {return ;} 

    else if(p0_code==0&&p1_code==0) //表示两个点都在裁剪区内,不需要裁剪 

         {

              CClientDC dc(this);

                    dc.MoveTo(x0,y0 );

              dc.LineTo(x1,y1);

                    return;

         } else

         {

                   int x2,y2;

                   x2=(x0+x1)/2;

                   y2=(y0+y1)/2;

                   if(x0-x2>1||x2-x0>1)

                   {

                            Mid_CutLine(x0,y0,x2,y2);

                   }

                   if(x1-x2>1||x2-x1>1)

                   {

                            Mid_CutLine(x2,y2,x1,y1);

                   }

         }

 

         return;

}

 

 

 

  • 8
    点赞
  • 73
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值