Universidad Iberoamericana

Programación Lógica

Primavera 1997

Manuel López Michelone

Víctor Manuel Iniestra Álvarez

Proyecto Final

Visualizador Tridimensional

Descripción:

Este programa es capaz de visualizar una representación bidimensional de un cuerpo o silueta tridimensional. Ésta esta formada por puntos en el espacio y aquellos deberán estar contenidos en un espacio limitado. Se darán tres coordenadas (XYZ) por cada punto, cada una de estas coordenadas podrá  variar de 0 a 256 (un Byte). El método para almacenar los datos es el de archivos; los archivos guardarán la información en formato binario y con un punto por cada tres bytes. La visualización se hará en todos los  ángulos posibles pudiendo variarlos 1 cada vez. Además del formato de archivos propuesto (simple) se podrán leer y guardar en formato DXF (AutoCad).

Especificaciones Técnicas:

DEBE ESTAR EN MODO VIDEO 800x600

El programa vis.exe (visualizador tridimensional) se desarrolló en:

El primer archivo es vis.dpr:

program vis;

uses

Forms,

visual in 'visual.pas' {Form1},

carga in 'carga.pas' {Form2},

genera in 'genera.pas' {Form3},

guarda in 'guarda.pas' {Form4};

{$R *.RES}

begin

Application.Initialize;

Application.CreateForm(TForm1, Form1);

Application.CreateForm(TForm2, Form2);

Application.CreateForm(TForm3, Form3);

Application.CreateForm(TForm4, Form4);

Application.Run;

end.

Aquí se define el programa y se nombran a las unidades (formas) que lo conforman.

Cada forma necesita dos archivos: unit.dfm y unit.pas. Los archivos .dfm contienen la definición visual de la forma, los archivos .pas contienen los procedimientos y las declaraciones que se le definen.

Visual (Form1):

unit visual;

{Esta unidad define la ventana principal con su área de dibujo y los

procedimientos respectivos para que el dibujo se traze y se guarden los

datos en la memoria.}

interface

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

Menus, StdCtrls;

type

TForm1 = class(TForm)

MainMenu1: TMainMenu;

Archivo1: TMenuItem;

Ejes1: TMenuItem;

Abrir: TMenuItem;

Generar: TMenuItem;

xy1: TMenuItem;

xz1: TMenuItem;

xyz1: TMenuItem;

xzy1: TMenuItem;

yxz1: TMenuItem;

yzx1: TMenuItem;

zxy1: TMenuItem;

zyx1: TMenuItem;

Marco1: TMenuItem;

ScrollBar1: TScrollBar;

yz1: TMenuItem;

Herramientas1: TMenuItem;

Escala1: TMenuItem;

X1: TMenuItem;

Y1: TMenuItem;

Z1: TMenuItem;

Ver1: TMenuItem;

Puntos1: TMenuItem;

Lineas1: TMenuItem;

Polgonos1: TMenuItem;

Guardar: TMenuItem;

Salir: TMenuItem;

procedure AbrirClick(Sender: TObject);

procedure FormPaint(Sender: TObject);

procedure FormCreate(Sender: TObject);

procedure Marco1Click(Sender: TObject);

procedure xy1Click(Sender: TObject);

procedure xz1Click(Sender: TObject);

procedure yz1Click(Sender: TObject);

procedure xyz1Click(Sender: TObject);

procedure xzy1Click(Sender: TObject);

procedure yxz1Click(Sender: TObject);

procedure yzx1Click(Sender: TObject);

procedure zxy1Click(Sender: TObject);

procedure zyx1Click(Sender: TObject);

procedure Escala1Click(Sender: TObject);

procedure X1Click(Sender: TObject);

procedure Y1Click(Sender: TObject);

procedure Z1Click(Sender: TObject);

procedure Puntos1Click(Sender: TObject);

procedure Lineas1Click(Sender: TObject);

procedure Polgonos1Click(Sender: TObject);

procedure SalirClick(Sender: TObject);

procedure GenerarClick(Sender: TObject);

