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 }
]
}
...
...
...
|