Transformacions.

Tutorial de VRML97

Node Transform

Per a situar, orientar i escalar els objectes al nostre gust dins l'entorn que estem construïnt, cal poder aplicar transformacions. Les transformacions bàsiques són: translació, rotació i escalat. També existeixen variants d'aquestes però que no veurem.

Per a fer transformacions en VRML, cal utilitzar el node Transform. Aquest node pot realitzar qualsevol de les tres operacions o les tres. Per a veure com funciona anirem fent exemples:

Translacions

Exemple1: Definirem una esfera vermella a l'origen de coordenades i una esfera verda traslladada 10 unitats en l'eix de les X.


Shape { # Esfera vermella que ens senyala l'origen de coordenades
	geometry Sphere { radius 2 }
	appearance Appearance { material Material { diffuseColor 1 0 0 } }
}

Transform {
	translation 10 0 0
	children [
		Shape { # Esfera verda traslladada 10 unitats en l'eix X
			geometry Sphere { radius 2 }
			appearance Appearance { material Material { diffuseColor 0 1 0 } }
		}
	]
}

Analitzem el que fa aquest fragment de codi. La primera part, defineix l'esfera vermella que ens servirà de referència per a veure clarament que l'esfera verda ha estat traslladada. Com es pot observar, l'esfera vermella no pateix cap transformació.

La segona part és la que realment ens interessa. Aquí es defineix un node Transform. Aquest té un field translation on es defineix el desplaçament que patirà l'objecte que volem traslladar. Així doncs, es defineix un desplaçament de 10 unitats en l'eix X, 0 unitats en l'eix Y i 0 unitats en l'eix Z.

Després del field translation podem veure el field children. Aquest field, permet donar una llista d'objectes que seran afectats per la trasnformació que estem fent. En aquest cas, la llista d'objectes es limita a un de sol. És l'esfera verda que volem situar a 10 unitats de l'origen en l'eix X. (De fet, aquest node és un dels nodes agrupadors que esmentabem al mòdul Nodes, Camps i Esdeveniments I).

(NOTA: Com a referència pel que fa els tipus dels fields, el field children és de tipus MFNode, és a dir, de tipus node multivaluat pel fet que pot contenir una llista de valors).

Compliquem una mica més l'entorn:

