Project

General

Profile

Download (13.8 KB) Statistics
| Branch: | Tag: | Revision:

magiccube / src / main / java / org / distorted / objects / TwistyCube.java @ 0ad6b867

1 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 Leszek Koltunski                                                               //
3
//                                                                                               //
4 fdec60a3 Leszek Koltunski
// This file is part of Magic Cube.                                                              //
5 0c52af30 Leszek Koltunski
//                                                                                               //
6 fdec60a3 Leszek Koltunski
// Magic Cube is free software: you can redistribute it and/or modify                            //
7 0c52af30 Leszek Koltunski
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11 fdec60a3 Leszek Koltunski
// Magic Cube is distributed in the hope that it will be useful,                                 //
12 0c52af30 Leszek Koltunski
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17 fdec60a3 Leszek Koltunski
// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
18 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
19
20 1f9772f3 Leszek Koltunski
package org.distorted.objects;
21 0c52af30 Leszek Koltunski
22 ccf9fec5 Leszek Koltunski
import android.content.res.Resources;
23 0c52af30 Leszek Koltunski
24 f10a88a8 Leszek Koltunski
import org.distorted.helpers.ObjectShape;
25 9c06394a Leszek Koltunski
import org.distorted.helpers.ObjectSticker;
26 0c52af30 Leszek Koltunski
import org.distorted.library.main.DistortedEffects;
27
import org.distorted.library.main.DistortedTexture;
28 efa8aa48 Leszek Koltunski
import org.distorted.library.mesh.MeshSquare;
29 0c52af30 Leszek Koltunski
import org.distorted.library.type.Static3D;
30
import org.distorted.library.type.Static4D;
31 6fd4a72c Leszek Koltunski
import org.distorted.main.R;
32 0c52af30 Leszek Koltunski
33 7c969a6d Leszek Koltunski
import java.util.Random;
34
35 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
36
37 9c2f0c91 Leszek Koltunski
class TwistyCube extends TwistyObject
38 0c52af30 Leszek Koltunski
{
39 e844c116 Leszek Koltunski
  // the three rotation axis of a RubikCube. Must be normalized.
40 ad38d800 Leszek Koltunski
  static final Static3D[] ROT_AXIS = new Static3D[]
41 efef689c Leszek Koltunski
         {
42
           new Static3D(1,0,0),
43
           new Static3D(0,1,0),
44
           new Static3D(0,0,1)
45
         };
46
47 925ed78f Leszek Koltunski
  private static final int[] BASIC_ANGLE = new int[] { 4,4,4 };
48
49 37a25788 Leszek Koltunski
  private static final int[] FACE_COLORS = new int[]
50 efef689c Leszek Koltunski
         {
51 ece1b58d Leszek Koltunski
           COLOR_YELLOW, COLOR_WHITE,
52
           COLOR_BLUE  , COLOR_GREEN,
53 323b217c Leszek Koltunski
           COLOR_RED   , COLOR_ORANGE
54 efef689c Leszek Koltunski
         };
55
56 10585385 Leszek Koltunski
  // All legal rotation quats of a RubikCube of any size.
57 efef689c Leszek Koltunski
  // Here's how to compute this:
58
  // 1) compute how many rotations there are (RubikCube of any size = 24)
59
  // 2) take the AXIS, angles of rotation (90 in RubikCube's case) compute the basic quaternions
60
  // (i.e. rotations of 1 basic angle along each of the axis) and from there start semi-randomly
61
  // multiplying them and eventually you'll find all (24) legal rotations.
62 9f4c44fe Leszek Koltunski
  // Example program in C, res/raw/compute_quats.c , is included.
63 10585385 Leszek Koltunski
  private static final Static4D[] QUATS = new Static4D[]
64 efef689c Leszek Koltunski
         {
65 10585385 Leszek Koltunski
         new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),
66
         new Static4D(  1.0f,   0.0f,   0.0f,   0.0f),
67
         new Static4D(  0.0f,   1.0f,   0.0f,   0.0f),
68
         new Static4D(  0.0f,   0.0f,   1.0f,   0.0f),
69
70
         new Static4D( SQ2/2,  SQ2/2,  0.0f ,   0.0f),
71
         new Static4D( SQ2/2, -SQ2/2,  0.0f ,   0.0f),
72
         new Static4D( SQ2/2,   0.0f,  SQ2/2,   0.0f),
73
         new Static4D(-SQ2/2,   0.0f,  SQ2/2,   0.0f),
74
         new Static4D( SQ2/2,   0.0f,   0.0f,  SQ2/2),
75
         new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),
