3.6.5  Elipsoide Supercuádrico

A veces queremos usar un objeto similar a una caja, cuyos bordes no sean rectos, sino redondeados (suavizados). El elipsoide supercuádrico generado por la sentencia superellipsoid es muy útil para ese fin. Se describe mediante una sencilla sintaxis:

  superellipsoid { <Valor_E, Valor_N >}

Donde Valor_E y Valor_N son números entre cero y uno. Probemos algunos de estos valores para averiguar qué tipos de formas producen.

Creamos un archivo llamado supellps.pov y escribimos:

  #include "colors.inc"
  camera {
    location <10, 5, -20>
    look_at 0
    angle 15
  }
  background { color rgb <.5, .5, .5> }
  light_source { <10, 50, -100> White }

El color de fondo gris hace más sencillo ver nuestro objeto. Ahora escribamos:

  superellipsoid { <.25, .25>
    pigment { Red }
  }

Guardamos el archivo y lo trazamos a 200x150 -A. Parece una caja, pero sus bordes están redondeados. Ahora experimentaremos diferentes valores para Valor_E y Valor_N. Para la siguiente prueba, intenta <1, 0.2>. Parece un cilindro, aunque los bordes de las bases están redondeados. Intentémoslo ahora con <0.1, 1>. Es difícil describir esta figura, pero es interesante. Finalmente, probemos <1, 1>. Éste es más familiar...¡una esfera!

Debemos tener en cuenta algunas cosas para usar los superelipsoides. En primer lugar, no debemos usar el valor cero para ninguno de los dos parámetros. Esto causaría el dibujo de una caja negra en lugar de nuestra figura. En segundo lugar, valores muy pequeños de Valor_E y Valor_N producen resultados muy extraños, así que es conveniente evitarlos. Finalmente, el método Sturm para resolver ecuaciones no funcionará con estas figuras.

Los superelipsoides son finitos, de forma que responden muy bien al encapsulado automático, y pueden utilizarse muy bien en composición de objetos CSG (intersecciones, uniones...).

Ahora usaremos esta figura para hacer algo útil en una escena. Haremos un suelo agrupando varios, usándolos como baldosas, y situaremos un puñado de ellos flotando encima. Podemos empezar con el archivo anterior.

Le cambiamos el nombre a tiles.pov y lo editamos para que contenga:

  #include "colors.inc"
  #include "textures.inc"
  camera {
    location <10, 5, -20>
    look_at 0
    angle 15
  }
  background { color rgb <.5, .5, .5> }
  light_source{ <10, 50, -100> White }

Observa que hemos añadido #include "textures.inc" para poder usar texturas predefinidas.

Ahora definimos el superelipsoide que usaremos de baldosa.

  #declare Tile = superellipsoid { <0.5, 0.1>
    scale <1, .05, 1>
  }

Los superelipsoides miden alrededor de 2 por 2 por 2, de forma que lo escalamos para que tenga el tamaño apropiado. Como queremos apilarlos juntos, hemos de tener cuidado al separarlos para que no se solapen. Elegimos un valor ligeramente superior a 2 como desplazamiento, con el fin de dejar un poco de espacio que se llenará con cemento. Escribimos:

  #declare Offset = 2.1;

Coloquemos una fila de baldosas. Cada una será desplazada un múltiplo del desplazamiento escogido en la dirección del eje z (en ambos sentidos). Multiplicaremos este desplazamiento por el orden que ocupa la baldosa en la fila para lograr este efecto. Unimos todos estos objetos en uno solo llamado Row (fila), como éste:

  #declare Row = union {
    object { Tile }
    object { Tile translate z*Offset }
    object { Tile translate z*Offset*2 }
    object { Tile translate z*Offset*3 }
    object { Tile translate z*Offset*4 }
    object { Tile translate z*Offset*5 }
    object { Tile translate z*Offset*6 }
    object { Tile translate z*Offset*7 }
    object { Tile translate z*Offset*8 }
    object { Tile translate z*Offset*9 }
    object { Tile translate z*Offset*10 }
    object { Tile translate -z*Offset }
    object { Tile translate -z*Offset*2 }
    object { Tile translate -z*Offset*3 }
    object { Tile translate -z*Offset*4 }
    object { Tile translate -z*Offset*5 }
    object { Tile translate -z*Offset*6 }
  }

Esto nos crea una sencilla fila de 17 baldosas, suficiente para llenar una pantalla. Ahora debemos hacer copias de esta fila y trasladarlas con ayuda del desplazamiento (offset) prefijado en la dirección del eje x, de la misma forma.

  object { Row }
  object { Row translate x*Offset }
  object { Row translate x*Offset*2 }
  object { Row translate x*Offset*3 }
  object { Row translate x*Offset*4 }
  object { Row translate x*Offset*5 }
  object { Row translate x*Offset*6 }
  object { Row translate x*Offset*7 }
  object { Row translate -x*Offset }
  object { Row translate -x*Offset*2 }
  object { Row translate -x*Offset*3 }
  object { Row translate -x*Offset*4 }
  object { Row translate -x*Offset*5 }
  object { Row translate -x*Offset*6 }
  object { Row translate -x*Offset*7 }

Finalmente, las unimos para darles una sola textura, un mármol blanco como pigmento y un acabado brillante con algo de reflexión:

  union{
    object { Row }
    object { Row translate x*Offset }
    object { Row translate x*Offset*2 }
    object { Row translate x*Offset*3 }
    object { Row translate x*Offset*4 }
    object { Row translate x*Offset*5 }
    object { Row translate x*Offset*6 }
    object { Row translate x*Offset*7 }
    object { Row translate -x*Offset }
    object { Row translate -x*Offset*2 }
    object { Row translate -x*Offset*3 }
    object { Row translate -x*Offset*4 }
    object { Row translate -x*Offset*5 }
    object { Row translate -x*Offset*6 }
    object { Row translate -x*Offset*7 }
    pigment { White_Marble }
    finish { phong 1 phong_size 50 reflection .35 }
  }

Ahora añadimos el cemento. Esto será sencillamente un plano de color blanco. Incrementamos su valor de luz ambiente para que parezca más blanco.

  plane {
    y, 0  //este es el cemento
    pigment { color White }
    finish { ambient .4 diffuse .7 }
  }

Para completar la escena, añadimos cinco superelipsoides diferentes, cada uno de un color, flotando sobre las baldosas y reflejándose en ellas.

  superellipsoid {
    <0.1, 1>
    pigment { Red }
    translate <5, 3, 0>
    scale .45
  }
  superellipsoid {
    <1, 0.25>
    pigment { Blue }
    translate <-5, 3, 0>
    scale .45
  }
  superellipsoid {
    <0.2, 0.6>
    pigment { Green }
    translate <0, 3, 5>
    scale .45
  }
  superellipsoid {
    <0.25, 0.25>
    pigment { Yellow }
    translate <0, 3, -5>
    scale .45
  }
  superellipsoid {
    <1, 1>
    pigment { Pink }
    translate y*3
    scale .45
  }
Objetos superelipsoides flotando sobre un suelo de baldosas
Objetos superelipsoides flotando sobre un suelo de baldosas

Trazamos la escena a 320x200 -A para ver el resultado. Si estamos contentos con él, la imagen final podemos crearla a 640x480 y con anti-alias de 0.2.