28.05.2013 Views

3.7. Trigonometría

3.7. Trigonometría

3.7. Trigonometría

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

GAmuza Hybrid live coding / modular application<br />

116<br />

<strong>3.7.</strong> <strong>Trigonometría</strong><br />

3. Lenguaje de programación<br />

La trigonometría es una rama de las matemáticas cuyo significado etimológico es “la medición de los<br />

triángulos” y sirve para definir relaciones entre los lados y ángulos de los triángulos. Básicamente es<br />

una extensión del Teorema de Pitágoras Las funciones trigonométricas y las funciones que más se<br />

utilizan son las del seno y coseno, con ellas se generan números repetitivos que pueden ser utilizados<br />

para dibujar ondas, círculos, arcos y espirales.<br />

La unidad de medida angular propia de la trigonometría es el radian, en una circunferencia completa<br />

hay 2π radianes.<br />

Esta unidad puede traducirse a Grado sexagesimal: unidad angular que divide una circunferencia<br />

en 360 grados; o al Grado centesimal: unidad angular que divide la circunferencia en 400 grados<br />

centesimales.<br />

OpenFrameworks cuenta con las siguientes constantes para trabajar con unidades radianes:<br />

PI<br />

TWO_PI<br />

M_TWO_PI<br />

FOUR_PI<br />

HALF_PI<br />

Para convertir grados a radianes y viceversa, pueden utilizarse las funciones de Lua math.deg() y<br />

math.rad() y también las funciones de openFrameworks of.degToRad() y of.radTodeg().<br />

Las funciones math.sin(x) y math.cos(x) se utilizan para determinar el valor del seno y coseno de<br />

un ángulo en radianes. Ambas funciones requieren un parámetro, el ángulo. El siguiente gráfico orienta<br />

los valores del seno y coseno en función de los ángulos58 .<br />

58 Más información sobre funciones matemáticas Lua en http://lua-users.org/wiki/MathLibraryTutorial [30.07.2012]<br />

117


GAmuza Hybrid live coding / modular application<br />

118<br />

Para ver cómo funcionan gráficamente, retomamos un ejemplo de Ben Fry y Casey Reas 59 , traducido al<br />

lenguaje de programación de GAmuza, porque permite observar qué parámetros controlan la amplitud<br />

y frecuencia de las ondas utilizando la función math.sin() en una estructura for.<br />

/*<br />

GAmuza 0.4.1 examples<br />

---------------------<br />

Math/sineWave.ga dibujo onda sinusoidal<br />

creado por mj<br />

*/<br />

_angle = 0.0<br />

pos = OUTPUT_H/2 // posicion Y<br />

amplitud = 40.0 // altura de la onda<br />

inc = PI/30.0 // incremento del ángulo<br />

function draw()<br />

ga.background(1.0,1.0)<br />

for x = 0, OUTPUT_W, 5 do<br />

y = pos + (math.sin(_angle) *amplitud)<br />

of.setColor(0)<br />

of.rect(x, y, 2, 4)<br />

_angle = _angle + inc<br />

end<br />

_angle = 0.0<br />

end<br />

59 Casey Reas y Ben Fry, (2007) Processing, a Programming Handbook for Visual Designers and Artist and. Cambridge(MA): The<br />

MIT Press, pág. 119-120.<br />

3. Lenguaje de programación<br />

Si en este ejemplo se modifican los valores asignados a las variables se puede observar los cambios<br />

en la frecuencia de la onda. La variable pos define la coordenada Y de la onda, la variable amplitud<br />

controla la altura de la onda, y la variable inc el incremento del ángulo.<br />

Las siguientes imágenes muestran los cambios de frecuencia al modificar esos valores y el ángulo.<br />

pos = 25<br />

pos = 75<br />

amplitud=5.0<br />

amplitud=45.0<br />

inc=PI/12.0<br />

inc=PI/90.0<br />

angle=HALF_PI<br />

angle = PI<br />

119


GAmuza Hybrid live coding / modular application<br />

120<br />

