From the category archives:

Maxin Lab

Cuando era niño, programaba juegos en mi compú donde todo vivía en un mundo de dos dimensiones. No estaba tan mal porque las gráficas en ese entonces eran muy sencillas. De hecho, una nave espacial solía ser un aburrido cuadro rojo. Sin embargo, conforme fuí aprendiendo física, me fue necesario construir un mundo tridimensional, no sólo para hacer juegos, sino también para hacer mis cálculos y simulaciones.

Antes de consultar libros sobre el tema, intenté resolver el problema por mi cuenta. Yo lo visualizaba como convertir un espacio 3D (el mundo) a un espacio 2D (la pantalla). La manera más sencilla que se me ocurrió fue simplemente proyectar todos los puntos a una pared imaginaria en frente de mí. Las proyecciones podían ser de forma recta ignorando simplemente el eje Z; pero así no es muy atractivo porque no se crea la sensación de perspectiva. Es mejor proyectar con un ángulo imaginando que es el ángulo de visión del ojo. Mi primera representación (aplanada) fue esta:


Diagrama 1

Nuestro observador esta en el origen y mirando hacia Z, P es el punto que queremos proyectar, X es el punto proyectado y d es la distancia a nuestra pantalla imaginaria.

Ahora, ni modo, a hacer álgebra. Por triángulos semejantes tenemos:

