3.2.5  Objeto Toroide

Podemos pensar en un toride o toro como en un "donut" o un neumático. Es una forma que se usa mucho en operaciones de composición de objetos, de forma que POV-Ray ha adoptado esa función  polinómica de cuarto grado como forma primitiva. Su sintaxis es muy sencilla, así que es sencillo aprender a usarla una vez que se ha comprendido lo que significan los dos valores que se deben indicar. En lugar de describirlos, creemos un objeto de este tipo y experimentemos con él.

Creamos un archivo llamado tordemo.pov y escribimos:

  #include "colors.inc"

  camera {
   location <0, .1, -25>
   look_at 0
   angle 30
  }

  background { color Gray50 } // para hacer el toro más visible

  light_source{ <300, 300, -1000> White }

  torus { 4, 1               // radio externo y grosor del toro
   rotate -90*x              // para verlo de frente
   pigment { Green }
  }

Trazamos la escena. Bien, lo que vemos es una especie de neumático. Cambiemos el radio externo y el grosor y veamos qué pasa. Escribimos:

  torus { 5, .25            // radio externo y grosor del toro

¡Esto parece un aro! Probemos lo siguiente:

  torus { 3.5, 2.5          // radio externo y grosor del toro

Esto es... ¡Un neumático excesivamente inflado!

Con una sintaxis tan simple, no hay mucho que hacer con un toro salvo cambiarle la textura...¿no? Veamos...

Los toros son muy útiles en composición de formas. Hagamos un pequeño experimento. Veamos qué forma tiene la diferencia entre un toro y una caja:

  difference {
   torus { 4, 1
    rotate x*-90  // para verlo de frente
   }
   box { <-5, -5, -1>, <5, 0, 1> }
   pigment { Green }
  }

Interesante... medio toro. Ahora añadiremos otro al revés. Sólo hay que declararlo y hacer las transformaciones necesarias para usarlo en dos posiciones distintas:

  #declare Medio_Toro = difference {
   torus { 4, 1
    rotate -90*x  // para verlo de frente
   }
   box { <-5, -5, -1>, <5, 0, 1> }
   pigment { Green }
 }
  #declare Rotacion = 180*x;
  #declare Trans_Toro = 8;  // doble del radio externo
Ahora creamos la unión de dos semi-toros:
  union {
    object { Medio_Toro }
    object { Medio_Toro
      rotate Rotacion
      translate Trans_Toro*x
    }
  }
Esto produce un objeto con forma de S, pero no lo podemos ver totalmente desde la posición actual de la cámara. Añadamos unas cuantas piezas más de este tipo, moviendo nuestro objeto en la dirección del eje "z" y girándolo un poco con respecto al eje "y" para poder ver algo más. También observemos que aparece un pequeño vacío donde se juntan los dos semi-toros. Este defecto se debe al hecho de ver esta escena directamente desde el plano x-z (un defecto debido al tipo de cálculo que hace el programa; en general, no conviene que nuestra cámara coincida con un plano de alguna de las cajas usada en la imagen). Cambiamos la coordenada y de la cámara de 0 a 0.1 para evitar este defecto.
  union {
    object { Medio_Toro }
    object { Medio_Toro
      rotate Rotacion
      translate x*Trans_Toro
    }
    object { Medio_Toro
      translate x*Trans_Toro*2
    }
    object { Medio_Toro
      rotate Rotacion
      translate x*Trans_Toro*3
    }
    object { Medio_Toro
      rotate Rotacion
      translate -x*Trans_Toro
    }
    object { Medio_Toro
      translate -x*Trans_Toro*2
    }
    object { Medio_Toro
      rotate Rotacion
      translate -x*Trans_Toro*3
    }
    object { Medio_Toro
      translate -x*Trans_Toro*4
    }
    rotate y*45
    translate z*20
  }
Al crear la imagen veremos una forma serpenteante muy curiosa. Pero querremos modelar algo más útil, que podamos encontrar en la vida real. ¿Qué tal una cadena?

Pensemos un momento. Hay que observar que un eslabón de una cadena puede ser modelado de forma muy sencilla usando dos semi-toros y dos cilindros. Creamos un nuevo archivo, en el que podemos usar el mismo fondo, la cámara, la luz y las declaraciones de objetos que usamos en tordemo.pov:

  #include "colors.inc"

  camera {
    location <0, .1, -25>
    look_at 0
    angle 30
  }
  background { color Gray50 }
  light_source{ <300, 300, -1000> White }
  #declare Medio_Toro = difference {
    torus { 4,1
      sturm
      rotate x*-90  // para verlo desde arriba
    }
    box { <-5, -5, -1>, <5, 0, 1> }
    pigment { Green }
  }
  #declare Rotacion = x*180;
  #declare Trans_Toro = 8;