En el siguiente ejemplo se utilizan valores del seno y el coseno para calcular los centros de una espiral<br />

de círculos, haciendo una conversión de grados a radianes<br />

/*<br />

GAmuza 0.4.1 examples<br />

---------------------<br />

Trigonometria/sin_cos.ga<br />

grados a radianes, espiral<br />

*/<br />

radio = 30<br />

function setup()<br />

end<br />

of.enableSmoothing()<br />

function draw()<br />

end<br />

ga.background(0.0, 1.0)<br />

of.setColor(255)<br />

radio = 30<br />

for grado = 0, 360*4, 10 do<br />

end<br />

angle = math.rad(grado)<br />

x = UTPUT_W/2+ (math.cos(angle) * radio)<br />

y = OUTPUT_H/2+ (math.sin(angle) * radio)<br />

of.circle(x, y, 4)<br />

radio = radio + 1<br />

La estructura for recorre cuatro veces los 360º de un círculo de 10 en 10 grados. El resultado de los<br />

grados que se obtiene (10, 20, 30, 40,...) se pasa a radianes mediante la función de Lua math.rad(),<br />

por ejemplo math.rad(180) = 3.1415926535898, es decir PI.<br />

La espiral crece por el incremento del radio, si se comenta o quita radio=radio+1, el código dibuja<br />

un círculo de círculos.<br />

La repetición del valor inicial de la variable, radio = 30, en el draw() y fuera del for sirve para<br />

detener el crecimiento en loop de su valor.<br />

3. Lenguaje de programación<br />

Una variación del este ejemplo nos lleva a la configuación de obra Rotating Disc (1925) de Marcel<br />

Duchamp. En el apartado 3.10 volveremos a ella para aplicarle la rotación. De momento analizamos el<br />

código para generar la imagen fija.<br />

/*<br />

GAmuza 0.4.1 examples<br />

---------------------<br />

Artists/duchampRotoreliefs.ga<br />

created by n3m3da && mj<br />

*/<br />

radio = 15<br />

spiralFactor = 15<br />

numCircles = 23<br />

function setup()<br />

of.enableSmoothing()<br />

of.setCircleResolution(50)<br />

end<br />

function update()<br />

end<br />

function draw()<br />

ga.background(0.0, 1.0)<br />

of.setColor(255)<br />

of.noFill()<br />

of.setLineWidth(3)<br />

radio = 15<br />

for i = 0, numCircles do<br />

angulo = i*TWO_PI/((numCircles/2) +1)<br />

x = (OUTPUT_W/2) + (math.cos(angulo) * spiralFactor)<br />

y = (OUTPUT_H/2) + (math.sin(angulo) * spiralFactor)<br />

of.circle(x, y, radio)<br />

radio = radio + spiralFactor<br />

end<br />

end<br />

El centro de todos los circulos está situado en el perímetro de un círculo no dibujado, cada uno de ellos<br />

separado por 45º. La diferencia de sus radios se corresponde al valor de ese mismo circulo invisible<br />

que distribuye la tangencia de los otros, es esa tangencia lo que produce la percepción de una espiral.<br />

121


GAmuza Hybrid live coding / modular application<br />

122<br />

3.8. Archivos de imagen<br />

Sintaxis<br />

of.image() Clase de openFrameworks<br />

loadImage() Método de esta clase<br />

ga.importFile() Función de GAmuza<br />

La clase of.image() permite incorporar fácilmente archivos de imagen a la ventana de salida de<br />

GAmuza, estos archivos deben estar en la carpeta data situada en el ordenador junto al script.<br />

Se vincula la clase of.image() a una variable al inicio del programa. Después en el bloque setup() se<br />

le asignan los parámetros de localización con el método, loadImage() cuyo parámetro es una función<br />

de GAmuza ga.importFile(“nombreArchivo.jpg”) que localiza ese archivo en la carpeta data. El<br />

método loadImage()se vincula al nombre de la variable por medio del operador “:”. Y por último en el<br />

bloque function draw() se vincula esa misma variable al método draw() cuyos 4 parámetros señalan<br />

