Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyMinx.java @ 3e605536

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is free software: you can redistribute it and/or modify                            //
7
// 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
// Magic Cube is distributed in the hope that it will be useful,                                 //
12
// 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
// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

    
20
package org.distorted.objects;
21

    
22
import android.content.res.Resources;
23

    
24
import org.distorted.library.main.DistortedEffects;
25
import org.distorted.library.main.DistortedTexture;
26
import org.distorted.library.mesh.MeshSquare;
27
import org.distorted.library.type.Static3D;
28
import org.distorted.library.type.Static4D;
29

    
30
import java.util.Random;
31

    
32
///////////////////////////////////////////////////////////////////////////////////////////////////
33

    
34
abstract class TwistyMinx extends TwistyObject
35
{
36
  private static final int FACES_PER_CUBIT =6;
37

    
38
  static final int NUM_CORNERS = 20;
39
  static final int NUM_CENTERS = 12;
40
  static final int NUM_EDGES   = 30;
41

    
42
  static final float C2       = (SQ5+3)/4;
43
  static final float LEN      = (float)(Math.sqrt(1.25f+0.5f*SQ5));
44
  static final float SIN54    = (SQ5+1)/4;
45
  static final float COS54    = (float)(Math.sqrt(10-2*SQ5)/4);
46
  static final float SIN18    = (SQ5-1)/4;
47
  static final float COS18    = (float)(0.25f*Math.sqrt(10.0f+2.0f*SQ5));
48
  static final float COS_HALFD= (float)(Math.sqrt(0.5f-0.1f*SQ5)); // cos(half the dihedral angle)
49
  static final float SIN_HALFD= (float)(Math.sqrt(0.5f+0.1f*SQ5)); // sin(half the dihedral angle)
50

    
51
  // the six rotation axis of a Minx. Must be normalized.
52
  static final Static3D[] ROT_AXIS = new Static3D[]
53
         {
54
           new Static3D(    C2/LEN, SIN54/LEN,    0      ),
55
           new Static3D(   -C2/LEN, SIN54/LEN,    0      ),
56
           new Static3D( 0        ,    C2/LEN, SIN54/LEN ),
57
           new Static3D( 0        ,   -C2/LEN, SIN54/LEN ),
58
           new Static3D( SIN54/LEN,    0     ,    C2/LEN ),
59
           new Static3D( SIN54/LEN,    0     ,   -C2/LEN )
60
         };
61

    
62
  private static final int[] BASIC_ANGLE = new int[] { 5,5,5,5,5,5 };
63

    
64
  static final int MINX_LGREEN = 0xff53aa00;
65
  static final int MINX_PINK   = 0xfffd7ab7;
66
  static final int MINX_SANDY  = 0xffefd48b;
67
  static final int MINX_LBLUE  = 0xff00a2d7;
68
  static final int MINX_ORANGE = 0xffff6200;
69
  static final int MINX_VIOLET = 0xff7d59a4;
70
  static final int MINX_DGREEN = 0xff007a47;
71
  static final int MINX_DRED   = 0xffbd0000;
72
  static final int MINX_DBLUE  = 0xff1a29b2;
73
  static final int MINX_DYELLOW= 0xffffc400;
74
  static final int MINX_WHITE  = 0xffffffff;
75
  static final int MINX_GREY   = 0xff727c7b;
76

    
77
  static final int[] FACE_COLORS = new int[]
78
         {
79
           MINX_LGREEN, MINX_PINK   , MINX_SANDY , MINX_LBLUE,
80
           MINX_ORANGE, MINX_VIOLET , MINX_DGREEN, MINX_DRED ,
81
           MINX_DBLUE , MINX_DYELLOW, MINX_WHITE , MINX_GREY
82
         };
83

    
84
  // All 60 legal rotation quats of a Minx
85
  static final Static4D[] QUATS = new Static4D[]
86
         {
87
           new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),  //0
88
           new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
89
           new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
90
           new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
91

    
92
           new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),  //4
93
           new Static4D(  0.5f,  0.5f, -0.5f,  0.5f ),
94
           new Static4D(  0.5f, -0.5f,  0.5f,  0.5f ),
95
           new Static4D(  0.5f, -0.5f, -0.5f,  0.5f ),
96
           new Static4D( -0.5f,  0.5f,  0.5f,  0.5f ),
97
           new Static4D( -0.5f,  0.5f, -0.5f,  0.5f ),
98
           new Static4D( -0.5f, -0.5f,  0.5f,  0.5f ),
99
           new Static4D( -0.5f, -0.5f, -0.5f,  0.5f ),
