Universidad Iberoamericana
		Programacin Lgica
					     Otoo 1996
	Manuel Lpez Michelone
					Vctor Manuel Iniestra Alvarez
Proyecto Final
			Visualizador Tridimensional

Descripcin:

	Este programa es capaz de visualizar una representacin bidimensional de un cuerpo o silueta tridimensional. sta estar formada por puntos en el espacio y aquellos debern estar contenidos en un espacio limitado. Se darn tres coordenadas (XYZ) po

/*******************************Dibuja.pro****************************/

En este archivo se encuentran los procedimientos que realizan el dibujo propiamente.

Predicates
	dibuja(llist_integer,real,real,char,char)        
	dibujap(llist_integer,real,real,char,char)
	dibujapa(llist_integer,real,real)
	dibujas(llist_integer,real,real,char,char)
	dibujasa(llist_integer,real,real)
	marco(real,real)
	sombra(real,real,real,real,bgi_ilist)
Clauses
	
-marco necesita conocer el ngulo de vista (su seno y su coseno) para poder calcular la posicin de las lneas (azul).

	marco(Anrc,Anrs):-MaxX(MaxX),MaxY(MaxY),
		X2=MaxX/(1+Anrc),
		Y2=MaxY/(1+Anrs),
		X3=X2*Anrc,
		Y3=Y2*Anrs,
		setcolor(blue),
		SetLineStyle(4,1,1),
		rectangle(0,0,X2,Y2),
		line(X2,Y2,MaxX,MaxY),
		SetLineStyle(0,0,0),
		rectangle(X3,Y3,MaxX,MaxY),
		line(0,0,0,Y2),
		line(0,0,X2,0),
		line(0,Y2,X3,MaxY),
		line(0,0,X3,Y3),
		line(X2,0,MaxX,Y3),
		setcolor(white),!.

-dibujapa tiene dos funciones: dibujar puntos aislados si se le mandan tres coordenadas o dibujar lneas continuas si se le mandan seis coordenadas (dos puntos).
 X1 y Y1 son las coordenadas X y Y "movidas" Z veces sobre el ngulo de vista.

Nota: X,Y y Z van desde 0 hasta 255, por ello se usa X/255.

	dibujapa([[X,Y,Z]|[]],Anrc,Anrs):-MaxX(MaxX),MaxY(MaxY),
		X1=MaxX*((X/255)+(Z/255)*Anrc)/(1+Anrc),
		Y1=MaxY*((Y/255)+(Z/255)*Anrs)/(1+Anrs),
		PutPixel(X1,Y1,white),!.
	dibujapa([[Xa,Ya,Za],[Xb,Yb,Zb]],Anrc,Anrs):-MaxX(MaxX),MaxY(MaxY),
		X1=MaxX*((Xa/255)+(Za/255)*Anrc)/(1+Anrc),
		Y1=MaxY*((Ya/255)+(Za/255)*Anrs)/(1+Anrs),
		X2=MaxX*((Xb/255)+(Zb/255)*Anrc)/(1+Anrc),
		Y2=MaxY*((Yb/255)+(Zb/255)*Anrs)/(1+Anrs),
		line(X1,Y1,X2,Y2),!.

-sombra recibe los coeficientes del plano del polgono y el ngulo de vista, con estos dos datos calcula el tipo de sombreado que le corresponde.

	sombra(A,B,C,_,P):-A*A+B*B+C*C=0,P=[$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF].
  Aqu se descarta el caso de que los tres puntos dados NO formen un plano        
  
	sombra(A,B,C,Anrc,P):-Q=Anrc*((A+B)/(sqrt(A*A+B*B+C*C))),Q>=0,PC=4-3*Q,
			random(PC,P1),random(PC,P2),random(PC,P3),random(PC,P4),
			random(PC,P5),random(PC,P6),random(PC,P7),random(PC,P8),
			P11=P1+63*PC,P12=32*P2+32*PC,P13=16*P3+48*PC,P14=8*P4+56*PC,
			P15=32*P5+32*PC,P16=8*P6+56*PC,P17=P7+63*PC,P18=32*P8+32*PC,
			P=[P11,P12,P13,P14,P15,P16,P17,P18].
  (A+B)/(sqrt(A*A+B*B+C*C)) es una forma simplificada del ngulo del plano. PC es un valor de 1 a 4, se generan 8 valores en este rango al azar y
  son sumados de tal forma que se obtienen 8 valores de 0 a 255 que son los tonos que le llegan al plano en cuestin.

	sombra(A,B,C,Anrc,P):-Q=1+Anrc*((A+B)/(sqrt(A*A+B*B+C*C))),PC=4-3*Q,
			random(PC,P1),random(PC,P2),random(PC,P3),random(PC,P4),
			random(PC,P5),random(PC,P6),random(PC,P7),random(PC,P8),
			P11=P1+63*PC,P12=32*P2+32*PC,P13=16*P3+48*PC,P14=8*P4+56*PC,
			P15=32*P5+32*PC,P16=8*P6+56*PC,P17=P7+63*PC,P18=32*P8+32*PC,
			P=[P11,P12,P13,P14,P15,P16,P17,P18].
   Q puede ser negativo, con esta otra clusula se salva el problema.

