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