多边型绘图.docx
《多边型绘图.docx》由会员分享,可在线阅读,更多相关《多边型绘图.docx(121页珍藏版)》请在冰豆网上搜索。
多边型绘图
第六章多邊型繪圖
作者:
南台科技大學電子系黎靖
1.座標系統:
2.繪製立體圖
//viewing.cpp:
viewing
#include"Marco_Lee.h"
#include"Graph_Lee.h"
Point3Viewing(Point3);
voidCoeff(float,float,float);
floatv11,v12,v13,v21,v22,v23,v32,v33,v43;
voidmain()
{
Point3P[]={
{100,80,50,0},{100,0,50,1},{100,0,0,1},{100,80,0,1},
{0,80,0,1},{0,80,50,1},{100,80,50,1},{100,80,0,1},
{100,0,50,0},{0,0,50,1},{0,0,0,1},{100,0,0,1},
{0,0,50,0},{0,80,50,1},{0,0,0,0},{0,80,0,1},
{100,0,50,0},{100,40,80,1},{100,80,50,1},{0,0,50,0},
{0,40,80,1},{0,80,50,1},{100,40,80,0},{0,40,80,1},
{100,50,72,0},{100,50,90,1},{100,65,90,1},{100,65,61,1},
{80,65,61,1},{80,65,90,1},{80,50,90,1},{100,50,90,1},
{100,65,90,0},{80,65,90,1},{80,50,90,0},{80,50,72,1},
{80,65,61,1},{100,50,72,0},{80,50,72,1},{0,0,0,-999}};
Point3p1,p2;
floatrho=500,theta=50,phi=70;
setWorkSpace(-100,-100,100,100);//x1,y1,x2,y2
setViewSpace(1,1,9,7);
Coeff(rho,theta,phi);
setWindow();
for(intk=0;P[k].connect!
=-999;k++)
{
p2=Viewing(P[k]);
if(0!
=P[k].connect)DrawLine(p1,p2,0,black);
p1=p2;
}
viewWindow();closeWindow();
}
voidCoeff(floatrho,floattheta,floatphi)//p.127
{
doublecosth,sinth,cosph,sinph;
costh=COS(theta);sinth=SIN(theta);
cosph=COS(phi);sinph=SIN(phi);
//ElementsofmatrixV,seeEq.(4-9):
v11=-sinth;v12=-cosph*costh;v13=-sinph*costh;
v21=costh;v22=-cosph*sinth;v23=-sinph*sinth;
v32=sinph;v33=-cosph;
v43=rho;
}
/******************************************************************/
Point3Viewing(Point3P)//p.127
{
Point3T;
//Eyecoordinates,computedasinEq.(4-2):
T.x=v11*P.x+v21*P.y;
T.y=v12*P.x+v22*P.y+v32*P.z;
T.z=v13*P.x+v23*P.y+v33*P.z+v43;
returnT;
}
3.加入視角的考慮
//perspective.cpp:
#include"Marco_Lee.h"
#include"Graph_Lee.h"
Point3Perspective(Point3);
voidCoeff(float,float,float);
floatv11,v12,v13,v21,v22,v23,v32,v33,v43;
floatscreen_dist=200,c1=50,c2=-10;
voidmain()
{
Point3P[]={
{100,80,50,0},{100,0,50,1},{100,0,0,1},{100,80,0,1},
{0,80,0,1},{0,80,50,1},{100,80,50,1},{100,80,0,1},
{100,0,50,0},{0,0,50,1},{0,0,0,1},{100,0,0,1},
{0,0,50,0},{0,80,50,1},{0,0,0,0},{0,80,0,1},
{100,0,50,0},{100,40,80,1},{100,80,50,1},{0,0,50,0},
{0,40,80,1},{0,80,50,1},{100,40,80,0},{0,40,80,1},
{100,50,72,0},{100,50,90,1},{100,65,90,1},{100,65,61,1},
{80,65,61,1},{80,65,90,1},{80,50,90,1},{100,50,90,1},
{100,65,90,0},{80,65,90,1},{80,50,90,0},{80,50,72,1},
{80,65,61,1},{100,50,72,0},{80,50,72,1},{0,0,0,-999}};
Point3p1,p2;
floatrho=300,theta=50,phi=70;
setWorkSpace(-100,-100,100,100);//x1,y1,x2,y2
setViewSpace(1,1,9,7);
Coeff(rho,theta,phi);
setWindow();
for(intk=0;P[k].connect!
=-999;k++)
{
p2=Perspective(P[k]);
if(0!
=P[k].connect)DrawLine(p1,p2,0,black);
p1=p2;
}
viewWindow();closeWindow();
}
voidCoeff(floatrho,floattheta,floatphi)//p.127
{
doublecosth,sinth,cosph,sinph;
costh=COS(theta);sinth=SIN(theta);
cosph=COS(phi);sinph=SIN(phi);
//ElementsofmatrixV,seeEq.(4-9):
v11=-sinth;v12=-cosph*costh;v13=-sinph*costh;
v21=costh;v22=-cosph*sinth;v23=-sinph*sinth;
v32=sinph;v33=-cosph;
v43=rho;
}
/******************************************************************/
Point3Perspective(Point3P)//p.127
{
Point3T,Pe;
//Eyecoordinates,computedasinEq.(4-2):
T.x=v11*P.x+v21*P.y;
T.y=v12*P.x+v22*P.y+v32*P.z;
T.z=v13*P.x+v23*P.y+v33*P.z+v43;
//Screencoordinates,computedasinEqs.(4-12)and(4.13)
Pe.x=screen_dist*T.x/T.z+c1;
Pe.y=screen_dist*T.y/T.z+c2;
returnPe;
}
screen_dist=500,c1=50,c2=-10;rho=400,theta=50,phi=70;
4.隱藏線處理(simple)
//common.h
#include
#include
#include
#include
#include"d_draw.h"//openWindow();viewWindow();closeWindow();
#include"d_linesh.h"//lineShapeclass
#defineMAX(x,y)((x)>(y)?
(x):
(y))
#defineMIN(x,y)((x)<(y)?
(x):
(y))
#defineMAX3(x,y,z)((x)>(y)?
MAX((x),(z)):
MAX((y),(z)))
#defineMIN3(x,y,z)((x)<(y)?
MIN((x),(z)):
MIN((y),(z)))
#defineSWAP(aux,a,b){(aux)=(a);(a)=(b);(b)=(aux);}
#defineSWAP3(aux,a,b,c){(aux)=(a);(a)=(b);(b)=(c);(c)=(aux);}
#defineSIGN(x)((x)>eps?
1:
(x)-1:
0)
#defineRD(0.0174533)//RD=3.14159/180
#defineBIG1.e30
typedefintINDEX;
typedeffloatCOEF;
typedeffloatDEGREE;
structPOSI{floatx,y,z;};
structWorkSpace{floatx1,y1,x2,y2;}WS;
structViewSpace{floatx1,y1,x2,y2;}VS;
POSIViewing(POSIP);
voidCoeff();
DEGREErho,theta,phi;
COEFv11,v12,v13,v21,v22,v23,v32,v33,v43;
/******************************************************************/
voidCoeff()//p.127
{
doubleth,ph,costh,sinth,cosph,sinph;
//anglesinradians:
th=theta*RD;ph=phi*RD;
costh=cos(th);sinth=sin(th);
cosph=cos(ph);sinph=sin(ph);
//ElementsofmatrixV,seeEq.(4-9):
v11=-sinth;v12=-cosph*costh;v13=-sinph*costh;
v21=costh;v22=-cosph*sinth;v23=-sinph*sinth;
v32=sinph;v33=-cosph;
v43=rho;
}
/******************************************************************/
POSIViewing(POSIP)//p.127
{
POSIT;
//Eyecoordinates,computedasinEq.(4-2):
T.x=v11*P.x+v21*P.y;
T.y=v12*P.x+v22*P.y+v32*P.z;
T.z=v13*P.x+v23*P.y+v33*P.z+v43;
returnT;
}
//Hidlin1.cpp:
Asimpleprogramforhidden-lineelimination
//TheoutputofthisprogramisthefileA.SCRATCH,
//whichistobereadbyGENPLOT.
#include"common.h"
#definenvertex200//Maxnoofvertices
#definentriangle200//Maxnoof(nobackface)trianglestobestored
structTria{intA,B,C;floata,b,c,h;};
voidReadData();
voidskipf();
intreflo(float*px);
intreint(int*pi);
voiderror(char*str);
voidlinesegment(POSI,POSI,int);
intntr=0;
floateps=1e-5,meps=-1e-5,oneminus=1-1.e-5,oneplus=1+1.e-5;
POSIVx[nvertex];
TriaTRI[ntriangle];
FILE*fin,*fout;
/******************************************************************/
voidmain()
{
inti,j;
fin=fopen("a.dat","r");
fout=fopen("a.scratch","w");
if(fout==NULL)error("filea.scratchcannotbeopened");
ReadData();
while(skipf(),fscanf(fin,"%d%d",&i,&j))
{
linesegment(Vx[i],Vx[j],0);
}
fclose(fout);
}
voidReadData()
{
inti;floatr;
POSIOr,P,A,B,C;Triat;charch;
fscanf(fin,"%f%f%f",&(Or.x),&(Or.y),&(Or.z));
skipf();
fscanf(fin,"%f%f%f",&rho,&theta,&phi);
Coeff();
while(skipf(),ch=getc(fin),ch!
='#')
{
ungetc(ch,fin);
fscanf(fin,"%d%f%f%f",&i,&(P.x),&(P.y),&(P.z));
if(i<0||i>=nvertex)error("illegalvertexnumber");
P.x-=Or.x;P.y-=Or.y;P.z-=Or.z;
Vx[i]=Viewing(P);
if(Vx[i].z<=eps)
{
printf("Objectpoint0andvertex%dlieon",i);
error("differentsidesofviewpointE.");
}
}
while(skipf(),ch=getc(fin),ch!
='#')
{
ungetc(ch,fin);
fscanf(fin,"%d%d%d",&(t.A),&(t.B),&(t.C));
A=Vx[t.A];B=Vx[t.B];C=Vx[t.C];
t.a=A.y*(B.z-C.z)-B.y*(A.z-C.z)+C.y*(A.z-B.z);
t.b=-(A.x*(B.z-C.z)-B.x*(A.z-C.z)+C.x*(A.z-B.z));
t.c=A.x*(B.y-C.y)-B.x*(A.y-C.y)+C.x*(A.y-B.y);
t.h=A.x*(B.y*C.z-C.y*B.z)-B.x*(A.y*C.z-C.y*A.z)+
C.x*(A.y*B.z-B.y*A.z);
if(t.h>0)
{
if(ntr==ntriangle)error("Toomanytriangles");
r=sqrt(t.a*t.a+t.b*t.b+t.c*t.c);
t.a/=r;t.b/=r;t.c/=r;t.h/=r;
TRI[ntr++]=t;
}
}
}
voidskipf(){while(getc(fin)!
='\n');}
voiderror(char*str){printf("%s\n",str);exit
(1);}
voidlinesegment(POSIP,POSIQ,intk0)
{
//linesegmentPQistobedrawn,asfarasitisnothiddenbythe
//trianglestrset[k0]totrset[ntrset-1].
boolworktodo=1,Pbeyond,Qbeyond,outside,
Poutside,Qoutside;
POSIA,B,C,T;
intk=k0,ia,ib,ic,i,sum;
floata,b,c,h,hP,hQ,r1,r2,r3,dA,dB,dC,labmin,labmax,
lab,mu,xmin,ymin,zmin,xmax,ymax,zmax,c1,c2,c3,
k1,k2,k3,denom1,denom2,Cpos,Ppos,Qpos,aux,eps1;
while(k{
a=TRI[k].a;b=TRI[k].b;c=TRI[k].c;h=TRI[k].h;
eps1=eps+eps*h;
//Test1:
hP=a*P.x+b*P.y+c*P.z;hQ=a*Q.x+b*Q.y+c*Q.z;
if(hP<=h+eps1&&hQ<=h+eps1)//PQnotbehindABC
{k++;continue;}
//Test2:
k1=P.y*Q.z-Q.y*P.z;k2=P.z*Q.x-Q.z*P.x;
k3=P.x*Q.y-Q.x*P.y;
ia=TRI[k].A;ib=TRI[k].B;ic=TRI[k].C;
A=Vx[ia];B=Vx[ib];C=Vx[ic];
dA=k1*A.x+k2*A.y+k3*A.z;dB=k1*B.x+k2*B.y+k3*B.z;
dC=k1*C.x+k2*C.y+k3*C.z;
//IfdA,dB,dChavethesamesign,theverticesA,B,C
//lieatthesamesideofplaneEPQ.
sum=SIGN(dA)+SIGN(dB)+SIGN(dC);
if(abs(sum)>=2){k++;continue;}
//Ifthistestsucceeds,the(infinite)linePQliesoutside
//pyramidEABC(orthelineandthepyramidhaveatmostone
//pointincommon).Ifthetestfails,thereisapointof
//intersection.
//Test3:
Poutside=Qoutside=0;labmin=1.;labmax=0.;
for(i=0;i<3;i++)
{
c1=A.y*B.z-B.y*A.z;c2=A.z*B.x-B.z*A.x;
c3=A.x*B.y-B.x*A.y;
//c1x+c2y+c3z=0isplaneEAB
Cpos=c1*C.x+c2*C.y+c3*C.z;
Ppos=c1*P.x+c2*P.y+c3*P.z;
Qpos=c1*Q.x+c2*Q.y+c3*Q.z;
denom1=Qpos-Ppos;
if(Cpos>eps)
{
Pbeyond=Pposoutside=(Pbeyond&&Qpos<=eps)||
(Qbeyond&&Ppos<=eps);
}
elseif(Cpos{
Pb