Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyMinx.java @ bb11be2a

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.helpers.FactoryCubit;
25
import org.distorted.library.main.DistortedEffects;
26
import org.distorted.library.main.DistortedTexture;
27
import org.distorted.library.mesh.MeshBase;
28
import org.distorted.library.mesh.MeshSquare;
29
import org.distorted.library.type.Static3D;
30
import org.distorted.library.type.Static4D;
31

    
32
import java.util.Random;
33

    
34
///////////////////////////////////////////////////////////////////////////////////////////////////
35

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

    
40
  static final int NUM_CORNERS = 20;
41
  static final int NUM_CENTERS = 12;
42
  static final int NUM_EDGES   = 30;
43

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

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

    
64
  private static final int MINX_LGREEN = 0xff53aa00;
65
  private static final int MINX_PINK   = 0xfffd7ab7;
66
  private static final int MINX_SANDY  = 0xffefd48b;
67
  private static final int MINX_LBLUE  = 0xff00a2d7;
68
  private static final int MINX_ORANGE = 0xffff6200;
69
  private static final int MINX_VIOLET = 0xff7d59a4;
70
  private static final int MINX_DGREEN = 0xff007a47;
71
  private static final int MINX_DRED   = 0xffbd0000;
72
  private static final int MINX_DBLUE  = 0xff1a29b2;
73
  private static final int MINX_DYELLOW= 0xffffc400;
74
  private static final int MINX_WHITE  = 0xffffffff;
75
  private 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

    
328
///////////////////////////////////////////////////////////////////////////////////////////////////
329

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

    
336
///////////////////////////////////////////////////////////////////////////////////////////////////
337

    
338
  Static4D[] getQuats()
339
    {
340
    return QUATS;
341
    }
342

    
343
///////////////////////////////////////////////////////////////////////////////////////////////////
344

    
345
  int getNumFaces()
346
    {
347
    return FACE_COLORS.length;
348
    }
349

    
350
///////////////////////////////////////////////////////////////////////////////////////////////////
351

    
352
  boolean shouldResetTextureMaps()
353
    {
354
    return false;
355
    }
356

    
357
///////////////////////////////////////////////////////////////////////////////////////////////////
358

    
359
  int getNumCubitFaces()
360
    {
361
    return FACES_PER_CUBIT;
362
    }
363

    
364
///////////////////////////////////////////////////////////////////////////////////////////////////
365

    
366
  float returnMultiplier()
367
    {
368
    return 2.0f;
369
    }
370

    
371
///////////////////////////////////////////////////////////////////////////////////////////////////
372

    
373
  float[] getRowChances(int numLayers)
374
    {
375
    float[] chances = new float[numLayers];
376
    float denom = (float)(numLayers-1);
377
    int change  = (numLayers-1)/2;
378

    
379
    for(int i=     0; i<change   ; i++) chances[i] = (i+1)/denom;
380
    for(int i=change; i<numLayers; i++) chances[i] = (i  )/denom;
381

    
382
    return chances;
383
    }
384

    
385
///////////////////////////////////////////////////////////////////////////////////////////////////
386

    
387
  MeshBase createCornerMesh(int numLayers, float width)
