www.pudn.com > ZhuYouyong.rar > Graph.cpp


#include "stdafx.h" 
#include "Graph.h" 
#include "math.h" 
CGraph::CGraph(CWnd *cp):CClientDC(cp) 
{} 
 
void CGraph::DDAline(int x1,int y1,int x2,int y2)  
{ 
 
 int n,t,s; 
 float x,y,dx,dy; 
 
 t=x2-x1;s=y2-y1;n=abs(t); 
 if(n0) 
 { 
	 x+=dx; 
	 y+=dy; 
	 SetPixel(int(x+0.5),int(y+0.5),color); 
 } 
 
} 
 
 
 
 
 
 
void CGraph::bresenhamline(int x1,int y1,int x2,int y2) 
{int dx,dy,tmp,di,const1,const2,inc; 
	dx=x2-x1;dy=y2-y1;inc=1; 
if (abs(dx)>abs(dy)) 
{ if (dx<0) 
	{tmp=x1;x1=x2;x2=tmp;tmp=y1; 
        y1=y2;y2=tmp;dx=-dx;dy=-dy; 
    } 
   if (dy<0) 
   {dy=-dy;inc=-1;} 
    
    di=2*dy-dx; 
    const1=2*dy-2*dx; 
    const2=2*dy; 
    SetPixel(x1,y1,RGB(0,0,0)); 
    while (x1=0) 
		{y1=y1+inc; 
            di=di+const1; 
		} 
        else 
            di=di+const2; 
         
        SetPixel(x1,y1,RGB(0,0,0)); 
    } 
} 
else  
{if (dy<0) 
{tmp=x1;x1=x2;x2=tmp;tmp=y1; 
        y1=y2;y2=tmp;dx=-dx;dy=-dy; 
} 
    if (dx<0) 
	{ inc=-1;dx=-dx; 
    } 
    di=dy-2*dx; 
    const1=-2*dx; 
    const2=2*dy-2*dx; 
    SetPixel(x1,y1,RGB(0,0,0)); 
     
    while (y1=0) 
            di=di+const1; 
        else 
		{x1=x1+inc;di=di+const2; 
        } 
        SetPixel(x1,y1,RGB(0,0,0)); 
    } 
} 
} 
 
 
void CGraph::bresenham_circle(int x,int y,int m,int n) 
{ 
	double r,di; 
    int x1,y1; 
	 
	x1=x;y1=y; 
	r=sqrt((m-x)*(m-x)+(n-y)*(n-y)); 
 
 
	y=(int)(y+r); 
	di=3-2*r; 
    while(x<=y+x1-y1)        //曾在此犯了一个小错误! 
	{                       //坐标没有负的,全是正的。 
		if(di<0) 
		{ 
			x+=1; 
			di+=4*x+6-4*x1; 
		} 
		else 
		{ 
			x+=1; 
			y-=1; 
			di+=4*(x-y)+10-4*x1+4*y1; 
		} 
		 
		SetPixel(x,y,color); 
		SetPixel(x,2*y1-y,color); 
		SetPixel(2*x1-x,2*y1-y,color); 
		SetPixel(2*x1-x,y,color); 
		SetPixel(y+x1-y1,x-x1+y1,color); 
		SetPixel(y+x1-y1,y1+x1-x,color); 
		SetPixel(x1+y1-y,y1+x1-x,color); 
		SetPixel(x1+y1-y,x-x1+y1,color); 
	} 
} 
 
 
void CGraph::oval(int x,int y,int m,int n) 
{ 
	double a,b,fuck1,fuck2,x1,y1,x2,y2,di,mao; 
 
	x1=(x+m)/2;y1=(y+n)/2;   //椭圆心(x1,y1) 
	x2=x1;y2=y1; 
 
	if(n>y) 
	{ 
		a=(n-y1+sqrt((n-y1)*(n-y1)+4*(m-x1)*(m-x1)))/2; 
		b=sqrt((n-y1)*a); 
	} 
	else 
	{ 
		a=(y1-n+sqrt((y1-n)*(y1-n)+4*(m-x1)*(m-x1)))/2; 
		b=sqrt((y1-n)*a); 
	} 
 
	y2+=b;                       //椭圆上的点(x2,y2) 
	fuck1=2*b*b*(x2-x1); 
	fuck2=2*a*a*(y2-y1); 
 
	if(fuck1=0) 
			{ 
				x2+=1; 
				y2-=1; 
				di=di+2*b*b*(x2-x1)-2*a*a*(y2-y1)+b*b; 
			} 
			else 
			{ 
				x2+=1; 
				di=di+b*b+2*b*b*(x2-x1); 
			} 
			SetPixel(int(x2),(int)(y2),color); 
		    SetPixel(int(x2),(int)(2*y1-y2),color); 
		    SetPixel((int)(2*x1-x2),(int)(2*y1-y2),color); 
		    SetPixel((int)(2*x1-x2),(int)(y2),color); 
		    
			fuck1=2*b*b*(x2-x1); 
			fuck2=2*a*a*(y2-y1); 
		} 
	} 
 
	if(y2>=y1) 
		{ 
			mao=b*b*(x2+1-x1)*(x2+1-x1)+a*a*(y2-y1-0.5)*(y2-y1-0.5)-a*a*b*b; 
			di=mao+3*(a*a-b*b)/4-(fuck1+fuck2)/2; 
			while(y2>=y1) 
			{ 
				if(di>=0) 
				{ 
					y2-=1; 
					di=di-2*a*a*(y2-y1)+a*a; 
				} 
				else 
				{ 
					x2+=1; 
					y2-=1; 
					di=di+2*b*b*(x2-x1)-2*a*a*(y2-y1)+a*a; 
				} 
				SetPixel((int)(x2),(int)(y2),color); 
		    SetPixel((int)(x2),(int)(2*y1-y2),color); 
		    SetPixel((int)(2*x1-x2),(int)(2*y1-y2),color); 
		    SetPixel((int)(2*x1-x2),(int)(y2),color); 
		     
			} 
		} 
	 
 
	 
} 
 
 
void CGraph::spline(int x,int y,int m,int n,int p,int q) 
{ 
	double t=0,xx,yy; 
 
	while((t<=1)&&(m!=p)&&(n!=q)) 
	{ 
		xx=(t*t-2*t+1)*x/2+(t+0.5-t*t)*m+t*t*p/2; 
		yy=(t*t-2*t+1)*y/2+(t+0.5-t*t)*n+t*t*q/2; 
		SetPixel((int)(xx),(int)(yy),color); 
		t+=0.01; 
	} 
} 
 