-dibujasa es el procedimiento que dibuja los tringulos. Necesita tres puntos y el ngulo de vista.
 A,B y C son los coeficientes de la ecuacin del plano que forman los puntos.
 P es el patrn de sombras.

	dibujasa([[Xa,Ya,Za],[Xb,Yb,Zb],[Xc,Yc,Zc]],Anrc,Anrs):-MaxX(MaxX),MaxY(MaxY),
		X1=MaxX*((Xa/255)+(Za/255)*Anrc)/(1+Anrc),
		Y1=MaxY*((Ya/255)+(Za/255)*Anrs)/(1+Anrs),
		X2=MaxX*((Xb/255)+(Zb/255)*Anrc)/(1+Anrc),
		Y2=MaxY*((Yb/255)+(Zb/255)*Anrs)/(1+Anrs),
		X3=MaxX*((Xc/255)+(Zc/255)*Anrc)/(1+Anrc),
		Y3=MaxY*((Yc/255)+(Zc/255)*Anrs)/(1+Anrs),              
		A=(((-Yb/255)+(Ya/255))*((Zc/255)-(Za/255))+((Zb/255)-(Za/255))*((Yc/255)-(Ya/255)))/2,
		B=(((-Zb/255)+(Za/255))*((Xc/255)-(Xa/255))+((Xb/255)-(Xa/255))*((Zc/255)-(Za/255)))/2,
		C=(((-Xb/255)+(Xa/255))*((Yc/255)-(Ya/255))+((Yb/255)-(Ya/255))*((Xc/255)-(Xa/255)))/2,         
		sombra(A,B,C,Anrc,P),           
		SetFillStyle(0,white),          
		SetFillPattern(P,white),                
		FillPoly([X1,Y1,X2,Y2,X3,Y3]),
		setcolor(black),DrawPoly([X1,Y1,X2,Y2,X3,Y3]),
		DrawPoly([X2,Y2,X3,Y3,X1,Y1]),setcolor(white),!.

/*******************************Puntos**********************************/

- dibuja manda llamar a dibujapa para que se dibujen los puntos. Tan solo permite tener
  vistas diferentes y prender o apagar el marco. Las vistas se logran leyendo la misma
  informacin pero en distinto orden. Para las vistas x,y,z simplemente se pone un
  ngulo de vista igual a 0 en su Seno y en su Coseno; adems de pasarle un 0 en
  lugar de la cordenada que NO se quiere ver.

	dibuja([],Anrc,Anrs,_,'5'):-marco(Anrc,Anrs).
	dibuja([],_,_,_,_).
	dibuja([[X,Y,Z]|Coor],Anrc,Anrs,'1',M):-dibujapa([[X,Y,Z]],Anrc,Anrs),
		dibuja(Coor,Anrc,Anrs,'1',M).
	dibuja([[X,Z,Y]|Coor],Anrc,Anrs,'2',M):-dibujapa([[X,Y,Z]],Anrc,Anrs),
		dibuja(Coor,Anrc,Anrs,'2',M).
	dibuja([[Y,X,Z]|Coor],Anrc,Anrs,'3',M):-dibujapa([[X,Y,Z]],Anrc,Anrs),
		dibuja(Coor,Anrc,Anrs,'3',M).
	dibuja([[Y,Z,X]|Coor],Anrc,Anrs,'7',M):-dibujapa([[X,Y,Z]],Anrc,Anrs),
		dibuja(Coor,Anrc,Anrs,'7',M).
	dibuja([[Z,X,Y]|Coor],Anrc,Anrs,'8',M):-dibujapa([[X,Y,Z]],Anrc,Anrs),
		dibuja(Coor,Anrc,Anrs,'8',M).
	dibuja([[Z,Y,X]|Coor],Anrc,Anrs,'9',M):-dibujapa([[X,Y,Z]],Anrc,Anrs),
		dibuja(Coor,Anrc,Anrs,'9',M).
	dibuja([[_,Y,Z]|Coor],_,_,'x',M):-dibujapa([[Y,Z,0]],0,0),
		dibuja(Coor,0,0,'x',M).
	dibuja([[X,_,Z]|Coor],_,_,'y',M):-dibujapa([[X,Z,0]],0,0),
		dibuja(Coor,0,0,'y',M).
	dibuja([[X,Y,_]|Coor],_,_,'z',M):-dibujapa([[X,Y,0]],0,0),
		dibuja(Coor,0,0,'z',M).