procedure GuardarClick(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

{Se define un punto como un registro que tiene cordenadas x,y y z

del tipo real y un a puntador a un registro del mismo tipo.}

lis_punto=^punto;

punto = record

x,y,z: real;

Next: lis_punto;

end;

{Definimos a una coord como un registro con valores x, y y z de tipo

real}

coord = record

x,y,z: real;

end;

{Un universo será un registro que contiene una lista de puntos (coord),

y una variable booleana llamada lleno.}

universo = record

coord: lis_punto;

lleno: Boolean;

end;

var

mundo:universo; {Aquí guardaremos el trazo 3D}

vista:Integer; {Con esta variable identificaremos que vista está activa}

Ver:Char; {Para elegir que se quiere ver: puntos, líneas o polígonos}

R: TRect; {Sobre la ventana se dibujará un rectángulo blanco (para tener

coordenadas sobre las cuales trabajar)}

marc:Boolean; {Con esto sabremos si queremos ver el marco o no}

Form1: TForm1;

implementation

uses {Tenemos que hacer referencia a las otras ventanas ya que serán abiertas

desde aquí}

carga, genera, guarda;

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject); {En cuanto sea creada la ventana...}

begin

Ver:='1'; {Deseo ver el dibujo con nube de puntos}

vista:=1; {Con los ejes xyz (ese orden)}

marc:=False; {Sin ver el marco}

mundo.lleno:=False; {Pero como todavía no se ha cargado nada...}

end;

procedure TForm1.Marco1Click(Sender: TObject); {Opción Marco Ejes}

begin

if marc then

marc:=False

else

marc:=True;

Form1.FormPaint(Sender);

end;

procedure TForm1.xy1Click(Sender: TObject); {Opción xy Ejes}

begin

vista:=7;

marc:=False;

Form1.FormPaint(Sender);

end;

procedure TForm1.xz1Click(Sender: TObject); {Opción xz Ejes}

begin

vista:=8;

marc:=False;

Form1.FormPaint(Sender);

end;

procedure TForm1.yz1Click(Sender: TObject); {Opción yz Ejes}

begin

vista:=9;

marc:=False;

Form1.FormPaint(Sender);

end;

procedure TForm1.xyz1Click(Sender: TObject); {Opción xyz Ejes}

begin

vista:=1;

Form1.FormPaint(Sender);

end;

procedure TForm1.xzy1Click(Sender: TObject); {Opción xzy Ejes}

begin

vista:=2;

Form1.FormPaint(Sender);

end;

procedure TForm1.yxz1Click(Sender: TObject); {Opción yxz Ejes}

begin

vista:=3;

Form1.FormPaint(Sender);

end;

procedure TForm1.yzx1Click(Sender: TObject); {Opción yzx Ejes}

begin

vista:=4;

Form1.FormPaint(Sender);

end;

procedure TForm1.zxy1Click(Sender: TObject); {Opción zxy Ejes}

begin

vista:=5;

Form1.FormPaint(Sender);

end;

procedure TForm1.zyx1Click(Sender: TObject); {Opción zyx Ejes}

begin

vista:=6;

Form1.FormPaint(Sender);

end;

procedure TForm1.Puntos1Click(Sender: TObject); {Opción polígonos puntos}

begin

Ver:='1';

Form1.FormPaint(Sender);

end;

procedure TForm1.Lineas1Click(Sender: TObject); {Opción polígonos líneas}

begin

Ver:='2';

Form1.FormPaint(Sender);

end;

procedure TForm1.Polgonos1Click(Sender: TObject); {Opción polígonos ver}

begin

Ver:='3';

Form1.FormPaint(Sender);

end;

procedure intercambia(eje:char); {Este procedimiento "invierte" los datos

en la memoria respecto al eje que sirve de parámetro}

var

temp: real;

data: lis_punto;

begin

New(data);

data:=mundo.coord;

repeat

if eje='x' then

data^.x:=255-data^.x;

if eje='y' then

data^.y:=255-data^.y;

if eje='z' then

data^.z:=255-data^.z;

data:=data^.next;

until (data^.next=nil);

if eje='x' then

data^.x:=255-data^.x;

if eje='y' then

data^.y:=255-data^.y;

if eje='z' then

data^.z:=255-data^.z;

end;

procedure TForm1.X1Click(Sender: TObject); {Opción x Herramientas}

begin

if mundo.lleno then intercambia('x');{Ve si hay algo que invertir

antes de invertir}