void CGraph::areafill(int cnt,CPoint *pts) 
{ 
	Edge *edges[WINDOW_HEIGH],*active; 
	int i,scan,scanmax=0,scanmin=WINDOW_HEIGH; 
     
	for(i=0;ipts[i].y) 
			scanmin=pts[i].y; 
	} 
 
	for(scan=scanmin;scan<=scanmax;scan++) 
	{ 
		edges[scan]=(Edge *)malloc(sizeof(Edge)); 
		edges[scan]->next=0; 
	} 
 
	buildedgelist(cnt,pts,edges);    //建立EOT 
 
	active=(Edge *)malloc(sizeof(Edge)); 
	active->next=0; 
 
	for(scan=scanmax;scan>=scanmin;scan--) 
	{ 
		buildactivelist(scan,active,edges); 
		fillscan(scan,active); 
		updateactivelist(scan-1,active); 
	} 
} 
 
 
void CGraph::buildedgelist(int cnt,CPoint *pts,Edge *edges[]) 
{ 
	Edge *edge; 
	CPoint p1,p2; 
	int i; 
	p1=pts[cnt-1]; 
	for(i=0;idx=-(float)(p2.x-p1.x)/(p2.y-p1.y); 
			if(p1.y>p2.y) 
			{ 
				edge->x=float(p1.x); 
				edge->ymin=p2.y; 
				insertedge(edges[p1.y],edge); 
			} 
			else 
			{ 
				edge->x=float(p2.x); 
				edge->ymin=p1.y; 
				insertedge(edges[p2.y],edge); 
			} 
		} 
		p1=p2; 
	} 
} 
 
 
void CGraph::insertedge(Edge *list,Edge *edge) 
{ 
	Edge *p,*q=list; 
	p=q->next; 
	while(p) 
	{ 
		if(edge->xx||edge->x+edge->dxx+p->dx) 
			p=0; 
		else 
		{ 
			q=p; 
			p=p->next; 
		} 
	} 
	edge->next=q->next; 
	q->next=edge; 
} 
 
 
void CGraph::buildactivelist(int scan,Edge *active,Edge *edges[])  //创建AET表 
{ 
	Edge *q=edges[scan],*p; 
	p=q->next; 
	while(p) 
	{ 
		q=p->next;              //grave 
		insertedge(active,p);   //grave 
		p=q;                    //grave 
 
		//    insertedge(active,p); 
		//    p=p->next; 
		//    此乃出错原因之所在!见explain. 
	} 
} 
 