/*******************************Lneas**********************************/

-dibujap manda llamar a dibujapa para dibujar las lneas, ahora se le mandan dos puntos
 y dibujapa los une. Lo importante aqu es usar todos los puntos DOS veces para que se
 unan y no salga intermitente. Aqu tambin se usan las vistas y el marco.

	dibujap([],Anrc,Anrs,_,'5'):-marco(Anrc,Anrs).
	dibujap([],_,_,_,_).    
		
	dibujap([[X,Y,Z]|[]],Anrc,Anrs,'1',M):-dibujapa([[X,Y,Z]],Anrc,Anrs),
		dibujap([],Anrc,Anrs,'1',M).
	dibujap([[Xa,Ya,Za],[Xb,Yb,Zb]|Coor],Anrc,Anrs,'1',M):-dibujapa([[Xa,Ya,Za],[Xb,Yb,Zb]],Anrc,Anrs),
		dibujap([[Xb,Yb,Zb]|Coor],Anrc,Anrs,'1',M).
		
	dibujap([[X,Z,Y]|[]],Anrc,Anrs,'2',M):-dibujapa([[X,Y,Z]],Anrc,Anrs),
		dibujap([],Anrc,Anrs,'2',M).
	dibujap([[Xa,Za,Ya],[Xb,Zb,Yb]|Coor],Anrc,Anrs,'2',M):-dibujapa([[Xa,Ya,Za],[Xb,Yb,Zb]],Anrc,Anrs),
		dibujap([[Xb,Zb,Yb]|Coor],Anrc,Anrs,'2',M).
		
	dibujap([[Y,X,Z]|[]],Anrc,Anrs,'3',M):-dibujapa([[X,Y,Z]],Anrc,Anrs),
		dibujap([],Anrc,Anrs,'3',M).
	dibujap([[Ya,Xa,Za],[Yb,Xb,Zb]|Coor],Anrc,Anrs,'3',M):-dibujapa([[Xa,Ya,Za],[Xb,Yb,Zb]],Anrc,Anrs),
		dibujap([[Yb,Xb,Zb]|Coor],Anrc,Anrs,'3',M).
	
	dibujap([[Y,Z,X]|[]],Anrc,Anrs,'7',M):-dibujapa([[X,Y,Z]],Anrc,Anrs),
		dibujap([],Anrc,Anrs,'7',M).
	dibujap([[Ya,Za,Xa],[Yb,Zb,Xb]|Coor],Anrc,Anrs,'7',M):-dibujapa([[Xa,Ya,Za],[Xb,Yb,Zb]],Anrc,Anrs),
		dibujap([[Yb,Zb,Xb]|Coor],Anrc,Anrs,'7',M).             
		
	dibujap([[Z,X,Y]|[]],Anrc,Anrs,'8',M):-dibujapa([[X,Y,Z]],Anrc,Anrs),
		dibujap([],Anrc,Anrs,'8',M).
	dibujap([[Za,Xa,Ya],[Zb,Xb,Yb]|Coor],Anrc,Anrs,'8',M):-dibujapa([[Xa,Ya,Za],[Xb,Yb,Zb]],Anrc,Anrs),
		dibujap([[Zb,Xb,Yb]|Coor],Anrc,Anrs,'8',M).     

	dibujap([[Z,Y,X]|[]],Anrc,Anrs,'9',M):-dibujapa([[X,Y,Z]],Anrc,Anrs),
		dibujap([],Anrc,Anrs,'9',M).
	dibujap([[Za,Ya,Xa],[Zb,Yb,Xb]|Coor],Anrc,Anrs,'9',M):-dibujapa([[Xa,Ya,Za],[Xb,Yb,Zb]],Anrc,Anrs),
		dibujap([[Zb,Yb,Xb]|Coor],Anrc,Anrs,'9',M).

	dibujap([[_,Y,Z]|[]],_,_,'x',M):-dibujapa([[Y,Z,0]],0,0),
		dibujap([],0,0,'x',M).
	dibujap([[_,Ya,Za],[_,Yb,Zb]|Coor],_,_,'x',M):-dibujapa([[Ya,Za,0],[Yb,Zb,0]],0,0),
		dibujap([[0,Yb,Zb]|Coor],0,0,'x',M).
		
	dibujap([[X,_,Z]|[]],_,_,'y',M):-dibujapa([[X,Z,0]],0,0),
		dibujap([],0,0,'y',M).
	dibujap([[Xa,_,Za],[Xb,_,Zb]|Coor],_,_,'y',M):-dibujapa([[Xa,Za,0],[Xb,Zb,0]],0,0),
		dibujap([[Xb,0,Zb]|Coor],0,0,'y',M).
	
	dibujap([[X,Y,_]|[]],_,_,'z',M):-dibujapa([[X,Y,0]],0,0),
		dibujap([],0,0,'z',M).
	dibujap([[Xa,Ya,_],[Xb,Yb,_]|Coor],_,_,'z',M):-dibujapa([[Xa,Ya,0],[Xb,Yb,0]],0,0),
		dibujap([[Xb,Yb,0]|Coor],0,0,'z',M).
	
