/////////(Copyright)//////(No modificar estas 11 primeras Lineas)/////////
// Autor: Antonio Castro Snurmacher (E-mail )
//
// Este fuente puede ser utilizado, distribuido, y modificado libremente
// pero siempre se deberá respetar la propiedad intelectual de su autor.
// El autor renuncia a todo tipo de beneficio económico y no se hace
// responsable de los posibles perjuicios derivados del uso del mismo.
// Toda modificación queda sujeta a las mismas condiciones de uso que el
// original. En caso de traducción deberá conservarse el texto original
// de esta cabecera y añadirse la traducción a continuación de ella.
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
// erizo.pov (1-Mayo-1998)
//-----------------------------------------------------------------------
// Esta versión esta dedicada a su inclusión en la revista LinuxFocus
//-----------------------------------------------------------------------
#include "colors.inc"
#include "textures.inc"
#include "balistap.inc"
#declare RadioCuerpo = 5;
#declare NumEspinasMeridiano = 40;
// Definimos el tamaño de las puas en función del tamaño del cuerpo
// Los erizos de mar en la naturaleza presentan puas largas en la
// parte superior y cortas en la parte inferior.
#declare LongitudMaximaPua = RadioCuerpo * 2;
#declare LongitudMinimaPua = RadioCuerpo / 4;
// Color del erizo
#declare TexturePua = texture { pigment {VeryDarkBrown} }
#declare TextureCuerpo = texture { pigment {DarkBrown} }
// Todas las definiciones que siguen a continuación están calculadas
// a partir de las anteriores.
// Suponemos inicialmente un erizo con cuerpo esférico.
// pi está predefinido como #declare pi = 3.1415926535897932384626
#declare LongitudMeridiano = 2 * pi * RadioCuerpo;
// Suponemos que está totalmente recubierto de púas cónicas.
// El radio de una púa en su base será 'RadioPua'
#declare MeridianoPua = LongitudMeridiano / NumEspinasMeridiano;
#declare RadioPua = MeridianoPua / 2;
// Usaremos la notación de eje, meridiano, y paralelo en el erizo tal
// como lo haríamos con el eje, los meridianos, y paralelos terrestres.
// Para recubrir el erizo totalmente de púas trazaremos varios circulos
// 'paralelos del erizo', y para ello tomaremos un 'meridiano del erizo'
// como punto de partida de todos ellos. Llamaremos angulo vertical al
// angulo formado con el 'eje del erizo' y el punto de comienzo de un
// paralelo. En los polos este angulo vertical valdrá 0 y 180, y en el
// ecuador valdrá 90. Necesitamos ir incrementado este angulo para procesar
// en cada uno de ellos las puas de un paralelo.
// Para calcular el incremento del angulo vertical hacemos una regla de tres
// LongitudMeridiano ---> 360
// MeridianoPua ---> IncAngVert
#declare IncAngVert = 360 * MeridianoPua / LongitudMeridiano;
// Para que el erizo no sen unda en la arena ni flote en el agua
// calculamos la distancia del centro al extremo de las puas pequeñas
// situadas en la parte inferior del erizo.
#declare CorreccionY = RadioCuerpo + LongitudMinimaPua;
camera {
location < -40, 40, -40>
look_at < 25, CorreccionY , 25>
}
// En el fondo del mar la luz llega de varios puntos debido al oleaje en
// la superficie. Para simular esto usaremos varias fuentes de luz.
light_source { <-200, 300, -200> color White}
light_source { <-300, 300, -100> color White}
light_source { <-100, 300, -300> color White}
light_source { <0, 1200, 0> color White}
// Para conseguir la coloracion del agua utilizamos un efecto
// atmosférico.
fog { distance 250 color SeaGreen }
// La arena la definimos con un color Sienna, y con profundas
// ondulaciones de gran tamaño.
plane { y, 0
pigment { Sienna }
normal {
ripples 1.0
frequency 300.0
}
finish {
ambient 0.1
diffuse 0.9
}
scale <3000, 3000, 3000>
}
// ******************* Declaracion del erizo ****************************
#declare erizo = object {
union {
// Calcularemos un paralelo de puas para cada valor de AngVert
// El primer valor será 0. (0 puas en la misma direccion del eje vertical.
// El segundo valor serán una pocas puas situadas en el primero paralelo
// El máximo valor se conseguirá para AngVert == a 90 porque es la zona
// del ecuador donde cabe el máximo de puas.
// Las puas en un mismo meridiano se calculan variando el angulo horizontal
// 'AngHoriz'
#declare AngVert=0;
#while (AngVert < 180 )
#declare RadParalelo = abs ( RadioCuerpo * sin(radians(AngVert)));
#declare LongitudParalelo = 2 * pi * RadParalelo;
#declare NumEspinasParalelo = LongitudParalelo / MeridianoPua;
#declare LongitudPua = LongitudMinimaPua + ( (LongitudMaximaPua-LongitudMinimaPua) * ((180-AngVert)/180) );
// #declare LongitudPua = LongitudMaximaPua;
#declare IncAngHoriz = 360 / NumEspinasParalelo;
#declare Ybase = RadioCuerpo * cos (radians(AngVert));
#debug concat("\nAngVert=", str(AngVert,5,0), " LongitudPua=", str(LongitudPua,5,0)," Ybase=", str(Ybase,5,0), " ")
#declare Ypunta = (RadioCuerpo + LongitudPua)* cos (radians(AngVert));
#declare AngHoriz=0;
#while (AngHoriz < 360)
#declare Xbase = RadParalelo * cos (radians(AngHoriz));
#declare Xpunta = (RadParalelo + LongitudPua) * cos (radians(AngHoriz));
#declare Zbase = RadParalelo * sin (radians(AngHoriz));
#declare Zpunta = (RadParalelo + LongitudPua) * sin (radians(AngHoriz)) ;
//#debug concat( "Vert=", str(AngVert,5,0), " Horiz=", str(AngHoriz,5,0), "\n")
cone { , RadioPua, , 0
texture { TexturePua }
}
#declare AngHoriz =AngHoriz + IncAngHoriz;
#end
#declare AngVert=AngVert+IncAngVert;
#end
// El cuerpo es una esfera.
sphere { <0,0,0> RadioCuerpo
texture { TextureCuerpo }
}
} // end union
// Colocamos el erizo a la altura correcta.
translate y*CorreccionY
// Pero los erizos no son esféricos sino que tanto el cuerpo como el resto
// estan achatados. Lo que hacemos es conservar la porporción en el eje Y
// aumentando las proporciones en X, y Z. Multiplicandolas por 1.5
scale <1.5, 1, 1.5>
} // end object erizo
// Ya tenemos un erizo perfecto. Vamos a colocar unos cuantos
// En primero lugar establecemos una distancia mínima entre ellos.
#declare DistanciaMinima = 3 * (RadioCuerpo+LongitudMaximaPua);
// Vamos a disponerlos en un cuadrado de 5 * 5.
// Para evitar que se vean como una formación excesivamente geometrica
// Los deplazamos ligeramente en horizontal con valores aleatorios.
#declare Xi=0;
#declare R1 = seed(0);
#while (Xi < 5)
#declare Yi=0;
#while (Yi<5)
#declare Xpos= Xi * DistanciaMinima + ( rand(R1) * DistanciaMinima * 0.5 );
#declare Ypos= Yi * DistanciaMinima + ( rand(R1) * DistanciaMinima * 0.5 );
#debug concat ("\nXpos=", str(Xpos, 5, 0), " Ypos=", str(Ypos, 5,0))
object {erizo
translate
}
#declare Yi= Yi+1;
#end
#declare Xi= Xi+1;
#end
// Vamos ahora a colocal los peces. Usaremos un procedimiento muy
// parecido al utilizado para colocar los erizos. En este caso en
// lugar de disponerlos en un unico cuadrado de 5 * 5 los colocaremos
// en tres grupos de 4 * 4
// En primero lugar establecemos una distancia mínima entre ellos.
#declare DistanciaMinima = 90;
#declare Xi=0;
#declare R1 = seed(0);
#while (Xi < 4)
#declare Yi=0;
#while (Yi<4)
#declare Xpos= Xi * DistanciaMinima + ( rand(R1) * DistanciaMinima * 0.5 );
#declare Ypos= Yi * DistanciaMinima + ( rand(R1) * DistanciaMinima * 0.5 );
#debug concat ("\nXpos=", str(Xpos, 5, 0), " Ypos=", str(Ypos, 5,0))
object { Balistap
scale 1.2
rotate y*50*rand(R1)
translate
}
object { Balistap
scale 1.2
rotate y*50*rand(R1)
translate
}
object { Balistap
scale 1.2
rotate y*50*rand(R1)
translate
}
#declare Yi= Yi+1;
#end
#declare Xi= Xi+1;
#end
// Vamos a colocar a uno de ellos como si estuviera comiendo
// algo en el fondo.
object { Balistap
scale 1.1
rotate z* -45
rotate y*200
translate<80, 19, 360>
}
/******** Este nos puede servir para visualizar el pez completo *****
object { Balistap
scale 1.1
rotate y*225
translate<25, 40, 25>
}
**********************/