void CGraph::fillscan(int scan,Edge *active) 
{ 
	Edge *p,*q=active; 
	p=q->next; 
	while(p&&p->next) 
	{ 
		bresenhamline((int)(p->x),scan,(int)(p->next->x),scan); 
		p=p->next->next; 
	} 
} 
 
void CGraph::updateactivelist(int scan,Edge *active) 
{ 
	Edge *p,*q=active; 
	p=q->next; 
	while(p) 
	{ 
		if(scan<=p->ymin)        //删除该节点! 
		{ 
			q->next=p->next; 
			p=p->next; 
		} 
		else 
		{ 
		p->x=p->x+p->dx; 
		q=p; 
		p=p->next; 
		} 
	} 
} 
 
 
 
 
void CGraph::Line3D(Point3D ps,Point3D pe,double D,double R,double theta,double phi) 
{ 
	CPoint p1,p2; 
	p1=PTrans(ps,D,R,theta,phi); 
	p2=PTrans(pe,D,R,theta,phi);          
	DDAline(p1.x+400,p1.y+200,p2.x+400,p2.y+200); 
} 
 
CPoint CGraph::PTrans(Point3D p3,double D,double R,double theta,double phi) 
{ 
	CPoint p; 
	double stheta=sin(theta*3.14159/180), 
		   ctheta=cos(theta*3.14159/180), 
		   sphi=sin(phi*3.14159/180), 
		   cphi=cos(phi*3.14159/180); 
	double xe=-p3.x*stheta+p3.y*ctheta, 
		   ye=-p3.x*ctheta*cphi-p3.y*stheta*cphi+p3.z*sphi, 
	       ze=-p3.x*ctheta*sphi-p3.y*stheta*sphi-p3.z*cphi+R; 
	p.x=D*xe/ze; 
	p.y=D*ye/ze; 
	return p; 
} 
 