/*******************************Superficies**********************************/
			
- dibujas es el que manda llamar a dibujasa para dibujar los tringulos, con vistas y marco.
  Aqu tambin se usan ms de un punto (tres) pero NO se toman ms de una vez. En lugar
  de ello se necesitan poner en orden (y repetidos si se necesita) en un procedimiento extra.

	dibujas([],Anrc,Anrs,_,'5'):-marco(Anrc,Anrs).
	dibujas([],_,_,_,_).
	
	dibujas([[Xa,Ya,Za],[Xb,Yb,Zb],[Xc,Yc,Zc]|Coor],Anrc,Anrs,'1',M):-
		dibujasa([[Xa,Ya,Za],[Xb,Yb,Zb],[Xc,Yc,Zc]],Anrc,Anrs),
		!,dibujas(Coor,Anrc,Anrs,'1',M).
		
	dibujas([[Xa,Za,Ya],[Xb,Zb,Yb],[Xc,Zc,Yc]|Coor],Anrc,Anrs,'2',M):-
		dibujasa([[Xa,Ya,Za],[Xb,Yb,Zb],[Xc,Yc,Zc]],Anrc,Anrs),
		!,dibujas(Coor,Anrc,Anrs,'2',M).
		
	dibujas([[Ya,Xa,Za],[Yb,Xb,Zb],[Yc,Xc,Zc]|Coor],Anrc,Anrs,'3',M):-
		dibujasa([[Xa,Ya,Za],[Xb,Yb,Zb],[Xc,Yc,Zc]],Anrc,Anrs),
		!,dibujas(Coor,Anrc,Anrs,'3',M).
	
	dibujas([[Ya,Za,Xa],[Yb,Zb,Xb],[Yc,Zc,Xc]|Coor],Anrc,Anrs,'7',M):-
		dibujasa([[Xa,Ya,Za],[Xb,Yb,Zb],[Xc,Yc,Zc]],Anrc,Anrs),
		!,dibujas(Coor,Anrc,Anrs,'7',M).

	dibujas([[Za,Xa,Ya],[Zb,Xb,Yb],[Zc,Xc,Yc]|Coor],Anrc,Anrs,'8',M):-
		dibujasa([[Xa,Ya,Za],[Xb,Yb,Zb],[Xc,Yc,Zc]],Anrc,Anrs),
		!,dibujas(Coor,Anrc,Anrs,'8',M).
	
	dibujas([[Za,Ya,Xa],[Zb,Yb,Xb],[Zc,Yc,Xc]|Coor],Anrc,Anrs,'9',M):-
		dibujasa([[Xa,Ya,Za],[Xb,Yb,Zb],[Xc,Yc,Zc]],Anrc,Anrs),
		!,dibujas(Coor,Anrc,Anrs,'9',M).

	dibujas([[_,Ya,Za],[_,Yb,Zb],[_,Yc,Zc]|Coor],_,_,'x',M):-
		dibujasa([[Ya,Za,0],[Yb,Zb,0],[Yc,Zc,0]],0,0),
		!,dibujas(Coor,0,0,'x',M).
	
	dibujas([[Xa,_,Za],[Xb,_,Zb],[Xc,_,Zc]|Coor],_,_,'y',M):-
		dibujasa([[Xa,Za,0],[Xb,Zb,0],[Xc,Zc,0]],0,0),
		!,dibujas(Coor,0,0,'y',M).
	
	dibujas([[Xa,Ya,_],[Xb,Yb,_],[Xc,Yc,_]|Coor],_,_,'z',M):-
		dibujasa([[Xa,Ya,0],[Xb,Yb,0],[Xc,Yc,0]],0,0),
		!,dibujas(Coor,0,0,'z',M).

