Ir al HogarVer ÍndiceBuscarEnlacesAcerda de nosotros
[LinuxFocus Image]
[Navegation Bar]
  Noticias   Archivos   Compañías   Consejos  

Nociones generales sobre Povray

por Antonio Castro

  Este es el segundo artículo de la serie dedicado a Povray. En el presente explicaremos alguna nociones generales y comenzaremos con los elementos básicos del lenguaje

Imágenes del artículo

Fundamentos del render

Los siete errores

El lenguaje de Povray

Conceptos básicos sobre animación

POV Ver 2.0

Aspectos 3D

Posución

Traslación

Giro

Escalado

Luz

Cámara

 

© 1998 Antonio Castro 
Páginas web mantenidas por Miguel A Sepulveda

Imágenes del artículo. 

En este artículo las imágenes se presentan con tamaño reducido y en formato 'jpg'  Pinchando en la imagen podremos ver una imagen en formato 'gif' mayor y con mucha más calidad . 

Las animaciones se construirán sobre una resolución baja y solo se mostraran 15 fotogramas en formato 'jpg'. 
Esto se hace asi para no ocupar excesivo espacio de disco duro y para evitar que la descarga de este artículo resulte demasiado lenta. 
De todas formas como siempre proporcionaremos los fuentes y disponemos una herramienta 'pov' que ya presentamos en el artículo anterior, para que cualquiera pueda renderizar con la resolución que quiera, o cambiar el fuente para experimentar y aprender el lenguaje de Povray. 

Si aún no ha instalado Povray en su ordenador puede hacerlo guiandose por  el artículo anterior con el que iniciamos la serie dedicada a Povray. Le animamos a hacerlo. 

Fundamentos del render.

En el capítulo anterior mencionamos de pasada la noción de trazado de rayos, y vamos a profundizar algo más ahora. 
El render es la técnica más completa para lograr una imagen sintética. 
Para ello se intenta emular de la manera mas realista y menos costosa posible el comportamiento de la luz en la realidad y sus efectos visuales. 

En nuestro artículo anterior mencionamos que el render calcula cantidad de rayos luminosos pero curiosamente en este modelo la fuente de luz se comporta como sumidero de los rayos y la cámara será el punto del que salgan todos los rayos. La razón de esto, es que si lo hiciéramos al revés la mayoría de los rayos solo supondrían cálculo inútil y solo unos pocos alcanzarían la cámara. Al hacerlo al revés partimos de cada uno de los puntos de la imagen que queremos obtener. Cada uno de los puntos de la futura imagen se corresponde con un punto de una hipotética película fotosensible de nuestra cámara virtual. De esta manera procesamos cada uno de estos puntos por separado. Nosotros hemos configurado Povray para que construya una imagen y luego la visualizamos con un visualizador externo. Si hubiéramos configurado Povray para SVGA habríamos comprobado como resulta posible ir visualizando la imagen a medida que esta se calcula. Esto se hace pixel a pixel, de izquierda a derecha de la pantalla y de arriba abajo. El orden no es casual. El formato de salida más normal para Povray es el TGA de 24 bits, y también se construye en este orden. 

Si alguien se anima a configurar Povray para SVGA. (Yo no lo he hecho) verá que la velocidad de construcción de la imagen depende de que estemos en una parte complicada o sencilla. 
Podemos observar que las zonas con muchos objetos en la imagen tardan mas tiempo en procesarse que las que tienen uno solo o ninguno. Desde cada uno de los impactos de esos rayos en los objeto se calcula el efecto luminoso correspondiente comprobando la posición de la fuente de luz. La orientación de la superficie relativa a la fuente de luz y también las características de color, textura, y otras características definidas en el objeto. El resultado de este análisis se concreta el tres valores RGB que definen el color y luminosidad de ese punto de la imagen. 

Una digresión 

El formato TGA de 24 bits es un formato que ocupa mucho espacio pero resulta trivial generarlo o procesarlo. 

Cada pixel viene dado por tres números de 8 bits para codificar el color en RGB. 
8bits *3 = 24 bits; 2^24 = 16777216 (16 millones de colores) 

Para averiguar el ancho y alto:  

int w, h, i; 
fseek(fi, 12L, SEEK_SET); 
fread(&w, 2L, 1L, fi); /** pos 12 **/ 
fread(&h, 2L, 1L, fi); /** pos 14 **/ 

