]> git.llucax.com Git - z.facultad/75.07/algowars.git/blob - doc/src-html/vista/Camara.pas
Import inicial después del "/var incident". :(
[z.facultad/75.07/algowars.git] / doc / src-html / vista / Camara.pas
1 <HTML><HEAD>\r
2 <TITLE>File: camara.pas </TITLE>\r
3 <META NAME="GENERATOR" CONTENT="PasToHTML(Bystricky Vladimir)">\r
4 </HEAD>\r
5 <BODY BGCOLOR="#FFFFFF">\r
6 <A NAME=camara.pas><CENTER><H3>camara.pas</H3></A><I> from <A HREF=/proyecto/doc/src-html/AlgoWars.html> Project: AlgoWars.dpr</A></I></CENTER>\r
7 <HR>\r
8 <PRE>\r
9 <I><FONT COLOR="Navy">{** Implementa una cámara que se encarga de representar los objetos en 2D.<br> \r
10     <i>Cambios:</i> \r
11     <PRE> \r
12     10/11/00: Se agrega el manejo de excepciones para evitar usar la camara cuando el cameraman fue destruido. \r
13               Para lograr esto se crea una excepcion (ECameramanDestruido) que se lanza cuando hay una excepcion \r
14               de violacion de acceso a memoria. Esta excepcion debe ser manejada por quien meneje la camara y puede \r
15               ser lanzada por mGetDebugInfo o mProyectar. \r
16     01/12/00: Se elimina el atributo aApertura porque era absolutamente inecesario. \r
17               Se cambia la estructura interna para que el filtrado de los objetos los realice un cFiltro. \r
18     07/12/00: Se agregan nuevos métodos (protegidos) para obtener información de la cámara para poder crear subclases, \r
19               para lo cual tambien se hace virtual el método mProyectar. \r
20     08/12/00: Se quita el método para setear el filtro y se agrega un contructor que admite un filtro para reemplazarlo. \r
21               Se cambia esta clase para que sea abstracta. Se deja la implementacion del método mProyectar para las \r
22               subclases exlusivamente ya que ahora es abstracto. La cámara frontal (que antes se implementaba en \r
23               esta unidad), ahora está implementado la unidad Camaras al igual que el resto. \r
24     </PRE>}</FONT></I> \r
25 <B>unit</B> Camara; \r
26  \r
27 <B>interface</B> \r
28  \r
29 <B>uses</B> \r
30   <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
31   Objeto, \r
32   <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
33   Tipos, \r
34   Coordenadas, \r
35   Vectores, \r
36   ObjetoVolador, \r
37   NavePropia, \r
38   Espacio, \r
39   Classes, \r
40   Sysutils, \r
41   Filtro, \r
42   Lista; \r
43  \r
44 <B>type</B> \r
45   <I><FONT COLOR="Navy">{** Datos de un Objeto Volador procesado por una cámara }</FONT></I> \r
46   tProyectado = <B>record</B> \r
47     oOV:  cObjetoVolador; \r
48     x:    tLongitud; \r
49     y:    tLongitud; \r
50     tam:  tLongitud; \r
51   <B>end</B>; \r
52  \r
53   <I><FONT COLOR="Navy">{** Puntero a tProyectado}</FONT></I> \r
54   tPProy = ^tProyectado; \r
55  \r
56   <I><FONT COLOR="Navy">{** Excepcion producida por la cámara si se utiliza cuando el cameraman fue destruido}</FONT></I> \r
57   ECameramanDestruido = <B>class</B>( Exception ) \r
58     <B>public</B> \r
59       <I><FONT COLOR="Navy">{** Constructor}</FONT></I> \r
60       <B>constructor</B> create; \r
61   <B>end</B>; \r
62  \r
63   <I><FONT COLOR="Navy">{** Implementa una cámara que se encarga de representar los objetos en 2D.}</FONT></I> \r
64   cCamara = <B>class</B><I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I>( cObjeto )<I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
65     <B>private</B> \r
66       aCameraman:     cObjetoVolador; <I><FONT COLOR="Navy">// Objeto volador que porta la camara </FONT></I>\r
67       aRadioMaximo:   tLongitud;      <I><FONT COLOR="Navy">// Alcance maximo de la camara (los </FONT></I>\r
68                                       <I><FONT COLOR="Navy">//  objetos mas lejanos no se veran) </FONT></I>\r
69       aRadioMinimo:   tLongitud;      <I><FONT COLOR="Navy">// Alcance minimo de la camara (los </FONT></I>\r
70                                       <I><FONT COLOR="Navy">//  objetos mas cercanos no se veran) </FONT></I>\r
71       <I><FONT COLOR="Navy">// Estos 3 ultimos atributos están ligados entre si (y son en parte redundantes) </FONT></I>\r
72       aRadioPantalla: tLongitud;      <I><FONT COLOR="Navy">// Radio de la pantalla. </FONT></I>\r
73       aDistPantalla:  tLongitud;      <I><FONT COLOR="Navy">// Distancia (mínima) hasta la pantalla </FONT></I>\r
74       aCosApertura:   tAngulo;        <I><FONT COLOR="Navy">// Coseno del Angulo de vision de la camara, </FONT></I>\r
75                                       <I><FONT COLOR="Navy">//   se almacena sólo el coseno porque el </FONT></I>\r
76                                       <I><FONT COLOR="Navy">//   ángulo en sí no se usa. </FONT></I>\r
77       aFiltro:        cFiltro;        <I><FONT COLOR="Navy">// Filtro que utiliza la cámara para evaluar </FONT></I>\r
78                                       <I><FONT COLOR="Navy">//  cuales objetos están visibles y cuales no. </FONT></I>\r
79  \r
80     <B>protected</B> \r
81       <I><FONT COLOR="Navy">{** Obtiene la proyección del objeto volador en X, Y}</FONT></I> \r
82       <B>procedure</B> <A HREF="#cCamara.mProyectar">mProyectar</A>(ov: cObjetoVolador; <B>var</B> x, y, tam: tLongitud); <B>virtual</B>; <B>abstract</B>; \r
83       <I><FONT COLOR="Navy">{** Devuelve el objeto portador de la cámara}</FONT></I> \r
84       <B>function</B> <A HREF="#cCamara.mGetCameraman">mGetCameraman</A>: cObjetoVolador; \r
85       <I><FONT COLOR="Navy">{** Permite asignar un nuevo portador de la cámara}</FONT></I> \r
86       <B>procedure</B> <A HREF="#cCamara.mSetCameraman">mSetCameraman</A>( oOV: cObjetoVOlador ); \r
87       <I><FONT COLOR="Navy">{** Devuelve distancia a la pantalla}</FONT></I> \r
88       <B>function</B> <A HREF="#cCamara.mGetDistPantalla">mGetDistPantalla</A>: tLongitud; \r
89       <I><FONT COLOR="Navy">{** Devuelve el radio mínimo de detección}</FONT></I> \r
90       <B>function</B> <A HREF="#cCamara.mGetRadioMinimo">mGetRadioMinimo</A>: tLongitud; \r
91       <I><FONT COLOR="Navy">{** Devuelve el radio máximo de detección}</FONT></I> \r
92       <B>function</B> <A HREF="#cCamara.mGetRadioMaximo">mGetRadioMaximo</A>: tLongitud; \r
93       <I><FONT COLOR="Navy">{** Asigna un nuevo filtro}</FONT></I> \r
94       <B>Procedure</B> <A HREF="#cCamara.mSetFiltro">mSetFiltro</A>( filtro: cFiltro ); \r
95     <B>public</B> \r
96       <I><FONT COLOR="Navy">{** Constructor}</FONT></I> \r
97       <B>constructor</B> create( cameraman: cObjetoVolador; angulo: tAngulo = PI/4; maximo: tLongitud = 5000; distPantalla: tLongitud = 0 ); overload; \r
98       <I><FONT COLOR="Navy">{** Procesa una lista de objetos, devolviendo solo los visibles en una lista de records tProyectado \r
99           ordenada ascendentemente por el tamaño proporcional (es decir, el objeto de tamaño menor está primero en la lista).}</FONT></I> \r
100       <B>function</B> <A HREF="#cCamara.mProcesar">mProcesar</A>( l: TList ): cLista; \r
101       <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
102       <I><FONT COLOR="Navy">{** Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar \r
103           y la información entregada depende del parámetro tDebugInfo.}</FONT></I> \r
104       <B>function</B> <A HREF="#cCamara.mGetDebugInfo">mGetDebugInfo</A>( debugLevel: tDebugInfo = DI_MINI ): <B>string</B>; <B>override</B>; \r
105       <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
106       <I><FONT COLOR="Navy">{** Obtiene el radio de la pantalla}</FONT></I> \r
107       <B>function</B> <A HREF="#cCamara.mGetRadioPantalla">mGetRadioPantalla</A>: tLongitud; \r
108   <B>end</B>; \r
109  \r
110  \r
111 <B>implementation</B> \r
112  \r
113 <B>uses</B> \r
114   Filtros, \r
115   Math; \r
116  \r
117 <I><FONT COLOR="Navy">{** Funcion para ordenar los elementos de la lista que se devuelve \r
118     @param  item1 Item a comparar (puntero) \r
119     @param  item2 Item a comparar (puntero) \r
120     @return       <b>1</b> si item1 > item2<br>&nbsp;&nbsp;&nbsp; \r
121                   <b>-1</b> si item1 < item2<br>&nbsp;&nbsp;&nbsp; \r
122                   <b>0</b> si item1 = item2}</FONT></I> \r
123 <B>function</B> listSort( item1, item2: pointer ): integer; \r
124 <B>var</B> \r
125   p1, \r
126   p2: tPProy; \r
127 <B>begin</B> \r
128   p1 := tPProy( item1 ); \r
129   p2 := tPProy( item2 ); \r
130   result := 0; \r
131   <B>if</B> p1^.tam > p2^.tam <B>then</B> \r
132     result := 1 \r
133   <B>else</B> \r
134     <B>if</B> p1^.tam < p2^.tam <B>then</B> \r
135       result := -1 \r
136 <B>end</B>; \r
137  \r
138 <I><FONT COLOR="Navy">{ cCamara }</FONT></I> \r
139  \r
140 <I><FONT COLOR="Navy">{** Contructor \r
141     @param cameraman Objeto Volador en el que estará montada la cámara (obligatorio) \r
142     @param angulo         Angulo de apertura (visión) de la cámara (default = pi/4) \r
143     @param maximo         Distancia máxima en la que se considera visible a un objeto (default = 5000) \r
144     @param distPantalla   Distancia hasta la pantalla de proyección (default = 0). Si tiene el valor por default \r
145                             o cualquier valor menor o igual a cero, se usa el tamaño del objeto volador}</FONT></I> \r
146 <B>constructor</B> cCamara.create(cameraman: cObjetoVolador; \r
147   angulo: tAngulo; maximo: tLongitud; \r
148   distPantalla: tLongitud ); \r
149 <B>begin</B> \r
150   <B>inherited</B> create; \r
151   aCameraman    := cameraman; \r
152   aRadioMaximo  := maximo; \r
153   aCosApertura  := cos( angulo ); \r
154   <B>if</B> distPantalla > 0 <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// Si la distancia es positiva, se la asigna y calcula el radio minimo </FONT></I>\r
155     aDistPantalla := distPantalla; \r
156     <I><FONT COLOR="Navy">// El radio minimo se calcula basado en la formula sen(a) = adyacente / HIPOTENUSA </FONT></I>\r
157     aRadioMinimo  := aDistPantalla / sin( angulo ); \r
158   <B>end</B> <B>else</B> <B>begin</B> <I><FONT COLOR="Navy">// Si es negativo o cero (se paso como default o mal), lo extrae del objeto volador </FONT></I>\r
159     aRadioMinimo  := aCameraman.mGetDimension; \r
160     <I><FONT COLOR="Navy">// La distancia a la pantalla se calcula basado en la formula sen(a) = ADYACENTE / hipotenusa </FONT></I>\r
161     aDistPantalla := sin( angulo ) * aRadioMinimo; \r
162   <B>end</B>; \r
163   <I><FONT COLOR="Navy">// El radio de la pantalla se calcula basado en la formula cos(a) = OPUESTO / hipotenusa </FONT></I>\r
164   aRadioPantalla := aCosApertura * aRadioMinimo; \r
165   <I><FONT COLOR="Navy">// Crea un filtro frontal </FONT></I>\r
166   aFiltro := cFiltroFrontal.create( aCameraman, angulo, aRadioMaximo, aRadioMinimo ) \r
167 <B>end</B>; \r
168  \r
169 <I><FONT COLOR="Navy">{** Procesa una lista de objetos, devolviendo solo los visibles en una lista de records tProyectado \r
170     ordenada ascendentemente por el tamaño proporcional (es decir, el objeto de tamaño menor está primero en la lista). \r
171     @return  Lista con los objetos visibles y sus posiciones y tamaños, en un registro \r
172              del tipo <i>tProyectado</i>, ordenados de forma ascendente según el tamaño. \r
173     @param l Lista con los objetos a procesar}</FONT></I> \r
174 <B>function</B> <A NAME=cCamara.mProcesar>cCamara.mProcesar</A>( l: TList ): cLista; \r
175 <B>var</B> \r
176   lFiltrada:  TList; \r
177   lProcesada: cLista; \r
178   proy: tPProy; \r
179   oOV: cObjetoVolador; \r
180   i: integer; \r
181   x, \r
182   y, \r
183   tam: tLongitud; \r
184   sort: TListSortCompare; \r
185  \r
186 <B>begin</B> \r
187   lProcesada := cLista.create; \r
188   <B>try</B> \r
189     lFiltrada  := aFiltro.mFiltrar( l ); \r
190   <B>except</B> \r
191     on e: EObservadorDestruido <B>do</B> \r
192       <B>raise</B> ECameramanDestruido.create; \r
193   <B>end</B>; \r
194   <B>for</B> i:=0 <B>to</B> lFiltrada.count - 1 <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// recorre la lista de objetos </FONT></I>\r
195     oOV := lFiltrada.items[i]; <I><FONT COLOR="Navy">// obtiene el ObjetoVolador actual </FONT></I>\r
196     new( proy ); \r
197     mProyectar( oOV, x, y, tam ); \r
198     proy^.oOV := oOV; \r
199     proy^.x := x; \r
200     proy^.y := y; \r
201     proy^.tam := tam; \r
202     lProcesada.Add( proy ); \r
203   <B>end</B>; \r
204   sort := listSort; \r
205   lProcesada.Sort( sort ); \r
206   result := lProcesada; \r
207   lFiltrada.free; \r
208 <B>end</B>; \r
209  \r
210 <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
211 <I><FONT COLOR="Navy">{** Devuelve el estado del objeto basandose en la cantidad de datos requeridos:<br> \r
212     Siempre devuelve los valores de las componentes x, y, z y si debugLevel es mayor que DI_NORMAL, \r
213     también muestra el módulo. \r
214     @return             Cadena de texto con el estado del Objeto. \r
215     @param   debugLevel Cantidad de información requerida}</FONT></I> \r
216 <B>function</B> <A NAME=cCamara.mGetDebugInfo>cCamara.mGetDebugInfo</A>( debugLevel: tDebugInfo ): <B>string</B>; \r
217 <B>begin</B> \r
218   <I><FONT COLOR="Navy">// Construye la cadena dependiendo de la cantidad de informacion que se quiera obtener </FONT></I>\r
219   result := 'Radio Máximo: ' + FloatToStrF( aRadioMaximo, ffNumber, 5, 5 ) + \r
220             ' | Radio Mínimo: ' + FloatToStrF( aRadioMinimo, ffNumber, 5, 5 ) + \r
221             ' | Radio de Pantalla: ' + FloatToStrF( aRadioPantalla, ffNumber, 5, 5 ) + \r
222             ' | Distancia de Pantalla: ' + FloatToStrF( aDistPantalla, ffNumber, 5, 5 ); \r
223   <B>try</B> <I><FONT COLOR="Navy">// Probamos que el cameraman no este destruido </FONT></I>\r
224     <B>if</B> debugLevel = DI_NORMAL <B>then</B> \r
225       result := result + #13 + #10 + \r
226                 'Cameraman: ' + aCameraman.mGetDebugInfo; \r
227     <B>if</B> debugLevel = DI_MAXI <B>then</B> \r
228       result := result + #13 + #10 + \r
229                 'Cameraman: ' + aCameraman.mGetDebugInfo( debugLevel ); <I><FONT COLOR="Navy">// + #13 + #10 + </FONT></I>\r
230   <B>except</B> <I><FONT COLOR="Navy">// Si esta destruido cae en una excepcion </FONT></I>\r
231     on e: EAccessViolation <B>do</B> \r
232       <B>raise</B> ECameramanDestruido.create; <I><FONT COLOR="Navy">// Creamos una nueva excepcion especial </FONT></I>\r
233   <B>end</B>; \r
234 <B>end</B>; \r
235 <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
236  \r
237 <I><FONT COLOR="Navy">{** Obtiene el radio de la pantalla \r
238     @return Radio de la pantalla}</FONT></I> \r
239 <B>function</B> <A NAME=cCamara.mGetRadioPantalla>cCamara.mGetRadioPantalla</A>: tLongitud; \r
240 <B>begin</B> \r
241   result := aRadioPantalla; \r
242 <B>end</B>; \r
243  \r
244 <I><FONT COLOR="Navy">{** Devuelve el objeto portador de la cámara \r
245     @return Objeto portador de la cámara}</FONT></I> \r
246 <B>function</B> <A NAME=cCamara.mGetCameraman>cCamara.mGetCameraman</A>: cObjetoVolador; \r
247 <B>begin</B> \r
248   result := aCameraman; \r
249 <B>end</B>; \r
250  \r
251 <I><FONT COLOR="Navy">{** Permite asignar un nuevo portador de la cámara \r
252     @param oOV Objeto volador que será en nuevo portador de la cámara}</FONT></I> \r
253 <B>procedure</B> <A NAME=cCamara.mSetCameraman>cCamara.mSetCameraman</A>(oOV: cObjetoVOlador); \r
254 <B>begin</B> \r
255   aCameraman := oOV; \r
256   aFiltro.mSetObservador( oOV ); \r
257 <B>end</B>; \r
258  \r
259 <I><FONT COLOR="Navy">{** Devuelve distancia a la pantalla \r
260     @return Distancia a la pantalla}</FONT></I> \r
261 <B>function</B> <A NAME=cCamara.mGetDistPantalla>cCamara.mGetDistPantalla</A>: tLongitud; \r
262 <B>begin</B> \r
263   result:=aDistPantalla; \r
264 <B>end</B>; \r
265  \r
266 <I><FONT COLOR="Navy">{** Devuelve el radio mínimo de detección \r
267     @return Radio mínimo de detección}</FONT></I> \r
268 <B>function</B> <A NAME=cCamara.mGetRadioMaximo>cCamara.mGetRadioMaximo</A>: tLongitud; \r
269 <B>begin</B> \r
270   result:=aRadioMaximo; \r
271 <B>end</B>; \r
272  \r
273 <I><FONT COLOR="Navy">{** Devuelve el radio máximo de detección \r
274     @return Radio máximo de detección}</FONT></I> \r
275 <B>function</B> <A NAME=cCamara.mGetRadioMinimo>cCamara.mGetRadioMinimo</A>: tLongitud; \r
276 <B>begin</B> \r
277   result:=aRadioMinimo; \r
278 <B>end</B>; \r
279  \r
280 <I><FONT COLOR="Navy">{** Asigna un nuevo filtro}</FONT></I> \r
281 <B>procedure</B> <A NAME=cCamara.mSetFiltro>cCamara.mSetFiltro</A>(filtro: cFiltro); \r
282 <B>begin</B> \r
283   aFiltro.free; \r
284   aFiltro := filtro; \r
285 <B>end</B>; \r
286  \r
287 <I><FONT COLOR="Navy">{ ECameramanDestruido }</FONT></I> \r
288  \r
289 <I><FONT COLOR="Navy">{** Constructor}</FONT></I> \r
290 <B>constructor</B> ECameramanDestruido.create; \r
291 <B>begin</B> \r
292   <B>inherited</B> create( 'El Cameraman fue destruido.' ); \r
293 <B>end</B>; \r
294  \r
295 <B>end</B>. \r
296 </PRE>\r
297 </BODY>\r
298 </HTML>\r