#include "graphics.h"
#include "math.h"
#include "conio.h"
#include "stdio.h"
#include "ctype.h"
#define SCALE 1.35
typedef int Table[639];
Table HMax,HMin,TabAux;
enum {Perspective,Parallel} Projection;
float Aux1,Aux2,Aux3,Aux4,Aux5,Aux6,Aux7,Aux8,XObs,YObs,ZObs;
float Rol,Theta,Phi,DE,X1,X2,Y1,Y2,IncX,IncY,F1,F2,F3,F4,EchX,EchY,Ech;
float Slope,delta,X,Y,Z,Den,Xii,Yii,XProj,YProj,S;
int C1,C2,C3,C4,Xg,Yg,Xd,Yd,LNo,PNo,MaxX,MaxY;
char Scl;
int Ln,Pt,I,Sn,VisCur,VisPre;
float Th,Ph,w1,w2,w3,FV,e1,e2,v1,v2,v1v2,Aux;
int Xe,Ye,XPre,YPre,XCur,YCur,*pi,LimY;
int XYi[2],Vis,Ma,Mi,XX,YY,dX,Xi,Yi;
void EnterData()
{
unsigned short Choice;
clrscr();
printf("SURFACES OF EQUATION Z=F(X,Y)\n");
printf("=================================\n");
printf("Enter X axis interval[X1,X2]:(-190,190)\n");
scanf("%f,%f",&X1,&X2);
printf("Enter Y axis interval[X1,X2]:(-120,120)\n");
scanf("%f,%f",&Y1,&Y2);
printf("How many lines(158)?\n");
scanf("%d",&LNo);
printf("How many Points(100)?\n");
scanf("%d",&PNo);
printf("Is X and Y the same scale?(Y/N)\n");
Scl=getch();
printf("Choose the following projection.\n");
printf("=================================\n");
printf("1.Projection:perspective\n");
printf("2.Projection:parallel\n");
printf("3.Projection:dimetrical parallel\n");
printf("4.Projection:isometrical parallel\n");
printf("Which Projection?(3)\n");
scanf("%d",&Choice);
Projection=Parallel;
switch(Choice)
{
case 1:
{
printf("Enter R:(20)\n");
scanf("%f",&Rol);
printf("Enter D:(300)\n");
scanf("%f",&DE);
printf("Enter Theta:(48)\n");
scanf("%f",&Theta);
printf("Enter Phi:(39)\n");
scanf("%f",&Phi);
Projection=Perspective;
break;
}
case 2:
{
printf("Zoom scale?(20)\n");
scanf("%f",&S);
printf("Enter Theta:(45)\n");
scanf("%f",&Theta);
printf("Enter Phi:(34)\n");
scanf("%f",&Phi);
break;
}
case 3:
{
printf("Zoom scale?(20)\n");
scanf("%f",&S);
Theta=22.20765;
Phi=20.704811;
break;
}
case 4:
{
printf("Zoom scale?(20)\n");
scanf("%f",&S);
Theta=45;
Phi=35.26439;
break;
}
}
}
void InitData()
{
MaxX=getmaxx();
MaxY=getmaxy();
IncX=(X2-X1)/PNo;
IncY=(Y2-Y1)/LNo;
C1=0;
C2=MaxX;
C3=0;
C4=MaxY;
F1=1E37;
F2=-1E37;
F3=1E37;
F4=-1E37;
Xg=-1;
Yg=-1;
Xd=-1;
Yd=-1;
for(I=0;I<=MaxX;I++)
HMax[I]=0;
for(I=0;I<=MaxX;I++)
HMin[I]=MaxY;
if((Theta<0)||(Theta>180))
{
Aux=X1;
X1=X2;
X2=Aux;
IncX=-IncX;
Aux=Y1;
Y1=Y2;
Y2=Aux;
IncY=-IncY;
}
}
void InitProject()
{
Th=3.1415926*Theta/180.0;
Ph=3.1415926*Phi/180.0;
Aux1=sin(Th);
Aux2=sin(Ph);
Aux3=cos(Th);
Aux4=cos(Ph);
Aux5=Aux3*Aux2;
Aux6=Aux1*Aux2;
Aux7=Aux3*Aux4;
Aux8=Aux1*Aux4;
}
void Project(float X,float Y,float Z)
{
XObs=-X*Aux1+Y*Aux3;
YObs=-X*Aux5-Y*Aux6+Z*Aux4;
if(Projection==Perspective)
{
ZObs=-X*Aux7-Y*Aux8-Z*Aux2+Rol;
XProj=DE*XObs/ZObs;
YProj=DE*YObs/ZObs;
}
else
{
XProj=S*XObs;
YProj=S*YObs;
}
}
float F(float X,float Y)
{
e1=2.0;
e2=1.0;
v1=35.8;
v2=32.0;
w1=(X-e1)/v1;
w2=(Y-e2)/v2;
w3=-(w1*w1+w2*w2)/2;
v1v2=2*3.1415926*v1*v2;
FV=1000000.0*exp(w3)/v1v2;
return(FV);
}
int Sign(float X)
{
if(X>0) Sn=1;
else if(X<0) Sn=-1;
else Sn=0;
return(Sn);
}
void FindWindow()
{
for(Ln=0;Ln<=LNo;Ln++)
{
Y=Y2-Ln*IncY;
for(Pt=0;Pt<=PNo;Pt++)
{
X=X1+Pt*IncX;
Z=F(X,Y);
Project(X,Y,Z);
if(XProj<F1) F1=XProj;
if(XProj>F2) F2=XProj;
if(YProj<F3) F3=YProj;
if(YProj>F4) F4=YProj;
}
}
}
void CalculateScale()
{
EchX=(C2-C1)/(F2-F1);
EchY=(C4-C3)/(F4-F3);
if(toupper(Scl)=='Y')
{
if(EchX<EchY) EchY=EchX;
else
EchX=EchY;
}
}
int Max(int X1,int X2)
{
if(X1>X2) Ma=X1;
else Ma=X2;
return(Ma);
}
int Min(int X1,int X2)
{
if(X1<X2) Mi=X1;
else
Mi=X2;
return(Mi);
}
void Horizon(int X1,int Y1,int X2,int Y2)
{
delta=X2-X1;
dX=Sign(delta);
if(dX==0)
{
HMax[X2+1]=Max(HMax[X2],Y2);
HMin[X2+1]=Min(HMin[X2],Y2);
}
else
{
Slope=(Y2-Y1)/(X2-X1);
for(XX=X2+1;XX<=X1;XX++)
{
YY=Slope*(XX-X1)+Y1;
HMax[XX]=Max(HMax[XX],YY);
HMin[XX]=Min(HMin[XX],YY);
}
}
}
int Visibility(int X,int Y)
{
if((Y<HMax[X])&&(Y>HMin[X])) Vis=0;
else if(Y>=HMax[X]) Vis=1;
else Vis=-1;
return(Vis);
}
int *Inter(int X1,int Y1,int X2,int Y2,Table TabAux)
{
if(X2-X1==0)
{
Xii=X2;
Yii=TabAux[X2];
}
else
{
Den=Y2-Y1-TabAux[X2]+TabAux[X1];
if(Den!=0)
{
Xii=(X1*(Y2-TabAux[X2])+X2*(TabAux[X1]-Y1))/Den;
Yii=(Y2*TabAux[X1]-Y1*TabAux[X2])/Den;
}
else
{
Xii=X2;
Yii=Y2;
}
}
XYi[0]=Xii+0.5;
XYi[1]=Yii+0.5;
return(XYi);
}
void FillEdge(int X,int Y,int XLateral,int YLateral)
{
if(XLateral!=-1) Horizon(XLateral,YLateral,X,Y);
XLateral=X;YLateral=Y;
}
void Drawing()
{
LimY=getmaxy();
for(Ln=0;Ln<=LNo;Ln++)
{
Y=Y2-Ln*IncY;
X=X1;
Z=F(X,Y);
Project(X,Y,Z);
XPre=0.5+(XProj-F1)*EchX+C1;
YPre=0.5+(YProj-F3)*EchY+C3;
FillEdge(XPre,YPre,Xd,Yd);
VisPre=Visibility(XPre,YPre);
for(Pt=0;Pt<=PNo;Pt++)
{
X=X1+Pt*IncX;
Z=F(X,Y);
Project(X,Y,Z);
XCur=0.5+(XProj-F1)*EchX+C1;
YCur=0.5+(YProj-F3)*EchY+C3;
VisCur=Visibility(XCur,YCur);
if((HMax[XCur]==0)||(HMax[XCur]==LimY)) VisCur=VisPre;
if(VisCur==VisPre)
{
if((VisCur==1)||(VisCur==-1))
{
if(0<=XCur)
line(XPre,LimY-60-YPre,XCur,LimY-60-YCur);
else if(0<=YCur)
line(XPre,LimY-60-YPre,XPre,LimY-60-YCur);
else
line(XPre,LimY-60-YPre,XPre,LimY-60-YPre);
Horizon(XPre,YPre,XCur,YCur);
}
}
else
{
if(VisCur==0)
{
if(VisPre==1)
{
pi=Inter(XPre,YPre,XCur,YCur,HMax);
Xi=*pi;
Yi=*(pi+1);
}
else
{
pi=Inter(XPre,YPre,XCur,YCur,HMin);
Xi=*pi;
Yi=*(pi+1);
}
if(0<=Xi)
line(XPre,LimY-60-YPre,Xi,LimY-60-Yi);
else if(0<=Yi)
line(XPre,LimY-60-YPre,XPre,LimY-60-Yi);
else
line(XPre,LimY-60-YPre,XPre,LimY-60-YPre);
Horizon(XPre,YPre,Xi,Yi);
}
else
{
if(VisCur==1)
{
if(VisPre==0)
{
pi=Inter(XPre,YPre,XCur,YCur,HMax);
Xi=*pi;
Yi=*(pi+1);
if(0<=Xi)
line(Xi,LimY-60-Yi,XCur,LimY-60-YCur);
else if(0<=Yi)
line(XCur,LimY-60-Yi,XCur,LimY-60-YCur);
else
line(XCur,LimY-60-YCur,XCur,LimY-60-YCur);
Horizon(Xi,Yi,XCur,YCur);
}
else
{
pi=Inter(XPre,YPre,XCur,YCur,HMin);
Xi=*pi;
Yi=*(pi+1);
if(0<=Xi)
line(XPre,LimY-60-YPre,Xi,LimY-60-Yi);
else if(0<=Yi)
line(XPre,LimY-60-YPre,XPre,LimY-60-Yi);
else
line(XPre,LimY-60-YPre,XPre,LimY-60-YPre);
Horizon(XPre,YPre,Xi,Yi);
pi=Inter(XPre,YPre,XCur,YCur,HMax);
Xi=*pi;
Yi=*(pi+1);
if(0<=Xi)
line(Xi,LimY-60-Yi,XCur,LimY-60-YCur);
else if(0<=Yi)
line(XCur,LimY-60-Yi,XCur,LimY-60-YCur);
else
line(XCur,LimY-60-YCur,XCur,LimY-60-YCur);
Horizon(Xi,Yi,XCur,YCur);
}
}
else
{
if(VisPre==0)
{
pi=Inter(XPre,YPre,XCur,YCur,HMin);
Xi=*pi;
Yi=*(pi+1);
if(0<=Xi)
line(Xi,LimY-60-Yi,XCur,LimY-60-YCur);
else if(0<=Yi)
line(XCur,LimY-60-Yi,XCur,LimY-60-YCur);
else
line(XCur,LimY-60-YCur,XCur,LimY-60-YCur);
Horizon(Xi,Yi,XCur,YCur);
}
else
{
pi=Inter(XPre,YPre,XCur,YCur,HMax);
Xi=*pi;
Yi=*(pi+1);
if(0<=Xi)
line(XPre,LimY-60-YPre,Xi,LimY-60-Yi);
else if(0<=Yi)
line(XPre,LimY-60-YPre,XPre,LimY-60-Yi);
else