Para leer el primer pixel: 

fseek(fi, 16L, SEEK_SET); /** pos 16 **/ 
Blue=fgetc(fi); 
Green=fgetc(fi); 
Red=fgetc(fi); 

 
 

Simplemente con esta información ya seria posible procesar algunas imágenes para lograr algunos efectos sencillos. 
Si es un manitas de la programación le proponemos los siguientes ejercicios: 

1) Aclarar/oscurecer  una imagen.  (Los pixels blancos valen  255,255,255, y  los negros 0,0,0) 
2) Superrponer una imagen con fondo negro a otra tomando el negro como transparente. 
3) Fundir dos imagenes en una promedio. 
5)  Realzar/atenuar  un color 
6) Obtener el histograma de color de una imagen (Lista de colores y sus frecuencias). 

Estas cosa normalmente se puede conseguir utilizando programas auxiliares pero puede que alguna vez necesitemos 
hacer un tratamiento trivial de una imagen y sin embargo no encontrar una herramienta que lo haga.  Este formato TGA 
de 24 bits le resultará muy manegable. 

Fin de la digresión 

Vamos a resaltar un aspecto de este proceso. Los rayos salen de un punto de la película fotosensible de nuestra cámara virtual pero para calcular el color resultante van comprobando si alguno de los objetos definidos en la escena va a interceptar al rayo. En caso afirmativo se continua analizando las características del objeto en la parte alcanzada por el rayo. Pues bien existe una técnica de optimización muy efectiva cuando se diseñan objetos complejos. Consiste en definir un objeto invisible y muy simple de forma que todo el objeto complejo quede en su interior. Generalmente como objeto simple se utilizan esferas. También cajas. La idea es que este objeto sirva para indicar al trazador que si un rayo no puede pasar por este objeto sencillo tampoco lo hará por el objeto complejo situado en su interior. Esto elimina mucho proceso de calculo. La primitiva se llama "bounced_by" y la he comentado ahora porque ilustra muy bien como funciona el trazador. Veremos algún ejemplo más adelante en este artículo cuando hablemos de figuras compuestas. 

Es interesante resaltar que las cosas en un trazador de rayos no son siempre lo que parecen. 

Los siete errores.

Para ilustrar lo comentado hasta ahora vamos a mostrar una imagen donde se han utilizado varias técnicas pero poniendo de manifiesto el truco empleado. 

Esta escena la he titulado los 7 errores. 

LF2-7errores.gif 

7errores

Si nos fijamos atentamente veremos que hay alunos aspectos de esta imagen que no resultan normales. 

  1. Hay un único foco de luz intensa situado en el centro de un anillo, pero pese a estar mirando casi directamente a ses punto, no se puede ver. 
  2. Hemos puesto un poco más atrás de este foco una bola blanca que proyecta una sombra en el cielo. Por ello descubrimos que en lugar de un cielo tenemos un decorado barato,  porque la sombra nos indica la presencia de una boveda celeste sólida. 
  3. El mar tiene olas pero está construido con una delgadísima superficie totalmente plana. Para poderlo apreciar hemos cortado el mar y vemos que el corte es totalmente recto. (sin olas) 
  4. En un plano cercano tenemos tres cajas. Vemos que la del centro no produce sombra. 
  5. Considerando en conjunto las tres cajas se produce una situación extraña. Que clase de iluminación hay realmente. Un foco directo provocando sombras duras. Luz difusa indirecta provocando sombras suaves? Al parecer la luz ambiente es distinta para cada caja. 
  6. La bola de cristal parece maciza en su parte izquierda pero también hemos recortado un trocito a la derecha y hemos introducido un objeto por ese lado para que se pueda apreciar que también es hueca. 
  7. La séptima resulta de mirar la imagen en su conjunto. Esta imagen carece de efectos atmosféricos y hay un exceso de transparencia en el aire. El color del mar debería ser un poco más azulado i difuminado al fondo. La bola blanca provoca un cono de sombra que no deja el menor rastro en el aire .
En este momento no podemos explicar los detalles del las numerosas técnicas empleadas.Solo quería hacer ver que los trazadores de rayos utilizan técnicas que simplemente imitan los fenómenos naturales de forma no siempre fiel a la realidad porque existe un precio a pagar como tiempo de proceso. Algunas técnicas sirven solo como parches para disimular defectos producidos por otras técnicas. Lo que importa es que el resultado final sea bueno sin un excesivo trabajo de CPU. 