Form1.FormPaint(Sender);

end;

procedure TForm1.Y1Click(Sender: TObject); {Opción y Herramientas}

begin

if mundo.lleno then intercambia('y'); {Ve si hay algo que invertir

antes de invertir}

Form1.FormPaint(Sender);

end;

procedure TForm1.Z1Click(Sender: TObject); {Opción z Herramientas}

begin

if mundo.lleno then intercambia('z'); {Ve si hay algo que invertir

antes de invertir}

Form1.FormPaint(Sender);

end;

procedure escala; {Este procedimiento "escala" los valores que se

encuentran en la memoria para que el dibujo pueda ser apreciado en la

pantalla.}

var

xmin,ymin,zmin,xmax,ymax,zmax:real;

data,datos: lis_punto;

begin

New(data);

data:=mundo.coord;

xmin:=0; ymin:=0; zmin:=0;

xmax:=0; ymax:=0; zmax:=0;

repeat

if data^.x<xmin then xmin:=data^.x;

if data^.y<ymin then ymin:=data^.y;

if data^.z<zmin then zmin:=data^.z;

if data^.x>xmax then xmax:=data^.x;

if data^.y>ymax then ymax:=data^.y;

if data^.z>zmax then zmax:=data^.z;

data:=data^.next;

until (data^.next=nil);

if data^.x<xmin then xmin:=data^.x;

if data^.y<ymin then ymin:=data^.y;

if data^.z<zmin then zmin:=data^.z;

if data^.x>xmax then xmax:=data^.x;

if data^.y>ymax then ymax:=data^.y;

if data^.z>zmax then zmax:=data^.z;

New(data);

data:=mundo.coord;

repeat

data^.x:=255*(-xmin+data^.x)/(-xmin+xmax);

data^.y:=255*(-ymin+data^.y)/(-ymin+ymax);

data^.z:=255*(-zmin+data^.z)/(-zmin+zmax);

data:=data^.next;

until (data^.next=nil);

data^.x:=255*(-xmin+data^.x)/(-xmin+xmax);

data^.y:=255*(-ymin+data^.y)/(-ymin+ymax);

data^.z:=255*(-zmin+data^.z)/(-zmin+zmax);

end;

procedure TForm1.Escala1Click(Sender: TObject); {Opción Escala Herramientas}

begin

if mundo.lleno then escala; {Ve si hay algo que escalar

antes de escalar}

Form1.FormPaint(Sender);

end;

procedure TForm1.SalirClick(Sender: TObject); {Opción salir del menú Archivo}

begin

close;

end;

procedure TForm1.AbrirClick(Sender: TObject); {Opción abrir del menú Archivo}

begin

carga.Form2.ShowModal;

end;

procedure TForm1.GenerarClick(Sender: TObject); {Opción generar del menú Archivo}

begin

genera.Form3.ShowModal;

end;

procedure TForm1.GuardarClick(Sender: TObject); {Opción guardar del menú Archivo}

begin

guarda.Form4.ShowModal;

end;

procedure TForm1.FormPaint(Sender: TObject); {Este procedimiento se activa

cada vez que se vuelva a pintar la ventana; ya sea porque la ventana se mueve,

se re-escale o porque se mande llamar desde dentro del programa.}

procedure marco(Anrc,Anrs:Real); {Dibuja el marco en la ventana}

var

X2,Y2,X3,Y3:integer;

begin

X2:=Round(R.Right/(1+Anrc));

Y2:=Round(R.Bottom/(1+Anrs));

X3:=Round(X2*Anrc);

Y3:=Round(Y2*Anrs);

Canvas.Pen.Color := clBlue;

Canvas.PolyLine([Point(X2,0), Point(X2,Y2)]);

Canvas.PolyLine([Point(0,Y2), Point(X2,Y2)]);

Canvas.PolyLine([Point(X2,Y2), Point(R.Right,R.Bottom)]);

Canvas.PolyLine([Point(X3,Y3), Point(R.Right,Y3)]);

Canvas.PolyLine([Point(X3,Y3), Point(X3,R.Bottom)]);

Canvas.PolyLine([Point(0,Y2), Point(X3,R.Bottom)]);