/********************************Interact.pro*************************/                
		
Predicates
	interac(llist_integer,real,char,char,char)
	trans(integer,real,real)

Clauses

- trans pasa de Angn (0..90) al seno y coseno respectivo.

	trans(Angn,Anrc,Anrs):-Anr=Angn*3.141592/180,
		Anrc=cos(Anr),
		Anrs=sin(Anr),!.

- interac es el procedimiento que "interactua" con el usuario durante la visualizacin
  del cuerpo tridimensional. Manda llamar a dibuja, dibujap o a dibujas dependiendo de
  lo que se desea (puntos, lneas o tringulos resp.). Se tiene una opcin que da ayuda .

	interac(_,_,'\27',_,_).
	interac(Coor,Ang,'+',Vista,M):-Ang<90,Angn=Ang+1,
				trans(Angn,Anrc,Anrs),
				clearviewport(),dibuja(Coor,Anrc,Anrs,Vista,M),readchar(X),
				!,interac(Coor,Angn,X,Vista,M).
	interac(Coor,Ang,'-',Vista,M):-Ang>0,Angn=Ang-1,
				trans(Angn,Anrc,Anrs),
				clearviewport(),dibuja(Coor,Anrc,Anrs,Vista,M),readchar(X),
				!,interac(Coor,Angn,X,Vista,M).
	interac(Coor,Ang,'*',Vista,M):-Ang<=80,Angn=Ang+10,
				trans(Angn,Anrc,Anrs),
				clearviewport(),dibuja(Coor,Anrc,Anrs,Vista,M),readchar(X),
				!,interac(Coor,Angn,X,Vista,M).
	interac(Coor,Ang,'/',Vista,M):-Ang>=10,Angn=Ang-10,
				trans(Angn,Anrc,Anrs),
				clearviewport(),dibuja(Coor,Anrc,Anrs,Vista,M),readchar(X),
				!,interac(Coor,Angn,X,Vista,M).
	interac(Coor,Angn,'1',_,M):-Vista='1',
				trans(Angn,Anrc,Anrs),
				clearviewport(),dibuja(Coor,Anrc,Anrs,Vista,M),readchar(X),
				!,interac(Coor,Angn,X,Vista,M).
	interac(Coor,Angn,'2',_,M):-Vista='2',
				trans(Angn,Anrc,Anrs),
				clearviewport(),dibuja(Coor,Anrc,Anrs,Vista,M),readchar(X),
				!,interac(Coor,Angn,X,Vista,M).
	interac(Coor,Angn,'3',_,M):-Vista='3',
				trans(Angn,Anrc,Anrs),
				clearviewport(),dibuja(Coor,Anrc,Anrs,Vista,M),readchar(X),
				!,interac(Coor,Angn,X,Vista,M).
	interac(Coor,Angn,'7',_,M):-Vista='7',
				trans(Angn,Anrc,Anrs),
				clearviewport(),dibuja(Coor,Anrc,Anrs,Vista,M),readchar(X),
				!,interac(Coor,Angn,X,Vista,M).
	interac(Coor,Angn,'8',_,M):-Vista='8',
				trans(Angn,Anrc,Anrs),
				clearviewport(),dibuja(Coor,Anrc,Anrs,Vista,M),readchar(X),
				!,interac(Coor,Angn,X,Vista,M).
	interac(Coor,Angn,'9',_,M):-Vista='9',
				trans(Angn,Anrc,Anrs),
				clearviewport(),dibuja(Coor,Anrc,Anrs,Vista,M),readchar(X),
				!,interac(Coor,Angn,X,Vista,M).
	interac(Coor,Ang,'x',_,M):-Vista='x',
				clearviewport(),dibuja(Coor,0,0,Vista,M),readchar(X),
				!,interac(Coor,Ang,X,Vista,M).
	interac(Coor,Ang,'y',_,M):-Vista='y',
				clearviewport(),dibuja(Coor,0,0,Vista,M),readchar(X),
				!,interac(Coor,Ang,X,Vista,M).
	interac(Coor,Ang,'z',_,M):-Vista='z',
				clearviewport(),dibuja(Coor,0,0,Vista,M),readchar(X),
				!,interac(Coor,Ang,X,Vista,M).
	interac(Coor,Ang,'.',Vista,M):-Angn=Ang,Anr=Angn*3.141592/180,
				Anrc=cos(Anr),
				Anrs=sin(Anr),
				dibujap(Coor,Anrc,Anrs,Vista,M),readchar(X),
				!,interac(Coor,Angn,X,Vista,M).
	interac(Coor,Angn,',',Vista,M):-
				trans(Angn,Anrc,Anrs),
				dibujas(Coor,Anrc,Anrs,Vista,M),readchar(X),
				!,interac(Coor,Angn,X,Vista,M).
	interac(Coor,Ang,'5',Vista,'5'):-!,interac(Coor,Ang,'4',Vista,'0').
	interac(Coor,Ang,'5',Vista,'0'):-!,interac(Coor,Ang,'4',Vista,'5').
	interac(Coor,Ang,';',Vista,M):-
				moveto(0,0),OutText("Visualizador Tridimensional"),
				moveto(0,30),OutText("Funciones:"),
				moveto(0,50),OutText("1        Vista XYZ"),
				moveto(0,60),OutText("2        Vista XZY"),
				moveto(0,70),OutText("3        Vista YXZ"),
				moveto(0,80),OutText("7        Vista YZX"),
				moveto(0,90),OutText("8        Vista ZXY"),
				moveto(0,100),OutText("9        Vista ZYX"),
				moveto(0,110),OutText("x        Vista YZ"),
				moveto(0,120),OutText("y        Vista XZ"),
				moveto(0,130),OutText("z        Vista XY"),
				moveto(0,150),OutText("+        Incrementa un Grado el ngulo de vista"),
				moveto(0,160),OutText("-        Decrementa un Grado el ngulo de vista"),
				moveto(0,170),OutText("*        Incrementa 10 Grados el ngulo de vista"),
				moveto(0,180),OutText("/        Decrementa 10 Grados el ngulo de vista"),
				moveto(0,200),OutText("5        Prende y Apaga el Marco"),
				moveto(0,220),OutText(".        Une los puntos con lneas (til para \"genera()\")."),
				moveto(0,240),OutText(",        Une los puntos con tringulos (til para \"generar()\")."),
				moveto(0,270),OutText("ESC      Sale al Men"),
				readchar(_),
				!,interac(Coor,Ang,'4',Vista,M).
	interac(Coor,Angn,'4',Vista,M):-
				trans(Angn,Anrc,Anrs),
				clearviewport(),dibuja(Coor,Anrc,Anrs,Vista,M),readchar(X),
				!,interac(Coor,Angn,X,Vista,M).
	interac(Coor,Ang,_,Vista,M):-readchar(X),!,
				interac(Coor,Ang,X,Vista,M).

