/////////////////////////////////////////////////// // RubikSimul.java // 3D-Simulation des Rubik-Wuerfels // Autor: H. Ring, Universitaet - GH - Siegen, 1996 // // zwei Versionen: // // 1. Applet (benötigt html-Datei zum Start) // Kommentare unveraendert lassen // // 2. Application // hierzu folgende Ergaenzungen aus Kommentar herausnehmen: // - Klasse AppletFrame // - Methode main() der Klasse RubikSimul import java.awt.*; import java.applet.Applet; /*** nur fuer die Application-Version: //////////////////////////////////////////////////////////////////// // AppletFrame // class AppletFrame extends Frame { public static void startApplet (String className, String title) { Applet a; try { a = (Applet) Class.forName(className).newInstance(); } catch (ClassNotFoundException e) {return;} catch (InstantiationException e) {return;} catch (IllegalAccessException e) {return;} a.init(); a.start(); AppletFrame f = new AppletFrame (title); f.add ("Center", a); f.pack(); // passt die Groesse an preferredSize() der Komponenten an f.show(); } public AppletFrame (String name) { super (name); // java.awt.Frame(String) constructor } public boolean handleEvent (Event e) { if (e.id == Event.WINDOW_DESTROY) { System.exit (0); return true; } return super.handleEvent(e); } } ***/ //////////////////////////////////////////////////////////////////// // Projektion // class Point3 { public Point3 () { X = new float[3]; X[0] = 0.0f; X[1] = 0.0f; X[2] = 0.0f; } public Point3 (float x, float y, float z) { X = new float[3]; X[0] = x; X[1] = y; X[2] = z; } // Zur Einsparung von Modulo-Arithmetik public float get (int n) {return X[n%3];} public void set (int n, float value) {X[n%3] = value;} public void inc (int n, float value) {X[n%3] += value;} private float[] X; } class Prj { // private static final int border = 8; private static final int a = 23; // halbe Laenge der projizierten Wuerfelkanten private static final int a2 = 2*a; private static final int b = 40; // a * sqrt(3) /* kleinere Variante // private static final int border = 6; private static final int a = 15; // halbe Laenge der projizierten Wuerfelkanten private static final int a2 = 2*a; private static final int b = 26; // a * sqrt(3) */ private static final int x0 = border + (int)(5.5*b); private static final int y0 = border + (int)(8.5*a); // / \ In Wirklichkeit // y / \ z alle Winkel // \ / \ / im 30°-Raster // \ / \ / // |\ /| // | \ / | // | \ / | // | \ / | // | | | // |.......|..b....| // \ | / // \ a| /a2 // \ | / // \|/ // | // | // x public static Point P2D (Point3 p) { return new Point ((int)(x0 - b*p.get(1) + b*p.get(2)), (int)(y0 + a2*p.get(0) - a*p.get(1) - a*p.get(2))); } public static Dimension preferredSize () { return new Dimension (11 * b + 2*border, (int)(19.5 * a) + 2 * border); } } //////////////////////////////////////////////////////////////////// // Elementarwuerfel // class Cube { private static Color[] color; static { color = new Color[6]; color[0] = new Color (255, 0, 0); // hellrot color[1] = new Color ( 0, 0, 255); // blau color[2] = new Color (255, 255, 255); // weiss color[3] = new Color (255, 255, 0); // gelb color[4] = new Color ( 0, 128, 0); // gruen color[5] = new Color (128, 0, 0); // dunkelrot } public Cube () { face = new int[6]; reset (); } void reset () { for (int i=0; i<6; i++) face[i] = i; } void rotate (int nAxis) { int h = face[ (nAxis+2)%3]; face[ (nAxis+2)%3] = face[3+(nAxis+1)%3]; face[3+(nAxis+1)%3] = face[3+(nAxis+2)%3]; face[3+(nAxis+2)%3] = face[ (nAxis+1)%3]; face[ (nAxis+1)%3] = h; } void paint (Graphics g, Point3 X, boolean back) { // Lage im Gesamtwuerfel // zeigt den Einzelwuerfel als Teil eines n*n*n-Wuerfels // nur die aussenliegenden Flaechen werden gemalt for (int n=0; n<3; n++) { if (X.get(n) == (back ? 2 : 0)) { // Ebene n ? (0=y-z, 1=z-y, 2=x-y) Point P; if (back) X.inc (n, 3.5f); Polygon p = new Polygon(); P = Prj.P2D (X); p.addPoint (P.x, P.y); X.inc(n+1, 1); P = Prj.P2D (X); p.addPoint (P.x, P.y); X.inc(n+2, 1); P = Prj.P2D (X); p.addPoint (P.x, P.y); X.inc(n+1,-1); P = Prj.P2D (X); p.addPoint (P.x, P.y); X.inc(n+2,-1); P = Prj.P2D (X); p.addPoint (P.x, P.y); // Polygon schliessen if (back) X.inc (n, -3.5f); g.setColor (color[face[(n + (back ? 3 : 0)) % 6]]); g.fillPolygon (p); g.setColor (Color.black); g.drawPolygon (p); } } } int[] face; // Farbnummern der Seiten, } // Reihenfolge: x=0, y=0, z=0, x=1, y=1, z=1 //////////////////////////////////////////////////////////////////// // Rubik-Wuerfel // class RubikCube { RubikCube () { cube = new Cube[N][N][N]; for (int x=0; x0; i--) cube[X[i]][Y[i]][Z[i]] = cube[X[i-1]][Y[i-1]][Z[i-1]]; cube[X[0]][Y[0]][Z[0]] = h; } } } } private boolean bPreview; // Richtungspfeil zeigen private int nAxis; // \. private int nLevel; // > Daten für Richtungspfeil private int nRot; // / boolean getMouseInfo (int xM, int yM) { Point[] P = new Point[4]; for (int n=0; n<3; n++) { // Mausklick in Ebene n ? Point3 X = new Point3 (0,0,0); // (0=y-z, 1=z-y, 2=x-y) //X[n] = 0; for (int i=0; i