76
         new Static4D(  0.0f,  SQ2/2,  SQ2/2,   0.0f),
77
         new Static4D(  0.0f,  SQ2/2, -SQ2/2,   0.0f),
78
         new Static4D(  0.0f,  SQ2/2,   0.0f,  SQ2/2),
79
         new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),
80
         new Static4D(  0.0f,   0.0f,  SQ2/2,  SQ2/2),
81
         new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),
82
83
         new Static4D(  0.5f,   0.5f,   0.5f,   0.5f),
84
         new Static4D(  0.5f,   0.5f,  -0.5f,   0.5f),
85
         new Static4D(  0.5f,   0.5f,  -0.5f,  -0.5f),
86
         new Static4D(  0.5f,  -0.5f,   0.5f,  -0.5f),
87
         new Static4D( -0.5f,  -0.5f,  -0.5f,   0.5f),
88
         new Static4D( -0.5f,   0.5f,  -0.5f,  -0.5f),
89
         new Static4D( -0.5f,   0.5f,   0.5f,  -0.5f),
90
         new Static4D( -0.5f,   0.5f,   0.5f,   0.5f)
91 efef689c Leszek Koltunski
         };
92 411c6285 Leszek Koltunski
93 b1f2ccf5 Leszek Koltunski
  private static final double[][] VERTICES = new double[][]
94
          {
95
              { 0.5, 0.5, 0.5 },
96
              { 0.5, 0.5,-0.5 },
97
              { 0.5,-0.5, 0.5 },
98
              { 0.5,-0.5,-0.5 },
99
              {-0.5, 0.5, 0.5 },
100
              {-0.5, 0.5,-0.5 },
101
              {-0.5,-0.5, 0.5 },
102
              {-0.5,-0.5,-0.5 },
103
          };
104
105
  private static final int[][] VERT_INDEXES = new int[][]
106
          {
107
              {2,3,1,0},   // counterclockwise!
108
              {7,6,4,5},
109
              {4,0,1,5},
110
              {7,3,2,6},
111
              {6,2,0,4},
112
              {3,7,5,1}
113
          };
114
115
  private static final float[][] STICKERS = new float[][]
116
          {
117
              { -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f }
118
          };
119
120 9c06394a Leszek Koltunski
  private static final ObjectSticker[] mStickers;
121
122
  static
123
    {
124
    final float radius = 0.10f;
125
    final float stroke = 0.08f;
126
    final float[] radii = {radius,radius,radius,radius};
127
    mStickers = new ObjectSticker[STICKERS.length];
128
    mStickers[0] = new ObjectSticker(STICKERS[0],null,radii,stroke );
129
    }
130
131 411c6285 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
132
133 9c2f0c91 Leszek Koltunski
  TwistyCube(int size, Static4D quat, DistortedTexture texture,
134
             MeshSquare mesh, DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
135 411c6285 Leszek Koltunski
    {
136 db875721 Leszek Koltunski
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.CUBE, res, scrWidth);
137 411c6285 Leszek Koltunski
    }
138
139 a480ee80 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
140
141
  int[] getSolvedQuats(int cubit, int numLayers)
142
    {
143
    int status = retCubitSolvedStatus(cubit,numLayers);
144
    return status<0 ? null : buildSolvedQuats(MovementCube.FACE_AXIS[status],QUATS);
145
    }