100

    
101
           new Static4D(  0.5f, SIN54, SIN18,  0.0f ), // 12
102
           new Static4D(  0.5f, SIN54,-SIN18,  0.0f ),
103
           new Static4D(  0.5f,-SIN54, SIN18,  0.0f ),
104
           new Static4D(  0.5f,-SIN54,-SIN18,  0.0f ),
105
           new Static4D( SIN18,  0.5f, SIN54,  0.0f ),
106
           new Static4D( SIN18,  0.5f,-SIN54,  0.0f ),
107
           new Static4D(-SIN18,  0.5f, SIN54,  0.0f ),
108
           new Static4D(-SIN18,  0.5f,-SIN54,  0.0f ),
109
           new Static4D( SIN54, SIN18,  0.5f,  0.0f ),
110
           new Static4D( SIN54,-SIN18,  0.5f,  0.0f ),
111
           new Static4D(-SIN54, SIN18,  0.5f,  0.0f ),
112
           new Static4D(-SIN54,-SIN18,  0.5f,  0.0f ),
113

    
114
           new Static4D(  0.0f, SIN18, SIN54,  0.5f ), //24
115
           new Static4D(  0.0f, SIN18,-SIN54,  0.5f ),
116
           new Static4D(  0.0f,-SIN18, SIN54,  0.5f ),
117
           new Static4D(  0.0f,-SIN18,-SIN54,  0.5f ),
118
           new Static4D( SIN18, SIN54,  0.0f,  0.5f ),
119
           new Static4D( SIN18,-SIN54,  0.0f,  0.5f ),
120
           new Static4D(-SIN18, SIN54,  0.0f,  0.5f ),
121
           new Static4D(-SIN18,-SIN54,  0.0f,  0.5f ),
122
           new Static4D( SIN54,  0.0f, SIN18,  0.5f ),
123
           new Static4D( SIN54,  0.0f,-SIN18,  0.5f ),
124
           new Static4D(-SIN54,  0.0f, SIN18,  0.5f ),
125
           new Static4D(-SIN54,  0.0f,-SIN18,  0.5f ),
126

    
127
           new Static4D(  0.0f, SIN54,  0.5f, SIN18 ), //36
128
           new Static4D(  0.0f, SIN54, -0.5f, SIN18 ),
129
           new Static4D(  0.0f,-SIN54,  0.5f, SIN18 ),
130
           new Static4D(  0.0f,-SIN54, -0.5f, SIN18 ),
131
           new Static4D(  0.5f,  0.0f, SIN54, SIN18 ),
132
           new Static4D(  0.5f,  0.0f,-SIN54, SIN18 ),
133
           new Static4D( -0.5f,  0.0f, SIN54, SIN18 ),
134
           new Static4D( -0.5f,  0.0f,-SIN54, SIN18 ),
135
           new Static4D( SIN54,  0.5f,  0.0f, SIN18 ),
136
           new Static4D( SIN54, -0.5f,  0.0f, SIN18 ),
137
           new Static4D(-SIN54,  0.5f,  0.0f, SIN18 ),
138
           new Static4D(-SIN54, -0.5f,  0.0f, SIN18 ),
139

    
140
           new Static4D(  0.0f,  0.5f, SIN18, SIN54 ), //48
141
           new Static4D(  0.0f,  0.5f,-SIN18, SIN54 ),
142
           new Static4D(  0.0f, -0.5f, SIN18, SIN54 ),
143
           new Static4D(  0.0f, -0.5f,-SIN18, SIN54 ),
144
           new Static4D(  0.5f, SIN18,  0.0f, SIN54 ),
145
           new Static4D(  0.5f,-SIN18,  0.0f, SIN54 ),
146
           new Static4D( -0.5f, SIN18,  0.0f, SIN54 ),
147
           new Static4D( -0.5f,-SIN18,  0.0f, SIN54 ),
148
           new Static4D( SIN18,  0.0f,  0.5f, SIN54 ),
149
           new Static4D( SIN18,  0.0f, -0.5f, SIN54 ),
150
           new Static4D(-SIN18,  0.0f,  0.5f, SIN54 ),
151
           new Static4D(-SIN18,  0.0f, -0.5f, SIN54 ),
152
         };
153

    
154
  // Coordinates of all 20 corners of a Minx
155
  static final float[][] CORNERS = new float[][]
