Article's Images
All the images in this article have been reduced to thumbnail size
and in JPEG format. Better quality images in full size GIF versions can be accessed
by clicking on any of the thumbnail icons.
The animations were built in low resolution with only 15 frames
in JPEG format. Limiting the resolution and size of the animation
we hope to avoid using too much hard disk and making this article
slow to download. Nevertheless, as always the sources for these
images will be also provided and the readers have access to the
tool 'pov' (discussed in the previous issue) that will render
the images at any desired resolution, or allow readers to modify
and experiment with the images.
If the reader has not installed Povray yet in his/hers system please
follow the directions in the previous article of this series
where we gave sufficient information on the location of the sources,
installation and configuration of POVRAY.
Rendering Fundaments.
In the previous article we mentioned briefly the notion of ray tracing.
Let us now explore this issue in more detail.
Rendering is the most complete technique to achieve a synthetic image.
It tries to emulate in the most realistically but inexpensive manner the
behavior of light and its visual effects on objects.
In our previous article we mentioned that the renderer computes
the number of light rays but interestingly enough the light source under
this model behaves not as a source but as a sink, meanwhile the camera
acts as the source of rays. There is a reason for this inversion of roles,
if rays departed from the light source then there would be a great waste of
computational time because out of all the rays the leave the light source
only a very small number eventually reach the camera. Following the
points the image from the camera we are reducing the number of rays to
only those which are relevant for the image. Each of the points in the image
corresponds to a point in the hypothetical photosensitive film
of our virtual camera. Every point is then process independently.
We have configured Povray to build the image and then visualize it
with an external viewer. Had we configured Povray for SVGA then we could
see that it is possible to view the image as it is being computed. This is
done pixel by pixel, from left to right on the screen and from top to
bottom. The order is not coincidental. The most common output format for
Povray is TGA 24 bits, which is constructed precisely in that order.
If anyone gets interested on configuring Povray for SVGA (I have not
done it myself) the first thing he will learn is that the speed of
rendering depends on the region of the image, complex regions take longer
than simpler regions. Zones with many objects take longer time to process
than zones with one or none. For every impact of the rays into the objects
the renderer calculates the effect on the light by looking at the
position and color of the light source, its relative position with respect
to the object's surface as well as the texture of the object and other
physical characteristics. The result of this calculation is specified in
three value RGB that define the color and intensity of the point in the image.
A brief detour
The TGA 24bits format occupies a lot of space but is trivial
to generate and easy to process.
Each pixel is given by three numbers of 8 bits that codify the
RGB packet
8bits *3 = 24 bits; 2^24 = 16777216 (16 millons colours)
To find out the width and height:
int w, h, i;
fseek(fi, 12L, SEEK_SET);
fread(&w, 2L, 1L, fi); /** pos 12 **/
fread(&h, 2L, 1L, fi); /** pos 14 **/
To read the first pixel:
fseek(fi, 16L, SEEK_SET); /** pos 16 **/
Blue=fgetc(fi);
Green=fgetc(fi);
Red=fgetc(fi); |
|
Only this information should be sufficient to process some images and achive
a few interesting effects. If the reader has some experience with programming
we propose the following exercises:
1) Brighten/Darken an image (white pixels are 255,255,255 and black
pixels 0,0,0
2) Superimpose and image with a black background on top
of another one using black as a transparent value
3) Blend two images by averaging color values
5) Enhance/reduce a given colour
6) Obtain the colour histogram of an image (list of colours and
their frecuency)
All these operations can be acomplished using auxiliary programs
often available on the web. Nevertheless on some ocasion we may need
to apply a non trivial transformation to the image and this TGA format of 24 bits
is very manageble.
End of Detour
The rays depart from a point in the film of the virtual camera but to
calculate the resulting colour each ray determines whether it intercepts
any of the objects in the scene. If it does the ray-tracing algorithm continues
analysing the characteristics of the object in the area reached by the ray.
Then there is a very effective optimization technique for designing complex
objects. It consits on defining a new invisible object that contains the
first complex object. Generally the most common used container is an sphere,
but boxes are also popular. The main goal here is to used the container to
force the ray-tracer to approximate the complex object by using the container
instead, arriving rays bounce off the invisible spherical container. This removes
a great deal of the computational process. The primitive used is "bounce_by" and
it is commented next to illustrate how well the ray-tracer works. We will
see an example later on in the article when we treat complex figures.
The seven errors
As an illustration of the issues explored so far let us review an image
created using several techniques and discuss them one by one
This scene is titled the "7 Errors"
Please notice carefully that some of the features of the scene are odd:
-
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.
-
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.
-
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)
-
En un plano cercano tenemos tres cajas. Vemos que la del centro no produce
sombra.
-
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.
-
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.
-
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 (acastro@ctv.es)
#
#####################################################################
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 utilidadtes 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:
-
Usamos como fuente $HOME/dat/pov/LF2-PlanetBue/LF2-PlanetBue.pov
-
Tamaño 4 = (266x200)
-
Calidad 9 (La más alta)
-
Fotograma inicial = 1
-
Fotograma final = 100
-
Valor inicial de clock = 1
-
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 planetblue.jpg
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
|