‘Exploración espacial’ (parte 3): Ruta en 3D.

Comprendo la impaciencia del que ve en estos artículos una especie de ‘cómo se hizo’ de algo que aún no se sabe que es exactamente.

Los asiduos seguidores de mi Blog, en su mayoría profanos, en esto de la animación 3D o del trazador de Rayos Povray, estarán deseando de ver ya el producto final de esta serie de artículos, pero aún falta para eso, porque para los interesados en aventurarse a usar este trazador de rayos, hay que ir paso a paso explicando el procedimiento empleado.

En este artículo vamos a mostrar el vídeo que resulta de haber incorporado a nuestra ruta los datos relativos a la altura estimada del terreno en cada punto de la ruta.

De momento para no complicarnos, usaremos como sucedáneo del vehículo una simple bola, porque aún no hemos explicado como se consigue dar orientación a un vehículo en correspondencia con una ruta spline.

Difícilmente una bola de color uniforme se puede orientar apuntando a ninguna parte, así que no notaremos esta deficiencia.

Hemos modificado nuestro programa Python ‘rutaspline.py’ para que incluya la coordenada Y responsable de la altura.

Ini=  [1123, -1.8,  327]
p1=   [1053, -2.2,  687]
tramo1=[
[1194, -1.2,  843],
[1401, -1,    921],
[1602,  0.15, 960]
]
P2=   [1695, -1.1,  924]
tramo2=[
[1668, -1.5,  846],
[1581, -1.5, 783],
[...]
fp=open("rutaspline.inc", "w")
y=0.0
for n in range(1, len(ruta)-1): # Los extremos no intervienen
   x=fx(ruta[n][0])
   y=ruta[n][1]
   z=fz(ruta[n][2])
   if n==len(ruta)-1:
      fp.write ("%d, <%f,%f,%f>\n" % (n, x, y, z))
   else:
      fp.write ("%d, <%f,%f,%f>,\n" % (n, x, y, z))
fp.close()
[...]

El resultado es un nuevo fichero ‘rutaspline.inc’ que contendrá lo siguiente:

1, <1.060000,-2.200000,6.260000>,
2, <3.880000,-1.200000,3.140000>,
3, <8.020000,-1.000000,1.580000>,
4, <12.040000,0.150000,0.800000>,
5, <13.900000,-1.100000,1.520000>,
6, <13.360000,-1.500000,3.080000>,
7, <11.620000,-1.500000,4.340000>,
8, <9.820000,-2.000000,6.620000>,
9, <10.840000,-2.000000,8.420000>,
[...]

Dejaremos la construcción de la nave para el siguiente capítulo, pero ahora vamos aprovechar para probar que efecto visual tendría incluir en la nave tres faros delanteros que iluminen el camino. Para ello usaremos a la propia nave como punto de referencia a la cual el foco y la propia cámara virtual (que viaja que grabando la escena) apuntarán.

Para los focos hemos usado un tipo de luz ‘spotlight’. Recordemos que en Povray todos los giros se aplican tomando el origen de coordenadas. Por ello los giros de un objeto que se hagan sobre sí mismos  (ya sea nave, luz spotight, cámara, etc.) y que no se encuentren previamente en <0,0,0> requieren ser  trasladarlos en primer lugar a ese punto de origen, luego girarlos, y por último volverlos a dejar en su sitio.

Matemáticamente la diferencia de dos vectores A -B se define como la suma del vector A con el B invertido de dirección. (Si tenemos los vectores  A y B la resta A -B es lo mismo que A+ (B*-1) ). Cosas de vectores. Suena algo lioso, pero si no tienes un modelador o un software que te resuelva este tipo de cosas, necesitaras tener una base de matemáticas (vectores y trigonometría). De momento esto te ayudará a entender el fuente si te da por ahí.

La primitiva spotlight ademas de la dirección de la luz necesita un radio para determinar la anchura del cono con brillo total y un varor falloff que será el radio del cono de luz donde esta muere.

En el fuente POV usaremos lo siguiente:

#declare Ruta = spline { natural_spline
   #include "rutaspline.inc"  // ** Incluye la funcion Ruta que calcula cada punto por   interpolación spline
}

#declare camara1=camera{ // ** Usar para vista desde vehículo.
   location Ruta(clock) + <0,1,0> //
   look_at  Ruta(clock+.75) + <0,.20,0>
   right <4/3,0,0> // **
   angle 80 // gran angular
}

camera {camara1}

#declare Bola= object {sphere {<0,0,0> 0.3} pigment {Yellow}}
object {Bola translate Ruta(clock+1)+<0,0.5,0>  }

#macro TripleFaro (PotFaro, RadFaro, From, At)
#local Fall=RadFaro*3;
union {
   /** Antes de girar hay que llevarlo a <0,0,0> y luego volver a dejarlo
   donde estaba  ***/
   object { light_source { <0,0,0> White*PotFaro*.6
      spotlight point_at (At - From) // La resta de vectores nos da la dirección correcta en <0,0,0>
      radius RadFaro falloff Fall}
   rotate y*(15)
   translate From
   }
   object { light_source { From White*PotFaro
      spotlight point_at At
      radius RadFaro falloff Fall}
   }
   /** Antes de girar hay que llevarlo a <0,0,0> y luego volver a dejarlo
   donde estaba  ***/
   object { light_source { <0,0,0> White*PotFaro*.6
      spotlight point_at (At - From) // La resta de vectores nos da la dirección correcta en <0,0,0>
      radius RadFaro falloff Fall}
   rotate y*(-15)
   translate From
   }
}
#end

TripleFaro(1, 4,  Ruta(clock)  +<0,1.5,0>,  Ruta(clock+0.8)+<0,-0.3,0> )
TripleFaro( .9, 4,  Ruta(clock+1)+<0, 1 ,0>,  Ruta(clock+2  )+<0,-0.5,0> )

Para finalizar:

Hemos continuado trabajando con el mismo escenario y con el mismo número de fotogramas para poder contrastar las imagenes de la escena en un determinado momento desde distintas perspectivas, pero ya hemos completado la ruta 3D. En futuros ensayos seremos libres para abandonar estas restricciones que nos habíamos autoimpuesto.

Share

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

*