import java.awt.geom.*; import java.awt.*; import java.lang.Math; import java.util.*; /** * Representacion grafica 3D de un cubo rubik completo. */ public class FigRubik { /** * Posicion de la camara (observador o punto de vista). */ private Point3D camPos; /** * Ejes de la camara. Definen que direcciones en el espacio 3D * corresonderian a las direcciones en el plano 2D. * Ejemplo, una linea 3D paralela a 'camEje.h' se veria en pantalla como * una linea horizontal. */ private Ejes3D camEje; /** * Arrego de Piezas (3x3x3=27) que forman un cubo rubik completo. */ private ArrayList piezaList; /** * Modelo logico del cubo rubik asociado a este modelo grafico. */ private ModRubik modelo; /** * Crea un FigRubik sin colores definidos. */ public FigRubik(ModRubik mod) { camPos = new Point3D(12f,8f,8f); camEje = new Ejes3D(camPos, new Point3D()); piezaList = new ArrayList(); int x, y, z; for (x=0; x<3; x++) for (y=0; y<3; y++) for (z=0; z<3; z++) { piezaList.add(new Pieza(x-1, y-1, z-1, 0,0,0,0,0,0)); } Pieza.setVista(camPos); modelo = mod; } /** * Cambia la referencia al modelo logico del cubo rubik. * @param mod Nuevo modelo. */ public void setModelo(ModRubik mod) { modelo = mod; } /* public Point2D.Float getPos2D(Point3D p) { Point3D pt = p.clone(); pt.menos(camPos); pt.normalizar(camEje); float x = pt.getY() / -pt.getX(); float y = pt.getZ() / pt.getX(); return new Point2D.Float(x, y); } */ /** * Retorna una lista de Triangulos, que son los que se deberian dibujar * en pantalla para que el cubo rubik se vea correctamente. * @return Una lista de Triangulos. */ public ArrayList getTrianList() { Collections.sort(piezaList); ArrayList retList = new ArrayList(); //para return int p, c; Cara3D cara; Point3D v0, v1, v2; Pieza piezaTemp; float p0x, p0y, p1x, p1y, p2x, p2y; for (p=0; p<27; p++) { piezaTemp = piezaList.get(p).clone(); // IMPORTANTE el clone() piezaTemp.normalizar(); for (c=0; c<12; c++) { cara = piezaTemp.getCaraArray()[c]; v0 = cara.getVertices()[0].clone(); // v1 = cara.getVertices()[1].clone(); // IMPORTANTES los clone() v2 = cara.getVertices()[2].clone(); // v0.menos(camPos); v1.menos(camPos); v2.menos(camPos); v0.normalizar(camEje); v1.normalizar(camEje); v2.normalizar(camEje); if (cara.getVectorNormal().pPunto(camEje.getD()) > 0.2) { p0x = v0.getY() / -v0.getX() + 0.1f; p0y = v0.getZ() / v0.getX(); p1x = v1.getY() / -v1.getX() + 0.1f; p1y = v1.getZ() / v1.getX(); p2x = v2.getY() / -v2.getX() + 0.1f; p2y = v2.getZ() / v2.getX(); } else if (cara.getColor() != 0) { p0x = v0.getY() / -v0.getX() / 2 - 0.4f; p0y = v0.getZ() / v0.getX() / 2; p1x = v1.getY() / -v1.getX() / 2 - 0.4f; p1y = v1.getZ() / v1.getX() / 2; p2x = v2.getY() / -v2.getX() / 2 - 0.4f; p2y = v2.getZ() / v2.getX() / 2; } else continue; retList.add(new Triangulo(p0x, p0y, p1x, p1y, p2x, p2y, cara.getColor())); } } return retList; } /** * Invoca el metodo 'ajustar()' de cada una de la 27 Piezas que forman el * cubo rubik. */ public void ajustar() { float x, y, z; for (int i=0; i<27; i++) piezaList.get(i).ajustar(); } /** * Interpreta el comando 'com' y lo traduce en un giro del cubo rubik * completo o solo una de sus capas. * @param com Tipo de giro que debe hacer el cubo rubik. * @param grados Grados (sexagesimales) del giro. */ public void mover(String com, float grados) { if (com.equals("X ")) for (int i=0; i<27; i++) piezaList.get(i).rotar_X(grados); else if (com.equals("X' ")) for (int i=0; i<27; i++) piezaList.get(i).rotar_X(-grados); if (com.equals("Y ")) for (int i=0; i<27; i++) piezaList.get(i).rotar_Y(grados); else if (com.equals("Y' ")) for (int i=0; i<27; i++) piezaList.get(i).rotar_Y(-grados); else if (com.equals("Z ")) for (int i=0; i<27; i++) piezaList.get(i).rotar_Z(grados); else if (com.equals("Z' ")) for (int i=0; i<27; i++) piezaList.get(i).rotar_Z(-grados); else //--- if (com.equals("A ")) for (int i=0; i<27; i++) { if (piezaList.get(i).getCentro().getZ() > 1.5) piezaList.get(i).rotar_Z(grados); } else if (com.equals("A' ")) for (int i=0; i<27; i++) { if (piezaList.get(i).getCentro().getZ() > 1.5) piezaList.get(i).rotar_Z(-grados); } else if (com.equals("I ")) for (int i=0; i<27; i++) { if (piezaList.get(i).getCentro().getY() < -1.5) piezaList.get(i).rotar_Y(-grados); } else if (com.equals("I' ")) for (int i=0; i<27; i++) { if (piezaList.get(i).getCentro().getY() < -1.5) piezaList.get(i).rotar_Y(grados); } else if (com.equals("F ")) for (int i=0; i<27; i++) { if (piezaList.get(i).getCentro().getX() > 1.5) piezaList.get(i).rotar_X(grados); } else if (com.equals("F' ")) for (int i=0; i<27; i++) { if (piezaList.get(i).getCentro().getX() > 1.5) piezaList.get(i).rotar_X(-grados); } else if (com.equals("D ")) for (int i=0; i<27; i++) { if (piezaList.get(i).getCentro().getY() > 1.5) piezaList.get(i).rotar_Y(grados); } else if (com.equals("D' ")) for (int i=0; i<27; i++) { if (piezaList.get(i).getCentro().getY() > 1.5) piezaList.get(i).rotar_Y(-grados); } else if (com.equals("T ")) for (int i=0; i<27; i++) { if (piezaList.get(i).getCentro().getX() < -1.5) piezaList.get(i).rotar_X(-grados); } else if (com.equals("T' ")) for (int i=0; i<27; i++) { if (piezaList.get(i).getCentro().getX() < -1.5) piezaList.get(i).rotar_X(grados); } else if (com.equals("B ")) for (int i=0; i<27; i++) { if (piezaList.get(i).getCentro().getZ() < -1.5) piezaList.get(i).rotar_Z(-grados); } else if (com.equals("B' ")) for (int i=0; i<27; i++) { if (piezaList.get(i).getCentro().getZ() < -1.5) piezaList.get(i).rotar_Z(grados); } } /** * Asigna a cada Cara3D el valor indicado por el modelo logico (ModRubik). */ public void pintar() { int x, y, z, t=0, f=0, c=0; for (int p=0; p<27; p++) { Pieza pieza = piezaList.get(p); for (int ca=0; ca<12; ca++) { boolean caraInterior = false; Cara3D cara = pieza.getCaraArray()[ca]; x = (int)Math.rint(cara.getCentro().getX()); y = (int)Math.rint(cara.getCentro().getY()); z = (int)Math.rint(cara.getCentro().getZ()); if (z >= 3) { t = 0; f = x/2 + 1; c = y/2 + 1; } else if (y <= -3) { t = 1; f = -z/2 + 1; c = x/2 + 1; } else if (x >= 3) { t = 2; f = -z/2 + 1; c = y/2 + 1; } else if (y >= 3) { t = 3; f = -z/2 + 1; c = -x/2 + 1; } else if (x <= -3) { t = 4; f = -z/2 + 1; c = -y/2 + 1; } else if (z <= -3) { t = 5; f = -x/2 + 1; c = y/2 + 1; } else caraInterior = true; if (caraInterior) cara.setColor(0); else cara.setColor(modelo.getCara(t).getArreglo()[f][c]); } } } }