su posición x, y, y las dimensiones de ancho y alto. En el siguiente ejemplo se establece una fórmula<br />

para ajustar el tamaño a las dimensiones de la ventana de salida:<br />

/*<br />

GAmuza 0.4.1 examples<br />

---------------------<br />

Image/loadImage.ga<br />

creado por n3m3da | www.d3cod3.org<br />

*/<br />

imagen = of.image() -- variable vinculada a la clase<br />

function setup()<br />

imagen:loadImage(ga.importFile(“nombreArchivo.jpg”)) -- cargar la imagen<br />

end<br />

function draw()<br />

ga.background(0.0, 1.0)<br />

// para centrar y escalar la imagen ajustada a la ventana de salida<br />

w = OUTPUT_W<br />

h = (w/img:getWidth())*img:getHeight()<br />

posX = 0<br />

posY = (OUTPUT_H-h)/2<br />

// dibuja la imagen<br />

of.setColor(255)<br />

img:draw(posX,posY,w,h)<br />

end<br />

GAmuza puede incorporar archivos de imagen del tipo .jpg, .gif, .tga, .tiff, bmp y .png<br />

3.8.1. Efectos imagen<br />

3. Lenguaje de programación<br />

Además de los efectos de imagen que se pueden hacer desde en la interface del módulo Live Coding<br />

(ver pág. 33) también se puedenn utilizar algunas clases del addon ofx de openFrameworks para<br />

efectos de imagen o gráficos como ofx.blur()para desenfocar . Este efectos se basa en la técnica<br />

Shader que actúa directamente en la Ram de la tarjeta gráfica por lo que el renderizado es más rápido<br />

y no resta capacidad al procesador del ordenador. En el siguiente ejemplo el nivel de desenfoque de<br />

la imagen está relacionado con la posición del ratón.<br />

/*<br />

GAmuza 0.4.1 examples<br />

---------------------<br />

SHADERS ejemplo - blur<br />

created by n3m3da | www.d3cod3.org<br />

*/<br />

_blur = ofx.blur() -- se vinculan las variables a las clases<br />

imag = of.image()<br />

function setup()<br />

imag:loadImage(“nombreArchivo.jpg”)<br />

_blur:allocate(OUTPUT_W,OUTPUT_H)<br />

_blur:setPasses(6)<br />

end<br />

function update()<br />

blur:setRadius(ga.mouseX()/ OUTPUT_W*10) // valor variable según posición ratón<br />

end<br />

function draw()<br />

ga.background(0.0,1.0)<br />

w = OUTPUT_W<br />

h = (w/imag:getWidth())*imag:getHeight()<br />

posX = 0<br />

posY = (OUTPUT_H-h)/2<br />

end<br />

_blur:beginFx() // inicio de funciones afectadas por el efecto<br />

of.setColor(255) // siempre hay que definir el color para que dibuje algo<br />

imag:draw(posX,posY,w,h) // tamaño imagen adaptada a la ventana de salida<br />

of.circle(ga.mouseX(),ga.mouseY(),5) //círculo para aplicarle también el efecto<br />

_blur:endFx(true) // señala el final de las funciones vinculadas al efecto<br />

of.enableAlphaBlending()<br />

of.setColor(255) // de nuevo para que no altere el color<br />

_blur:draw(0,0) // aplica el efecto<br />

of.disableAlphaBlending()<br />

123


GAmuza Hybrid live coding / modular application<br />

Además de vincular la clase of.image() a una variable global, se declara otra para la clase ofx.<br />

blur().<br />

En el bloque setup() se le aplican los métodos con el operador “:”. Los parámetros del método<br />

allocated() especifican anchura y altura de la textura a aplicar en el FBO, setRadius() describe<br />

el radio del kernel de desenfoque, cuanto mayor sea el radio, más tiempo de computación se necesita,<br />

shape() describe la circularidad o cuadratura del kernel, para un núcleo más circular se utilizan valores<br />

más pequeños, como 0,2, y para un kernel más cuadrado se usan valores más amplios, como 10.<br />