/*******************************Proyecta.pro****************************/                                

include "g:\\lenguaje\\prolog\\programs\\GrapDecl.PRO"
/*include "GrapDecl.PRO"*/

CONSTANTS       
  intlist = BGI_ilist
    bgi_Path = "g:\\lenguaje\\prolog\\bgi"
/*  bgi_Path = "g:\\lenguaje\\prolog\\bgi"*/
Domains
	file=entrada;salida
	list_integer=integer *
	llist_integer=list_integer *
	list_char=char *

/************************************************************************
		Local data base
*************************************************************************/

Database - graphics
  Determ driver(Integer,Integer,String)
  Determ maxcolors(Integer)
  Determ maxX(Integer)
  Determ maxY(Integer)
  Determ aspectCorr(Real)
  Determ graphCoord(Integer,Integer)
  Determ lineStyleDBA(Integer,Integer,Integer)
  Determ textHeightDBA(Integer)

/************************************************************************
		Return name of driver
*************************************************************************/

PREDICATES

  GetDriverName2(Integer,String) 

CLAUSES
  GetDriverName2(0,"Detect").   GetDriverName2(1,"CGA").
  GetDriverName2(2,"MCGA").     GetDriverName2(3,"EGA").
  GetDriverName2(4,"EGA64").    GetDriverName2(5,"EGAMono").
  GetDriverName2(6,"Reserved"). GetDriverName2(7,"HercMono").
  GetDriverName2(8,"ATT400").   GetDriverName2(9,"VGA").
  GetDriverName2(10,"PC3270").

