Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyRedi.java @ 7d8cc029

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
  float getScreenRatio()
215
    {
216
    return 0.50f;
217
    }
218

    
219
///////////////////////////////////////////////////////////////////////////////////////////////////
220

    
221
  Static4D[] getQuats()
222
    {
223
    return QUATS;
224
    }
225

    
226
///////////////////////////////////////////////////////////////////////////////////////////////////
227

    
228
  int getNumFaces()
229
    {
230
    return FACE_COLORS.length;
231
    }
232

    
233
///////////////////////////////////////////////////////////////////////////////////////////////////
234

    
235
  boolean shouldResetTextureMaps()
236
    {
237
    return false;
238
    }
239

    
240
///////////////////////////////////////////////////////////////////////////////////////////////////
241

    
242
  int getNumStickerTypes(int numLayers)
243
    {
244
    return 2;
245
    }
246

    
247
///////////////////////////////////////////////////////////////////////////////////////////////////
248

    
249
  float[] getCuts(int size)
250
    {
251
    float[] cuts = new float[2];
252

    
253
    cuts[0] = -SQ3/3 -0.05f;
254
    cuts[1] = +SQ3/3 +0.05f;
255

    
256
    return cuts;
257
    }
258

    
259
///////////////////////////////////////////////////////////////////////////////////////////////////
260

    
261
  int getNumCubitFaces()
262
    {
263
    return FACES_PER_CUBIT;
264
    }
265

    
266
///////////////////////////////////////////////////////////////////////////////////////////////////
267

    
268
  float[][] getCubitPositions(int size)
269
    {
270
    return CENTERS;
271
    }
272

    
273
///////////////////////////////////////////////////////////////////////////////////////////////////
274

    
275
  private Static4D getQuat(int cubit)
276
    {
277
    switch(cubit)
278
      {
279
      case  0: return QUATS[0];                          //  unit quat
280
      case  1: return new Static4D( SQ2/2,0,0,SQ2/2);    //  90 along X
281
      case  2: return new Static4D(-SQ2/2,0,0,SQ2/2);    // -90 along X
282
      case  3: return QUATS[1];                          // 180 along X
283
      case  4: return new Static4D(0, SQ2/2,0,SQ2/2);    //  90 along Y
284
      case  5: return QUATS[2];                          // 180 along Y
285
      case  6: return QUATS[3];                          // 180 along Z
286
      case  7: return new Static4D(SQ2/2,0,-SQ2/2,0);    // 180 along (SQ2/2,0,-SQ2/2)
287

    
288
      case  8: return QUATS[0];
289
      case  9: return QUATS[5];
290
      case 10: return QUATS[3];
291
      case 11: return QUATS[11];
292
      case 12: return QUATS[4];
293
      case 13: return QUATS[7];
294
      case 14: return QUATS[9];
295
      case 15: return QUATS[10];
296
      case 16: return QUATS[2];
297
      case 17: return QUATS[8];
298
      case 18: return QUATS[1];
299
      case 19: return QUATS[6];
300
      }
301

    
302
    return null;
303
    }
304

    
305
///////////////////////////////////////////////////////////////////////////////////////////////////
306

    
307
  MeshBase createCubitMesh(int cubit, int numLayers)