Exemple2: Ara volem afegir un con blau sobre la nostre esfera verda. Per a fer això, hem de traslladar el con 10 unitats en l'eix de les X igual que l'esfera, però a més, l'hem de traslladar 3 unitats en l'eix de les Y (segons les mesures de l'esfera i el con).


Shape { # Esfera vermella que ens senyala l'origen de coordenades
	geometry Sphere { radius 2 }
	appearance Appearance { material Material { diffuseColor 1 0 0 } }
}

Transform {
	translation 10 0 0
	children [
		Shape { # Esfera verda traslladada 10 unitats en l'eix X
			geometry Sphere { radius 2 }
			appearance Appearance { material Material { diffuseColor 0 1 0 } }
		}
	]
}

Transform {
	translation 10 3 0
	children [
		Shape { # Con blau traslladat 10 unitats en l'eix X i 3 en l'eix Y
			geometry Cone { bottomRadius 2 height 2 }
			appearance Appearance { material Material { diffuseColor 0 0 1 } }
		}
	]
}

Ara hem definit un altre node Transform per a la translació del con blau. També podiem haver aprofitat pel con el desplaçament de 10 unitats en l'eix X que ja tenim fet en l'esfera verda. Llavors ja només hauriem d'afegir una transformació de 3 unitats en l'eix Y de la següent manera:


Shape { # Esfera vermella que ens senyala l'origen de coordenades
	geometry Sphere { radius 2 }
	appearance Appearance { material Material { diffuseColor 1 0 0 } }
}

Transform {
	translation 10 0 0
	children [

		Shape { # Esfera verda traslladada 10 unitats en l'eix X
			geometry Sphere { radius 2 }
			appearance Appearance { material Material { diffuseColor 0 1 0 } }
		}

		Transform { # Germà de l'esfera verda
			translation 0 3 0
			children [
				Shape { # Con blau traslladat 10 unitats en l'eix X i 3 en l'eix Y
					geometry Cone { bottomRadius 2 height 2 }
					appearance Appearance { material Material { diffuseColor 0 0 1 } }
				}
			]
		}

	]
}
Resultat

Com es pot observar, hem ficat la transformació de translació de 3 unitats en l'eix Y com a fill de la translació de 10 unitats en l'eix X. És a dir, com a germà de l'esfera verda. D'aquesta manera, el con pateix primer un desplaçament de 3 unitats en l'eix Y, i tot seguit s'agrupa amb l'esfera verda. Un cop agrupats, tots dos pateixen el desplaçament de 10 unitats en l'eix X.

Rotacions

Exemple3: Definirem una caixa groga a l'origen de coordenades amb les cares paral.leles als plans coordenats, i una altra caixa blava(més estreta i més alta) rotada 45 graus respecte l'eix Y.


Shape { # Caixa groga que ens senyala la rotació zero
	geometry Box { size 4 2 4 }
	appearance Appearance { material Material { diffuseColor 1 1 0 } }
}

Transform {
	rotation 0 1 0  0.7854 # 45 graus en radians
	children [
		Shape { # Caixa blava que es rotada 45 graus respecte l'eix Y
			geometry Box { size 2 4 2 }
			appearance Appearance { material Material { diffuseColor 0 0 1 } }
		}
	]
}

Analitzem el que fa aquest fragment de codi. La primera part, defineix la caixa groga que ens servirà de referència per a veure clarament que la caixa blava ha estat rotada. Com es pot observar, la caixa groga no pateix cap transformació i per tant té les seves cares paral.leles al plans coordenats.

La segona part és la que realment ens interessa. Aquí es defineix un node Transform. Aquest té un field rotation on es defineix la rotació que patirà l'objecte que volem modificar. Així doncs, es defineix una rotació de 45 graus (0.7854 radians) respecte l'eix Y. Això es defineix d'una forma molt curiosa en VRML.

El field rotation té en realitat dues parts. Els tres primers valors defineixen un vector en l'espai 3D, és a dir, l'orientació de l'eix de rotació. L'eix de rotació coïncideix amb els eixos coordenats quan:

Aquest sistema de definir l'eix de rotació de la transformació és molt flexible i general, però resulta complicada quan l'eix té una orientació diferent a la dels eixos coordenats.

La segona part és l'angle de rotació que volem aplicar (expressat en radians) al voltant de l'eix que hem definit amb els tres primers valors.

Després del field translation podem veure el field children que, com abans, engloba la llista d'objectes que seran afectats per la rotació. En aquest cas, la llista d'objectes torna a ser un de sol, la caixa blava que volem rotar 45 graus respecte l'eix Y.

Compliquem una mica més l'entorn:

Exemple4: Ara volem que la caixa blava també roti 45 graus respecte l'eix X.


Shape { # Caixa groga que ens senyala la rotació zero
	geometry Box { size 4 2 4 }
	appearance Appearance { material Material { diffuseColor 1 1 0 } }
}

Transform {
	rotation 1 0 0  0.7854 # Rotació eix X
	children [

		Transform {
			rotation 0 1 0  0.7854 # Rotació eix Y
			children [
				Shape { # Caixa blava
					geometry Box { size 2 4 2 }
					appearance Appearance { material Material { diffuseColor 0 0 1 } }
				}
			]
		}

	]
}

Escalats

Pel que fa els escalats cal pensar que es poden diferenciar dos tipus d'escalats: els uniformes i els no uniformes (tot i que els uniformes són un cas particular dels no uniformes). Els uniformes, engrandeixen o redueixen un objecte en totes direccions per igual, mentre que els no uniformes ho fan en tan sols alguna direcció o direccions. Per tant, en els escalats uniformes, els objectes mantenen les seves proporcions, mentre que en els no uniformes, els objectes queden deformats.

Exemple5: Definirem un escalat no uniforme sobre un cub. En concret, escalarem el cub al doble de la seva mida en la direcció de l'eix de les X.


Transform {
	scale 2 1 1 # Creix al doble en la direcció X i queda igual en les direccions Y i Z
	children [
		Shape { # Cub taronja
			geometry Box { size 1 1 1 }
			appearance Appearance { material Material { diffuseColor 1 0.5 0 } }
		}
	]
}

Analitzem el que fa aquest fragment de codi. Aquí es defineix un node Transform que té un field scale on es defineix l'escalat no uniforme que patirà l'objecte que volem modificar. Per a definir l'escalat li diem el tant per u que volem engrandir/reduïr l'objecte en cada una de les direccions que defineixen els eixos.

Com que l'escalat no uniforme que definim en l'exemple es de [2 1 1], és per això que el cub de 1 unitat ja no apareix com a tal, si no com a una caixa allargada horitzontalment que fa exactament 2 unitats d'ample, 1 unitat d'alçada i 1 unitat de fons.

Si volem aplicar un escalat uniforme, tan sols cal posar la mateixa xifra d'escalat en totes tres direccions.

Encadenament de Transformacions

Quan es vol fer més d'una transformació, no cal definir necessàriament un node Transform per a cada una, si no que podem posar-les totes sota un mateix node.

Exemple6: Definirem un cub de 1 unitat i li aplicarem una translació de [5 4 0], una rotació de 30 graus respecte l'eix X i un escalat de [0.5 0.5 2].


Transform {
	translation 5 4 0
	rotation 1 0 0  0.5236 # 30 graus
	scale 0.5 0.5 1
	children [
		Shape { # Cub verd fosc
			geometry Box { size 1 1 1 }
			appearance Appearance { material Material { diffuseColor 0 0.5 0.2 } }
		}
	]
}

Analitzem el que fa aquest fragment de codi. El que hem definit aquí no és tan senzill com sembla ja que no obtenim el mateix resultat si apliquem les tres operacions en un ordre que si les apliquem en un altre.

Per definició, VRML defineix un ordre de preferència d'operacions de transformació que és el següent:

  1. En primer lloc aplica l'escalat.
  2. En segon lloc aplica la rotació.
  3. En tercer lloc aplica la translació.

Per tant el codi d'adalt seria equivalent al següent si fessim les transformacions per separat:


Transform {
	translation 5 4 0
	children [
		Transform {
			rotation 1 0 0  0.5236 # 30 graus
			children [
				Transform {
					scale 0.5 0.5 1
					children [
						Shape { # Cub verd fosc
							geometry Box { size 1 1 1 }
							appearance Appearance { material Material { diffuseColor 0 0.5 0.2 } }
						}
					]
				}
			]
		}
	]
}
Resultat.

Com podem comprobar el resultat és el mateix que abans.

Cal no caure en l'error de pensar que això es llegeix de dalt a baix. Aquest codi cal llegir-lo de dins cap a fora i per tant l'ordre en que s'apliquen les operacions és començant per l'objecte i anar sortint en fora: Cub escalat rotat i traslladat.

Per aplicar les transformacions en l'ordre que hem dit inicialment caldria invertir-ho de la següent manera:


Transform {
	scale 0.5 0.5 1
	children [
		Transform {
			rotation 1 0 0  0.5236 # 30 graus
			children [
				Transform {
					translation 5 4 0
					children [
						Shape { # Cub verd fosc
							geometry Box { size 1 1 1 }
							appearance Appearance { material Material { diffuseColor 0 0.5 0.2 } }
						}
					]
				}
			]
		}
	]
}
Resultat.

Com podem comprobar el resultat és totalment diferent dels dos d'abans. De fet la nostre caixa ha que era un paral.lelepíped d'angles rectes ara ha quedat deformada.

Exercicis proposats:

Diverses Transformacions
Com exercicis proposem que intenteu definir diversos objectes i els situeu en l'espai per tal d'entendre bé el funcionament de les transformacions i en concret el seu funcionament en VRML.




< Anterior | Menú ^ | Següent >