Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyRedi.java @ 680469e6

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
import android.graphics.Canvas;
24
import android.graphics.Paint;
25

    
26
import org.distorted.helpers.FactoryCubit;
27
import org.distorted.helpers.FactorySticker;
28
import org.distorted.library.effect.MatrixEffectQuaternion;
29
import org.distorted.library.main.DistortedEffects;
30
import org.distorted.library.main.DistortedTexture;
31
import org.distorted.library.mesh.MeshBase;
32
import org.distorted.library.mesh.MeshSquare;
33
import org.distorted.library.type.Static3D;
34
import org.distorted.library.type.Static4D;
35
import org.distorted.main.R;
36

    
37
import java.util.Random;
38

    
39
///////////////////////////////////////////////////////////////////////////////////////////////////
40

    
41
public class TwistyRedi extends TwistyObject
42
{
43
  private static final int FACES_PER_CUBIT =6;
44

    
45
  // the four rotation axis of a RubikRedi. Must be normalized.
46
  static final Static3D[] ROT_AXIS = new Static3D[]
47
         {
48
           new Static3D(+SQ3/3,+SQ3/3,+SQ3/3),
49
           new Static3D(+SQ3/3,+SQ3/3,-SQ3/3),
50
           new Static3D(+SQ3/3,-SQ3/3,+SQ3/3),
51
           new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
52
         };
53

    
54
  private static final int[] FACE_COLORS = new int[]
55
         {
56
           COLOR_YELLOW, COLOR_WHITE,
57
           COLOR_BLUE  , COLOR_GREEN,
58
           COLOR_RED   , COLOR_ORANGE
59
         };
60

    
61
  // All legal rotation quats of a RubikRedi
62
  private static final Static4D[] QUATS = new Static4D[]
63
         {
64
           new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),
65
           new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
66
           new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
67
           new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
68

    
69
           new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),
70
           new Static4D(  0.5f,  0.5f,  0.5f, -0.5f ),
71
           new Static4D(  0.5f,  0.5f, -0.5f,  0.5f ),
72
           new Static4D(  0.5f,  0.5f, -0.5f, -0.5f ),
73
           new Static4D(  0.5f, -0.5f,  0.5f,  0.5f ),
74
           new Static4D(  0.5f, -0.5f,  0.5f, -0.5f ),
75
           new Static4D(  0.5f, -0.5f, -0.5f,  0.5f ),
76
           new Static4D(  0.5f, -0.5f, -0.5f, -0.5f )
77
         };
78

    
79
  private static final float DIST_CORNER = 1.0f;
80
  private static final float DIST_EDGE   = 1.5f;
81

    
82
  // centers of the 8 corners + 12 edges ( i.e. of the all 20 cubits)
83
  private static final float[][] CENTERS = new float[][]
84
         {
85
             { DIST_CORNER, DIST_CORNER, DIST_CORNER },
86
             { DIST_CORNER, DIST_CORNER,-DIST_CORNER },
87
             { DIST_CORNER,-DIST_CORNER, DIST_CORNER },
88
             { DIST_CORNER,-DIST_CORNER,-DIST_CORNER },
89
             {-DIST_CORNER, DIST_CORNER, DIST_CORNER },
90
             {-DIST_CORNER, DIST_CORNER,-DIST_CORNER },
91
             {-DIST_CORNER,-DIST_CORNER, DIST_CORNER },
92
             {-DIST_CORNER,-DIST_CORNER,-DIST_CORNER },
93

    
94
             {      0.0f, DIST_EDGE, DIST_EDGE },
95
             { DIST_EDGE,      0.0f, DIST_EDGE },
96
             {      0.0f,-DIST_EDGE, DIST_EDGE },
97
             {-DIST_EDGE,      0.0f, DIST_EDGE },
98
             { DIST_EDGE, DIST_EDGE,      0.0f },
99
             { DIST_EDGE,-DIST_EDGE,      0.0f },
100
             {-DIST_EDGE,-DIST_EDGE,      0.0f },
101
             {-DIST_EDGE, DIST_EDGE,      0.0f },
102
             {      0.0f, DIST_EDGE,-DIST_EDGE },
103
             { DIST_EDGE,      0.0f,-DIST_EDGE },
104
             {      0.0f,-DIST_EDGE,-DIST_EDGE },
105
             {-DIST_EDGE,      0.0f,-DIST_EDGE }
106
         };