Dejemos todo esto como una colección de enigmas que poco a poco el avezado alumno irá resolviendo en su larga búsqueda hacia la perfección infográfica. Una vez alcanzada podrá considerarse a si mismo como master del universo virtual. 
Y si esta  maravillosa justificación no le convence, da igual porque no pienso explicar nada más sobre el ejemplito de los siete errores por el momento. 

El Lenguaje de Povray.

Una vez más insistimos en advertir queestos articulos sobre Povray no pueden hacer otra cosa que tratar distintos temas de forma superficial. El lenguaje de Povray es demasiado amplio para tratarlo en profundidad. Quizas por es resaltar en unas pocas lineas lo más destacado del mismo es lo más acertado que podemos hacer en este momento. 
En Povray es frecuente encontrar varias formas gramaticales para conseguir el mismo resultado. Esto es debido a que la sintaxis actual es el resultado de  profundos cambios entre las distintas versiones de Povray.  La sintáxis actual es mucho mejor y quizas no sufra tantos cambios en el futuro. Por razones de portabilidad se conservan formas sintácticas antiguas o parecidas a las antiguas. Un ejemplo de esta flexibilidad en la sintaxis son los giros que veremos mas adelante. 

Existe una directiva de compilación que permite utilizar fuentes de versiones antiguas de Povray. 

Ejemplo: 
 
Para  usar en un mismo fuente la sintáxis de la versión 1, 2, y 3:  

#version 1.0 
....... 
#version 2.0 
....... 
#version 3.0 
....... 

 
 
 

Esto permite mezclar en un mismo fuente las tres formas de sintaxis que se corresponden con los números principales de las versiones de Povray 

No se pretende hacer un recorrido completo de la sintaxis. Existe un manual muy bueno para ello, y esto no es un segundo manual.  Intentaremos ganar tiempo señalando únicamente lo mas importante. Vamos a adelantar ahora algunas cuestiones referentes al lenguaje. 

Comentarios, Declaraciones, Ficheros include. 

Los comentarios son como en C++. 
 

Ejemplo: 
 
Para poner comentarios: 

// Este comentario termina con el final de linea 
/* Este comentario termina con asterisco slash */ 
 

 
 

Los elementos del lenguaje que empiezan por '#' se llaman directivas de lenguaje (Language Directives). 
Las más usadas son '#declare' e '#include'. 
 

 
Las llamadas declaraciones tienen la forma:  

#declare IDENTIFIER = ITEM 

 
 

Ejemplo: 
 
Para  declarar diversos tipos de elementos:  

#declare Rows = 5 
#declare Count = Count+1 
#declare Here = <1,2,3> 
#declare White = rgb <1,1,1> 
#declare Cyan = color blue 1.0 green 1.0 
#declare Font_Name = "ariel.ttf" 
#declare Ring = torus {5,1} 
#declare Checks = pigment { checker White, Cyan } 

 
 

La sentencia '#declare' permite almacenar una gran variedad de elementos. Desde un giro, una textura, un color, un objeto un valor numérico, etc.... 

Otro elemento imprescindible del lenguaje son la referencia a ficheros include. 

Permiten incluir en el fuente otros segmentos de otros fuentes. 

Por defecto busca en el directorio actual. En caso contrario busca en Library_Path. 
Nosotros usaremos dos lugares: 

Library_Path=${POVRAY}/include // Aqui los includes de Povray 
Library_Path=${HOMEPOV}/include // Aqui los includes del usuario 

Así es como lo tenemos definido en nuestra nueva versión de 'pov'  para que genere el fichero de inicialización correcto. Hablaremos más adelante de eso. 

Existe una colección de ficheros include que conviene conocer para poder sacar todo el partido posible al Povray. Es una librería de recursos que podemos usar no solo para incluirlas sino para obtener copias modificadas a nuestro gusto. 
 
Algunos includes de Povray de uso corriente: 

#include "colors.inc" 
#include "textures.inc" 
#include "shapes.inc" 
#include "finish.inc" 
#include "glass.inc" 
#include "metals.inc" 
#include "stones.inc" 
#include "woods.inc" 
#include "atmos.inc" 

 