Canvas.PolyLine([Point(0,0), Point(X3,Y3)]);

Canvas.PolyLine([Point(X2,0), Point(R.Right,Y3)]);

Canvas.Pen.Color := clBlack;

end;

procedure pon(Anrc,Anrs,x1,y1,z1,x2,y2,z2,x3,y3,z3:real); {Hace el dibujo

3D en la pantalla, se le pasan 11 datos (un triángulo y el seno y el coseno

de un triángulo).}

var

Xp1,Yp1,Xp2,Yp2,Xp3,Yp3:Integer;

begin

Xp1:=Round(R.Right*((x1/255)+(z1/255)*Anrc)/(1+Anrc));

Yp1:=Round(R.Bottom*((y1/255)+(z1/255)*Anrs)/(1+Anrs));

Xp2:=Round(R.Right*((x2/255)+(z2/255)*Anrc)/(1+Anrc));

Yp2:=Round(R.Bottom*((y2/255)+(z2/255)*Anrs)/(1+Anrs));

Xp3:=Round(R.Right*((x3/255)+(z3/255)*Anrc)/(1+Anrc));

Yp3:=Round(R.Bottom*((y3/255)+(z3/255)*Anrs)/(1+Anrs));

{Esto lo rescala a un cubo de 0 a 255 pixeles y lo "aplana" usando el

seno y el coseno del triángulo.}

case Ver of

'1': begin

Canvas.Pixels[Xp1,Yp1]:=clBlack;

Canvas.Pixels[Xp2,Yp2]:=clBlack;

Canvas.Pixels[Xp3,Yp3]:=clBlack;

end;

'2': Canvas.Polyline([Point(Xp1, Yp1), Point(Xp2, Yp2), Point(Xp3, Yp3), Point(Xp1, Yp1)]);

'3': Canvas.Polygon([Point(Xp1, Yp1), Point(Xp2, Yp2), Point(Xp3, Yp3)]);

{Se hace el trazo ya sea con puntos, líneas o triángulos.}

end;

end;

procedure dib; {Este procedimiento hace el trazo}

var

Anrc,Anrs:Real;

data:lis_punto;

x1,y1,z1,x2,y2,z2,x3,y3,z3:real;

begin

Anrc:=cos(ScrollBar1.Position*3.141592/180); {"Lee" el ángulo de vista}

Anrs:=sin(ScrollBar1.Position*3.141592/180); {del scrollbar}

New(data);

data:=mundo.coord;

repeat

data:=data^.next;

x1:=data^.x;

y1:=data^.y;

z1:=data^.z;

data:=data^.next;

x2:=data^.x;

y2:=data^.y;

z2:=data^.z;

data:=data^.next;

if (data^.next<>nil) then

begin

x3:=data^.x;

y3:=data^.y;

z3:=data^.z;

case vista of

1:pon(Anrc,Anrs,x1,y1,z1,x2,y2,z2,x3,y3,z3);

2:pon(Anrc,Anrs,x1,z1,y1,x2,z2,y2,x3,z3,y3);

3:pon(Anrc,Anrs,y1,x1,z1,y2,x2,z2,y3,x3,z3);

4:pon(Anrc,Anrs,y1,z1,x1,y2,z2,x2,y3,z3,x3);

5:pon(Anrc,Anrs,z1,x1,y1,z2,x2,y2,z3,x3,y3);

6:pon(Anrc,Anrs,z1,y1,x1,z2,y2,x2,z3,y3,x3);

7:pon(0,0,x1,y1,0,x2,y2,0,x3,y3,0);

8:pon(0,0,x1,z1,0,x2,z2,0,x3,z3,0);

9:pon(0,0,y1,z1,0,y2,z2,0,y3,z3,0);

end;

end;

until (data^.next=nil);

x3:=data^.x;

y3:=data^.y;

z3:=data^.z;

case vista of

1:pon(Anrc,Anrs,x1,y1,z1,x2,y2,z2,x3,y3,z3);

2:pon(Anrc,Anrs,x1,z1,y1,x2,z2,y2,x3,z3,y3);

3:pon(Anrc,Anrs,y1,x1,z1,y2,x2,z2,y3,x3,z3);

4:pon(Anrc,Anrs,y1,z1,x1,y2,z2,x2,y3,z3,x3);