107

    
108
  // Colors of the faces of cubits.
109
  // YELLOW 0 WHITE 1 BLUE 2 GREEN 3 RED 4  BROWN 5
110
  // YELLOW 6 WHITE 7 BLUE 8 GREEN 9 RED 10 BROWN 11
111
  private static final int[][] mFaceMap = new int[][]
112
         {
113
           {  4, 2, 0,12,12,12 },
114
           {  2, 5, 0,12,12,12 },
115
           {  3, 4, 0,12,12,12 },
116
           {  5, 3, 0,12,12,12 },
117
           {  1, 2, 4,12,12,12 },
118
           {  5, 2, 1,12,12,12 },
119
           {  4, 3, 1,12,12,12 },
120
           {  1, 3, 5,12,12,12 },
121

    
122
           { 10, 8,12,12,12,12 },
123
           {  6,10,12,12,12,12 },
124
           { 10, 9,12,12,12,12 },
125
           {  7,10,12,12,12,12 },
126
           {  8, 6,12,12,12,12 },
127
           {  9, 6,12,12,12,12 },
128
           {  9, 7,12,12,12,12 },
129
           {  8, 7,12,12,12,12 },
130
           { 11, 8,12,12,12,12 },
131
           {  6,11,12,12,12,12 },
132
           { 11, 9,12,12,12,12 },
133
           {  7,11,12,12,12,12 },
134
         };
135

    
136
  private static final float G = 0.72f;
137

    
138
  private static final double[][] VERTICES_CORNER = new double[][]
139
          {
140
             { 0.0f, 0.0f, 0.0f },
141
             {-0.5f, 0.5f, 0.5f },
142
             {-0.5f,-0.5f, 0.5f },
143
             { 0.5f, 0.5f, 0.5f },
144
             { 0.5f,-0.5f, 0.5f },
145
             { 0.5f, 0.5f,-0.5f },
146
             { 0.5f,-0.5f,-0.5f },
147
             {-0.5f, 0.5f,-0.5f },
148

    
149
             {-0.5f, 0.5f*G, 0.5f },
150
             {-0.5f,-0.5f*G, 0.5f },
151
             {-0.5f*G,-0.5f, 0.5f },
152
             { 0.5f*G,-0.5f, 0.5f },
153
             { 0.5f,-0.5f, 0.5f*G },
154
             { 0.5f,-0.5f,-0.5f*G },
155
             { 0.5f,-0.5f*G,-0.5f },
156
             { 0.5f, 0.5f*G,-0.5f },
157
             { 0.5f*G, 0.5f,-0.5f },
158
             {-0.5f*G, 0.5f,-0.5f },
159
             {-0.5f, 0.5f,-0.5f*G },
160
             {-0.5f, 0.5f, 0.5f*G },
161
          };
162

    
163
  private static final int[][] VERT_INDEXES_CORNER = new int[][]
164
          {
165
             { 2,4,3,1 },
166
             { 1,3,5,7 },
167
             { 4,6,5,3 },
168

    
169
             { 2,10,11,4,0,5,16,17,7,0},
170
             { 4,12,13,6,0,7,18,19,1,0},
171
             { 1, 8, 9,2,0,6,14,15,5,0}
172
          };
173

    
174
  private static final double[][] VERTICES_EDGE = new double[][]
175
          {
176
             {-0.5f, 0.0f, 0.0f},
177
             { 0.5f, 0.0f, 0.0f},
178
             {-0.5f,-1.0f, 0.0f},
179
             { 0.5f,-1.0f, 0.0f},
180
             { 0.0f,-1.5f, 0.0f},
181
             {-0.5f, 0.0f,-1.0f},
182
             { 0.5f, 0.0f,-1.0f},
183
             { 0.0f, 0.0f,-1.5f},
184
          };
185

    
186
  private static final int[][] VERT_INDEXES_EDGE = new int[][]
187
          {
188
             { 0,2,4,3,1 },
189
             { 0,1,6,7,5 },
190
             { 1,3,6 },
191
             { 0,2,5 },
192
             { 4,7,6,3 },
193
             { 4,7,5,2 }
194
          };