Finalmente, utilizando los parámetros setPasses() y Downsample(), se puede ejecutar el filtro de<br />

desenfoque múltiple veces a diferentes escalas y ofx.blur() combina los resultados,creando un<br />

efecto similar a la niebla. 60<br />

En el bloque draw()se acota el efecto señalando al inicio nombreVariable:beginFX() y al final<br />

nombreVariable:endFX() esto es necesario cuando se trabaja con texturas FBO y shaders.<br />

Las funciones of.enableAlphaBlending() y of.disableAlphaBlending(), activan y desactivan el<br />

alpha blending de OpenGL, que está desactivado por defecto porque consume más recursos del<br />

ordenador. Por ello se activan los comandos de OpenGL que permiten este tipo particular de blending<br />

necesario para aplicar el desenfoque y después se desactivan.<br />

60 ofxBlur [12.08.2012]<br />

124<br />

3.9. Archivos de video<br />

Sintaxis<br />

of.videoPlayer() Clase de openFrameworks<br />

loadMovie() Método de esta clase<br />

ga.importFile() Función de GAmuza<br />

3. Lenguaje de programación<br />

La clase of.videoPlayer() permite incorporar fácilmente archivos de vídeo a la ventana de salida de<br />

GAmuza, estos archivos deben estar en la carpeta data situada en el ordenador junto al script.<br />

Se vincula la clase of.videoPlayer() a una variable al inicio del programa. Después, al igual que con los<br />

archivos de imagen, en el bloque setup() se le asignan los parámetros de localización con el método,<br />

loadMovie() cuyo parámetro es una función de GAmuza ga.importFile(“nombreArchivo.jpg”)<br />

que localiza ese archivo en la carpeta data, y según las características de reproducción que se deseen,<br />

en loop, una sola vez, o que se repita en loop invertido, se utiliza el método setLoopState() cuyo<br />

parámetro puede ser: OF_LOOP_NONE, para una sola reproducción, OF_LOOP_NORMAL, para reproducción<br />

en loop y OF_LOOP_PALINDROME para reproducción en ida y vuelta.<br />

En el bloque function update() se actualiza cada frame la información del video, ya que es un<br />

objeto en movimento, mediante el método update(). En el bloque function draw() se vincula esa<br />

misma variable al método draw() cuyos 4 parámetros señalan su posición x, y, y las dimensiones de<br />

ancho y alto. En el siguiente ejemplo se establece una fórmula para ajustar el tamaño a las dimensiones<br />

de la ventana de salida, utilizando los métodos getWidth() y getHeight() para obtener el ancho y<br />

alto del video original. También se utiliza el método setPaused() en los bloques mousePressed() y<br />

mouseReleased(), con el parámetro (tue) para detener la reproducción del video, o (false) para<br />

continuar.<br />

/*<br />

GAmuza 0.4.1 examples<br />

---------------------<br />

Video/videoPlayer.ga<br />

creado por n3m3da | www.d3cod3.org<br />

*/<br />

myVideo = of.videoPlayer()<br />

function setup()<br />

myVideo:loadMovie(ga.importFile(“video.mov”))<br />

myVideo:play()<br />

myVideo:setLoopState(OF_LOOP_PALINDROME) // reproducción de ida y vuelta<br />

end<br />

125


GAmuza Hybrid live coding / modular application<br />

126<br />

function update()<br />

myVideo:update()<br />

end<br />

function draw()<br />

ga.background(0.0,1.0)<br />

of.setColor(255)<br />

scaleH = (OUTPUT_W/myVideo:getWidth())*myVideo:getHeight()<br />

myVideo:draw(0,OUTPUT_H/2 - scaleH/2,OUTPUT_W,scaleH)<br />

end<br />

function mousePressed()<br />

myVideo:setPaused(true) // detiene la reproducción<br />

end<br />

function mouseReleased()<br />

myVideo:setPaused(false) // reanuda la reproducción<br />

end<br />

3. Lenguaje de programación<br />

127

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!