388
    {
389
    float A = (2*SQ3/3)*SIN54;
390
    float B = 0.4f;
391
    int   N = numLayers==3 ? 5 : 3;
392
    int   E = numLayers==3 ? 4 : 1;
393

    
394
    double X = width*COS18*SIN_HALFD;
395
    double Y = width*SIN18;
396
    double Z = width*COS18*COS_HALFD;
397

    
398
    double[][] vertices = new double[][]
399
        {
400
            { 0.0, 0.0      , 0.0 },
401
            {   X,   Y      ,  -Z },
402
            { 0.0, 2*Y      ,-2*Z },
403
            {  -X,   Y      ,  -Z },
404
            { 0.0, 0.0-width, 0.0 },
405
            {   X,   Y-width,  -Z },
406
            { 0.0, 2*Y-width,-2*Z },
407
            {  -X,   Y-width,  -Z },
408
        };
409

    
410
    int[][] vertIndexes = new int[][]
411
        {
412
            {4,5,1,0},
413
            {7,4,0,3},
414
            {0,1,2,3},
415
            {4,5,6,7},
416
            {6,5,1,2},
417
            {7,6,2,3}
418
        };
419

    
420
    float[][] bands     = new float[][]
421
      {
422
         {0.04f,34,0.3f,0.2f, N, 1, 1},
423
         {0.00f, 0,0.0f,0.0f, 2, 1, E}
424
      };
425
    int[] bandIndexes   = new int[] { 0,0,0,1,1,1};
426
    float[][] corners   = new float[][] { {0.04f,0.10f} };
427
    int[] cornerIndexes = new int[] { 0,-1,-1,-1,-1,-1,-1,-1 };
428
    float[][] centers   = new float[][] { {0.0f, -(float)Math.sqrt(1-A*A)*B,-A*B} };
429
    int[] centerIndexes = new int[] { 0,-1,-1,-1,-1,-1,-1,-1 };
430

    
431
    FactoryCubit factory = FactoryCubit.getInstance();
432
    factory.createNewFaceTransform(vertices,vertIndexes);
433

    
434
    return factory.createRoundedSolid(vertices, vertIndexes,
435
                                      bands, bandIndexes,
436
                                      corners, cornerIndexes,
437
                                      centers, centerIndexes,
438
                                      getNumCubitFaces() );
439
    }
440

    
441
///////////////////////////////////////////////////////////////////////////////////////////////////
442
// PUBLIC API
443

    
444
  public Static3D[] getRotationAxis()
445
    {
446
    return ROT_AXIS;
447
    }
448

    
449
///////////////////////////////////////////////////////////////////////////////////////////////////
450

    
451
  public int getBasicAngle()
452
    {
453
    return 5;
454
    }
455

    
456
///////////////////////////////////////////////////////////////////////////////////////////////////
457

    
458
  public void randomizeNewScramble(int[][] scramble, Random rnd, int num)
459
    {
460
    if( num==0 )
461
      {
462
      scramble[num][0] = rnd.nextInt(ROTATION_AXIS.length);
463
      }
464
    else
465
      {
466
      int newVector = rnd.nextInt(ROTATION_AXIS.length-1);
467
      scramble[num][0] = (newVector>=scramble[num-1][0] ? newVector+1 : newVector);
468
      }
469

    
470
    if( num==0 )
471
      {
472
      float rowFloat = rnd.nextFloat();
473

    
474
      for(int row=0; row<mRowChances.length; row++)
475
        {
476
        if( rowFloat<=mRowChances[row] )
477
          {
478
          scramble[num][1] = row;
479
          break;
480
          }
481
        }
482
      }
483
    else
484
      {
485
      int size = mRowChances.length;
486
      int nom = (size-1)/2;
487
      int row = rnd.nextInt(nom);
488
      boolean opposite = OPPOSITE_ROWS[scramble[num-1][0]][scramble[num][0]];
489
      boolean low = opposite^(scramble[num-1][1]<nom);
490
      scramble[num][1] = low ? row : size-1-row;
491
      }
492

    
493
    switch( rnd.nextInt(4) )
494
      {
495
      case 0: scramble[num][2] = -2; break;
496
      case 1: scramble[num][2] = -1; break;
497
      case 2: scramble[num][2] =  1; break;
498
      case 3: scramble[num][2] =  2; break;
499
      }
500
    }
501

    
502
///////////////////////////////////////////////////////////////////////////////////////////////////
503
// only needed for solvers - there are no Minx solvers ATM)
504

    
505
  public String retObjectString()
506
    {
507
    return "";
508
    }
509
}
(28-28/33)