// FILE: SomaDisplay.java // PURPOSE: display soma cube solutions // MODS: mckeeman @ digital -- 96.09.25 -- original // METHOD: The solutions were precomputed. See SomaSolutions.java. // The master data for the display is the exterior points of the // 3x3x3 cube (64 total - 8 interior = 56); Each facelet is a // polygon. The color of the facelet is determined by the color // of the soma cube piece occupying its cubelet. There are three // orientations for facelets (perpendicular to x, y, and z axes). // During the construction of the facelets, the coordinates of the // corners are recorded in an array in class Vertices. The facelet // itself points to its corners. All of the vertices can be rotated // together (orthogonal matrix multiply). Each facelet thereby gets // new coordinates for display. The x-y coordinates are used to // place the image. The z coordinate contributes to a computation // which simulates highlighting from above (shadow). // // A particular solution can be picked with the buttons. Each // solution can be physically manipulated by mouse drag. Near the // center of the figure the mouse tumbles the cube in the xz and yz // planes. Near the periphery of the figure the mouse rotates the // figure about the z axis. Double buffering and clipping are // used to minimize flicker. In addition very small rotations are // ignored so that the figure is not redrawn as often. // // Almost all dimenions are hardwired into the display. Screen // resize does not affect centering or scaling. import java.awt.*; import java.applet.*; class Pt { // a point in 3 space double[] v; // the coordinates public Pt(double x, double y, double z) { // ctor v = new double[3]; v[0] = x; v[1] = y; v[2] = z; } public boolean equal(Pt w) { // same x y z coordinates for (int i=0; i<3; i++) { if (v[i] != w.v[i]) return false; } return true; } public void set(double[] w) { // reset coordinates for (int i=0; i0; // positive means vis } public boolean isDown(Face f) { Facelet t = f.f[4]; // center facelet double s = 0; for (int i=0; i<4; i++) { s += vs.vs[t.t[i]].v[1]; // y coord } return s>0; // positive means down } public void drawCube(Graphics g) { for (int i=0; i Math.abs(Y); double dir = ew?sign(dy*X):sign(-dx*Y); // 1 = cclockwise s = s*dir; rotxy(s, c); } private void cubeRotate(double rot[][]){ for (int i=0; i240) solution = 1; } else if (((String)o).equals("-1")) { solution--; if (solution<1) solution = 240; } else if (((String)o).equals("+10")) { solution += 10; if (solution>240) solution -= 240;; } else if (((String)o).equals("-10")) { solution -= 10;; if (solution<1) solution += 240; } number.setText("solution = "+solution); cube = new Cube(solution, screen); showStatus("new solution"); cubeRotate(accrot); offScreenPaint(); repaint(0,0, x2,y2); return true; // all done } return false; // none of my business } public void start() { // applet start showStatus("SomaDisplay started"); } public void stop() { showStatus("SomaDisplay stopped"); } } // end SomaDisplay