/////////(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> } **********************/