Вы находитесь на странице: 1из 11

ROTACION DE UN CUBO

Se muestra una manera sencilla de graficar y rotar un Cubo. Se comienza con la teora de transformaciones lineales y proyecciones en el plano, se describen las matrices de rotacin y al final se muestra un cdigo muy sencillo de una aplicacin hecha en Java que ejemplifica y muestra las transformaciones descritas. Introduccin Se puede rotar una figura en tres dimensiones, sobre el eje X, sobre el eje Y o sobre el eje Z. En el caso de una computadora, la pantalla es un espacio de dos dimensiones, por lo tanto hay que hacer una proyeccin sobre el plano XY cada vez que se manipulen figuras tridimensionales.

Existe un vector en el plano R2 con coordenadas (x, y) y un ngulo con respecto al eje X, se desea rotar el vector en un ngulo en sentido contrario de las manecillas del reloj con respecto al eje X. El nuevo vector forma un ngulo + respecto al vector y existe la misma longitud r en ambos vectores como se muestra en la figura:

Utilizando las definiciones de seno y coseno obtenemos que para el vector

Para el vector

, de forma similar, se obtiene que:

La suma de dos ngulos esta dada por:

Si se considera r = 1 y se sustituyen los valores correspondientes de x e y de la figura 1 tenemos.

Escribiendo las mismas ecuaciones en forma de matrices se obtiene:

La matriz (1) es mejor conocida como matriz de rotacin, la cual determina las nuevas coordenadas (x, y) obtenidas por rotar un ngulo un punto (x, y) en sentido contrario de las manecillas del reloj. Si las rotaciones se quieren hacer en el espacio R3, se necesita considerar el valor del eje de rotacin (en el cual se desea girar) igual a uno y poner el resto de los valores igual a cero. En el caso de la matriz (1) se considera que rota con respecto al eje z.

Las matrices de rotacin correspondientes a cada uno de los ejes estn dadas por:

Para poder mostrar la rotacin en tres dimensiones en un plano de dos dimensiones hay que hacer una proyeccin. Una proyeccin es una trasnformacin lineal que toma un punto en el espacio de tres dimensiones y lo proyecta en un plano, que en este caso sera el plano xy. La matriz de transfomacin que nos brinda la proyeccin de un punto en el plano xy es:

Ahora vamos a usar las matrices anteriores para tratar de rotar un cubo. Para construir un cubo se pueden tomar una lista de vrtices, aristas o caras, para ejemplos ilustrativos vamos a tomar una lista de ocho vrtices y vamos a enumerarlos como sigue:

Si trazamos lineas que unan los vrtices de forma tal que formen las aristas del cubo, se obtiene la siguiente figura:

La figura 3 muestra un cubo centrado en el origen pero a pesar de que la figura mostrada aparenta ser un cuadrado (dos dimensiones) se sabe que tiene una tercera dimensin dado que tiene las tres coordenadas en cada uno de sus ocho vrtices, pero al proyectar sus puntos en el plano xy todos los valores z de los puntos son "planchados" al plano xy. Para

darse cuenta de la forma tridimensional de la figura basta con rotar los puntos del cubo sobre el eje x o sobre el eje y.

El cubo aparenta estar representado en el espacio de tres dimensiones, pero carece de volumen, propiedad tpica de los cuerpos tridimensionales. Para lograr una apariencia de volumen se necesitan crear diferentes polgonos que representen cada una de las caras del cubo, los vrtices de cada cara del cubo sern los vrtices de cada polgono y se puede asignar un color diferente a cada uno de ellos como se muestra.

Para ilustrar mejor lo antes mencionado, se contruy un applet que muestra un cubo en 3D el cual puede rotar utlizando las matrices descritas.

CODIGO FUENTE DE LA ROTACION DE UN CUBO

import import import import import

java.applet.*; java.awt.*; java.awt.event.*; java.lang.Math; java.awt.Polygon;