5:pon(Anrc,Anrs,z1,x1,y1,z2,x2,y2,z3,x3,y3);

6:pon(Anrc,Anrs,z1,y1,x1,z2,y2,x2,z3,y3,x3);

7:pon(0,0,x1,y1,0,x2,y2,0,x3,y3,0);

8:pon(0,0,x1,z1,0,x2,z2,0,x3,z3,0);

9:pon(0,0,y1,z1,0,y2,z2,0,y3,z3,0);

end;

if marc then marco(Anrc,Anrs); {Si se necesita visualizar el marco,

lo visualiza}

end;

begin

R := GetClientRect; {Obtén las dimensiones de la ventana}

Canvas.Rectangle(R.Left,R.Top,R.Right,R.Bottom); {Haz un rectángulo

que ocupe toda la ventana}

If mundo.lleno Then {Si hay algo en la memoria, dibújalo}

dib;

end;

end.

 

Carga (Form2):

unit carga; {Esta unidad (y su ventana) sirven para cargar en memoria

un archivo para ser visualizado}

interface

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

FileCtrl, StdCtrls;

type

TForm2 = class(TForm)

Edit1: TEdit;

Button1: TButton;

Button2: TButton;

DriveComboBox1: TDriveComboBox;

DirectoryListBox1: TDirectoryListBox;

FilterComboBox1: TFilterComboBox;

FileListBox1: TFileListBox;

procedure Button1Click(Sender: TObject);