/************************************************************************
	Convert the current device mode into a string
*************************************************************************/

PREDICATES
  GetMode(Integer,Integer,String)

CLAUSES
  GetMode(cga,cgaHi,"CGAHi"):-!.
  GetMode(cga,GraphMode,S):- !,format(S,"CGA%",GraphMode).
  GetMode(mcga,mcgaMed,"MCGAMed"):- !.
  GetMode(mcga,mcgahi,"MCGAHi"):- !.
  GetMode(mcga,GraphMode,S):- !,format(S,"MCGA%",GraphMode).
  GetMode(ega,egaLo,"EGALo"):- !.
  GetMode(ega,egaHi,"EGAHi"):- !.
  GetMode(ega64,ega64Lo,"EGA64Lo"):- !.
  GetMode(ega64,ega64Hi,"EGA64Hi"):- !.
  GetMode(hercMono,_,"HercMonoHi"):- !.
  GetMode(egaMono,_,"EGAMonoHi"):- !.
  GetMode(pc3270,_,"PC3270Hi"):- !.
  GetMode(att400,att400Med,"ATT400Med"):- !.
  GetMode(att400,att400Hi,"ATT400Hi"):- !.
  GetMode(att400,GraphMode,S):- !,format(S,"ATT400%",GraphMode).
  GetMode(vga,vgaLo,"VGALo"):- !.
  GetMode(vga,vgaMed,"VGAMedo"):- !.
  GetMode(vga,vgaHi,"VGAHi"):- !.
  GetMode(_,_,"UnKnown"):- !.

/************************************************************************
		Mode switching
*************************************************************************/

PREDICATES
  ToGraphic
  ToText
  KeepColor(integer,integer,integer)

CLAUSES
  ToGrapHic:-
	/* Detect graphic equipment */
	DetectGraph(G_Driver, G_Mode1),
	KeepColor(G_Driver,G_Mode1,G_Mode),
	GetDriverName2(G_Driver,G_Name),
	assert(driver(G_Driver,G_Mode,G_Name)),
	InitGraph(G_Driver,G_Mode, _, _, bgi_Path),!.

  ToText:-
	closegraph().
	
KeepColor(1,_,0).
KeepColor(_,Mode,Mode).

/************************************************************************
		Initialize video and Global flags
*************************************************************************/

PREDICATES
  Initialize

CLAUSES
  Initialize:-
	retractall(_, graphics),
	ToGraphic,
	GetMaxColor(MaxColors),   assert(maxcolors(MaxColors)),
	GetMaxX(MaxX),    assert(maxX(MaxX)),
	GetMaxY(MaxY),    assert(maxY(MaxY)),
	GetAspectRatio(Xasp,Yasp),
	AspectRatio = Xasp/Yasp,  assert(aspectCorr(AspectRatio)).

/************************************************************************
		Mi cdigo al fin...
*************************************************************************/

include "dibuja.pro"
include "interact.pro"

Predicates
	error(integer)
	abre_lect(string)
	abre_escr(string)
	lee_archivo(llist_integer,llist_integer)
	genera(char)
	generar
	char_real(char,real)
	real_char(real,char)
	menu(char)
Goal        
	    menu('0').
Clauses                                           
	