Ahora, creamos un toro completo a partir de dos semi-toros:
  union {
    object { Medio_Toro }
    object { Medio_Toro rotate Rotacion }
  }
Esto parece una forma algo artificiosa de crear un toro, pero realmente vamos a desplazar cada mitad para dejar sitio a los cilindros. Primero, declaremos los cilindros que vamos a usar:
  #declare Segmento_Eslabon = cylinder { <0, 4, 0>, <0, -4, 0>, 1
    pigment { Green }
  }
Después añadiremos dos de estos cilindros a la unión de los dos semi-toros, trasladándolos de forma que queden alineados con el radio exterior de los toros a cada lado:
  union {
    object { Medio_Toro }
    object { Medio_Toro rotate Rotacion }
    object { Segmento_Eslabon translate  x*Trans_Toro/2 }
    object { Segmento_Eslabon translate -x*Trans_Toro/2 }
  }
Ahora trasladamos los semi-toros en la dirección vertical para que sus extremos coincidan con los de los cilindros. La distancia coincide con la mitad de la definida como Trans_Toro:
  union {
    object { Medio_Toro
      translate y*Trans_Toro/2
    }
    object { Medio_Toro
      rotate Rotacion
      translate -y*Trans_Toro/2
    }
    object { Segmento_Eslabon
      translate x*Trans_Toro/2
    }
    object { Segmento_Eslabon
      translate -x*Trans_Toro/2
    }
  }
Trazamos el resultado y tenemos un eslabón de la cadena. ¡Pero aún no hemos acabado! ¿Alguien ha visto una cadena de color verde? Usemos una apariencia metálica sobre ellos. En primer lugar, borremos todos los pigmentos de las declaraciones de los toros y cilindros. Después, declaremos lo siguiente antes de la unión:
  #declare Oro_Cadena = texture {
    pigment { BrightGold }
    finish {
      ambient .1
      diffuse .4
      reflection .25
      specular 1
      metallic
    }
  }
Ahora, añadamos esta textura a la unión y nombrémosla apropiadamente:
  #declare Eslabon = union {
    object { Medio_Toro
      translate y*Trans_Toro/2
    }
    object { Medio_Toro
      rotate Rotacion
      translate -y*Trans_Toro/2
    }
    object { Segmento_Eslabon
      translate x*Trans_Toro/2
    }
    object { Segmento_Eslabon
      translate -x*Trans_Toro/2
    }
    texture { Oro_Cadena }
  }
por fin, uniremos dos eslabones. El segundo eslabón debe ser trasladado en dirección vertical de forma que su cara interior coincida con la cara interior del primer eslabón. La distancia adecuada debe ser el doble de la distancia Trans_Toro menos 2 (dos veces el radio exterior). Esto puede escribirse mediante la expresión:
  Trans_Toro*2-2*y
Declaramos la expresión como sigue:
  #declare Trans_Eslabon = Trans_Toro*2-2*y;
En el bloque en el que situemos el objeto, usaremos este valor multiplicándolo para insertar nuevos eslabones. Ahora, rotaremos el segundo eslabón 90*y para que sea perpendicular al primero (como los verdaderos eslabones de una cadena). Finalmente, reduciremos el tamaño de la unión a un cuarto de su tamaño para poder ver el resultado completamente:
  union {
    object { Eslabon }
    object { Eslabon translate y*Trans_Eslabon rotate y*90 }
    scale .25
  }
Al trazar esto, podremos ver un par de eslabones muy realistas. Si queremos hacer una cadena completa, necesitamos declarar esta unión y crear otra unión usando como pieza este par de eslabones. Quitamos el escalado de la primera declaración para poder escalar sólo el objeto definitivo:
  #declare Par_Eslabones =
  union {
    object { Eslabon }
    object { Eslabon translate y*Trans_Eslabon rotate y*90 }
  }
Ahora declaramos nuestra cadena:
  #declare Cadena = union {
    object { Par_Eslabones}
    object { Par_Eslabones translate  y*Trans_Eslabon*2 }
    object { Par_Eslabones translate  y*Trans_Eslabon*4 }
    object { Par_Eslabones translate  y*Trans_Eslabon*6 }
    object { Par_Eslabones translate -y*Trans_Eslabon*2 }
    object { Par_Eslabones translate -y*Trans_Eslabon*4 }
    object { Par_Eslabones translate -y*Trans_Eslabon*6 }
  }
Y, finalmente, situamos nuestra cadena añadiendo unas transformaciones para hacerla visible en su totalidad. Estas transformaciones incluyen escalarla un factor 1/10, trasladarla y girarla para poder ver bien todos los enlaces:
  object { Cadena scale .1 rotate <0, 45, -45> }
El toro se puede usar para crear cadenas

El toro se puede usar para crear cadenas.

En la imagen podemos ver una cadena dorada que cruza diagonalmente la pantalla.