procedure Button2Click(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

var

Form2: TForm2;

implementation

uses

visual; {Se necesita la unidad visual (para tener acceso a las

variables globales)}

{$R *.DFM}

procedure lee_dxf(nombre:String); {Lee el formato DXF de AutoCad, se le

pasa el nombre del archivo a leer}

var

archivo: Text; {Los archivos DXF son de tipo texto}

dato1, dato2, dato3: real;

data: lis_punto;

temp: string;

cont: Integer;

procedure AgregaDat(x,y,z:real); {Este procedimiento anexa un dato a la

lista data}

var

dato: lis_punto;

begin

new(dato);

data^.Next:=dato;

dato^.x:=x;

dato^.y:=y;

dato^.z:=z;

dato^.Next:=nil;

data:=dato;

end;

Function busca(bandera:string):String; {Este procedimiento busca una

"bandera" dentro del archivo DXF y regresa el contenido de la línea

siguiente}

var

temp:string;

begin

While (NOT(EOF(Archivo))AND(Not(temp=bandera))) DO

readln(archivo,temp);

readln(archivo,temp);

busca:=temp;

end;

begin

Assign(archivo,nombre);

Reset(archivo); {Asocia el nombre del archivo y abrelo para lectura}

New(data); {Prepara el listado de puntos}

data^.x:=0;

data^.y:=0;

data^.z:=0;

mundo.coord:=data; {Ancla el principio de la lista}

temp:='';

cont:=-2;

While Not(EOF(archivo)) DO

BEGIN

temp:=busca('3DFACE'); {Principio de definición de un triángulo}

if ((Not(EOF(archivo)))AND(temp<>'EOF')) then

begin

cont:=cont+3;

temp:=busca('10'); {x del 1 punto}

dato1:=StrToFloat(temp);

temp:=busca('20'); {y del 1 punto}

dato2:=StrToFloat(temp);

temp:=busca('30'); {z del 1 punto}

dato3:=StrToFloat(temp);

AgregaDat(dato1,dato2,dato3); {Agrega estos datos a la lista}

temp:=busca('11');

dato1:=StrToFloat(temp);

temp:=busca('21');

dato2:=StrToFloat(temp);

temp:=busca('31');

dato3:=StrToFloat(temp);

AgregaDat(dato1,dato2,dato3);

temp:=busca('12');

dato1:=StrToFloat(temp);

temp:=busca('22');

dato2:=StrToFloat(temp);

temp:=busca('32');

dato3:=StrToFloat(temp);

AgregaDat(dato1,dato2,dato3);

end;

END;

CloseFile(archivo); {Cierra el archivo}

end;

procedure lee_sim(nombre:String);

var

archivo:File of char; {Los archivos "simple" son de caracteres}

dato1, dato2, dato3: char;

data: lis_punto;

cont: Integer;

procedure AgregaDat(x,y,z:char); {Este procedimiento anexa un dato a la

lista data}

var

dato: lis_punto;

begin

new(dato);

data^.Next:=dato;

dato^.x:=ord(x);

dato^.y:=ord(y);

dato^.z:=ord(z);

dato^.Next:=nil;

data:=dato;

end;

begin

Assign(archivo,nombre);

Reset(archivo);

New(data);

data^.x:=0;

data^.y:=0;

data^.z:=0;

mundo.coord:=data;

cont:=-2;

While Not(EOF(archivo)) DO

BEGIN

Read(archivo,dato1);

If Not(EOF(archivo)) THEN

BEGIN

Read(archivo,dato2);

If Not(EOF(archivo)) THEN

Begin

Read(archivo,dato3);

cont:=cont+3;

AgregaDat(dato1,dato2,dato3); {Se leen 3 bytes seguidos,

cada uno de 0 a 255 es una coordenada de un punto}

END

ELSE

MessageDlg('Número de datos Incorrectos', mtInformation,[mbOk], 0);

END

ELSE

MessageDlg('Número de datos Incorrectos', mtInformation,[mbOk], 0);

END;

CloseFile(archivo);

end;

procedure TForm2.Button1Click(Sender: TObject); {Si se oprime el botón OK}

var

FileExt: string[4];

FilePath:string;

begin

FileExt := UpperCase(ExtractFileExt(Edit1.Text)); {Determina la extensión}

FilePath := ExtractFileDir(FileListBox1.Filename); {Lee el Path}

if (FileExt = '') then

BEGIN

lee_sim(FilePath+'\'+Edit1.Text); {Se lee con el formato simple}

mundo.lleno:=True;

END;

if (FileExt = '.DXF') then

BEGIN

lee_dxf(Edit1.Text); {Se lee con el formato DXF}

mundo.lleno:=True;

END;

close;

end;

procedure TForm2.Button2Click(Sender: TObject); {Si se oprime el botón Cancelar}

begin

close;

end;

 

end.

 

 

Genera (Form3):

unit genera; {Este procedimiento "genera" archivos "simples" de prueba}

interface

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

FileCtrl, StdCtrls;

type

TForm3 = class(TForm)

Listado: TButton;

arch_nom: TEdit;

Calculado: TButton;

Cancelar: TButton;

Label1: TLabel;

procedure ListadoClick(Sender: TObject);

procedure CalculadoClick(Sender: TObject);

procedure CancelarClick(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

var

Form3: TForm3;

implementation

{$R *.DFM}

procedure crea_lis(nombre:String); {Crea un archivo con los datos listados}

var

archivo: file of char;

c: array [1..29] of char;

cont : Integer;

begin

c[1]:=char(4);

c[2]:=char(0);

c[3]:=char(167);

c[4]:=char(12);

c[5]:=char(0);

c[6]:=char(168);

c[7]:=char(14);

c[8]:=char(0);

c[9]:=char(170);

c[10]:=char(14);

c[11]:=char(0);

c[12]:=char(227);

c[13]:=char(12);

c[14]:=char(0);

c[15]:=char(228);

c[16]:=char(4);

c[17]:=char(0);

c[18]:=char(229);

c[19]:=char(4);

c[20]:=char(0);

c[21]:=char(233);

c[22]:=char(28);

c[23]:=char(0);

c[24]:=char(233);

c[25]:=char(28);

c[26]:=char(0);

c[27]:=char(230);

c[28]:=char(71);

c[29]:=char(67);

Assign(archivo,nombre);

Rewrite(archivo);

for cont:=1 to 29 do

Write(archivo,c[cont]);

CloseFile(archivo);

end;

procedure crea_cal(nombre:String); {Crea un archivo con los datos calculados}

var

archivo: file of char;

x,y,z : Integer;

begin

Assign(archivo,nombre);

Rewrite(archivo);

for x:=1 to 255 do

begin

y:=round(127+127*cos(2*2*3.1415*(1-x/255))); {Círculos...}

z:=round(127+127*sin(4*2*3.1415*(1-x/255))); {+ círculos}

Write(archivo,char(x));

Write(archivo,char(y));

Write(archivo,char(z));

end;

CloseFile(archivo);

end;

procedure TForm3.ListadoClick(Sender: TObject);

begin

crea_lis(arch_nom.Text);

close;

end;

procedure TForm3.CalculadoClick(Sender: TObject);

begin

crea_cal(arch_nom.Text);

close;

end;

procedure TForm3.CancelarClick(Sender: TObject);

begin

close;

end;

end.

 

 

Guarda (Form4):

unit guarda; {Este procedimiento guarda los datos en memoria, sólo en

formato simple}

interface

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

FileCtrl, StdCtrls;

type

TForm4 = class(TForm)

Edit1: TEdit;

Button1: TButton;

Button2: TButton;

DriveComboBox1: TDriveComboBox;

DirectoryListBox1: TDirectoryListBox;

FilterComboBox1: TFilterComboBox;

FileListBox1: TFileListBox;

procedure Button2Click(Sender: TObject);

procedure Button1Click(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

var

Form4: TForm4;

implementation

uses

visual;

{$R *.DFM}

procedure esc_sim(nombre:String);

var

archivo:File of char;

data: lis_punto;

x,y,z: integer;

begin

New(data);

data:=mundo.coord;

Assign(archivo,nombre);

Rewrite(archivo);

repeat

data:=data^.next;

x:=round(data^.x);

y:=round(data^.y);

z:=round(data^.z);

Write(archivo,char(x));

Write(archivo,char(y));

Write(archivo,char(z));

until (data^.next=nil);

CloseFile(archivo);

end;

procedure esc_dxf(nombre:String);

var

archivo:Text; {Los archivos DXF son de tipo texto}

data: lis_punto;

x,y,z: real;

begin

New(data);

data:=mundo.coord;

Assign(archivo,nombre);

Rewrite(archivo);

writeln(archivo,'0');

writeln(archivo,'SECTION');

writeln(archivo,'2');

writeln(archivo,'HEADER');

writeln(archivo,'0');

writeln(archivo,'ENDSEC');

writeln(archivo,'0');

writeln(archivo,'SECTION');

writeln(archivo,'2');

writeln(archivo,'ENTITIES');

repeat

data:=data^.next;

x:=data^.x;

y:=data^.y;

z:=data^.z;

writeln(archivo,'0');

writeln(archivo,'3DFACE');

writeln(archivo,'8');

writeln(archivo,'Default');

writeln(archivo,'62');

writeln(archivo,'254');

writeln(archivo,'10');

Writeln(archivo,x);

writeln(archivo,'20');

Writeln(archivo,y);

writeln(archivo,'30');

Writeln(archivo,z);

data:=data^.next;

x:=data^.x;

y:=data^.y;

z:=data^.z;

writeln(archivo,'11');

Writeln(archivo,x);

writeln(archivo,'21');

Writeln(archivo,y);

writeln(archivo,'31');

Writeln(archivo,z);

data:=data^.next;

x:=data^.x;

y:=data^.y;

z:=data^.z;

writeln(archivo,'12');

Writeln(archivo,x);

writeln(archivo,'22');

Writeln(archivo,y);

writeln(archivo,'32');

Writeln(archivo,z);

writeln(archivo,'13');

Writeln(archivo,x);

writeln(archivo,'23');

Writeln(archivo,y);

writeln(archivo,'33');

Writeln(archivo,z);

until (data^.next=nil);

writeln(archivo,'0');

writeln(archivo,'ENDSEC');

writeln(archivo,'0');

writeln(archivo,'EOF');

CloseFile(archivo);

end;

procedure TForm4.Button2Click(Sender: TObject);

begin

close;

end;

procedure TForm4.Button1Click(Sender: TObject);

var

FileExt: string[4];

FilePath:string;

begin

if mundo.lleno then

begin

FileExt := UpperCase(ExtractFileExt(Edit1.Text));

FilePath := ExtractFileDir(FileListBox1.Filename);

if (FileExt = '') then

esc_sim(FilePath+'\'+Edit1.Text)

else if (FileExt = '.DXF') then

esc_dxf(Edit1.Text)

else showmessage('Formato desconocido.');

end

else

showmessage('No hay nada que guardar');

close;

end;

end.