Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyMinx.java @ 5e06e92f

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
import static org.distorted.helpers.FactoryCubit.COS18;
35
import static org.distorted.helpers.FactoryCubit.COS_HALFD;
36
import static org.distorted.helpers.FactoryCubit.SIN18;
37
import static org.distorted.helpers.FactoryCubit.SIN54;
38
import static org.distorted.helpers.FactoryCubit.SIN_HALFD;
39

    
40
///////////////////////////////////////////////////////////////////////////////////////////////////
41

    
42
abstract class TwistyMinx extends TwistyObject
43
{
44
  private static final int FACES_PER_CUBIT =6;
45

    
46
  static final int NUM_CORNERS = 20;
47
  static final int NUM_CENTERS = 12;
48
  static final int NUM_EDGES   = 30;
49

    
50
  static final float C0 = (SQ5-1)/4;                       // cos(72 deg)
51
  static final float C1 = (SQ5+1)/4;                       // cos(36 deg)
52
  static final float C2 = (SQ5+3)/4;
53
  static final float LEN= (float)(Math.sqrt(1.25f+0.5f*SQ5));
54

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

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

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

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

    
94
           new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),  //4
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
           new Static4D( -0.5f, -0.5f,  0.5f,  0.5f ),
101
           new Static4D( -0.5f, -0.5f, -0.5f,  0.5f ),
102

    
103
           new Static4D(  0.5f,    C1,    C0,  0.0f ), // 12
104
           new Static4D(  0.5f,    C1,   -C0,  0.0f ),
105
           new Static4D(  0.5f,   -C1,    C0,  0.0f ),
106
           new Static4D(  0.5f,   -C1,   -C0,  0.0f ),
107
           new Static4D(    C0,  0.5f,    C1,  0.0f ),
108
           new Static4D(    C0,  0.5f,   -C1,  0.0f ),
109
           new Static4D(   -C0,  0.5f,    C1,  0.0f ),
110
           new Static4D(   -C0,  0.5f,   -C1,  0.0f ),
111
           new Static4D(    C1,    C0,  0.5f,  0.0f ),
112
           new Static4D(    C1,   -C0,  0.5f,  0.0f ),
113
           new Static4D(   -C1,    C0,  0.5f,  0.0f ),
114
           new Static4D(   -C1,   -C0,  0.5f,  0.0f ),
115

    
116
           new Static4D(  0.0f,    C0,    C1,  0.5f ), //24
117
           new Static4D(  0.0f,    C0,   -C1,  0.5f ),
118
           new Static4D(  0.0f,   -C0,    C1,  0.5f ),
119
           new Static4D(  0.0f,   -C0,   -C1,  0.5f ),
120
           new Static4D(    C0,    C1,  0.0f,  0.5f ),
121
           new Static4D(    C0,   -C1,  0.0f,  0.5f ),
122
           new Static4D(   -C0,    C1,  0.0f,  0.5f ),
123
           new Static4D(   -C0,   -C1,  0.0f,  0.5f ),
124
           new Static4D(    C1,  0.0f,    C0,  0.5f ),
125
           new Static4D(    C1,  0.0f,   -C0,  0.5f ),
126
           new Static4D(   -C1,  0.0f,    C0,  0.5f ),
127
           new Static4D(   -C1,  0.0f,   -C0,  0.5f ),
128

    
129
           new Static4D(  0.0f,    C1,  0.5f,    C0 ), //36
130
           new Static4D(  0.0f,    C1, -0.5f,    C0 ),
131
           new Static4D(  0.0f,   -C1,  0.5f,    C0 ),
132
           new Static4D(  0.0f,   -C1, -0.5f,    C0 ),
133
           new Static4D(  0.5f,  0.0f,    C1,    C0 ),
134
           new Static4D(  0.5f,  0.0f,   -C1,    C0 ),
135
           new Static4D( -0.5f,  0.0f,    C1,    C0 ),
136
           new Static4D( -0.5f,  0.0f,   -C1,    C0 ),
137
           new Static4D(    C1,  0.5f,  0.0f,    C0 ),
138
           new Static4D(    C1, -0.5f,  0.0f,    C0 ),
139
           new Static4D(   -C1,  0.5f,  0.0f,    C0 ),
140
           new Static4D(   -C1, -0.5f,  0.0f,    C0 ),
141

    
142
           new Static4D(  0.0f,  0.5f,    C0,    C1 ), //48
143
           new Static4D(  0.0f,  0.5f,   -C0,    C1 ),
144
           new Static4D(  0.0f, -0.5f,    C0,    C1 ),
145
           new Static4D(  0.0f, -0.5f,   -C0,    C1 ),
146
           new Static4D(  0.5f,    C0,  0.0f,    C1 ),
147
           new Static4D(  0.5f,   -C0,  0.0f,    C1 ),
148
           new Static4D( -0.5f,    C0,  0.0f,    C1 ),
149
           new Static4D( -0.5f,   -C0,  0.0f,    C1 ),
150
           new Static4D(    C0,  0.0f,  0.5f,    C1 ),
151
           new Static4D(    C0,  0.0f, -0.5f,    C1 ),
152
           new Static4D(   -C0,  0.0f,  0.5f,    C1 ),
153
           new Static4D(   -C0,  0.0f, -0.5f,    C1 ),
154
         };
155

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

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

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

    
212

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

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

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

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

    
285
  static final float[][] mCenterCoords = new float[NUM_CENTERS][3];
286

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

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

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

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

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

    
317
  static final Static4D[] mBasicCornerV, mCurrCornerV;
318

    
319
  static
320
    {
321
    mBasicCornerV = new Static4D[3];
322
    mCurrCornerV  = new Static4D[3];
323

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

    
329

    
330
///////////////////////////////////////////////////////////////////////////////////////////////////
331

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

    
338
///////////////////////////////////////////////////////////////////////////////////////////////////
339

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

    
345
///////////////////////////////////////////////////////////////////////////////////////////////////
346

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

    
352
///////////////////////////////////////////////////////////////////////////////////////////////////
353

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

    
359
///////////////////////////////////////////////////////////////////////////////////////////////////
360

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

    
366
///////////////////////////////////////////////////////////////////////////////////////////////////
367

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

    
373
///////////////////////////////////////////////////////////////////////////////////////////////////
374

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

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

    
384
    return chances;
385
    }
386

    
387
///////////////////////////////////////////////////////////////////////////////////////////////////
388

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

    
396
    double X = width*COS18*SIN_HALFD;
397
    double Y = width*SIN18;
398
    double Z = width*COS18*COS_HALFD;
399

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

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

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

    
433
    FactoryCubit factory = FactoryCubit.getInstance();
434
    factory.createNewFaceTransform(vertices,vertIndexes);
435

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

    
443
///////////////////////////////////////////////////////////////////////////////////////////////////
444
// PUBLIC API
445

    
446
  public Static3D[] getRotationAxis()
447
    {
448
    return ROT_AXIS;
449
    }
450

    
451
///////////////////////////////////////////////////////////////////////////////////////////////////
452

    
453
  public int getBasicAngle()
454
    {
455
    return 5;
456
    }
457

    
458
///////////////////////////////////////////////////////////////////////////////////////////////////
459

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

    
472
    if( num==0 )
473
      {
474
      float rowFloat = rnd.nextFloat();
475

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

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

    
504
///////////////////////////////////////////////////////////////////////////////////////////////////
505
// only needed for solvers - there are no Minx solvers ATM)
506

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