Algunas otras directivas de lenguaje permiten implementar bucles y sentencias condicionales. En las primeras versiones de Povray no existían sentencias de bucles ni condicionales. Eso unido a que las descripciones de los elementos de la escena podían aparecer en cualquier orden suponía un cambio de mentalidad frente a un lenguaje de programación tradicional. 
El orden en que se declaran los elementos de una escena sigue siendo indiferente pero los bucles pueden evitarnos tener que escribir muchas lineas parecidas y las directivas condicionales nos permiten definir de distintas formas una misma escena en función por ejemplo del valor de 'clock' utilizado en animaciones. Pondremos un ejemplo de sentencia condicional  en  otros artículos más adelante. Cuando mencionemos la figuras compuestas. 

Existen muchas otras directivas de lenguaje (que empiezan por '#') pero insistimos en que estas dos que acabamos de mencionar '#declare' e '#include' son con diferencia las más utilizadas. 
 
No vamos a describir cosas que son muy similares a otros lenguajes, tales como expresiones aritméticas, constantes de diversos tipos, operadores lógicos, de comparación, operadores para vectores,  funciones predefinidas, y muchas cosas más.

Cuando tenga que declarar un identificador es conveniente usar alguna mayúscula. La razón es que las palabras reservadas del lenguaje.
(Ver el manual) solo utilizan minúsculas.  Si en algún fuente localiza una palabra que tiene alguna mayúscula se trata de un identificador
declarado en alguna parte. Esta es una buena forma de averiguar si tiene que buscar en el manual o en los includes.

Conceptos básicos sobre animación.

Tratar este tema tan pronto merece una aclaración. 
Siempre se ha dicho que una imagen vale más que mil palabras. Esto es especialmente cierto cuando intentamos explicar las funcionalidades de un trazador de rayos. Intentaremos ilustrar abundantemente cada concepto porque de otro modo estaríamos obligando al lector con ganas de aprender a comprobar por si mismo las explicaciones generando ejemplos para poderlas entender mejor. De esta forma usando abundante material gráfico no solo obtendremos un texto más ameno y de más fácil lectura sino una guía de consulta realmente útil porque algunas veces simplemente volviendo a consultar las imágenes relativas a la ilustración de un concepto nos evita tener que volver a releer toda la explicación. Una imagen tiene la virtud de refrescar la memoria de manera instantánea. Algunas veces no basta una imagen sino que es necesario una secuencia de ellas para poder apreciar ciertos efectos mediante la comparación de las imágenes, y es aquí donde se justifica la necesidad de hablar tan pronto de este tema. 
Povray básicamente se limita a generar la secuencia de imágenes y guardarlas en disco por separado. 
De momento solo nos interesa explicar una forma sencilla de conseguirlo. El trazador Povray será lanzado varias veces pasándole cada vez un valor distinto que es función del número de imagen que en el fuente será considerado produciendo una imagen distinta. Para lanzar varias veces el Povray se pueden usar ciertas opciones en el fichero *.ini pensadas para generar animaciones. 
 
 
Ejemplo para un fichero *.ini : 

Initial_Clock = 0.0 
Final_Clock = 2.0 
Initial_Frame = 1 
Final_Frame = 200 
Subset_Start_Frame = 51 
Subset_End_Frame = 75

 
 

Puesto que para generar el fichero *.ini propusimos en el artículo anterior un programa sencillo que nos permitía el uso sencillo y cómodo de Povray vamos a proceder a actualizarlo para que nos sirva para generar animaciones. 

Una modificación más. Hemos habilitado un directorio include que podrá ser compartido por varios proyectos. 
'$HOME/dat/pov/include'  Si desea crear su propia librería de includes este sería un buen lugar para colocarla. 
 

Pov ver 2.0

Ejemplo para un fichero *.ini : 
-----------------------------------------------8<-----------------