146
147 f10a88a8 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
148
149
  ObjectShape getObjectShape(int cubit, int numLayers)
150
    {
151
    int extraI, extraV, num;
152
    float height;
153
154
    switch(numLayers)
155
      {
156
      case 2 : num = 6; extraI = 2; extraV = 2; height = 0.045f; break;
157
      case 3 : num = 5; extraI = 2; extraV = 2; height = 0.045f; break;
158
      case 4 : num = 5; extraI = 1; extraV = 1; height = 0.045f; break;
159
      default: num = 5; extraI = 0; extraV = 0; height = 0.045f; break;
160
      }
161
162
    float[][] bands     = new float[][] { {height,35,0.5f,0.7f,num,extraI,extraV} };
163
    int[] bandIndices   = new int[] { 0,0,0,0,0,0};
164
    float[][] corners   = new float[][] { {0.036f,0.12f} };
165
    int[] cornerIndices = new int[] { 0,0,0,0,0,0,0,0 };
166
    float[][] centers   = new float[][] { {0.0f, 0.0f, 0.0f} };
167
    int[] centerIndices = new int[] { 0,0,0,0,0,0,0,0 };
168
169
    return new ObjectShape(VERTICES,VERT_INDEXES,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
170
    }
171
172 ac940e24 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
173
174 3e605536 Leszek Koltunski
  Static4D getQuat(int cubit, int numLayers)
175 ac940e24 Leszek Koltunski
    {
176 3e605536 Leszek Koltunski
    return QUATS[0];
177
    }
178 f10a88a8 Leszek Koltunski
179 3e605536 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
180 ac940e24 Leszek Koltunski
181 3e605536 Leszek Koltunski
  int getNumCubitVariants(int numLayers)
182
    {
183
    return 1;
184
    }
185 ac940e24 Leszek Koltunski
186 3e605536 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
187 f10a88a8 Leszek Koltunski
188 3e605536 Leszek Koltunski
  int getCubitVariant(int cubit, int numLayers)
189
    {
190
    return 0;
191 ac940e24 Leszek Koltunski
    }
192
193 7289fd6c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
194
195 9c06394a Leszek Koltunski
  int getColor(int face)
196 7289fd6c Leszek Koltunski
    {
197 9c06394a Leszek Koltunski
    return FACE_COLORS[face];
198
    }
199
200
///////////////////////////////////////////////////////////////////////////////////////////////////
201 7289fd6c Leszek Koltunski
202 9c06394a Leszek Koltunski
  ObjectSticker retSticker(int face)
203
    {
204
    return mStickers[face/NUM_FACES];
205 7289fd6c Leszek Koltunski
    }
206
207 411c6285 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
208
209 b1f2ccf5 Leszek Koltunski
  float[][] getCubitPositions(int numLayers)
210 a10ada2a Leszek Koltunski
    {
211 b1f2ccf5 Leszek Koltunski
    int numCubits = numLayers>1 ? 6*numLayers*numLayers - 12*numLayers + 8 : 1;
212 e6cf7283 Leszek Koltunski
    float[][] tmp = new float[numCubits][];
213 beb325a0 Leszek Koltunski
214 b1f2ccf5 Leszek Koltunski
    float diff = 0.5f*(numLayers-1);
215 a10ada2a Leszek Koltunski
    int currentPosition = 0;
216 beb325a0 Leszek Koltunski
217 b1f2ccf5 Leszek Koltunski
    for(int x = 0; x<numLayers; x++)
218
      for(int y = 0; y<numLayers; y++)
219
        for(int z = 0; z<numLayers; z++)
220
          if( x==0 || x==numLayers-1 || y==0 || y==numLayers-1 || z==0 || z==numLayers-1 )
221 beb325a0 Leszek Koltunski
            {
222 e6cf7283 Leszek Koltunski
            tmp[currentPosition++] = new float[] {x-diff,y-diff,z-diff};
223 a10ada2a Leszek Koltunski
            }
224 47ba5ddc Leszek Koltunski
225 a10ada2a Leszek Koltunski
    return tmp;
226
    }
227 47ba5ddc Leszek Koltunski
228 beb325a0 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
229
230 10585385 Leszek Koltunski
  Static4D[] getQuats()
231 a10ada2a Leszek Koltunski
    {
232 10585385 Leszek Koltunski
    return QUATS;
233 a10ada2a Leszek Koltunski
    }
234 47ba5ddc Leszek Koltunski
235 eaee1ddc Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
236
237
  boolean shouldResetTextureMaps()
238
    {
239
    return false;
240
    }
241
242 47ba5ddc Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
243
244 411c6285 Leszek Koltunski
  int getNumFaces()
245 a10ada2a Leszek Koltunski
    {
246 411c6285 Leszek Koltunski
    return FACE_COLORS.length;
247 8f53e513 Leszek Koltunski
    }
248
249 7403cdfa Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
250
251 e6734aa9 Leszek Koltunski
  float[][] getCuts(int numLayers)
252 7403cdfa Leszek Koltunski
    {
253 e6734aa9 Leszek Koltunski
    float[][] cuts = new float[3][numLayers-1];
254 a97e02b7 Leszek Koltunski
255 a64e07d0 Leszek Koltunski
    for(int i=0; i<numLayers-1; i++)
256 a97e02b7 Leszek Koltunski
      {
257 e6734aa9 Leszek Koltunski
      float cut = (2-numLayers)*0.5f + i;
258
      cuts[0][i] = cut;
259
      cuts[1][i] = cut;
260
      cuts[2][i] = cut;
261 a97e02b7 Leszek Koltunski
      }
262
263
    return cuts;
264 7403cdfa Leszek Koltunski
    }
265
266 169219a7 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
267
268
  int getSolvedFunctionIndex()
269
    {
270
    return 0;
271
    }
272
273 eab9d8f8 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
274
275 a64e07d0 Leszek Koltunski
  int getNumStickerTypes(int numLayers)
276 eab9d8f8 Leszek Koltunski
    {
277 b1f2ccf5 Leszek Koltunski
    return STICKERS.length;
278 eab9d8f8 Leszek Koltunski
    }
279
280 8f53e513 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
281
282
  int getNumCubitFaces()
283
    {
284
    return FACE_COLORS.length;
285 411c6285 Leszek Koltunski
    }
286 47ba5ddc Leszek Koltunski
287 f0fa83ae Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
288
289
  float getScreenRatio()
290
    {
291
    return 0.5f;
292
    }
293
294 f6d06256 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
295
296 f10a88a8 Leszek Koltunski
  int getFaceColor(int cubit, int cubitface, int numLayers)
297 f6d06256 Leszek Koltunski
    {
298 f10a88a8 Leszek Koltunski
    return CUBITS[cubit].mRotationRow[cubitface/2] == (cubitface%2==0 ? (1<<(numLayers-1)):1) ? cubitface : NUM_FACES;
299 f6d06256 Leszek Koltunski
    }
300
301 fb377dae Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
302
303
  float returnMultiplier()
304
    {
305 d99f3a48 Leszek Koltunski
    return getNumLayers();
306 fb377dae Leszek Koltunski
    }
307
308 e844c116 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
309
// PUBLIC API
310
311 12ad3fca Leszek Koltunski
  public Static3D[] getRotationAxis()
312
    {
313 ad38d800 Leszek Koltunski
    return ROT_AXIS;
314 12ad3fca Leszek Koltunski
    }
315
316
///////////////////////////////////////////////////////////////////////////////////////////////////
317
318 925ed78f Leszek Koltunski
  public int[] getBasicAngle()
319 e844c116 Leszek Koltunski
    {
320 925ed78f Leszek Koltunski
    return BASIC_ANGLE;
321 e844c116 Leszek Koltunski
    }
322 39e74052 Leszek Koltunski
323 7c969a6d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
324
325 9f171eba Leszek Koltunski
  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int total)
