直线段的扫描转换算法(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;
}