void CGraph::huatu(CPoint cao) 
{ 
int laji; 
double l,r,h,o,dou,pi,z; 
Point3D m1,m2,m3,m4,m5,m6,m7,m8,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10; 
CPoint c1,c2,c3; 
laji=100; 
m1.x=laji;m1.y=laji;m1.z=0;m2.x=laji;m2.y=laji+chad;m2.z=0; 
m3.x=laji+chad;m3.y=laji;m3.z=0;m4.x=laji+chad;m4.y=laji+chad;m4.z=0; 
m5.x=laji;m5.y=laji;m5.z=chad;m6.x=laji;m6.y=laji+chad;m6.z=chad; 
m7.x=laji+chad;m7.y=laji;m7.z=chad;m8.x=laji+chad;m8.y=laji+chad;m8.z=chad; 
 
dou=jian/sqrt(2);z=350;pi=3.14159; 
 
n1.x=0;n1.y=0;n1.z=0;n2.x=0;n2.y=0;n2.z=zuobiao; 
n3.x=0;n3.y=-dou;n3.z=zuobiao-dou;n4.x=0;n4.y=dou;n4.z=zuobiao-dou; 
n5.x=zuobiao;n5.y=0;n5.z=0;n6.x=zuobiao-dou;n6.y=-dou;n6.z=0; 
n7.x=zuobiao-dou;n7.y=dou;n7.z=0;n8.x=0;n8.y=zuobiao;n8.z=0; 
n9.x=-dou;n9.y=zuobiao-dou;n9.z=0;n10.x=dou;n10.y=zuobiao-dou;n10.z=0; 
 
 
r=sqrt(cao.x*cao.x+cao.y*cao.y+z*z); 
l=200;h=cao.x*360/1020;o=cao.y*360/645; 
 
//r=400;h=100;o=100; 
//h=atan(cao.y/cao.x)*180/pi; 
//o=(pi/2-atan(z/sqrt(cao.x*cao.x+cao.y*cao.y)))*180/pi; 
 
     Line3D(m1,m2,l,r,h,o); 
	 Line3D(m1,m3,l,r,h,o); 
	 Line3D(m3,m4,l,r,h,o); 
	 Line3D(m4,m2,l,r,h,o); 
 
	 Line3D(m5,m6,l,r,h,o); 
	 Line3D(m5,m7,l,r,h,o); 
	 Line3D(m7,m8,l,r,h,o); 
	 Line3D(m8,m6,l,r,h,o); 
 
	 Line3D(m1,m5,l,r,h,o); 
	 Line3D(m6,m2,l,r,h,o); 
	 Line3D(m3,m7,l,r,h,o); 
	 Line3D(m4,m8,l,r,h,o); 
	  
	 Line3D(n1,n2,l,r,h,o);Line3D(n3,n2,l,r,h,o);Line3D(n4,n2,l,r,h,o); 
	 Line3D(n1,n5,l,r,h,o);Line3D(n5,n6,l,r,h,o);Line3D(n5,n7,l,r,h,o); 
	 Line3D(n1,n8,l,r,h,o);Line3D(n8,n9,l,r,h,o);Line3D(n8,n10,l,r,h,o); 
} 
 
 
CPoint CGraph::clip3dline(Point3D p1,Point3D p2,CPoint cao) 
{ 
	float D,theta,phi,d=200,k2=106,k1=92,s; 
	float scf=1,pi=3.141592,sn1,sn2,cn1,cn2; 
	float xvmin=5,yvmin=5,xvmax=475,yvmax; 
	float xe1,ye1,ze1,xc1,yc1,zc1,w1,txs1,tys1,tzs1,xs1,ys1; 
	float xe2,ye2,ze2,xc2,yc2,zc2,w2,txs2,tys2,tzs2,xs2,ys2; 
	float wc[3][7],t,t1,t2,dx,dy,dz,dw,w; 
	int i,code[7]={0,1,2,4,8,16,32}; 
	unsigned char c1=0,c2=0; 
 
	CPoint fuck; 
 
	D=sqrt(cao.x*cao.x+cao.y*cao.y+350*350); 
    theta=cao.x*360/1020;phi=cao.y*360/645; 
 
	s=(xvmax-xvmin)/2; 
	yvmax=yvmin+s*2; 
	theta=theta*pi/180;phi=phi*pi/180; 
	sn1=sin(theta);sn2=sin(phi); 
	cn1=cos(theta);cn2=cos(phi); 
	xe1=-p1.x*sn1+p1.y*cn1; 
	ye1=-p1.x*cn1*cn2-p1.y*cn2*sn1+p1.z*sn2; 
	ze1=-p1.x*sn2*cn1-p1.y*sn2*sn1-p1.z*cn2+D; 
 
	xe2=-p2.x*sn1+p2.y*cn1; 
	ye2=-p2.x*cn1*cn2-p2.y*cn2*sn1+p2.z*sn2; 
	ze2=-p2.x*sn2*cn1-p2.y*sn2*sn1-p2.z*cn2+D; 
	xc1=xe1;yc1=ye1;w1=s*ze1/d; 
	zc1=s*k2*(ze1-k1)/(d*(k2-k1)); 
	xc2=xe2;yc2=ye2;w2=s*ze2/d; 
	zc2=s*k2*(ze2-k1)/(d*(k2-k1)); 
 
	wc[1][1]=w1+xc1;wc[1][2]=w1-xc1; 
	wc[1][3]=w1+yc1;wc[1][4]=w1-yc1; 
	wc[1][5]=zc1;wc[1][6]=w1-zc1; 
	for(i=1;i<=6;i++) 
		if(wc[1][i]<0) 
			c1=c1+code[i]; 
 
    wc[2][1]=w2+xc2;wc[2][2]=w2-xc2; 
	wc[2][3]=w2+yc2;wc[2][4]=w2-yc2; 
	wc[2][5]=zc2;wc[2][6]=w2-zc2; 
	for(i=1;i<=6;i++) 
		if(wc[2][i]<0) 
			c2=c2+code[i]; 
   
    if((c1&c2)!=0) 
		goto l1; 
	t1=0;t2=1; 
	for(i=1;i<=6;i++) 
		if((wc[1][i]<0)|wc[2][i]<0) 
		{ 
			t=wc[1][i]/(wc[1][i]-wc[2][i]); 
			if(wc[1][i]<0) 
				if(t>t1) 
					t1=t; 
			else 
				if(t=t1) 
	{ 
		dx=xc2-xc1;dy=yc2-yc1; 
		dz=zc2-zc1;dw=w2-w1; 
		if(t2!=1) 
		{ 
			xc2=xc1+t2*dx;yc2=yc1+t2*dy; 
			zc2=zc1+t2*dz;w2=w1+t2*dw; 
		} 
		if(t1!=0) 
		{ 
			xc1=xc1+t1*dx;yc1=yc1+t1*dy; 
			zc1=zc1+t1*dz;w1=w1+t1*dw; 
		} 
 
l1:  txs1=xc1/w1;tys1=yc1/w1;tzs1=zc1/w1; 
	 txs2=xc2/w2;tys2=yc2/w2;tzs2=zc2/w2; 
	 xs1=txs1*s+(xvmax+xvmin)/2;xs1=xs1*scf; 
	 ys1=tys1*s+(yvmax+yvmin)/2; 
	 xs2=txs2*s+(xvmax+xvmin)/2;xs2=xs2*scf; 
	 ys2=tys2*s+(yvmax+yvmin)/2; 
	 DDAline(xs1,480-ys1,xs2,480-ys2); 
	} 
l2:  ; 
fuck.x=xs1;fuck.y=480-ys1; 
	 return fuck; 
} 
 
void CGraph::draw3dline(CPoint cao) 
{ 
//	float x,y,z,x1,y1,z1,x2,y2,z2,dou; 
//	int flag,max=10,laji; 
//	Point3D j1,j2; 
int laji; 
float dou; 
Point3D m1,m2,m3,m4,m5,m6,m7,m8,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10; 
CPoint c1,c2,c3; 
laji=100; 
m1.x=laji;m1.y=laji;m1.z=0;m2.x=laji;m2.y=laji+chad;m2.z=0; 
m3.x=laji+chad;m3.y=laji;m3.z=0;m4.x=laji+chad;m4.y=laji+chad;m4.z=0; 
m5.x=laji;m5.y=laji;m5.z=chad;m6.x=laji;m6.y=laji+chad;m6.z=chad; 
m7.x=laji+chad;m7.y=laji;m7.z=chad;m8.x=laji+chad;m8.y=laji+chad;m8.z=chad; 
 
dou=jian/sqrt(2); 
 
n1.x=0;n1.y=0;n1.z=0;n2.x=0;n2.y=0;n2.z=zuobiao; 
n3.x=0;n3.y=-dou;n3.z=zuobiao-dou;n4.x=0;n4.y=dou;n4.z=zuobiao-dou; 
n5.x=zuobiao;n5.y=0;n5.z=0;n6.x=zuobiao-dou;n6.y=-dou;n6.z=0; 
n7.x=zuobiao-dou;n7.y=dou;n7.z=0;n8.x=0;n8.y=zuobiao;n8.z=0; 
n9.x=-dou;n9.y=zuobiao-dou;n9.z=0;n10.x=dou;n10.y=zuobiao-dou;n10.z=0; 
 
	//for(x=max;x>=-max;x--) 
	//{ 
	//	flag=0; 
	//	for(y=-max;y<=max;y=y+0.5) 
	//	{ 
	//		z=7*exp(-0.1*(x*x+y*y)); 
	//		if(flag==0) 
	//		{ 
	//			x1=x;y1=y;z1=z;flag=1;goto label; 
	//		} 
	//		x2=x;y2=y;z2=z; 
	//		j1.x=x1;j1.y=y1;j1.z=z1;j2.x=x2;j2.y=y2;j2.z=z2; 
	//		clip3dline(j1,j2,cao); 
	//		x1=x2;y1=y2;z1=z2; 
//label:  ; 
//		} 
//	} 
 
clip3dline(m1,m2,cao);clip3dline(m1,m3,cao);clip3dline(m3,m4,cao);clip3dline(m4,m2,cao); 
clip3dline(m5,m6,cao);clip3dline(m5,m7,cao);clip3dline(m7,m8,cao);clip3dline(m8,m6,cao); 
clip3dline(m1,m5,cao);clip3dline(m6,m2,cao);clip3dline(m3,m7,cao);clip3dline(m4,m8,cao); 
clip3dline(n1,n2,cao);clip3dline(n3,n2,cao);clip3dline(n4,n2,cao);clip3dline(n1,n5,cao); 
clip3dline(n5,n6,cao);clip3dline(n5,n7,cao);clip3dline(n1,n8,cao);clip3dline(n8,n9,cao); 
clip3dline(n8,n10,cao); 
 
}