/* Represents a point in space */ class Point{ public double x; public double y; public double z; Point(){ this.x=0; this.y=0; this.z=0; } Point(double x,double y, double z){ this.x=x; this.y=y; this.z=z; } /* for move it at origin */ int getXCoordinate(){return Cube.origin + (int)this.x;} int getYCoordinate(){return Cube.origin - (int)this.y;} int getZCoordinate(){return 0;} /* projection on XY plane*/ } class Face{ Point p1,p2,p3,p4; Polygon side= new Polygon(); Face(){} Face(Point p1,Point p2,Point p3,Point p4){ this.p1=p1;this.p2=p2;this.p3=p3;this.p4=p4; this.side.addPoint(p1.getXCoordinate(),p1.getYCoordinate()); this.side.addPoint(p2.getXCoordinate(),p2.getYCoordinate()); this.side.addPoint(p3.getXCoordinate(),p3.getYCoordinate()); this.side.addPoint(p4.getXCoordinate(),p4.getYCoordinate()); }

public void drawFace(Graphics g){ g.fillPolygon(side); } public boolean isVisible(){ Point aux1, aux2; aux1 = new Point(p2.x-p1.x, p2.y-p1.y, p2.z-p1.z); // p1->p2 aux2 = new Point(p4.x-p1.x, p4.y-p1.y, p4.z-p1.z); // p1->p4 if((aux1.x*aux2.y - aux1.y*aux2.x) > 0) return true; return false; }} public class Cube extends Applet implements Runnable, MouseMotionListener{ Thread luxury; static Point[] vertex = new Point[8]; // Cube vertexes static int maxSize =300; // screen size static int origin = maxSize/2; // (0,0) static int xMouseP=0, yMouseP =0; // X and Y mouse's positions int xAux , yAux ; // old X and Y mouse's positions int module = 50; // length of lines of cube. Image canvasAux; Graphics backBuffer; public void init(){ setSize(maxSize,maxSize); setBackground( new Color(0.2f,0.6f,0.1f,1.0f) ); addMouseMotionListener(this); /*Initial coordinates of eight vertex module is half the length of the cube*/ int[] coordX = new int[]{-module,module,module,-module,module,module,module,-module}; int[] coordY = new int[]{-module,-module,module,module,-module,module,module,module};

int[] coordZ = new int[]{module,module,module,module,-module,-module,module,-module}; canvasAux = createImage(500,500); backBuffer = canvasAux.getGraphics(); for(int i =0; i<vertex.length; i++){ vertex[i] = new Point(coordX[i],coordY[i],coordZ[i]); }} public void start(){ try { luxury = new Thread(this); luxury.start(); } catch (Exception e){} } public void run() {} public void stop(){} public void paint(Graphics g){ /* Cube's points. Requires four points to create a face, requires six faces to create a cube.*/ int[] pts1 = new int[]{0,1,5,0,0,3}; int[] pts2 = new int[]{1,5,4,3,4,2}; int[] pts3 = new int[]{2,6,7,7,5,6}; int[] pts4 = new int[]{3,2,6,4,1,7}; Color[] colorRGB = new Color[]{ Color.black, Color.blue,Color.orange, Color.pink,Color.red, Color.yellow}; Face[] faces = new Face[6]; backBuffer.clearRect(0,0,500,500); for(int i=0; i<6; i++){ backBuffer.setColor(colorRGB[i]); faces[i] = new Face(vertex[pts1[i]],vertex[pts2[i]],vertex[pts3[i]],vertex[pts4[i]]); if(faces[i].isVisible()){

faces[i].drawFace(backBuffer); } } g.drawImage(canvasAux,0,0,this); g.drawString(" Touche ", 30,30); g.drawString(" X " + xMouseP, 30,50); g.drawString(" Y " + yMouseP, 30,65); return; } public void update(Graphics g){ paint(g); } public void destroy(){ try {Thread.sleep(1500);} catch (InterruptedException e) { System.out.println("Exception in sleep"); }} /* Rotate each vertex of cube over X, Y and Z axis */ void rota(double angleTeta, double anglePhi, double anglePsi) { double teta= Math.toRadians(angleTeta); double phi= Math.toRadians(anglePhi); double psi= Math.toRadians(anglePsi); Point pAux = new Point(); Point pAux1 = new Point(); Point pAux2 = new Point(); for(int i =0; i<8; i++){ /* Rotating over x */ pAux1.x = vertex[i].x; pAux1.y= vertex[i].y * Math.cos(teta) + vertex[i].z * (-Math.sin(teta)); pAux1.z = vertex[i].y * Math.sin(teta) + vertex[i].z * Math.cos(teta); /* Rotating over y */

pAux2.x = pAux1.x * Math.cos(phi) + pAux1.z * Math.sin(phi); pAux2.y = pAux1.y; pAux2.z = pAux1.x * (-Math.sin(phi)) + pAux1.z * Math.cos(phi); /* Rotating over z */ pAux.x= pAux2.x * Math.cos(psi) + pAux2.y * (-Math.sin(psi)); pAux.y = pAux2.x * Math.sin(psi) + pAux2.y * Math.cos(psi); pAux.z= pAux2.z; /* new position */ vertex[i].x = pAux.x; vertex[i].y = pAux.y; vertex[i].z = pAux.z; }} /* For move the cube over X and Y axis */ public void mouseDragged( MouseEvent e ){ /* old coordinates */ xAux = xMouseP; yAux = yMouseP; /* new coordinates */ xMouseP = e.getX(); yMouseP = e.getY(); if(yMouseP > yAux){ rota(2,0,0); } if(yMouseP < yAux){ rota(-2,0,0); } if(xMouseP > xAux){ rota(0,2,0); } if(xMouseP < xAux){ rota(0,-2,0); } repaint(); e.consume(); } public void mouseMoved( MouseEvent e ) { } }

Вам также может понравиться