326 7c969a6d Leszek Koltunski
    {
327 9f171eba Leszek Koltunski
    if( curr==0 )
328 5cf34c5f Leszek Koltunski
      {
329 9f171eba Leszek Koltunski
      scramble[curr][0] = rnd.nextInt(NUM_AXIS);
330 7c969a6d Leszek Koltunski
      }
331
    else
332
      {
333 8e6dc249 Leszek Koltunski
      int newVector = rnd.nextInt(NUM_AXIS-1);
334 9f171eba Leszek Koltunski
      scramble[curr][0] = (newVector>=scramble[curr-1][0] ? newVector+1 : newVector);
335 8e6dc249 Leszek Koltunski
336
      // All three axis must be present among every four consecutive rotations.
337
      // Otherwise in case of odd-sized cubes we can get four consecutive rotations
338
      // that collapse to a NOP
339
      // (X,midLayer,180)->(Y,midLayer,180)->(X,midLayer,180)->(Y,midLayer,180) = NOP
340
      if( curr>=3 && scramble[curr-1][0]==scramble[curr-3][0] )
341
        {
342
        for( int ax=0; ax<NUM_AXIS; ax++)
343
          {
344
          if( scramble[curr-1][0]!=ax && scramble[curr-2][0]!=ax )
345
            {
346
            scramble[curr][0] = ax;
347
            break;
348
            }
349
          }
350
        }
351 5cf34c5f Leszek Koltunski
      }
352
353 7c969a6d Leszek Koltunski
    float rowFloat = rnd.nextFloat();
354 0203be88 Leszek Koltunski
    int numLayers = getNumLayers();
355 7c969a6d Leszek Koltunski
356 0203be88 Leszek Koltunski
    for(int row=0; row<numLayers; row++)
357 7c969a6d Leszek Koltunski
      {
358 0203be88 Leszek Koltunski
      if( rowFloat*numLayers <= row+1 )
359 bbc6471c Leszek Koltunski
        {
360 9f171eba Leszek Koltunski
        scramble[curr][1] = row;
361 bbc6471c Leszek Koltunski
        break;
362
        }
363 7c969a6d Leszek Koltunski
      }
364
365 5043d5d0 Leszek Koltunski
    switch( rnd.nextInt(4) )
366
      {
367 9f171eba Leszek Koltunski
      case 0: scramble[curr][2] = -2; break;
368
      case 1: scramble[curr][2] = -1; break;
369
      case 2: scramble[curr][2] =  1; break;
370
      case 3: scramble[curr][2] =  2; break;
371 5043d5d0 Leszek Koltunski
      }
372 e46e17fb Leszek Koltunski
    }