- menu es el procedimiento que indica los comandos disponibles al inicio del programa.

	menu('\27'):-exit.
	menu('1'):-makewindow(31,31,30,"Archivo a Guardar:",10,15,5,54),write("\nDame el nombre del archivo donde se salvar "),
		readln(FileName),abre_escr(FileName),
		genera(1),!,removewindow(),menu('0').  
	menu('2'):-makewindow(31,31,30,"Archivo a Guardar:",10,15,5,54),write("\nDame el nombre del archivo donde se salvar "),
		readln(FileName),abre_escr(FileName),
		generar,!,removewindow(),menu('0').  
	menu('3'):-makewindow(31,31,30,"",8,10,11,65),
		trap(dir("","*.",FileName,1,1,1),E,error(E)),FileName<>"",
		abre_lect(FileName),lee_archivo([],Coor),
		Initialize,interac(Coor,45,'4','1','5'),ToText,removewindow(),!,menu('0').
	menu('4'):-file_str("manusu.txt",Str),makewindow(32,112,126,"Manual del Usuario",1,1,23,77),
		clearwindow,EditMode=0,Indent=0,Insert=1,TextMode=1,
		edit(Str,_," ","manusu.txt","ESC para salir",0,"",EditMode,Indent,Insert,TextMode,_,_),
		removewindow(),menu('0').
	menu('5'):-file_str("mantec.txt",Str),makewindow(32,112,126,"Manual Tcnico",1,1,23,77),
		clearwindow,EditMode=0,Indent=0,Insert=1,TextMode=1,
		edit(Str,_," ","mantec.txt","ESC para salir",0,"",EditMode,Indent,Insert,TextMode,_,_),
		removewindow(),menu('0').

	menu(_):-makewindow(31,31,30,"Visualizador Tridimensional",8,10,13,66),
		write("\n1 Generar una grfica tridimensional modificable en \"genera(A)\"."),
		write("\n2 Generar una grfica tridimensional modificable en \"generar\".  "),
		write("\n3 Visualizar una grfica tridimensional (F1-Help)."),
		write("\n\n4 Manual del Usuario."),
		write("\n\n5 Manual Tcnico."),
		write("\n						ESC para salir"),
		readchar(I),removewindow(),!,menu(I).  
	
	error(_).
	
- Se tuvieron que que agregar estos dos procedimientos para poder hacer cambios de real a char y viceversa.
	char_real(X,A):-char_int(A,H),X=10*(H/10).
	real_char(X,A):-H=10*(X/10),char_int(A,H).
	
	abre_lect(FileName):-openread(entrada,FileName),filemode(entrada,0).
	
- Si el archivo ya existe, agrega los nuevos puntos, de lo contrario crealo.
	abre_escr(FileName):-not(ExistFile(FileName)),openwrite(salida,FileName),filemode(salida,0).
	abre_escr(FileName):-openappend(salida,FileName),filemode(salida,0).
	
- Aqu se pueden listar los puntos que se quieren visualizar. Los valores que
  estn sirven para analizar las sombras de tres tringulos.

	generar:-writedevice(salida),
		
		/*write('\0','\10','\200'),
		write('\127','\0','\200'),
		write('\255','\255','\200'),
		
		write('\0','\10','\100'),
		write('\64','\255','\200'),
		write('\127','\0','\100'),*/
		
		write('\93','\127','\93'),
		write('\93','\127','\64'),
		write('\64','\127','\64'),
		
		write('\64','\64','\127'),
		write('\64','\93','\127'),
		write('\93','\93','\127'),
		
		write('\127','\64','\64'),
		write('\127','\64','\93'),
		write('\127','\93','\93'),
		
		closefile(salida),writedevice(screen),!.

- En genera se originan puntos a partir de alguna ecuacin, es til para analizar
  como se unen con lneas. En generar y en genera se guardan los datos en un archivo.

	genera(256):-closefile(salida),writedevice(screen).
	genera(A):-writedevice(salida),
		char_real(X,A),Y=127+127*cos(2*2*3.1415*(1-X/255)),
		real_char(Y,B),Z=127+127*sin(4*2*3.1415*(1-X/255)),
		real_char(Z,C),
		write(A,B,C),
		D=A+1,!,genera(D).
			
- Con este procedimiento se "leen" los datos generados con alguno de los procedimientos
  anteriores.

	lee_archivo(Van,Coor):-readdevice(entrada),not(eof(entrada)),
		readchar(X),char_int(X,A),readchar(Y),char_int(Y,B),
		readchar(Z),char_int(Z,C),Coor1=[[A,B,C]|Van],!,
		lee_archivo(Coor1,Coor).
	lee_archivo(Coor,Coor):-closefile(entrada).

    Source: geocities.com/v.iniestra/apuntes/pro_log

               ( geocities.com/v.iniestra/apuntes)                   ( geocities.com/v.iniestra)