2 <TITLE>File: vectores.pas </TITLE>
\r
3 <META NAME="GENERATOR" CONTENT="PasToHTML(Bystricky Vladimir)">
\r
5 <BODY BGCOLOR="#FFFFFF">
\r
6 <A NAME=vectores.pas><CENTER><H3>vectores.pas</H3></A><I> from <A HREF=/proyecto/doc/src-html/AlgoWars.html> Project: AlgoWars.dpr</A></I></CENTER>
\r
9 <I><FONT COLOR="Navy">{** Es la implementación de un vector físico. Esta clase es el esqueleto de
\r
10 la aplicación ya que todas las velocidades y posiciones son del tipo cVector.
\r
11 Todos los calculos de movimientos, distancias, etc. se manejan con los metodos de esta clase<br>
\r
14 05/10/00: Se corrigió el método mAddModulo para que al verificar el signo del modulo resultante,
\r
15 si es negativo, setee el modulo a cero.
\r
16 28/10/00: Se cambiaron todos los metodos en los que se realizan operaciones con el vector para
\r
17 que devulvan un puntero a si mismo (para poder hacer asignaciones luego de la operacion).
\r
18 Ahora todos los métodos son funciones
\r
20 <B>unit</B> Vectores;
\r
29 <I><FONT COLOR="Navy">{** La clase cVector es la implementación de un vector físico. Esta clase es el esqueleto de
\r
30 la aplicación ya que todas las velocidades y posiciones son del tipo cVector.
\r
31 Todos los calculos de movimientos, distancias, etc. se manejan con los metodos de esta clase}</FONT></I>
\r
32 cVector = <B>class</B>( cObjetoPersistente )
\r
34 aX: tLongitud; <I><FONT COLOR="Navy">// Componente del vector en X </FONT></I>
\r
35 aY: tLongitud; <I><FONT COLOR="Navy">// Componente del vector en Y </FONT></I>
\r
36 aZ: tLongitud; <I><FONT COLOR="Navy">// Componente del vector en Z </FONT></I>
\r
38 <I><FONT COLOR="Navy">{** Constructor}</FONT></I>
\r
39 <B>constructor</B> create( x: tLongitud = 0; y: tLongitud = 0; z: tLongitud = 0 ); overload;
\r
40 <I><FONT COLOR="Navy">{** Constructor que copia los atributos de un Vector existente}</FONT></I>
\r
41 <B>constructor</B> create( v: cVector ); overload;
\r
42 <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I>
\r
43 <I><FONT COLOR="Navy">{** Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar
\r
44 y la información entregada depende del parámetro tDebugInfo.}</FONT></I>
\r
45 <B>function</B> <A HREF="#cVector.mGetDebugInfo">mGetDebugInfo</A>( debugLevel: tDebugInfo = DI_MINI ): <B>string</B>; <B>override</B>;
\r
46 <I><FONT COLOR="Navy">{$ENDIF}</FONT></I>
\r
47 <I><FONT COLOR="Navy">{** Convierte el vector en un versor (norma 1)}</FONT></I>
\r
48 <B>function</B> <A HREF="#cVector.mHacerVersor">mHacerVersor</A>: cVector;
\r
49 <I><FONT COLOR="Navy">{** Establece los valores del vector x, y, z}</FONT></I>
\r
50 <B>function</B> <A HREF="#cVector.mSet">mSet</A>( x, y, z: tLongitud ): cVector; overload;
\r
51 <I><FONT COLOR="Navy">{** Modifica las componentes del vector basandose en otro}</FONT></I>
\r
52 <B>function</B> <A HREF="#cVector.mSet">mSet</A>( v: cVector ): cVector; overload;
\r
53 <I><FONT COLOR="Navy">{** Setea la componente X}</FONT></I>
\r
54 <B>function</B> <A HREF="#cVector.mSetX">mSetX</A>( x: tLongitud ): cVector;
\r
55 <I><FONT COLOR="Navy">{** Setea la componente Y}</FONT></I>
\r
56 <B>function</B> <A HREF="#cVector.mSetY">mSetY</A>( y: tLongitud ): cVector;
\r
57 <I><FONT COLOR="Navy">{** Setea la componente Z}</FONT></I>
\r
58 <B>function</B> <A HREF="#cVector.mSetZ">mSetZ</A>( z: tLongitud ): cVector;
\r
59 <I><FONT COLOR="Navy">{** Agrega un valor a la componente X}</FONT></I>
\r
60 <B>function</B> <A HREF="#cVector.mAddX">mAddX</A>( x: tLongitud ): cVector;
\r
61 <I><FONT COLOR="Navy">{** Agrega un valor a la componente Y}</FONT></I>
\r
62 <B>function</B> <A HREF="#cVector.mAddY">mAddY</A>( y: tLongitud ): cVector;
\r
63 <I><FONT COLOR="Navy">{** Agrega un valor a la componente Z}</FONT></I>
\r
64 <B>function</B> <A HREF="#cVector.mAddZ">mAddZ</A>( z: tLongitud ): cVector;
\r
65 <I><FONT COLOR="Navy">{** Setea el modulo del vector a un valor determinado}</FONT></I>
\r
66 <B>function</B> <A HREF="#cVector.mSetModulo">mSetModulo</A>( modulo: tLongitud ): cVector;
\r
67 <I><FONT COLOR="Navy">{** Aumenta (o disminuye si el argumente es negativo) el modulo del vector}</FONT></I>
\r
68 <B>function</B> <A HREF="#cVector.mAddModulo">mAddModulo</A>( modulo: tLongitud ): cVector;
\r
69 <I><FONT COLOR="Navy">{** Obtiene la componente X}</FONT></I>
\r
70 <B>function</B> <A HREF="#cVector.mGetX">mGetX</A>: tLongitud;
\r
71 <I><FONT COLOR="Navy">{** Obtiene la componente Y}</FONT></I>
\r
72 <B>function</B> <A HREF="#cVector.mGetY">mGetY</A>: tLongitud;
\r
73 <I><FONT COLOR="Navy">{** Obtiene la componente Z}</FONT></I>
\r
74 <B>function</B> <A HREF="#cVector.mGetZ">mGetZ</A>: tLongitud;
\r
75 <I><FONT COLOR="Navy">{** Obtiene el modulo del vector}</FONT></I>
\r
76 <B>function</B> <A HREF="#cVector.mGetModulo">mGetModulo</A>: tLongitud;
\r
77 <I><FONT COLOR="Navy">{** Suma a si mismo el vector vec}</FONT></I>
\r
78 <B>function</B> <A HREF="#cVector.mSumar">mSumar</A>( vec: cVector ): cVector;
\r
79 <I><FONT COLOR="Navy">{** Resta a si mismo el vector vec}</FONT></I>
\r
80 <B>function</B> <A HREF="#cVector.mRestar">mRestar</A>( vec: cVector ): cVector;
\r
81 <I><FONT COLOR="Navy">{** Se multiplica vectorialmente a si mismo por el vector vec}</FONT></I>
\r
82 <B>function</B> <A HREF="#cVector.mMultiplicar">mMultiplicar</A>( vec: cVector ): cVector; overload;
\r
83 <I><FONT COLOR="Navy">{** Se multiplica por un escalar}</FONT></I>
\r
84 <B>function</B> <A HREF="#cVector.mMultiplicar">mMultiplicar</A>( esc: tLongitud ): cVector; overload;
\r
85 <I><FONT COLOR="Navy">{** Obtiene el producto escalar entre si mismo y el vector vec}</FONT></I>
\r
86 <B>function</B> <A HREF="#cVector.mMultiplicarEsc">mMultiplicarEsc</A>( vec: cVector ): tLongitud;
\r
87 <I><FONT COLOR="Navy">{** Obtiene la distancia al a otro vector}</FONT></I>
\r
88 <B>function</B> <A HREF="#cVector.mGetDistancia">mGetDistancia</A>( vec: cVector ): tLongitud;
\r
89 <I><FONT COLOR="Navy">{** Modifica el vector con basandose en otro vector (pensado como velocidad) y un
\r
90 intervalo de tiempo siguiendo la formula física X' = X + V * dt
\r
91 (este metodo esta pensado basicamente para calcular los movimientos)}</FONT></I>
\r
92 <B>function</B> <A HREF="#cVector.mModificarCon">mModificarCon</A>( vel: cVector; dT: tTiempo ): cVector;
\r
93 <I><FONT COLOR="Navy">// SERIALIZACION </FONT></I>
\r
94 <I><FONT COLOR="Navy">{** Devuelve una cadena de texto con el objeto serializado.}</FONT></I>
\r
95 <B>function</B> <A HREF="#cVector.mSerializar">mSerializar</A>: <B>string</B>; <B>override</B>;
\r
96 <I><FONT COLOR="Navy">{** Recrea el objeto a partir de una cadena de texto con el objeto
\r
97 serializado.}</FONT></I>
\r
98 <B>procedure</B> <A HREF="#cVector.mDesSerializar">mDesSerializar</A>( str: <B>string</B> ); <B>override</B>;
\r
101 <B>implementation</B>
\r
108 <I><FONT COLOR="Navy">{ cVector }</FONT></I>
\r
110 <I><FONT COLOR="Navy">{** Crea un nuevo vector basandose en los atributos de uno existente.
\r
111 @param v Vector a copiar}</FONT></I>
\r
112 <B>constructor</B> cVector.create(v: cVector);
\r
114 <B>inherited</B> create;
\r
115 <I><FONT COLOR="Navy">// Usa el metodo mSet para establecer los valores </FONT></I>
\r
119 <I><FONT COLOR="Navy">{** Crea un nuevo vector basandose en los atributos dados como parámetro.
\r
120 @param x Componente en el eje X
\r
121 @param y Componente en el eje Y
\r
122 @param z Componente en el eje Z}</FONT></I>
\r
123 <B>constructor</B> cVector.create(x, y, z: tLongitud);
\r
125 <B>inherited</B> create;
\r
126 <I><FONT COLOR="Navy">// Usa el metodo mSet para establecer los valores </FONT></I>
\r
130 <I><FONT COLOR="Navy">{** Setea el modulo del vector a un valor determinado (sólo tiene sentido si el modulo actual es distinto de cero)
\r
131 @param modulo Modulo a adherir al verctor}</FONT></I>
\r
132 <B>function</B> <A NAME=cVector.mAddModulo>cVector.mAddModulo</A>(modulo: tLongitud): cVector;
\r
134 <I><FONT COLOR="Navy">// Disminuye el módulo sólo si el resultante no es negativo </FONT></I>
\r
135 <B>if</B> (mGetModulo + modulo) <= 0 <B>then</B> <I><FONT COLOR="Navy">// Si el modulo resultante es negativo o cero </FONT></I>
\r
136 mSetModulo( 0 ) <I><FONT COLOR="Navy">// Setea el modulo en 0 </FONT></I>
\r
137 <B>else</B> <I><FONT COLOR="Navy">// Si el modulo resultante es positivo </FONT></I>
\r
138 mSetModulo( mGetModulo + modulo );
\r
142 <I><FONT COLOR="Navy">{** Agrega un valor a la componente X
\r
143 @param x Valor a sumarle a la componente X}</FONT></I>
\r
144 <B>function</B> <A NAME=cVector.mAddX>cVector.mAddX</A>(x: tLongitud): cVector;
\r
150 <I><FONT COLOR="Navy">{** Agrega un valor a la componente Y
\r
151 @param y Valor a sumarle a la componente Y}</FONT></I>
\r
152 <B>function</B> <A NAME=cVector.mAddY>cVector.mAddY</A>(y: tLongitud): cVector;
\r
158 <I><FONT COLOR="Navy">{** Agrega un valor a la componente Z
\r
159 @param z Valor a sumarle a la componente Z}</FONT></I>
\r
160 <B>function</B> <A NAME=cVector.mAddZ>cVector.mAddZ</A>(z: tLongitud): cVector;
\r
166 <I><FONT COLOR="Navy">{** Obtiene el modulo del vector
\r
167 @return Modulo (o norma) del vector}</FONT></I>
\r
168 <B>function</B> <A NAME=cVector.mGetModulo>cVector.mGetModulo</A>: tLongitud;
\r
170 <I><FONT COLOR="Navy">// Devuelve la raiz cuadrada de la suma de los cuadrados de las componentes </FONT></I>
\r
171 result := sqrt( sqr( aX ) + sqr( aY ) + sqr( aZ ) );
\r
174 <I><FONT COLOR="Navy">{** Obtiene la componente X
\r
175 @return Componente X del vector}</FONT></I>
\r
176 <B>function</B> <A NAME=cVector.mGetX>cVector.mGetX</A>: tLongitud;
\r
181 <I><FONT COLOR="Navy">{** Obtiene la componente Y
\r
182 @return Componente Y del vector}</FONT></I>
\r
183 <B>function</B> <A NAME=cVector.mGetY>cVector.mGetY</A>: tLongitud;
\r
188 <I><FONT COLOR="Navy">{** Obtiene la componente Z
\r
189 @return Componente Z del vector}</FONT></I>
\r
190 <B>function</B> <A NAME=cVector.mGetZ>cVector.mGetZ</A>: tLongitud;
\r
195 <I><FONT COLOR="Navy">{** Se multiplica vectorialmente a si mismo por el vector vec
\r
196 @param vec Vector por el cual se multiplica vectorialmente}</FONT></I>
\r
197 <B>function</B> <A NAME=cVector.mMultiplicar>cVector.mMultiplicar</A>(vec: cVector): cVector;
\r
203 <I><FONT COLOR="Navy">// Obtiene el resultado siguiendo la formula de producto vectorial </FONT></I>
\r
204 x := aY * vec.mGetZ - aZ * vec.mGetY;
\r
205 y := aX * vec.mGetZ - aZ * vec.mGetX;
\r
206 z := aX * vec.mGetY - aY * vec.mGetX;
\r
213 <I><FONT COLOR="Navy">{** Se multiplica por un escalar
\r
214 @param esc Escalar por el cual se multiplica}</FONT></I>
\r
215 <B>function</B> <A NAME=cVector.mMultiplicar>cVector.mMultiplicar</A>(esc: tLongitud): cVector;
\r
217 <I><FONT COLOR="Navy">// Multiplica cada componente por el escalar </FONT></I>
\r
224 <I><FONT COLOR="Navy">{** Obtiene el producto escalar entre si mismo y el vector vec
\r
225 @return Producto escalar entre los vectores
\r
226 @param vec Vector por el cual se multiplica escalarmente}</FONT></I>
\r
227 <B>function</B> <A NAME=cVector.mMultiplicarEsc>cVector.mMultiplicarEsc</A>(vec: cVector): tLongitud;
\r
229 <I><FONT COLOR="Navy">// Realiza el producto escalar (suma el producto componente a componente) </FONT></I>
\r
230 result := aX * vec.mGetX + aY * vec.mGetY + aZ * vec.mGetZ;
\r
233 <I><FONT COLOR="Navy">{** Resta a si mismo el vector vec
\r
234 @param vec Vector que se resta}</FONT></I>
\r
235 <B>function</B> <A NAME=cVector.mRestar>cVector.mRestar</A>(vec: cVector): cVector;
\r
237 aX := aX - vec.mGetX;
\r
238 aY := aY - vec.mGetY;
\r
239 aZ := aZ - vec.mGetZ;
\r
243 <I><FONT COLOR="Navy">{** Setea el modulo del vector a un valor determinado
\r
244 @param modulo Valor del nuevo Módulo}</FONT></I>
\r
245 <B>function</B> <A NAME=cVector.mSetModulo>cVector.mSetModulo</A>(modulo: tLongitud): cVector;
\r
247 <I><FONT COLOR="Navy">// Primero lo convertimos en un versor </FONT></I>
\r
249 <I><FONT COLOR="Navy">// Ahora multiplicamos el versor por la modulo deseada </FONT></I>
\r
250 mMultiplicar( modulo );
\r
254 <I><FONT COLOR="Navy">{** Modifica las componentes del vector basandose en otro
\r
255 @param v Vector del cual se obtendran los nuevos atributos}</FONT></I>
\r
256 <B>function</B> <A NAME=cVector.mSet>cVector.mSet</A>(v: cVector): cVector;
\r
264 <I><FONT COLOR="Navy">{** Establece las componentes del vector
\r
265 @param x Nuevo valor de la componente en el eje X
\r
266 @param y Nuevo valor de la componente en el eje Y
\r
267 @param z Nuevo valor de la componente en el eje Z}</FONT></I>
\r
268 <B>function</B> <A NAME=cVector.mSet>cVector.mSet</A>(x, y, z: tLongitud): cVector;
\r
276 <I><FONT COLOR="Navy">{** Setea la componente X
\r
277 @param x Nuevo valor de la componente en el eje X}</FONT></I>
\r
278 <B>function</B> <A NAME=cVector.mSetX>cVector.mSetX</A>(x: tLongitud): cVector;
\r
284 <I><FONT COLOR="Navy">{** Setea la componente Y
\r
285 @param y Nuevo valor de la componente en el eje Y}</FONT></I>
\r
286 <B>function</B> <A NAME=cVector.mSetY>cVector.mSetY</A>(y: tLongitud): cVector;
\r
292 <I><FONT COLOR="Navy">{** Setea la componente Z
\r
293 @param z Nuevo valor de la componente en el eje Z}</FONT></I>
\r
294 <B>function</B> <A NAME=cVector.mSetZ>cVector.mSetZ</A>(z: tLongitud): cVector;
\r
300 <I><FONT COLOR="Navy">{** Suma a si mismo el vector vec
\r
301 @param vec Vector a sumarle}</FONT></I>
\r
302 <B>function</B> <A NAME=cVector.mSumar>cVector.mSumar</A>(vec: cVector): cVector;
\r
304 aX := aX + vec.mGetX;
\r
305 aY := aY + vec.mGetY;
\r
306 aZ := aZ + vec.mGetZ;
\r
310 <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I>
\r
311 <I><FONT COLOR="Navy">{** Devuelve el estado del objeto basandose en la cantidad de datos requeridos:<br>
\r
312 Siempre devuelve los valores de las componentes x, y, z y si debugLevel es mayor que DI_NORMAL,
\r
313 también muestra el módulo.
\r
314 @return Cadena de texto con el estado del Objeto.
\r
315 @param debugLevel Cantidad de información requerida}</FONT></I>
\r
316 <B>function</B> <A NAME=cVector.mGetDebugInfo>cVector.mGetDebugInfo</A>( debugLevel: tDebugInfo ): <B>string</B>;
\r
318 <I><FONT COLOR="Navy">// Construye la cadena dependiendo de la cantidad de informacion que se quiera obtener </FONT></I>
\r
319 result := 'X: ' + FloatToStrF( mGetX, ffNumber, 5, 5 ) +
\r
320 ' | Y: ' + FloatToStrF( mGetY, ffNumber, 5, 5 ) +
\r
321 ' | Z: ' + FloatToStrF( mGetZ, ffNumber, 5, 5 );
\r
322 <B>if</B> debugLevel > DI_NORMAL <B>then</B>
\r
323 result := result + ' | Modulo: ' + FloatToStrF( mGetModulo, ffNumber, 5, 5 );
\r
325 <I><FONT COLOR="Navy">{$ENDIF}</FONT></I>
\r
327 <I><FONT COLOR="Navy">{** Obtiene la distancia al a otro vector (en realidad se tratan como puntos)
\r
328 @returns Distancia al otro vector
\r
329 @param vec Punto al cual se calcula la distancia}</FONT></I>
\r
330 <B>function</B> <A NAME=cVector.mGetDistancia>cVector.mGetDistancia</A>( vec: cVector ): tLongitud;
\r
334 <I><FONT COLOR="Navy">// Crea un nuevo vector basado en vec y le resta el vector actual </FONT></I>
\r
335 v := cVector.create( vec ).mRestar( self );
\r
336 <I><FONT COLOR="Navy">// devuelve el modulo </FONT></I>
\r
337 result := v.mGetModulo;
\r
338 <I><FONT COLOR="Navy">// Libera el vector temporal </FONT></I>
\r
342 <I><FONT COLOR="Navy">{** Modifica el vector con basandose en otro vector (pensado como velocidad) y un
\r
343 intervalo de tiempo siguiendo la formula física X' = X + V * dt
\r
344 (este metodo esta pensado basicamente para calcular los movimientos)
\r
345 @param vel Vector velocidad
\r
346 @param dT Intervalo de tiempo}</FONT></I>
\r
347 <B>function</B> <A NAME=cVector.mModificarCon>cVector.mModificarCon</A>(vel: cVector; dT: tTiempo): cVector;
\r
351 <I><FONT COLOR="Navy">// formula de MRU: SELF = SELF + VELOCIDAD * TIEMPO </FONT></I>
\r
352 v := cVector.create( vel ).mMultiplicar( dT );
\r
358 <I><FONT COLOR="Navy">{** Convierte el vector en un versor (sólo tiene sentido si el modulo actual es distinto de cero)}</FONT></I>
\r
359 <B>function</B> <A NAME=cVector.mHacerVersor>cVector.mHacerVersor</A>: cVector;
\r
361 <I><FONT COLOR="Navy">// Si el modulo es mayor que cero... </FONT></I>
\r
362 <B>if</B> mGetModulo > 0 <B>then</B>
\r
363 mMultiplicar( 1 / mGetModulo );
\r
367 <I><FONT COLOR="Navy">{** Recrea el objeto a partir de una cadena de texto con el objeto
\r
369 @param str Cadena de texto con el objeto serializado.}</FONT></I>
\r
370 <B>procedure</B> <A NAME=cVector.mDesSerializar>cVector.mDesSerializar</A>(str: <B>string</B>);
\r
374 <B>inherited</B> mDesSerializar( str ); <I><FONT COLOR="Navy">// SIEMPRE el ID debe ser el PRIMER atributo </FONT></I>
\r
375 r := TRegExpr.create;
\r
376 <B>try</B> <I><FONT COLOR="Navy">// ensure memory release </FONT></I>
\r
377 <I><FONT COLOR="Navy">// X </FONT></I>
\r
378 r.Expression := '<X>/s*([+/-]?/d+(/,/d+)?([eE][+/-]?/d+)?)/s*</X>';
\r
379 <B>if</B> r.Exec ( str ) <B>then</B>
\r
380 aX := StrToFloat( r.Match[1] )
\r
382 <B>raise</B> ESerializacion.create( 'No se encontro la componente en X' );
\r
383 <I><FONT COLOR="Navy">// Y </FONT></I>
\r
384 r.Expression := '<Y>/s*([+/-]?/d+(/,/d+)?([eE][+/-]?/d+)?)/s*</Y>';
\r
385 <B>if</B> r.Exec ( str ) <B>then</B>
\r
386 aY := StrToFloat( r.Match[1] )
\r
388 <B>raise</B> ESerializacion.create( 'No se encontro la componente en Y' );
\r
389 <I><FONT COLOR="Navy">// Z </FONT></I>
\r
390 r.Expression := '<Z>/s*([+/-]?/d+(/,/d+)?([eE][+/-]?/d+)?)/s*</Z>';
\r
391 <B>if</B> r.Exec ( str ) <B>then</B>
\r
392 aZ := StrToFloat( r.Match[1] )
\r
394 <B>raise</B> ESerializacion.create( 'No se encontro la componente en Z' );
\r
396 on e: ERegExpr <B>do</B> <B>begin</B>
\r
398 <B>raise</B> ESerializacion.create( ClassName + ': Error utilizando expresiones regulares: ' + e.<B>Message</B> );
\r
404 <I><FONT COLOR="Navy">{** Devuelve una cadena de texto con el objeto serializado.
\r
405 @return Cadena de texto con el objeto serializado.}</FONT></I>
\r
406 <B>function</B> <A NAME=cVector.mSerializar>cVector.mSerializar</A>: <B>string</B>;
\r
408 result := <B>inherited</B> mSerializar +
\r
409 '<X>' + FloatToStrF( aX, ffGeneral, 18, 0 ) + '</X>' +
\r
410 '<Y>' + FloatToStrF( aY, ffGeneral, 18, 0 ) + '</Y>' +
\r
411 '<Z>' + FloatToStrF( aZ, ffGeneral, 18, 0 ) + '</Z>';
\r