195

    
196
  private static final float[][] STICKERS = new float[][]
197
          {
198
             { -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f },
199
             { -0.3125f, 0.4375f, -0.3125f, -0.1875f, 0.0f, -0.5f, 0.3125f, -0.1875f, 0.3125f, 0.4375f }
200
          };
201

    
202
  private static MeshBase[] mMeshes;
203

    
204
///////////////////////////////////////////////////////////////////////////////////////////////////
205

    
206
  TwistyRedi(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
207
             DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
208
    {
209
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.REDI, res, scrWidth);
210
    }
211

    
212
///////////////////////////////////////////////////////////////////////////////////////////////////
213

    
214
  double[][] getVertices(int cubitType)
215
    {
216
    if( cubitType==0 ) return VERTICES_CORNER;
217
    if( cubitType==1 ) return VERTICES_EDGE;
218
    return null;
219
    }
220

    
221
///////////////////////////////////////////////////////////////////////////////////////////////////
222

    
223
  int[][] getVertIndexes(int cubitType)
224
    {
225
    if( cubitType==0 ) return VERT_INDEXES_CORNER;
226
    if( cubitType==1 ) return VERT_INDEXES_EDGE;
227
    return null;
228
    }
229

    
230
///////////////////////////////////////////////////////////////////////////////////////////////////
231

    
232
  int getNumCubitTypes(int numLayers)
233
    {
234
    return 2;
235
    }
236

    
237
///////////////////////////////////////////////////////////////////////////////////////////////////
238

    
239
  float getScreenRatio()
240
    {
241
    return 0.50f;
242
    }
243

    
244
///////////////////////////////////////////////////////////////////////////////////////////////////
245

    
246
  Static4D[] getQuats()
247
    {
248
    return QUATS;
249
    }
250

    
251
///////////////////////////////////////////////////////////////////////////////////////////////////
252

    
253
  int getNumFaces()
254
    {
255
    return FACE_COLORS.length;
256
    }
257

    
258
///////////////////////////////////////////////////////////////////////////////////////////////////
259

    
260
  boolean shouldResetTextureMaps()
261
    {
262
    return false;
263
    }
264

    
265
///////////////////////////////////////////////////////////////////////////////////////////////////
266

    
267
  int getNumStickerTypes(int numLayers)
268
    {
269
    return 2;
270
    }
271

    
272
///////////////////////////////////////////////////////////////////////////////////////////////////
273

    
274
  float[] getCuts(int size)
275
    {
276
    float[] cuts = new float[2];
277

    
278
    cuts[0] = -SQ3/3 -0.05f;
279
    cuts[1] = +SQ3/3 +0.05f;
280

    
281
    return cuts;
282
    }
283

    
284
///////////////////////////////////////////////////////////////////////////////////////////////////
285

    
286
  int getNumCubitFaces()
287
    {
288
    return FACES_PER_CUBIT;
289
    }
290

    
291
///////////////////////////////////////////////////////////////////////////////////////////////////
292

    
293
  float[][] getCubitPositions(int size)
294
    {
295
    return CENTERS;
296
    }
297

    
298
///////////////////////////////////////////////////////////////////////////////////////////////////
299

    
300
  private Static4D getQuat(int cubit)
301
    {
302
    switch(cubit)
303
      {
304
      case  0: return QUATS[0];                          //  unit quat
305
      case  1: return new Static4D( SQ2/2,0,0,SQ2/2);    //  90 along X
306
      case  2: return new Static4D(-SQ2/2,0,0,SQ2/2);    // -90 along X
307
      case  3: return QUATS[1];                          // 180 along X
308
      case  4: return new Static4D(0, SQ2/2,0,SQ2/2);    //  90 along Y
309
      case  5: return QUATS[2];                          // 180 along Y
310
      case  6: return QUATS[3];                          // 180 along Z
311
      case  7: return new Static4D(SQ2/2,0,-SQ2/2,0);    // 180 along (SQ2/2,0,-SQ2/2)
312

    
313
      case  8: return QUATS[0];
314
      case  9: return QUATS[5];
315
      case 10: return QUATS[3];
316
      case 11: return QUATS[11];
317
      case 12: return QUATS[4];
318
      case 13: return QUATS[7];
319
      case 14: return QUATS[9];
320
      case 15: return QUATS[10];
321
      case 16: return QUATS[2];
322
      case 17: return QUATS[8];
323
      case 18: return QUATS[1];
324
      case 19: return QUATS[6];
325
      }
326

    
327
    return null;
328
    }