308
    {
309
    if( mMeshes==null )
310
      {
311
      FactoryCubit factory = FactoryCubit.getInstance();
312
      factory.clear();
313
      mMeshes = new MeshBase[2];
314
      }
315

    
316
    MeshBase mesh;
317

    
318
    if( cubit<8 )
319
      {
320
      if( mMeshes[0]==null )
321
        {
322
        float[][] bands= new float[][]
323
          {
324
             {0.06f,35,0.5f,0.7f,6,2,2},
325
             {0.00f, 0,1.0f,0.0f,2,0,0}
326
          };
327
        int[] bandIndexes   = new int[] { 0,0,0,1,1,1 };
328
        float[][] corners   = new float[][] { {0.06f,0.12f} };
329
        int[] cornerIndexes = new int[] { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
330
        float[][] centers   = new float[][] { { 0.0f, 0.0f, 0.0f} };
331
        int[] centerIndexes = new int[] { -1,0,-1,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 };
332

    
333
        FactoryCubit factory = FactoryCubit.getInstance();
334
        factory.createNewFaceTransform(VERTICES_CORNER,VERT_INDEXES_CORNER);
335
        mMeshes[0] = factory.createRoundedSolid(VERTICES_CORNER, VERT_INDEXES_CORNER,
336
                                                bands, bandIndexes,
337
                                                corners, cornerIndexes,
338
                                                centers, centerIndexes,
339
                                                getNumCubitFaces() );
340
        }
341
      mesh = mMeshes[0].copy(true);
342
      }
343
    else
344
      {
345
      if( mMeshes[1]==null )
346
        {
347
        float[][] bands= new float[][]
348
          {
349
            {0.038f,35,0.250f,0.7f, 7,2,2},
350
            {0.020f,35,0.125f,0.2f, 3,1,2},
351
            {0.020f,35,0.125f,0.2f, 3,1,1}
352
          };
353
        int[] bandIndexes   = new int[] { 0,0,1,1,2,2 };
354
        float[][] corners   = new float[][] { {0.06f,0.20f} };
355
        int[] cornerIndexes = new int[] { 0,0,-1,-1,-1,-1,-1,-1 };
356
        float[][] centers   = new float[][] { { 0.0f,-0.75f,-0.75f} };
357
        int[] centerIndexes = new int[] { 0,0,-1,-1,-1,-1,-1,-1 };
358

    
359
        FactoryCubit factory = FactoryCubit.getInstance();
360
        factory.createNewFaceTransform(VERTICES_EDGE,VERT_INDEXES_EDGE);
361
        mMeshes[1] = factory.createRoundedSolid(VERTICES_EDGE, VERT_INDEXES_EDGE,
362
                                                bands, bandIndexes,
363
                                                corners, cornerIndexes,
364
                                                centers, centerIndexes,
365
                                                getNumCubitFaces() );
366
        }
367
      mesh = mMeshes[1].copy(true);
368
      }
369

    
370
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( getQuat(cubit), new Static3D(0,0,0) );
371
    mesh.apply(quat,0xffffffff,0);
372

    
373
    return mesh;
374
    }
375

    
376
///////////////////////////////////////////////////////////////////////////////////////////////////
377

    
378
  int getFaceColor(int cubit, int cubitface, int size)
379
    {
380
    return mFaceMap[cubit][cubitface];
381
    }
382

    
383
///////////////////////////////////////////////////////////////////////////////////////////////////
384

    
385
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
386
    {
387
    int COLORS = FACE_COLORS.length;
388
    int stickerType = face/COLORS;
389
    float R,S;
390

    
391
    switch(stickerType)
392
      {
393
      case 0:  R = 0.09f; S = 0.09f; break;
394
      case 1:  R = 0.06f; S = 0.06f; break;
395
      default: R = 0.00f; S = 0.00f; break;
396
      }
397

    
398
    FactorySticker factory = FactorySticker.getInstance();
399
    factory.drawRoundedPolygon(canvas, paint, left, top, STICKERS[stickerType], S, FACE_COLORS[face%COLORS], R);
400
    }
401

    
402
///////////////////////////////////////////////////////////////////////////////////////////////////
403

    
404
  float returnMultiplier()
405
    {
406
    return 2.0f;
407
    }
408

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

    
411
  float[] getRowChances(int numLayers)
412
    {
413
    float[] chances = new float[3];
414

    
415
    chances[0] = 0.5f;
416
    chances[1] = 0.5f;
417
    chances[2] = 1.0f;
418

    
419
    return chances;
420
    }
421

    
422
///////////////////////////////////////////////////////////////////////////////////////////////////
423
// PUBLIC API
424

    
425
  public Static3D[] getRotationAxis()
426
    {
427
    return ROT_AXIS;
428
    }
429

    
430
///////////////////////////////////////////////////////////////////////////////////////////////////
431

    
432
  public int getBasicAngle()
433
    {
434
    return 3;
435
    }
436

    
437
///////////////////////////////////////////////////////////////////////////////////////////////////
438

    
439
  public void randomizeNewScramble(int[][] scramble, Random rnd, int num)
440
    {
441
    if( num==0 )
442
      {
443
      scramble[num][0] = rnd.nextInt(ROTATION_AXIS.length);
444
      scramble[num][1] = rnd.nextFloat()<=0.5f ? 0:2;
445
      }
446
    else
447
      {
448
      int newVector = rnd.nextInt(ROTATION_AXIS.length-1);
449
      scramble[num][0] = (newVector>=scramble[num-1][0] ? newVector+1 : newVector);
450
      scramble[num][1] = (scramble[num-1][0]+scramble[num][0]==3 ? 2-scramble[num-1][1] : scramble[num-1][1]);
451
      }
452

    
453
    switch( rnd.nextInt(2) )
454
      {
455
      case 0: scramble[num][2] = -1; break;
456
      case 1: scramble[num][2] =  1; break;
457
      }
458
    }
459

    
460
///////////////////////////////////////////////////////////////////////////////////////////////////
461
// The Redi is solved if and only if:
462
//
463
// ??
464

    
465
  public boolean isSolved()
466
    {
467
    int q = CUBITS[0].mQuatIndex;
468

    
469
    return ( CUBITS[ 1].mQuatIndex == q &&
470
             CUBITS[ 2].mQuatIndex == q &&
471
             CUBITS[ 3].mQuatIndex == q &&
472
             CUBITS[ 4].mQuatIndex == q &&
473
             CUBITS[ 5].mQuatIndex == q &&
474
             CUBITS[ 6].mQuatIndex == q &&
475
             CUBITS[ 7].mQuatIndex == q &&
476
             CUBITS[ 8].mQuatIndex == q &&
477
             CUBITS[ 9].mQuatIndex == q &&
478
             CUBITS[10].mQuatIndex == q &&
479
             CUBITS[11].mQuatIndex == q &&
480
             CUBITS[12].mQuatIndex == q &&
481
             CUBITS[13].mQuatIndex == q &&
482
             CUBITS[14].mQuatIndex == q &&
483
             CUBITS[15].mQuatIndex == q &&
484
             CUBITS[16].mQuatIndex == q &&
485
             CUBITS[17].mQuatIndex == q &&
486
             CUBITS[18].mQuatIndex == q &&
487
             CUBITS[19].mQuatIndex == q  );
488
    }
489

    
490
///////////////////////////////////////////////////////////////////////////////////////////////////
491
// only needed for solvers - there are no Redi solvers ATM)
492

    
493
  public String retObjectString()
494
    {
495
    return "";
496
    }
497

    
498
///////////////////////////////////////////////////////////////////////////////////////////////////
499

    
500
  public int getObjectName(int numLayers)
501
    {
502
    return R.string.redi2;
503
    }
504

    
505
///////////////////////////////////////////////////////////////////////////////////////////////////
506

    
507
  public int getInventor(int numLayers)
508
    {
509
    return R.string.redi2_inventor;
510
    }
511

    
512
///////////////////////////////////////////////////////////////////////////////////////////////////
513

    
514
  public int getComplexity(int numLayers)
515
    {
516
    return 4;
517
    }
518
}
(31-31/33)