Sobre animación de maquinaria con engranajes en Povray, no he localizado nada en Internet. Lo más parecido que encontré fue sobre animación de objetos articulados.
Podría pensarse que el caso de hacer una animación con engranajes es más o menos parecido a las animaciones con objetos articulados, pero tiene algunas peculiaridades así que me he animado a hacer un tutorial sencillito.
Asumiremos que como mínimo ya tiene ciertos conocimientos, o en su defecto ya ha leído Povray conceptos básicos de animacion. (Tutorial)
En general se puede afirmar que animar un sistema de engranajes se trata de un problema más sencillo que la animación de objetos articulados. Comparte el hecho de que el movimiento de un objeto transmite movimiento a otro objeto que está ligado a él, pero la similitud termina aquí.
El problema de los engranajes necesita transformaciones más simples. Nosotros hemos buscado ilustrar una animación con un ejemplo muy sencillo y fácil de entender.
Por simplificar y hacerlo más didáctico:
- No se incluye otra cosa que el suelo y los engranajes.
- Todos los engranajes tienen un diseño muy simple.
- Todos los dientes de todos los engranajes son piezas de idéntico diseño y tamaño.
- No hay engranajes dobles compartiendo un mismo eje.
- No se recurre a la librería de Povray ‘transforms.inc’.
- Se hace todo en base a Macros propias bastante sencillas.
- No se hizo uso de ningún modelador.
Dado que el número de dientes de un engranaje en nuestro ejemplo (con todos los dientes iguales) determinará la longitud de la circunferencia, podemos afirmar lo siguiente:
La velocidad de rotación (velocidad angular) de dos engranajes directamente conectados entre sí, será inversamente proporcional la cantidad de dientes de cada uno de ellos.
Aplicando esta regla, la animación del conjunto resultará sencilla.
El cálculo de la ubicación de cada engranaje ha de hacerse teniendo en cuenta sus dimensiones para que el conjunto engrane con la necesaria precisión.
Hemos añadido una pequeña marca cerca del eje a cada engranaje para que se aprecie en la animación las velocidades relativas.
Dada su sencillez, la animación quedaba un poco sosa, por ello, hemos colocado dos puntos de iluminación, hemos hecho que la cámara gire volando al rededor del conjunto, y hemos usado una textura de mármol rojo. El vídeo dura sólo 20 segundos.
El código fuente es de libre distribución y copia bajo licencia GPL y está ampliamente comentado para hacer que sea lo más legible posible.
Como de costumbre usamos nuestro lanzador pov.py y generamos 500 fotogramas con valores de clock que irán de 1 a 7200.
// Hercules.pov
// (C) Antonio Castro Snurmacher
// Licencia GPL de GNU
// 1) rm -f engranaje*.png
// 2) pov.py engranaje n 11 11 1 500 1 7200
// 3) ffmpeg -f image2 -i engranaje%03d.png -sameq -y engranage.avi
#include "colors.inc"
#include "textures.inc"
#include "shapes.inc"
#include "stones.inc"
#declare Clock20=clock/20;
#declare Clock05=-clock/70;
#declare Luz1=light_source { <-60, 70, 80> color Gray70 }
#declare Luz2=light_source { <20, 70, 20> color Gray50 }
#declare Camera00= camera {
location <50, 30, 0>
look_at <-4, 2, 2>
angle 29
// AspectRatio debe declararse en el '.ini'
// Su valor es el ancho/alto y normalmente valdrá 16/9 o 4/3
right AspectRatio*x
//rotate Clock05
rotate <0,Clock05,0>
}
#declare Epsil=.000000001; // Un tamaño arbitrario muy pequeño.
#declare Metal1 = texture {
pigment {Gray70}
finish { ambient 0.2 diffuse 0.65 reflection 0.15 phong 0.7 phong_size 7 }
}
#declare Suelo2= plane { y, -1.5
texture {T_Stone21}
scale 8
}
/************************************************************
Construye el diente de un engranaje diente con las proporciones
de un cubo unitario en <0,0,0> (box{-.5,+.5})
Rad: Radio de curvatura del biselado. (En este ejemplo se usa siempre 1.7)
Escala: Dimensiones del diente.
RadEngr: Radio del engranaje.
Rot: rotación.
**************************************************************/
#macro Diente(Rad, Escala, RadEngr, Rot)
#local DX=.12; // Desplazamiento para el biselado (0..0.2)
object{
intersection{
box{-.5,+.5}
sphere{<-Rad+DX+.5,0,.5>, Rad}
sphere{< Rad-DX-.5,0,.5>, Rad}
}
scale Escala
translate <0,0,-RadEngr>
rotate <0,-Rot,0>
}
#end
/*******************************************************************
Calcula el tamaño del diente en funcio del radio del engranaje y del número de dientes.
Explicación. Divide la circunferencia (2*pi*r) por la circunferencia (2*NumDientes).
NumDientes: Número de dientes.
Rad: Radio del engranaje.
*******************************************************************/
#macro EscalaDiente(NumDientes, Rad)
pi*Rad/NumDientes;
#end
/********************************
Dispone los dientes formando un círculo.
Rad: Radio del engranaje.
NumDientes: Número de dientes.
LonjitudEje: Espesor del engranaje.
*******************************/
#macro Dentadura(Rad, NumDientes, BiselDiente, LongitudEje)
#local AngIncr= 360/NumDientes;
#local Ang=0;
#local EscalaXZ=EscalaDiente(NumDientes, Rad);
#local Escala=
#while (Ang<360)
Diente(BiselDiente, Escala, Rad, Ang)
#local Ang=Ang+AngIncr;
#end
#end
/*****************************
Construye la forma de un engranaje.
Rad: Radio del engranaje.
NumDientes: Número de dientes.
LonjitudEje: Espesor del engranaje.
RadInterior: Radio del hueco central.
******************************/
#macro Engranaje(Rad, NumDientes, BiselDiente, LonjitudEje, RadInterior)
#local EscalaXZ=EscalaDiente(NumDientes, Rad);
difference{
union{ // Formas que suman.
Dentadura(Rad, NumDientes, BiselDiente, LonjitudEje)
cylinder {<0,-LonjitudEje/2,0><0,LonjitudEje/2,0>,Rad-(EscalaXZ*0.48)}
}
union{ // Formas que restan.
cylinder {<0,-Epsil-LonjitudEje/2,0><0,Epsil+LonjitudEje/2,0>,RadInterior}
sphere {
}
}
#end
/**************************************************************
Devuelve el radio de un engranaje en función del número de dientes y su grosor.
NumDientes: Número de dientes
***************************************************************/
#macro RadioEngranaje(NumDientes, GrosorDiente)
#local Circunferencia= GrosorDiente*2*NumDientes;
#local Radio=Circunferencia/(2*pi);
Radio
#end
/*******************************************************************
Crea el engranaje como objeto y le aplica una rotación en funcion de clock (Clock20)
Asume un tipo de diente y un tipo de engranaje
NumDientes: Numero de dientes
Desfase: Es un valor para hacer coincidir los dientes de un engranaje con su engranaje
vecino y tomará los valores 0 o 0.5.
VRot: Velocidad de rotación.
********************************************************************/
#macro ObjEngranaje(NumDientes, Desfase, VRot)
#local BiselDiente=1.7;
// El tamaño de los dientes debe de ser contante para engranar bien unos con otros
#local GrosorDiente=EscalaDiente(20, 4);
#local GrosorEngranajes=1.5;
#local RadInterior=.5;
#local Rad=RadioEngranaje(NumDientes, GrosorDiente);
object{
Engranaje(Rad, NumDientes, BiselDiente, GrosorEngranajes, RadInterior)
rotate <0,(360/NumDientes)*Desfase+(Clock20*VRot),0>
}
#end
/**************************************************************/
/**************************************************************/
camera {Camera00}
Suelo2
Luz1
Luz2
/*** El tamaño de los dientes debe de ser contante para engranar bien ***/
#declare GrosorDiente=EscalaDiente(20, 4);
#declare GrosorEngranajes=1.5;
#declare NumDient1=20;
#declare NumDient2=26;
#declare NumDient3=18;
#declare NumDient4=14;
#declare NumDient5=10;
#declare NumDient6=8;
#declare NumDient7=40;
#declare Rad1=RadioEngranaje(NumDient1, GrosorDiente);
#declare Rad2=RadioEngranaje(NumDient2, GrosorDiente);
#declare Rad3=RadioEngranaje(NumDient3, GrosorDiente);
#declare Rad4=RadioEngranaje(NumDient4, GrosorDiente);
#declare Rad5=RadioEngranaje(NumDient5, GrosorDiente);
#declare Rad6=RadioEngranaje(NumDient6, GrosorDiente);
#declare Rad7=RadioEngranaje(NumDient7, GrosorDiente);
/*** Sistema de 7 engranajes. ***/
object{
union{
ObjEngranaje(NumDient1,0, -1 )
object{
ObjEngranaje(NumDient2,.5, NumDient1/NumDient2)
translate <0,0,Rad1+Rad2>
}
object{
ObjEngranaje(NumDient3,.5, NumDient1/NumDient3)
translate <0,0,-Rad1-Rad3>
}
object{
ObjEngranaje(NumDient4,0, NumDient1/NumDient4)
translate <-Rad1-Rad4,0,0>
}
object{
ObjEngranaje(NumDient5,0, NumDient1/NumDient5)
translate
}
object{
ObjEngranaje(NumDient6,.5, (NumDient1/NumDient4)*(-NumDient4/NumDient6))
translate <-Rad1-Rad4,0,Rad4+Rad6>
}
object{
ObjEngranaje(NumDient7,0, (NumDient1/NumDient4)*(-NumDient4/NumDient7))
rotate z*-90
translate <-Rad1-Rad4-Rad4-GrosorEngranajes*.45, Rad7+(GrosorEngranajes*.3),0>
}
}
texture{Metal1}
}