Interpoladores, el Sensor de Tiempo y las Rutas

Tutorial de VRML97

Ejemplo de la Noria de un parque de atracciones

Construiremos una noria de cuatro cestas a partir de una estructura de cruz y con una base triangular. Para todo el ejercicio utilizaremos únicamente primitivas geométricas para podernos concentrar en el funcionamiento, más que en la geometría. También utilizaremos a fondo el prototipage de VRML97.

Paso1: Empezaremos por definir dos cruces que serán la estructura principal que sustentará las cestas:

...
...
...

PROTO Cruz [ field SFVec3f posicion 0 0 0 ]
{
	Transform{
		translation IS posicnio
		children [
		Shape{
			geometry Box { size 12 0.5 0.2 }
			appearance Appearance { material Material { diffuseColor 0 0 1 } }
		}
		Shape{
			geometry Box { size 0.5 12 0.2 }
			appearance Appearance { material Material { diffuseColor 0 0 1 } }
		}
	  ]
	}
}

DEF Estructura Transform {
	children [
		Cruz{ posicion 0 0 1 }
		Cruz{ posicion 0 0 -1 }
	]
}

Aquí definimos un prototipo Cruz, el cual está formado por dos cajas de color azul. Este prototipo lo utilizamos al definir nuestra Estructura global, creando dos cruces paralelas y separadas por una distancia de 2 unidades. Resultado Paso1.

Paso2: Continuamos definiendo lo que será el motor de la noria:

...
...
...

DEF motorNoria TimeSensor {
	cycleInterval 3
	loop TRUE
}

DEF rotaNoria OrientationInterpolator {
	key	 [	 0,	      1 ]
	keyValue [ 0 0 1 0, 0 0 1 -1.57 ] # 90 gdosus o PI/2
}

...
...
...

ROUTE motorNoria.fraction_changed TO rotaNoria.set_fraction
ROUTE rotaNoria.value_changed TO Estructura.rotation

Con esto definimos un TimeSensor llamado motorNoria que realiza bucles de 3 segundos (cycleInterval = 3). También definimos un OrientationInterpolator llamado rotaNoria que nos interpola desde 0 (zero) grados de rotación hasta 90 grados (o -PI/2 radianes, o -1.57 radianes) alrededor del eje Z y en la dirección negativa. Finalmente definimos las rutas que encaminarán los eventos de entrada y de salida para ir moviendo la Estructura. Estas rutas hacen que el paso del tiempo de motorNoria vaya modificando el avance del interpolador rotaNoria. Así mismo, el avance del interpolador hace que rote nuestra Estructura. Resultado Paso2.

Nota: Tan solo se hace una rotación de 90 grados (y no de 360) porqué la noria tiene cuatro brazos y por lo tanto al haber rotado 90 grados, esta vuelve a estar en una situación totalmente análoga a la inicial.

Paso3: Ahora añadiremos las cestas, modelándolas con conos:

...
...
...

PROTO Cesta [
	exposedField SFRotation rotacion 1 0 0 0
	field SFVec3f posicion 0 0 0
]
{
	Transform {
		translation IS posicion
		children
			Transform {
				center 0 1.5 0
				rotation IS rotacion
				children Shape {
					geometry Cone {
						bottomRadius 0.8
						height 3
					}
					appearance Appearance { material Material { diffuseColor 0 1 0 } }
				}
			}
	}
}

...
...
...

DEF Estructura Transform {
	children [
		Cruz{ posicion 0 0 1 }
		Cruz{ posicion 0 0 -1 }
		DEF C1 Cesta { posicion 0 4.5 0 }
		DEF C2 Cesta { posicion 6 -1.5 0 }
		DEF C3 Cesta { posicion 0 -7.5 0 }
		DEF C4 Cesta { posicion -6 -1.5 0 }
	]
}

Con esto conseguimos definir un prototipo Cesta, el cual está formado por un cono de color verde que puede ser rotado según un pivote situado en su vértice superior y que puede ser trasladado a un punto dado, llamado posicion. Una vez definido este prototipo, lo utilizaremos para crear las cuatro cestas C1, C2, C3 i C4 que van colocadas cada una en un brazo de la cruz que hemos creado antes. Resultado Paso3.

Ahora vemos como las cestas comienzan su movimiento correctamente colocadas, pero al ser arrastradas por la rotación de la Estructura a la que pertenecen, van quedando mal orientadas. Al rotar la Cruz, ellas deberían compensar esta rotación rotando ellas respecto a su pivote en la dirección opuesta a la del conjunto.

Paso4: Así pues, para que las cestas siempre mantengan su verticalidad, hace falta que realicen una rotación de la misma cantidad de grados que la Estructura, pero de signo inverso. Esta rotación a demás, ha de realizarse respecto a su punto de pivotage (el vértice superior de cada cono). Por esta razón en la definición de la Cesta, se define el center. Veamos pués que debemos añadir al código para que esto funcione:

...
...
...

DEF rotaCesta OrientationInterpolator {
	key	 [	 0,	     1 ]
	keyValue [ 0 0 1 0, 0 0 1 1.57 ]
}

...
...
...

ROUTE motorNoria.fraction_changed TO rotaCesta.set_fraction
ROUTE rotaCesta.value_changed TO C1.rotacion
ROUTE rotaCesta.value_changed TO C2.rotacion
ROUTE rotaCesta.value_changed TO C3.rotacion
ROUTE rotaCesta.value_changed TO C4.rotacion

Esto define un nuevo OrientationInterpolator llamado rotaCesta que aprovechará el TimeSensor llamado motorNoria que habíamos definido anteriormente. El nuevo interpolador hace lo mismo que el anterior (rotaNoria) pero en el sentido inverso. A continuación definimos las rutas necesarias para rotar las cestas. Primero hacemos que el paso del tiempo de motorNoria vaya modificando el avance del interpolador rotaCesta. Del mismo modo, el avance del interpolador hace que rote cada Cesta: C1, C2, C3 y C4. Resultado Paso4.

Paso5: Finalmente solo falta añadir una base para que el cunjunto quede completo. Dejamos la comprensión de este código al lector:

...
...
...

PROTO TrianguloBase [ field SFVec3f posicion 0 0 0 ]
{
	Transform {
		translation IS posicion
		children [
		Transform { #Pie de la base
			translation 0 -10.4 0
			children Shape{
					geometry Box { size 12 0.5 0.2 }
					appearance Appearance { material Material { diffuseColor 1 0 0 } }
				 }
		}
		Transform { # Laterales de la base
			translation 0 -6 0
			children [
				Transform {
					center 0 6 0
					rotation 0 0 1 0.5236 # 30 grados o PI/6
					children Shape{
							geometry Box { size 0.5 12 0.2 }
							appearance Appearance { material Material { diffuseColor 1 0 0 } }
						 }
				}
				Transform {
					center 0 6 0
					rotation 0 0 1 -0.5236 # 30 grados o PI/6
					children Shape{
							geometry Box { size 0.5 12 0.2 }
							appearance Appearance { material Material { diffuseColor 1 0 0 } }
						 }
				}
			]
		}
	  ]
	}
}

...
...
...

DEF Base Group {
	children [
		TrianguloBase{ posicion 0 0 1.5 }
		TrianguloBase{ posicion 0 0 -1.5 }
	]
}

...
...
...

Resultado Paso5 y Final.



< Anterior | Menú ^