/************************************************************************* Demostracion de transformaciones graficas 0.1 (Processing) Copyright (c) 2010, Jorge Ivan Meza Martinez . http://jorgeivanmeza.com/ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Instrucciones: flechas - movimiento del carro q - terminar el sketch r - reiniciar el sketch s - girar a la izquierda d - girar a la derecha a - aumentar el nivel de acercamiento z - disminuir el nivel de acercamiento w - modifica el despliegue del contorno e - modifica el despliegue del grafico Imagen (Toyota Land Cruiser) tomada de OpenClipArt tp://www.openclipart.org/detail/8251 *************************************************************************/ /** * Representa el objeto (carro) a ser mostrado en el mundo grafico. */ class Car { /** * Coordenada X de la posicion */ int x; /** * Coordenada Y de la posicion */ int y; /** * Ancho */ int w; /** * Altura */ int h; /** * Angulo de inclinacion */ float angle; /** * Nivel de aumento */ float level; /** * Tamano del paso para el movimiento */ float stepMove; /** * Tamano del paso para el giro */ float stepTurn; /** * Tamano del paso para el cambio de acercamiento */ float stepZoom; /** * Bandera para mostrar el rectangulo */ boolean showRect; /** * Bandera para mostrar la imagen */ boolean showSprite; /** * Referencia a la imagen */ PImage sprite; /** * Color del fondo del rectangulo */ color background; /** * Constructor del carro * * @param w ancho del carro * @param h alto del carro * @param background color del fondo */ public Car(int w, int h, color background) { // Establece los valores para los atributos del carro this.w = w; this.h = h; this.background = background; // Carga la imagen del carro this.sprite = loadImage("car.png"); // Establece los valores iniciales para los atributos del carro this.reset(); } /** * Establece los valores para los atributos del carro */ public void reset() { // Posicion inicial del carro: mitad del mundo this.x = width / 2; this.y = height / 2; // Inclinacion inicial: cero grados this.angle = 0; // Nivel de aumento inicial: 1x this.level = 1; // Tamanos de los pasos para movimiento, rotacion, corte y aumento this.stepMove = 5; this.stepTurn = PI / 40; this.stepZoom = 0.1; // Valores para mostrar o no las representaciones graficas this.showSprite = true; this.showRect = false; } /** * Genera la representacion grafica del carro */ public void draw() { // Establece el fondo del color especificado fill(this.background); // Si es necesario dibuja el rectangulo del contorno, basada en (0, 0) if(this.showRect) rect(-this.w/2, -this.h/2, this.w, this.h); // Si es necesario dibuja la imagen del carro, basada en (0, 0) if(this.showSprite) image(this.sprite, -this.w/2, -this.h/2, this.w, this.h); } /** * Cambia el estado para mostrar o no el rectangulo del contorno */ public void toggleRect() { this.showRect = !this.showRect; } /** * Cambia el estado para mostrar o no la imagen del carro */ public void toggleSprite() { this.showSprite = !this.showSprite; } /** * Procesa una solicitud de movimiento * * @param direction Direccion del movimiento */ public void move(int direction) { switch(direction) { case UP: this.y -= this.stepMove; break; case DOWN: this.y += this.stepMove; break; case LEFT: this.x -= this.stepMove; break; case RIGHT: this.x += this.stepMove; break; } } /** * Ubica al carro en una posicion precisa * * @param x Coordenada X de la nueva posicion * @param y Coordenada Y de la nueva posicion */ public void locate(int x, int y) { this.x = x; this.y = y; } /** * Procesa una solicitud de giro * * @param direction Direccion del giro */ public void turn(int direction) { switch(direction) { case LEFT: this.angle -= this.stepTurn; break; case RIGHT: this.angle += this.stepTurn; break; } } /** * Procesa una solicitud de cambio del acercamiento * * @param direction Direccion del acercamiento */ public void zoom(int direction) { switch(direction) { case UP: this.level += this.stepZoom; break; case DOWN: this.level -= this.stepZoom; break; } } } ////////////////////////////////////////////////////////////////////// /** * Referencia global al carro */ Car car; ////////////////////////////////////////////////////////////////////// /** * Establece los valores iniciales del sketch */ void setup() { // Tamano de la ventana del sketch size(500, 500); // Dibujar los bordes suaves (anti-aliased) smooth(); // Crear la instancia del carro de 100 x 60 pixels car = new Car(100, 60, color(121, 189, 255)); } /** * Dibuja el contenido grafico del mundo */ void draw() { // Establece el color del fondo (borra el contenido anterior) background(color(255, 255, 255)); ////////////////////////////////////////////////////////////////////// // Almacena los valores de la matriz de transformacion actual en la pila pushMatrix(); // Realiza la translacion del punto de orgien al especificado translate(car.x, car.y); // Realiza la rotacion del plano en la cantidad de radianes especificados rotate(car.angle); // Realiza el cambio de acercamiento en el numero de veces especificadas scale(car.level); // Dibuja el contorno del plano (mundo) fill(255, 255, 255); rect(-car.x, -car.y, width, height); // Dibuja la representacion grafica del carro car.draw(); // Restaura los valores de la matriz de transformacion desde la pila popMatrix(); ////////////////////////////////////////////////////////////////////// // Muestra la informacion de las variables del carro en la ventana showInformation(); } /** * Procesa el evento de presion de las teclas */ void keyPressed() { // Procesa las teclas especiales if(key == CODED) { // Si se realizo un movimiento (teclas del cursor) if(keyCode == LEFT || keyCode == RIGHT || keyCode == UP || keyCode == DOWN) { // Procesar el mensaje del movimiento del carro car.move(keyCode); // Garantiza que el movimiento del carro no excede los limites del mundo car.x = constrain(car.x, 0 + car.w/2, width - car.w/2); car.y = constrain(car.y, 0 + car.h/2, height - car.h/2); } } // Procesa la solicitud de terminar el sketch if(key == 'q') exit(); // Procesa la solicitu de reiniciar los valores del sketch if(key == 'r') car.reset(); // Procesa la solicitud de girar el carro hacia la izquierda if(key == 's') car.turn(LEFT); // Procesa la solicitud de girar el carro hacia la derecha if(key == 'd') car.turn(RIGHT); // Garantiza que el giro del carro no exceda los [-90, 90] car.angle = constrain(car.angle, -PI/2, PI/2); // Procesa el acercamiento del carro if(key == 'a') car.zoom(UP); // Procesa el alejamiento del carro if(key == 'z') { car.zoom(DOWN); // Garantiza que el alejamiento no exceda el valor minimo if(car.level < 0) car.level = 0; } // Procesa el cambio de despliegue del rectangulo del contorno del carro if(key == 'w') car.toggleRect(); // Procesa el cambio de despliegue de la imagen del carro if(key == 'e') car.toggleSprite(); } /** * Procesa el evento de movimiento del raton */ void mouseMoved() { int x = constrain(mouseX, 0 + car.w/2, width - car.w/2); int y = constrain(mouseY, 0 + car.h/2, height - car.h/2); car.locate(x, y); } /** * Muestra la informacion de las variables del carro en la ventana */ void showInformation() { String str = "Car: x = " + car.x + "; y = " + car.y + "; angle = " + nf(degrees(car.angle), 0, 2) + "ยบ; zoom = " + nf(car.level, 0, 2) + "x;"; fill(0, 0, 0); text(str, 10, 15); } //////////////////////////////////////////////////////////////////////