373 f0336037 Leszek Koltunski
374
///////////////////////////////////////////////////////////////////////////////////////////////////
375 6fd4a72c Leszek Koltunski
376
  public int getObjectName(int numLayers)
377
    {
378
    switch(numLayers)
379
      {
380
      case 2: return R.string.cube2;
381
      case 3: return R.string.cube3;
382
      case 4: return R.string.cube4;
383
      case 5: return R.string.cube5;
384
      }
385
    return R.string.cube3;
386
    }
387
388
///////////////////////////////////////////////////////////////////////////////////////////////////
389
390
  public int getInventor(int numLayers)
391
    {
392
    switch(numLayers)
393
      {
394
      case 2: return R.string.cube2_inventor;
395
      case 3: return R.string.cube3_inventor;
396
      case 4: return R.string.cube4_inventor;
397
      case 5: return R.string.cube5_inventor;
398
      }
399
    return R.string.cube3_inventor;
400
    }
401
402
///////////////////////////////////////////////////////////////////////////////////////////////////
403
404
  public int getComplexity(int numLayers)
405
    {
406
    switch(numLayers)
407
      {
408
      case 2: return 4;
409
      case 3: return 6;
410
      case 4: return 8;
411
      case 5: return 10;
412
      }
413
    return 6;
414
    }
415 0c52af30 Leszek Koltunski
}