156
         {
157
             {  0.0f,  0.5f,    C2},
158
             {  0.0f,  0.5f,   -C2},
159
             {  0.0f, -0.5f,    C2},
160
             {  0.0f, -0.5f,   -C2},
161
             {    C2,  0.0f,  0.5f},
162
             {    C2,  0.0f, -0.5f},
163
             {   -C2,  0.0f,  0.5f},
164
             {   -C2,  0.0f, -0.5f},
165
             {  0.5f,    C2,  0.0f},
166
             {  0.5f,   -C2,  0.0f},
167
             { -0.5f,    C2,  0.0f},
168
             { -0.5f,   -C2,  0.0f},
169
             { SIN54, SIN54, SIN54},
170
             { SIN54, SIN54,-SIN54},
171
             { SIN54,-SIN54, SIN54},
172
             { SIN54,-SIN54,-SIN54},
173
             {-SIN54, SIN54, SIN54},
174
             {-SIN54, SIN54,-SIN54},
175
             {-SIN54,-SIN54, SIN54},
176
             {-SIN54,-SIN54,-SIN54},
177
         };
178

    
179
  static final int[][] mCornerFaceMap =
180
         {
181
           {  0, 1, 8 },
182
           {  6, 5,10 },
183
           {  1, 0,11 },
184
           {  5, 6, 3 },
185
           {  0, 9, 4 },
186
           {  5, 4, 9 },
187
           {  7, 1, 2 },
188
           {  2, 6, 7 },
189
           { 10, 9, 8 },
190
           {  4, 3,11 },
191
           {  7,10, 8 },
192
           {  3, 2,11 },
193
           {  0, 8, 9 },
194
           {  9,10, 5 },
195
           {  0, 4,11 },
196
           {  4, 5, 3 },
197
           {  1, 7, 8 },
198
           {  7, 6,10 },
199
           {  2, 1,11 },
200
           {  6, 2, 3 },
201
         };
202

    
203
  static final int[] QUAT_EDGE_INDICES =
204
      {
205
        56, 40, 43, 59,  0, 19,  9, 54, 58, 49,
206
        48, 24, 52,  4, 16, 32, 20, 11, 21, 35 ,
207
        37, 30,  8, 28, 36, 44,  1, 46, 12, 47
208
      };
209

    
210

    
211
  static final int[] QUAT_CORNER_INDICES =
212
      {
213
         0,  2,  3,  1, 40, 31, 41, 30, 39, 35,
214
        36, 34, 56, 32, 43, 21, 48, 28, 42, 23
215
      };
216

    
217
  static final boolean[][] OPPOSITE_ROWS =
218
      {
219
          {false,  true, false,  true, false, false},
220
          { true, false, false,  true,  true,  true},
221
          {false, false, false,  true, false,  true},
222
          { true,  true,  true, false, false,  true},
223
          {false,  true, false, false, false,  true},
224
          {false,  true,  true,  true,  true, false}
225
      };
226

    
227
  // the quadruple ( corner1, corner2, face1, face2 ) defining an edge.
228
  // In fact the 2 corners already define it, the faces only provide easy
229
  // way to get to know the colors. Order: arbitrary. Face1 arbitrarily on
230
  // the 'left' or right of vector corner1 --> corner2, according to Quat.
231
  static final int[][] mEdgeMap =
232
         {
233
           {  0, 12,  0,  8}, //0
234
           { 12,  4,  0,  9},
235
           {  4, 14,  0,  4},
236
           { 14,  2,  0, 11},
237
           {  2,  0,  0,  1},
238
           { 14,  9, 11,  4}, //5
239
           {  9, 11, 11,  3},
240
           { 11, 18, 11,  2},
241
           { 18,  2, 11,  1},
242
           { 18,  6,  1,  2},
243
           {  6, 16,  1,  7}, //10
244
           { 16,  0,  1,  8},
245
           { 16, 10,  8,  7},
246
           { 10,  8,  8, 10},
247
           {  8, 12,  8,  9},
248
           {  8, 13,  9, 10}, //15
249
           { 13,  5,  9,  5},
250
           {  5,  4,  9,  4},
251
           {  5, 15,  4,  5},
252
           { 15,  9,  4,  3},
253
           { 11, 19,  2,  3}, //20
254
           { 19,  7,  2,  6},
255
           {  7,  6,  2,  7},
256
           {  7, 17,  7,  6},
257
           { 17, 10,  7, 10},
258
           { 17,  1, 10,  6}, //25
259
           {  1,  3,  5,  6},
260
           {  3, 19,  3,  6},
261
           {  1, 13, 10,  5},
262
           {  3, 15,  5,  3},
263
         };
264

    
265
  // the five vertices that form a given face. Order: the same as colors
266
  // of the faces in TwistyMinx.