#!/bin/bash
#####################################################################
#  Autor: Antonio Castro Snurmacher  (Feb-1998)
#
#       pov (ver 2.0)
#
#       Esta versión esta dedicada a su inclusión en la
#       revista LinuxFocus   (freeware)
#
#  Esta version (2.0) incorpora posibilidad de generar animaciones
#
#  Requiere 'xv' e 'imagemagick (convert,animate) '
# 
#  Este programa puede ser utilizado, distribuido, y modificado
#  libremente pero siempre se deberá respetar la propiedad
#  intelectual de su autor. Esta cabecera debe ser conservada 
#  tal cual en todas las modificaciones. 
#
#  En caso de traduccion deberá conservarse el texto original de
#  esta cabecera y añadirse la traducción a continuación de ella.
#
#  El autor renuncia a todo tipo de beneficio económico y no se hace 
#  responsable de los posibles perjuicios derivados del uso del mismo. 
# 
#  E-mail ([email protected])
# 
#####################################################################
uso(){
   echo "Uso: pov <proyect> <size=0..6> <quality=1..11> "
   echo "    [ <Initial_Frame> <Final_Frame> <Initial_Clock> <Final_Clock>"
   echo "      [ <Subset_Start_Frame> <Subset_End_Frame> ] ]"
   echo
   echo "0) 40x30     (STD/20) No backup"
   echo "1) 80x60     (STD/10) No backup"
   echo "2) 100x75    (STD/8)  No backup"
   echo "3) 200x150   (STD/4)"
   echo "4) 266x200   (STD/3)"
   echo "5) 320x200 *"
   echo "6) 400x300   (STD/2)"
   echo "7) 640x480 *"
   echo "8) 800x600 *   (STD)"
   echo "9) 1024x768 *"
   echo
   echo "Los proyectos deben situarse en un directorio situado en"
   echo "${HOMEPOV} y se usará el mismo nombre  para el directorio"
   echo "que para el fichero fuente principal *.pov"
   echo "(STD) es la resolución elegida como referencia estandar."
   echo
   exit 1
}

newversion(){
mv ${PREFIX}.pov.8.gz ${PREFIX}.pov.9.gz 2> /dev/null
mv ${PREFIX}.pov.7.gz ${PREFIX}.pov.8.gz 2> /dev/null
mv ${PREFIX}.pov.6.gz ${PREFIX}.pov.7.gz 2> /dev/null
mv ${PREFIX}.pov.5.gz ${PREFIX}.pov.6.gz 2> /dev/null
mv ${PREFIX}.pov.4.gz ${PREFIX}.pov.5.gz 2> /dev/null
mv ${PREFIX}.pov.3 ${PREFIX}.pov.4 2> /dev/null
mv ${PREFIX}.pov.2 ${PREFIX}.pov.3 2> /dev/null
mv ${PREFIX}.pov.1 ${PREFIX}.pov.2 2> /dev/null
cp ${PREFIX}.pov   ${PREFIX}.pov.1 
gzip ${PREFIX}.pov.4 2> /dev/null
}

#################################################
size(){
   export SAVE="yes"
   case  $1 in
      0) Width=40 ; Height=30; SAVE="no" ;;
      1) Width=80 ; Height=60  SAVE="no" ;;
      2) Width=100; Height=75  SAVE="no" ;;
      3) Width=200; Height=150;;
      4) Width=266; Height=200;;
      5) Width=320; Height=200;;
      6) Width=400 ;Height=300;;
      7) Width=640 ;Height=480;;
      8) Width=800 ;Height=600;;
      9) Width=1024;Height=768;;
      *) uso
   esac
}

quality(){
   case $1 in
   1) ;;
   2) ;;
   3) ;;
   4) ;;
   5) ;;
   6) ;;
   7) ;;
   8) ;;
   9) ;;
   10) ;;
   11) ;;
       *) uso
   esac
   export Quality=$1
}

#############################################################
Single(){ 
cat <<-FIN >> ${PREFIX}.ini
   Output_File_Name=${PREFIX}.tga
   Post_Scene_Command=xv ${PREFIX}.tga
FIN
}

#############################################################
SubSet(){
cat <<-FIN >> ${PREFIX}.ini
   Subset_Start_Frame=$Subset_Start_Frame
   Subset_End_Frame=$Subset_End_Frame
FIN
}