frac { X_p } { sqrt { d^2 + {X_p}^2} } = frac { P_x } { sqrt { {P_x}^2 + {P_z}^2}

Haciendo un lado los pasos engorosos, despejamos Xp:

X_p = frac { P_x} { P_z } d

Por analogía, encontramos Yp:

Y_p = frac { P_y} { P_z } d

De las dos ecuaciones anteriores, es fácil deducir que d es matemáticamente un factor de escala y que al usar estas ecuaciones, los objetos se ven más grandes conforme se acercan al observador y reducen su tamaño al alejarse; sin importar si nuestros puntos se encuentran antes o después del punto d.

Pero no hemos terminado; nuestra pantalla hasta ahora esta en "coordenadas mundiales" las cuales no tienen porque concordar con las coordenadas de nuestra pantalla. De hecho, las coordenadas de nuestra pantalla son siempre positivas y el origen esta en la esquina superior izquierda. Es necesario hacer la transformación de coordenadas mundiales a coordenadas de la pantalla.


Diagrama 2

Con un poco de observación, se puede encontrar el factor de conversión para el eje x:

S_x = S_{xmin} + ( S_{xmax} - S{xmin} ) frac { X_p - W_L} { W_R - W_L }

En la mayoría de los casos se puede suponer para Sxmin un valor de cero:

S_x = S_{xmax}  frac { X_p - W_L} { W_R - W_L }

Si queremos manejar la pantalla mostrando 4 cuadrantes, entonces W_R = -W_L:

S_x = S_{xmax}  frac { X_p + W_L} { 2 W_R }

De forma similar para el caso del eje y:

S_y = S_{ymin} + ( S_{ymax} - S{ymin} ) frac { W_T - Y_P} { W_T - W_B }

De igual forma, se puede suponer para Symin un valor de cero:

S_y = S_{ymax} frac { W_T - Y_P} { W_T - W_B }

Para acomodar en cuatro cuadrantes, W_B = -W_T:

S_y = S_{ymax} frac { W_T - Y_P} { 2 W_T }

Conclusiones:

Ya con esto podemos armar una ciudad de casas de cerrillos con fórmulas con operaciones muy sencillas. Incluso corren relativamente rápido en las antigüas máquinas de 8 bits:


Aplicando las formulas en una computadora de 0.895 MHz

Las fórmulas presentadas aquí son muy limitadas, pero demuestran lo fácil que puede ser trabajar la tercera dimensión. En posts posteriores se trabajarán más para quitar las restricciones autoimpuestas como que el plano de proyección este únicamente perpendicular el eje Z y que el centro de proyección se encuentre únicamente en el origen.

{ 0 comments }

Automake y autoconfig son dos herramientas GNU que facilitan enormente el manejo de los proyectos escritos en C/C++. Permiten orden y estándarización que facilita la distribución e instalación de nuestros programas.

Importante:

Este post contiene unos apuentes que estan en desarrollo en este momento. No esta pensado como un tutorial y sólo está publico porque lo necesito en línea como una guía para mis proyectos personales.

Si caiste por accidente en esta página de internet y requieres de un tutorial en forma, te recomiendo que visites estas páginas:

http://www.openismus.com/documents/linux/automake/automake.shtml
http://www.seul.org/docs/autotut/#makefileam

Pasos a seguir

La receta que recomiendan muchos autores que escriben software libre es la siguiente:

1. Crear el directorio superior con el nombre del proyecto.

2. Crear un directorio src donde van todos los fuentes del proyecto.

3. Crear el archivo README

4. Crear el archivo AUTHORS

5. Crear el archivo COPYNG

6. Crear el archivo NEWS

7. Crear el archivo INSTALL

8. Escribir un archivo Makefile.am en el nivel más alto del directorio donde se tienen los fuentes y en cada subdirectorio de ese nivel.

- Para el caso de proyectos multidirectorio se indica su existencia en el respectivo nivel:

SUBDIRS = src

Por lo general, El Makefile.am del directorio raíz lleva esa línea.

- Para el caso que se tengan librerías, el archivo Makefile.am queda de la forma:

lib_LIBRARIES = library_name.a

# Los archivos fuentes de la librería:

library_name_a_SOURCES = filea.c

- Para el caso que se tengan librerías libtools, el archivo Makefile.am queda de la forma:

lib_LTLIBRARIES = nombre_libreria.la

# Los archivos fuentes de la librería:

nombre_libreria_la_SOURCES =
directorio/Fuente1.cpp
directorio/Fuente2.cpp

# Los archivos includes que se desean instalar en /usr/local/include

nobase_include_HEADERS =
directorio/encabezado1.h
directorio/encabezado2.h

- Si se quieren crear ejecutables el archivo queda:

bin_PROGRAMS = program_name

program_name_SOURCES = file1.cpp main.cpp

También se pueden usar las siguientes banderas:

_DEPENDENCIES

Dependencias adicionales.

_LDADD

Objetos adicionales que se quieran pasar al encadenador (Sólo programas).

_LDFLAGS

Banderas que se quieran pasar al encadenador.

_LIBADD

Igual que _LDADD', pero para librerías estáticas.

noinst_HEADERS

La lista de encabezados que van dentro de la distribución pero que no se instalan.

9. Crear el archivo configure.in, el cual es procesado por autoconf

################################################################
# AC_INIT is el primer macro en configure.in. El primer argumento es un archivo dentro del
# proyecto para revisar que el archivo configure.in esta en el directorio correcto.
################################################################

AC_INIT(configure.in)

################################################################
# Inicia automake
################################################################

PACKAGE=nombre_del proyecto
VERSION=0.1.0

AM_INIT_AUTOMAKE($PACKAGE, $VERSION)

################################################################
# Indica que el proyecto es en c++ y determina el compilador a usar
################################################################

AC_PROG_CXX

################################################################
# Revisa que esten algunos programas necesarios
#
# AC_CHECK_PROG
#
################################################################

################################################################
#
# Revisa de pendencias de encabezados
#
# AC_CHECK_HEADER(encabezado.h[,a[,b]])
#
# Si hay error se puede desplegar un mensaje con AC_MSG_ERROR(message), AC_MSG_WARNING(message)  y AC_ARG_ENABLE(feature,help[,a[,b]])
#
# donde
# a=action si se da el caso
# b=action si no se dio el caso
#
################################################################

################################################################
# Aquí se coloca los archivos Makefile que deben ser generados
################################################################

AC_OUTPUT([
src/fuente/Makefile
Makefile
])

Al ejecutar el comando aclocal, se genera el archivo aclocal.m4 que contiene todos los macros m4 necesarios para el script configure.ac:

aclocal

Finalmente, para crear el scripit configure, corremos:

autoconf

Con automake, se crean archivos Makefile.in de los archivos Makefile.ac:

$ automake --add-missing

Si se esta usando un svn, es recomendable hacer registro de la versión en que se realizo. Para esto, se usa el comando:

svn log -v> ChangeLog

Compilación e instalación del proyecto

Una vez que se han seguido estos, pasos ya es posible que compilar nuestro proyecto con los tradicionales ./configure, make y make install.

{ 0 comments }

Formulario de Cinemática

by Jorge Machin on September 6, 2007 · 0 comments

in Formularios, Física, Maxin Lab

Después de haber colocado el formulario de vectores, el paso obligado es colocar los formularios de Mécanica del Cuerpo Sólido. Pero para empezar, es mejor definir en el primer inciso, las áreas de la física que estudian a los cuerpos en movimiento.

1. Mecánica del cuerpo sólido

La mecánica es una rama de la física que estudia el equilibrio y movimiento de los cuerpos. La parte de la mecánica que estudia los cuerpos en reposo (sin movimiento) se llama estática, mientras que la parte que estudia a los cuerpos en movimiento se le denomina cinemática si no importa las cuasas que lo producen o alteran y dinámica si las toma en cuenta.

2. Posición, velocidad y aceleración

Representamos la posición de un punto P en movimiento a través del tiempo por medio del vector de posición vec r con respecto a un marco de referencia O:

vec r = vec r(t)

(2.1)

Entonces la tasa de cambio de la posición a través del tiempo o velocidad de P con respecto a O se obtiene derivando:

<br />
vec v = frac{dvec r }{dt}

(2.2)

Despejando y usando integrales definidas:

vec r = vec r_o + int_{t_o}^t vec v  dt

(2.3)

Continuando de (2.2), la aceleración de P con respecto al marco de referencia O en un tiempo t se obtiene con:

vec a=  frac {dvec v}{ dt }

(2.4)

o bien, en terminos del vector de posición:

vec a= frac { d^2vec r }{ dt^2 }

(2.5)

De igual forma de (2.4), despejando a la velocidad usando integrales definidas se tiene:

vec v = vec v_o + int_{t_o}^t vec a  dt

(2.6)

Finalmente de (2.2) y (2.6), haciendo integración definida se tiene:

vec r = vec r_o + vec v_o(t-t_o) + int_{t_o}^t int_{t_o}^t vec a  dt^2

(2.7)

Con estas ecuaciones, ya se tiene lo suficiente para analizar cualquier tipo de movimiento.

3. Ejemplo: Aceleración constante en una dimensión

De (2.3) tenemos:

vec r = vec r_o + vec v t

(3.1)

De (2.6) tenemos:

vec v = vec v_o +  vec at

(3.2)

Con la ecuación (3.2) es posible obtener el tiempo en alcanzar una velocidad.

De (2.7) tenemos:

vec r = vec r_o + vec v_o t +  frac {vec a t^2}{2}

(3.3)

Con la ecuación (3.3) se puede predecir el tiempo en recorrer una distancia, aplicando la fórmula general.

Usando (3.2) y (3.3), se obtiene:

vec r = vec r_o +  frac {vec v + vec v_o }{2} t

(3.4)

Como se puede ver, muchos problemas básicos de proyectiles se pueden resolver con operaciones simples; incluso sin son de varias dimensiones si se separan en componentes y se aplican como si fueran problemas de una dimensión.

{ 0 comments }

Exportar archivos ASE en Blender

by Jorge Machin on August 21, 2007 · 1 comment

in Blender, Maxin Lab

Un formato de archivo para modelos en 3D que puede ser muy útil para compartirlos entre distintas aplicaciones es el formato en ASE de 3D Studio. Es en ASCII y es muy fácil de parsear, por lo que también lo podemos utilizar en aplicaciones científicas y juegos hechas por nosotros con sólo tirar unas cuantas líneas de código.

Aunque Blender no incluye como exportar los archivos ASE, en la Red existe desde hace algunos años un script de python escrito por Goofos que hace el trabajo de forma correcta. Se puede bajar de http://www.katsbits.com/htm/tools_utilities.htm#ase

Instalación

Sólamente hay que desempaquetar el archivo zip en el directorio de scripts de Blender, el cual se encuentra generalmente en /usr/share/blender/scripts/ en sistemas Linux y en /Archivos de programas/Blender Foundation/Blender/.blender/scripts en sistemas Windows.

Consejos

Al exportar el modelo es muy importante que se triangulen antes de exportarlo, de lo contrario va a ocurrir el error UnboundLocalError: local variable 'mats' referenced before assignment o el archivo ASE resultante puede aparecer cortado. Para triangular el modelo, se debe presionar Ctrl T dentro de la ventana de vista 3D en el modo de edición.

En el caso de tener texturas, deben de estar mapeadas como UV-MAPS, de lo contrario no se importaran con el modelo.

{ 1 comment }

Formulario de Vectores

by Jorge Machin on June 18, 2007 · 4 comments

in Formularios, Física, Matemáticas, Maxin Lab

Los vectores son una herramienta muy util para representar en cálculos y en la computadora como es nuestra realidad. En este post pongo un breve formulario de algebra vectorial para consulta.

1. Magnitud o Norma de un vector


||vec A|| = d =sqrt{({x_2}-{x_1})^2+({y_2}-{y_1})^2+({z_2}-{z_1})^2}

(1.1)

2. Ecuaciones de traslación

Para trasladar un vector al origen, simplemente se resta el punto final con el punto inicial:

vec P_o = ( x_2 - x_1, y_2 - y_1, z_2 - z_1 )

(2.1)

Para trasladarlo a un punto P(k,l,m):

vec P = ( x - k, y - l, z- m )

(2.2)

3. Vector Unitario

hat U = frac{1}{||vec A||} vec A

(3.1)

4. Producto interno, euclidiano interior, escalar o punto

Geométricamente, el producto interno, escalar, euclidiano interior o punto está definido por cualquiera de las dos siguientes ecuaciones:

vec U cdot vec V = ||vec U || ||vec V || cos( theta )

(4.1)

o bien por componentes:

vec U cdot vec V = U_1 V_1 + U_2 V_2 + U_3 V_3

(4.2)

- Algunas de sus propiedades importantes son:

a) vec U cdot  vec V = vec V cdot vec U ( Propiedad conmutativa )