267
  static final int[][] mCenterMap =
268
         {
269
           { 0, 12,  4, 14,  2},
270
           { 0,  2, 18,  6, 16},
271
           { 6, 18, 11, 19,  7},
272
           { 3, 15,  9, 11, 19},
273
           { 4,  5, 15,  9, 14},
274
           { 1, 13,  5, 15,  3},
275
           { 1,  3, 19,  7, 17},
276
           {10, 16,  6,  7, 17},
277
           { 0, 12,  8, 10, 16},
278
           { 8, 13,  5,  4, 12},
279
           { 1, 13,  8, 10, 17},
280
           { 2, 14,  9, 11, 18},
281
         };
282

    
283
  static final float[][] mCenterCoords = new float[NUM_CENTERS][3];
284

    
285
  static
286
    {
287
    for(int center=0; center<NUM_CENTERS; center++)
288
      {
289
      int[] map = mCenterMap[center];
290

    
291
      float x = CORNERS[map[0]][0] +
292
                CORNERS[map[1]][0] +
293
                CORNERS[map[2]][0] +
294
                CORNERS[map[3]][0] +
295
                CORNERS[map[4]][0] ;
296

    
297
      float y = CORNERS[map[0]][1] +
298
                CORNERS[map[1]][1] +
299
                CORNERS[map[2]][1] +
300
                CORNERS[map[3]][1] +
301
                CORNERS[map[4]][1] ;
302

    
303
      float z = CORNERS[map[0]][2] +
304
                CORNERS[map[1]][2] +
305
                CORNERS[map[2]][2] +
306
                CORNERS[map[3]][2] +
307
                CORNERS[map[4]][2] ;
308

    
309
      mCenterCoords[center][0] = x/5;
310
      mCenterCoords[center][1] = y/5;
311
      mCenterCoords[center][2] = z/5;
312
      }
313
    }
314

    
315
  static final Static4D[] mBasicCornerV, mCurrCornerV;
316

    
317
  static
318
    {
319
    mBasicCornerV = new Static4D[3];
320
    mCurrCornerV  = new Static4D[3];
321

    
322
    mBasicCornerV[0] = new Static4D( (SQ5+1)*0.125f, (SQ5-1)*0.125f, -0.250f, 0.0f );
323
    mBasicCornerV[1] = new Static4D(-(SQ5+1)*0.125f, (SQ5-1)*0.125f, -0.250f, 0.0f );
324
    mBasicCornerV[2] = new Static4D(              0,        -0.500f,    0.0f, 0.0f );
325
    }
326

    
327
  private static int[][] mScrambleTable;
328
  private static int[] mPossibleAxis, mPossibleLayers;
329
  private static int[] mNumOccurences;
330

    
331
///////////////////////////////////////////////////////////////////////////////////////////////////
332

    
333
  TwistyMinx(int numLayers, int realSize, Static4D quat, DistortedTexture texture, MeshSquare mesh,
334
             DistortedEffects effects, int[][] moves, ObjectList obj, Resources res, int scrWidth)
335
    {
336
    super(numLayers, realSize, quat, texture, mesh, effects, moves, obj, res, scrWidth);
337
    }
338

    
339
///////////////////////////////////////////////////////////////////////////////////////////////////
340

    
341
  Static4D[] getQuats()
342
    {
343
    return QUATS;
344
    }
345

    
346
///////////////////////////////////////////////////////////////////////////////////////////////////
347

    
348
  int getNumFaces()
349
    {
350
    return FACE_COLORS.length;
351
    }
352

    
353
///////////////////////////////////////////////////////////////////////////////////////////////////
354

    
355
  boolean shouldResetTextureMaps()
356
    {
357
    return false;
358
    }
359

    
360
///////////////////////////////////////////////////////////////////////////////////////////////////
361

    
362
  int getNumCubitFaces()
363
    {
364
    return FACES_PER_CUBIT;
365
    }
366

    
367
///////////////////////////////////////////////////////////////////////////////////////////////////
368

    
369
  float returnMultiplier()
370
    {
371
    return 2.0f;
372
    }
373

    
374
///////////////////////////////////////////////////////////////////////////////////////////////////
375

    
376
  private void initializeScrambleTable(int[] first, int numLayers)