#############################################################
Animation(){
cat <<-FIN >> ${PREFIX}.ini
   Output_File_Name=${PREFIX}.tga
   Initial_Frame=$Initial_Frame
   Final_Frame=$Final_Frame
   Initial_Clock=$Initial_Clock
   Final_Clock=$Final_Clock
FIN
if [ $NumParm == 9 ]
   then 
      SubSet
fi
cat <<-FIN >> ${PREFIX}.ini
   Pre_Scene_Command=rm -f \`ls --color=none ${PREFIX}*.tga.gif\`   
   Pre_Frame_Command=rm -f \`ls --color=none ${PREFIX}*.tga\`   
   Post_Frame_Command=convert %o %o.gif
   Post_Scene_Command=animate -delay $DELAY  \`ls -tr --color=none ${PREFIX}*.tga.gif\` 
FIN
}

####################### main ##############################
export HOMEPOV=${HOME}/dat/pov
export PROYECT=$1
export PREFIX=${HOMEPOV}/${PROYECT}/${PROYECT}
if [ $# != 3 ] && [ $# != 7 ] && [ $# != 9 ]
   then uso
fi
NumParm=$#
if [ $NumParm -le 3 ] && [ grep Clock ${PREFIX}.pov > /dev/null 2>&1 ]
   then 
      echo "No econtrado identificador Clock en el fuente"
      uso
fi
export POVRAY=/usr/local/apli/povray/povray3
size $2
quality $3
Initial_Frame=$4
Final_Frame=$5
Initial_Clock=$6
Final_Clock=$7
Subset_Start_Frame=$8
Subset_End_Frame=$9

NumClocks=`expr $Final_Clock - $Initial_Clock`
if [ $NumClocks -gt 0 ]
   then if [ $NumClocks -le 40 ]
           then export DELAY=`expr 4000 / $NumClocks`
           else export DELAY=100
        fi
   else export DELAY=4000
fi

if [ $SAVE == "yes" ]
   then newversion
fi
cat <<-FIN > ${PREFIX}.ini
   Width=$Width
   Height=$Height
   Quality=$Quality
   Library_Path=${POVRAY}/include
   Library_Path=${HOMEPOV}/include
   Input_File_Name=${PREFIX}.pov
   Output_to_File=on
   Output_File_Type=t
   verbose=on
FIN
if [ $NumParm == 3 ]
   then ## Single image
       Single
   else ## Animation
      Animation
fi
#montage ${PREFIX}.tga.* ; animate ${PREFIX}.

#   Output_File_Type=t
## Others hight performace options ##
#   Antialias_Depth=3
#   Antialias=On
#   Antialias_Threshold=0.1
#   Jitter_Amount=0.5
#   Jitter=On

# Baja prioridad por si quiero hacer otras cosas.
nice -20 x-povray ${PREFIX}.ini 

if [ $SAVE != "yes" ]
    then echo "!! Atención !! No se generó backup de esta versión."
fi

---------------------------8<-----------------------------------
 
 

De vez en cuando utilizaremos programas externos a Povray. 

Para poder visualizar la animación usaremos las utilidades animate, y convert de imagemagick. 

Digresión  

Pregunté a Enrique Zanardi, encargado de mantener el paquete de Povray para Debian, si existía algún modelador para Povray. 

E.Zanardi wrote 

> Yo he usado el ScEd (también disponible para Debian). Una vez que le  coges el truquillo es bastante cómodo. 
> Además tienes la opción de compilarlo con un interprete de Scheme incorporado, de forma que puedes definir tus propias 
> órdenes, todo lo complejas que tú quieras. 
> También se recomienda mucho por ahí el Ac3D, pero creo que no es libre. 
 

Fin digresión  

Veremos un ejemplo de animación en el capitulo que viene a continuación, que nos servirá para ilustrar la forma de especificar giros y traslaciones. 

Vamos a comentar ahora brevemente otra forma de generar animación que es la que se utilizaba en las primeras versiones de Povray pero que aun continua siendo muy valida. 

Consiste en usar un programa externo que generara un bucle para lanzar el Povray varias veces. A cada iteración se escribirá un fichero incluido mediante una sentencia '#include' en el fuente principal y que contendrá las definiciones variables e el tiempo. 

Para hacer esto en C sería más o menos así: 

 
----------------------8<---------------------------------------------- 
for(Frame=1; Frame < UltimoFrame; Frame++){
   fi=fopen("pajaro.inc", "w");
   fprintf(fi, "#declare PosX_pajaro1 = %d\n", FuncionPosX_pajaro1(Frame));
   fprintf(fi, "#declare PosY_pajaro1 = %d\n", FuncionPosY_pajaro1(Frame));
   fprintf(fi, "#declare AnguloAlas_p1 = %d\n", FuncionAngAlas_p1(Frame));
   fclose(fi);
   sprintf(comando, "povray -ipajaro.pov -opajaro%04d.tga", Frame);
   system(comando);
}
----------------------8<---------------------------------------------- 
 

Aspectos 3D 

Hay una serie de operaciones 3D que podemos efectuar sobre un onjeto. 

Ademas los objetos se pueden agrupar de forma que resulte un objeto compuesto sobre el que podemos operar globalmente para trasladarlo, girarlo, o escalarlos. 

Posicion 

La posición de un objeto viene determinada por sus coordenadas  <x,y,z> o mejor es adpotar un mismo patrón de referencia para orientarnos más comodamente en nuestros diseños. 
Yosuelo situar siempre que puedo el objeto en el centro de coordenadas. 

Cualquier punto puede ser posicionado en un determinado punto indicando sus coordenadas  <x,y,z> . Los datos expresados en estaforma se llaman vectores. Se utilizan mucho en Povray. Una forma abreviada de expresar un vector cuando todos sus componentes son iguales es  con un solo numero entre corchetes angulares :
<24, 24, 24>  = <24>
Otra forma abreviada es multiplicar un escalar por un vector. Hay tres vectores predefinidos en el lenguaje que son x=<1,0,0>
y=<0,1,0> y z=<0,0,1>. Por ello los vectores siguientes son equivalentes.  3*y = <0,3,0>  -2*x = <-2,0,0>

Muchas veces es necesario trabajar con lapiz, papel para situar correctamente los objetos. 

Otra forma es colocarlos de forma aproximada y refinar las posiciones mediante prueba y error. Para estas pruebas es conveniente utilizar baja resolución y baja calidad para obtener resultados rápidos.

 

Existen una serie de operaciones de transformación. Esta son:

  rotate <VECTOR>
  scale <VECTOR>
  translate <VECTOR>

Los movimientos de traslación y giros tienen utilidad en animaciones asi como para la comoda colocación de los componentes de un objeto. 
 

Traslación 

Cualquier objeto puede ser trasladado a otro punto sumandole un vector de traslación. 
Esto quiere decir que la nueva posición será la suma de los vectores de posición actual y el vector traslacion.
Ejemplo:

sphere { <2, 2, 2>, 10
    pigment { White }
    translate <-3>                  //  Recuerde <-3> = <-3, -3, -3>
  }

El resultado sería una esfera de 10 de radio con el centro situado en la posición  <-1,-1,-1>

 

Giro 

Cualquier objeto puede ser girado y los giros se realizan respecto al centro de coordenadas. 
Los objetos que van a ser girados sobre si mismos suelen definirse situados en el centro del sistema de coordenados porque primero hay que girarlos y luego trasladarlos. Si lo que deseamos es que giren respecto a un eje distante lo situaremos a esa distancia y luego lo giraremos. 
Para girar un objeto definimos un eje y un angulo de giro respecto a ese eje. 

Para recordar el sentido de giro usaremos la regla de la mano izquierda. 
Imagine que toma un eje con su mano izquierda y deja el pulgar estirado en la dirección positiva del eje. La dirección de giro positivo viene dada por la dirección y la curva de los dedos restantes en su recorrido desde las bases de los dedos hasta las uñas. 

Existen dos formas sintácticas de definir un giro. 
Eje * grados o tres números  <n,n,n>  que representan respectivamente los giros al rededor de los ejes X, Y, y Z. 
Podremos algunos ejemplos. 

rotate x * 45 = rotate <45, 0, 0> 
rotate <45, -30, 20> = rotate x*45 rotate y*-30 rotate z*20 
rotate 20*z = rotate z*20 
rotate y*90 x*90 = rotate <0, 90, 0> rotate <90, 0, 0> 
rotate y*90 x*90 != rotate <90, 90, 0> 

El último ejemplo no es una equivalencia sino un caso que se presta a confusión. El orden en que se realizan los giros es importante. Cuando usamos la notación de <n,n,n> los giros siempre se realizan en el orden X, Y, Z y cuando se necesita otro orden hay que desglosar la orden en varias instrucciones de rotación distintas. 
Nosotros usaremos preferentemente la notacion eje*grados (tambien grados*eje) Si desea usar radianes puede usar la función radians. 
Existen muchas funciones aritméticas en Povray que facilitan los cálculos matemáticos. Especialmente utiles son las funciones trigonométricas, pero no entraremos en este tema. 
 

Escalado 

El tamaño de los objetos puede ser variados. 
Se utlizan tres números para multiplicar las dimensiones x, y, z de un objeto. Esto permite aumentar, disminuir, estrirar y achatar objetos. 
 Esto puede servir para construir un elipsoide apartir de una esfera
 
sphere { <0,0,0>, 10
    pigment { White }
    scale <1,4,10>
  }
 

Observaciones finales sobre las operaciones 3D.

Las operaciones de traslacion y escalado pueden hacer en cuanquier orden pero si interviene uno o más giros en las operaciones el resultado final suele variar totalmente dependiendo del orden de las operaciones.. Veremos un ejemplo sencillo para que el lector aprecie en que orden deben efectuarse las operaciones.Se trata de un cuerpo esférico de color azul oribitando sobre si mismo y al rededor de otro punto. El eje de giro sobre si mismo esta inclinado lligeramente respecto a la perpendicular del plano de la orbita.  (El caso es que este ejemplo me recuerda algo pero no caigo) 
 
 

----------------------------------8<------------------------------ 
#include "colors.inc" 
#include "textures.inc" 
//##### se recomienda usar ###### 
//# pov LF2-PlanetBue 4 9 1 100 1 360 # 
//############################### 
#declare RY1 = clock * 5 
#declare RZ1 = 25 
#declare T1 = <5 ,0 ,0 > 
#declare RY2 = clock 

camera { 
    location < -5, 5, 15> 
    look_at < 0, -2, 0> 

light_source { <-15, 15, 15> color White} 

sphere { <0, 0, 0> 4 
    texture { Shadow_Clouds } 
    rotate y * RY1 
    rotate z * RZ1 
    translate T1 rotate y * RY2 

----------------------------------8<------------------------------ 

Para obtener la animación lo lanzamos según la recomendación en el fuente. Usamos nuestra nueva versión de la herramienta 'pov'.  Usaremos el comando siguiente: 

pov LF2-PlanetBue 4 9 1 100 1 360 

El significado de los parámetros utilizados es: 
 

  1. Usamos como fuente $HOME/dat/pov/LF2-PlanetBue/LF2-PlanetBue.pov 
  2. Tamaño 4 = (266x200) 
  3. Calidad 9 (La más alta) 
  4. Fotograma inicial = 1 
  5. Fotograma final = 100 
  6. Valor inicial de clock = 1 
  7. Valor final de clock = 360 
Mostraremos unos pocos fotogramas para que se aprecie el resultado. 
Vemos una bola azul orbitando en circulo y girando sobre su propio eje que esta inclinado 25 grados. 

Como modelo real del planeta tierra no sirve pero metáfora si. 

Ejemplo ../../common/May1998/planetblue.jpg 
 

Planeta Azul

Luz

La luz se define como un punto infinitesimal en el espacio. 
Se trata de un punto invisible en el sentido que una cámara enfocada sobre este punto no es detectable. Un foco de luz solo se percibe por su efecto sobre los objetos que ilumina. 
Por defecto este punto irradia luz en todas las direcciones, aunque es posible definir conos de luz . 
Por defecto se asume luz blanca pero puede ser coloreada y puede ser amortiguada en intensidad. 

Se puede definir más de una fuente de luz para obtener determinados efectos de luces y sombras. 

Hay que tener en cuanta que al aumentar el número de fuentes de luz repercute proporcionalmente en la cantidad de tiempo CPU consumida para generar la imagen. 

La luz puede ser definida por su posición y color pero tambien hay opciones avanzadas para utilizar fuentes a modo de focos. 
De momento nos conformamos con las opciones más corrientes. En todos nuestros ejemplos usamos almenos una fuente de luz y una cámara. 

Cámara

La cámara es un objeto que puede ser orientado para apuntar a un determinado objeto. Se puede definir el ángulo de visión de la cámara. También se puede girar la la cámara en cualquier dirección. 
Existen distintas formas para definir una cámara pero la forma que estamos usando resulta muy flexible y fácil de usar. No todas las formas de definir una cámara son igual de útiles. Otras formas menos intuitivas se usan por razones de portabilidad con versiones anteriores. 
El ángulo de apertura de la cámara afecta al efecto de perspectiva sobre la imagen. 
Perdón si aveces parece esto una fotonovela pero veremos ejemplos de distintas perspectivas sobre un ejemplo en el próximo artículo. 
No se lo pierda. 
 


Fuentes de los programas de este artículo (3342 bytes)

Artículo original en Castellano

© 1998 Antonio Castro
Páginas web mantenidas por Miguel A Sepulveda.