329

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

    
332
  MeshBase createCubitMesh(int cubit, int numLayers)
333
    {
334
    if( mMeshes==null )
335
      {
336
      FactoryCubit factory = FactoryCubit.getInstance();
337
      factory.clear();
338
      mMeshes = new MeshBase[2];
339
      }
340

    
341
    MeshBase mesh;
342

    
343
    if( cubit<8 )
344
      {
345
      if( mMeshes[0]==null )
346
        {
347
        float[][] bands= new float[][]
348
          {
349
             {0.06f,35,0.5f,0.7f,6,2,2},
350
             {0.00f, 0,1.0f,0.0f,2,0,0}
351
          };
352
        int[] bandIndexes   = new int[] { 0,0,0,1,1,1 };
353
        float[][] corners   = new float[][] { {0.06f,0.12f} };
354
        int[] cornerIndexes = new int[] { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
355
        float[][] centers   = new float[][] { { 0.0f, 0.0f, 0.0f} };
356
        int[] centerIndexes = new int[] { -1,0,-1,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 };
357

    
358
        FactoryCubit factory = FactoryCubit.getInstance();
359
        factory.createNewFaceTransform(VERTICES_CORNER,VERT_INDEXES_CORNER);
360
        mMeshes[0] = factory.createRoundedSolid(VERTICES_CORNER, VERT_INDEXES_CORNER,
361
                                                bands, bandIndexes,
362
                                                corners, cornerIndexes,
363
                                                centers, centerIndexes,
364
                                                getNumCubitFaces() );
365
        }
366
      mesh = mMeshes[0].copy(true);
367
      }
368
    else
369
      {
370
      if( mMeshes[1]==null )
371
        {
372
        float[][] bands= new float[][]
373
          {
374
            {0.038f,35,0.250f,0.7f, 7,2,2},
375
            {0.020f,35,0.125f,0.2f, 3,1,2},
376
            {0.020f,35,0.125f,0.2f, 3,1,1}
377
          };
378
        int[] bandIndexes   = new int[] { 0,0,1,1,2,2 };
379
        float[][] corners   = new float[][] { {0.06f,0.20f} };
380
        int[] cornerIndexes = new int[] { 0,0,-1,-1,-1,-1,-1,-1 };
381
        float[][] centers   = new float[][] { { 0.0f,-0.75f,-0.75f} };
382
        int[] centerIndexes = new int[] { 0,0,-1,-1,-1,-1,-1,-1 };
383

    
384
        FactoryCubit factory = FactoryCubit.getInstance();
385
        factory.createNewFaceTransform(VERTICES_EDGE,VERT_INDEXES_EDGE);
386
        mMeshes[1] = factory.createRoundedSolid(VERTICES_EDGE, VERT_INDEXES_EDGE,
387
                                                bands, bandIndexes,
388
                                                corners, cornerIndexes,
389
                                                centers, centerIndexes,
390
                                                getNumCubitFaces() );
391
        }
392
      mesh = mMeshes[1].copy(true);
393
      }
394

    
395
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( getQuat(cubit), new Static3D(0,0,0) );
396
    mesh.apply(quat,0xffffffff,0);
397

    
398
    return mesh;
399
    }
400

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

    
403
  int getFaceColor(int cubit, int cubitface, int size)
404
    {
405
    return mFaceMap[cubit][cubitface];
406
    }
407

    
408
///////////////////////////////////////////////////////////////////////////////////////////////////
409

    
410
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
411
    {
412
    int COLORS = FACE_COLORS.length;
413
    int stickerType = face/COLORS;
414
    float R,S;
415

    
416
    switch(stickerType)
417
      {
418
      case 0:  R = 0.09f; S = 0.09f; break;
419
      case 1:  R = 0.06f; S = 0.06f; break;
420
      default: R = 0.00f; S = 0.00f; break;
421
      }
422

    
423
    FactorySticker factory = FactorySticker.getInstance();
424
    factory.drawRoundedPolygon(canvas, paint, left, top, STICKERS[stickerType], S, FACE_COLORS[face%COLORS], R);
425
    }
426

    
427
///////////////////////////////////////////////////////////////////////////////////////////////////
428

    
429
  float returnMultiplier()
430
    {
431
    return 2.0f;
432
    }
433

    
434
///////////////////////////////////////////////////////////////////////////////////////////////////
435

    
436
  float[] getRowChances(int numLayers)
437
    {
438
    float[] chances = new float[3];
439

    
440
    chances[0] = 0.5f;
441
    chances[1] = 0.5f;
442
    chances[2] = 1.0f;
443

    
444
    return chances;
445
    }
446

    
447
///////////////////////////////////////////////////////////////////////////////////////////////////
448
// PUBLIC API
449

    
450
  public Static3D[] getRotationAxis()
451
    {
452
    return ROT_AXIS;
453
    }
454

    
455
///////////////////////////////////////////////////////////////////////////////////////////////////
456

    
457
  public int getBasicAngle()
458
    {
459
    return 3;
460
    }
461

    
462
///////////////////////////////////////////////////////////////////////////////////////////////////
463

    
464
  public void randomizeNewScramble(int[][] scramble, Random rnd, int num)
465
    {
466
    if( num==0 )
467
      {
468
      scramble[num][0] = rnd.nextInt(ROTATION_AXIS.length);
469
      scramble[num][1] = rnd.nextFloat()<=0.5f ? 0:2;
470
      }
471
    else
472
      {
473
      int newVector = rnd.nextInt(ROTATION_AXIS.length-1);
474
      scramble[num][0] = (newVector>=scramble[num-1][0] ? newVector+1 : newVector);
475
      scramble[num][1] = (scramble[num-1][0]+scramble[num][0]==3 ? 2-scramble[num-1][1] : scramble[num-1][1]);
476
      }
477

    
478
    switch( rnd.nextInt(2) )
479
      {
480
      case 0: scramble[num][2] = -1; break;
481
      case 1: scramble[num][2] =  1; break;
482
      }
483
    }
484

    
485
///////////////////////////////////////////////////////////////////////////////////////////////////
486
// The Redi is solved if and only if:
487
//
488
// ??
489

    
490
  public boolean isSolved()
491
    {
492
    int q = CUBITS[0].mQuatIndex;
493

    
494
    return ( CUBITS[ 1].mQuatIndex == q &&
495
             CUBITS[ 2].mQuatIndex == q &&
496
             CUBITS[ 3].mQuatIndex == q &&
497
             CUBITS[ 4].mQuatIndex == q &&
498
             CUBITS[ 5].mQuatIndex == q &&
499
             CUBITS[ 6].mQuatIndex == q &&
500
             CUBITS[ 7].mQuatIndex == q &&
501
             CUBITS[ 8].mQuatIndex == q &&
502
             CUBITS[ 9].mQuatIndex == q &&
503
             CUBITS[10].mQuatIndex == q &&
504
             CUBITS[11].mQuatIndex == q &&
505
             CUBITS[12].mQuatIndex == q &&
506
             CUBITS[13].mQuatIndex == q &&
507
             CUBITS[14].mQuatIndex == q &&
508
             CUBITS[15].mQuatIndex == q &&
509
             CUBITS[16].mQuatIndex == q &&
510
             CUBITS[17].mQuatIndex == q &&
511
             CUBITS[18].mQuatIndex == q &&
512
             CUBITS[19].mQuatIndex == q  );
513
    }
514

    
515
///////////////////////////////////////////////////////////////////////////////////////////////////
516
// only needed for solvers - there are no Redi solvers ATM)
517

    
518
  public String retObjectString()
519
    {
520
    return "";
521
    }
522

    
523
///////////////////////////////////////////////////////////////////////////////////////////////////
524

    
525
  public int getObjectName(int numLayers)
526
    {
527
    return R.string.redi2;
528
    }
529

    
530
///////////////////////////////////////////////////////////////////////////////////////////////////
531

    
532
  public int getInventor(int numLayers)
533
    {
534
    return R.string.redi2_inventor;
535
    }
536

    
537
///////////////////////////////////////////////////////////////////////////////////////////////////
538

    
539
  public int getComplexity(int numLayers)
540
    {
541
    return 4;
542
    }
543
}
(31-31/33)