b) vec U cdot  ( vec V + vec W ) = vec U cdot vec V + vec U cdot vec W

c) k  ( vec V cdot vec W ) = kvec U cdot vec V =  vec U cdot kvec W

d) Si vec U cdot vec V = 0, entonces vec U perp vec V

- Algunas aplicaciones del producto escalar incluyen encontrar:

a) El ángulo entre dos vectores

cos( theta ) = frac { vec U cdot vec V } { ||vec U || ||vec V || }

(4.3)

b) El vector proyección

vec W_1 = frac {vec U cdot vec V } { ||vec U || } vec U

(4.4)

c) La magnitud de proyección ortogonal vec U sobre vec V

Si no se conoce el ángulo:

hat U cdot vec V = frac { vec U cdot vec V } { ||vec U || }

(4.5)

o conociendo el ángulo:

hat U cdot vec V = || vec V || cos( theta )

(4.6)

5. Producto vectorial o cruz

El producto vectorial o cruz da como resultado un vector ortogonal a los dos vectores originales.

vec U times vec V = ( U_2 V_3 - U_3 V_2, U_3 V_1 -U_1 V_3, U_1 V_2 - U_2 V_1 )

(5.1)

o bien

<br />
vec U times vec V = left|begin{array}{ccc}<br />
hat{i} & hat{j} & hat{k} \<br />
U_1 & U_2 & U_3 \<br />
V_1 & V_2 & V_3<br />
end{array}right|<br />

(5.2)

- Algunas de sus propiedades importantes son:

a) vec U times vec V = - ( vec V times vec U )

b) k ( vec U times vec V ) = k vec U times vec V = vec U times k vec V

6. Producto escalar triple

Próximamente.

7. Vector gradiente

Próximamente.

{ 4 comments }