377
    {
378
    if( mScrambleTable ==null ) mScrambleTable = new int[NUM_AXIS][2];
379
    if( mPossibleAxis  ==null ) mPossibleAxis  = new int[NUM_AXIS-1];
380
    if( mPossibleLayers==null ) mPossibleLayers= new int[NUM_AXIS-1];
381
    if( mNumOccurences ==null ) mNumOccurences = new int[NUM_AXIS-1];
382

    
383
    for(int i=0; i<NUM_AXIS; i++)
384
      for(int j=0; j<2; j++)
385
        {
386
        mScrambleTable[i][j] = 0;
387
        }
388

    
389
    int layer = convertRowIntoLayer(first[1],numLayers);
390

    
391
    mScrambleTable[first[0]][layer] = 1;
392
    }
393

    
394
///////////////////////////////////////////////////////////////////////////////////////////////////
395

    
396
  private int convertRowIntoLayer(int row, int numLayers)
397
    {
398
    return row>(numLayers-1)/2 ? 1 : 0;
399
    }
400

    
401
///////////////////////////////////////////////////////////////////////////////////////////////////
402

    
403
  private int convertLayerIntoRow(Random rnd, int layer, int numLayers)
404
    {
405
    int ran = numLayers>3 ? rnd.nextInt((numLayers-1)/2) : 0;
406
    return layer==0 ? ran : numLayers-1-ran;
407
    }
408

    
409
///////////////////////////////////////////////////////////////////////////////////////////////////
410

    
411
  private boolean areOpposite(int oldAxis, int newAxis, int oldRow, int nom)
412
    {
413
    return OPPOSITE_ROWS[oldAxis][newAxis]^(oldRow<nom);
414
    }
415

    
416
///////////////////////////////////////////////////////////////////////////////////////////////////
417

    
418
  private int retNewRotationIndex(Random rnd, int nom, int[] oldRot)
419
    {
420
    int index=0, max=0;
421

    
422
    for(int ax=0; ax<NUM_AXIS; ax++)
423
      {
424
      if( ax!=oldRot[0] )
425
        {
426
        mPossibleAxis[index] = ax;
427
        mPossibleLayers[index] = areOpposite(oldRot[0],ax,oldRot[1],nom) ? 0:1;
428
        int tmp = mScrambleTable[mPossibleAxis[index]][mPossibleLayers[index]];
429
        if( tmp>max ) max=tmp;
430
        index++;
431
        }
432
      }
433

    
434
    for(int ax=0; ax<NUM_AXIS-1; ax++)
435
      {
436
      int value = mScrambleTable[mPossibleAxis[ax]][mPossibleLayers[ax]];
437
      mNumOccurences[ax] = max - value + (ax==0 ? 0 : mNumOccurences[ax-1]);
438
      }
439

    
440
    float random= rnd.nextFloat()*mNumOccurences[NUM_AXIS-2];
441

    
442
    for(int ax=0; ax<NUM_AXIS-1; ax++)
443
      {
444
      if( random <= mNumOccurences[ax] )
445
        {
446
        index=ax;
447
        break;
448
        }
449
      }
450

    
451
    mScrambleTable[mPossibleAxis[index]][mPossibleLayers[index]]++;
452

    
453
    return index;
454
    }
455

    
456
///////////////////////////////////////////////////////////////////////////////////////////////////
457
// PUBLIC API
458

    
459
  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int total)
460
    {
461
    int numLayers = getNumLayers();
462
    int nom = (numLayers-1)/2;
463

    
464
    if( curr==0 )
465
      {
466
      int lf = rnd.nextInt(2);
467
      int row= rnd.nextInt(nom);
468
      scramble[curr][0] = rnd.nextInt(NUM_AXIS);
469
      scramble[curr][1] = (lf==0 ? row : numLayers-1-row);
470
      initializeScrambleTable(scramble[curr],numLayers);
471
      }
472
    else
473
      {
474
      int index = retNewRotationIndex(rnd,nom,scramble[curr-1]);
475
      scramble[curr][0] = mPossibleAxis[index];
476
      scramble[curr][1] = convertLayerIntoRow(rnd, mPossibleLayers[index], numLayers);
477
      }
478

    
479
    switch( rnd.nextInt(4) )
480
      {
481
      case 0: scramble[curr][2] = -2; break;
482
      case 1: scramble[curr][2] = -1; break;
483
      case 2: scramble[curr][2] =  1; break;
484
      case 3: scramble[curr][2] =  2; break;
485
      }
486
    }
487

    
488
///////////////////////////////////////////////////////////////////////////////////////////////////
489

    
490
  public Static3D[] getRotationAxis()
491
    {
492
    return ROT_AXIS;
493
    }
494

    
495
///////////////////////////////////////////////////////////////////////////////////////////////////
496

    
497
  public int[] getBasicAngle()
498
    {
499
    return BASIC_ANGLE;
500
    }
501
}
(32-32/41)