Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyRedi.java @ e6734aa9

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[] BASIC_ANGLE = new int[] { 3,3,3,3 };
55

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

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

    
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
           new Static4D(  0.5f, -0.5f, -0.5f,  0.5f ),
78
           new Static4D(  0.5f, -0.5f, -0.5f, -0.5f )
79
         };
80

    
81
  private static final float DIST_CORNER = 1.0f;
82
  private static final float DIST_EDGE   = 1.5f;
83

    
84
  // centers of the 8 corners + 12 edges ( i.e. of the all 20 cubits)
85
  private static final float[][] CENTERS = new float[][]
86
         {
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
             {-DIST_CORNER,-DIST_CORNER, DIST_CORNER },
94
             {-DIST_CORNER,-DIST_CORNER,-DIST_CORNER },
95

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

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

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

    
138
  private static final float G = 0.72f;
139

    
140
  private static final double[][] VERTICES_CORNER = new double[][]
141
          {
142
             { 0.0f, 0.0f, 0.0f },
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
             { 0.5f,-0.5f,-0.5f },
149
             {-0.5f, 0.5f,-0.5f },
150

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

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

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

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

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

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

    
204
  private static MeshBase[] mMeshes;
205

    
206
///////////////////////////////////////////////////////////////////////////////////////////////////
207

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

    
214
///////////////////////////////////////////////////////////////////////////////////////////////////
215

    
216
  float getScreenRatio()
217
    {
218
    return 0.50f;
219
    }
220

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

    
223
  Static4D[] getQuats()
224
    {
225
    return QUATS;
226
    }
227

    
228
///////////////////////////////////////////////////////////////////////////////////////////////////
229

    
230
  int getNumFaces()
231
    {
232
    return FACE_COLORS.length;
233
    }
234

    
235
///////////////////////////////////////////////////////////////////////////////////////////////////
236

    
237
  boolean shouldResetTextureMaps()
238
    {
239
    return false;
240
    }
241

    
242
///////////////////////////////////////////////////////////////////////////////////////////////////
243

    
244
  int getNumStickerTypes(int numLayers)
245
    {
246
    return 2;
247
    }
248

    
249
///////////////////////////////////////////////////////////////////////////////////////////////////
250

    
251
  float[][] getCuts(int size)
252
    {
253
    float[] cut = new float[] { -SQ3/3 -0.05f, +SQ3/3 +0.05f };
254
    return new float[][] { cut,cut,cut,cut };
255
    }
256

    
257
///////////////////////////////////////////////////////////////////////////////////////////////////
258

    
259
  int getNumCubitFaces()
260
    {
261
    return FACES_PER_CUBIT;
262
    }
263

    
264
///////////////////////////////////////////////////////////////////////////////////////////////////
265

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

    
271
///////////////////////////////////////////////////////////////////////////////////////////////////
272

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

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

    
300
    return null;
301
    }
302

    
303
///////////////////////////////////////////////////////////////////////////////////////////////////
304

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

    
314
    MeshBase mesh;
315

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

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

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

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

    
371
    return mesh;
372
    }
373

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

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

    
381
///////////////////////////////////////////////////////////////////////////////////////////////////
382

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

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

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

    
400
///////////////////////////////////////////////////////////////////////////////////////////////////
401

    
402
  float returnMultiplier()
403
    {
404
    return 2.0f;
405
    }
406

    
407
///////////////////////////////////////////////////////////////////////////////////////////////////
408
// PUBLIC API
409

    
410
  public Static3D[] getRotationAxis()
411
    {
412
    return ROT_AXIS;
413
    }
414

    
415
///////////////////////////////////////////////////////////////////////////////////////////////////
416

    
417
  public int[] getBasicAngle()
418
    {
419
    return BASIC_ANGLE;
420
    }
421

    
422
///////////////////////////////////////////////////////////////////////////////////////////////////
423

    
424
  public void randomizeNewScramble(int[][] scramble, Random rnd, int num)
425
    {
426
    if( num==0 )
427
      {
428
      scramble[num][0] = rnd.nextInt(NUM_AXIS);
429
      scramble[num][1] = rnd.nextFloat()<=0.5f ? 0:2;
430
      }
431
    else
432
      {
433
      int newVector = rnd.nextInt(NUM_AXIS -1);
434
      scramble[num][0] = (newVector>=scramble[num-1][0] ? newVector+1 : newVector);
435
      scramble[num][1] = (scramble[num-1][0]+scramble[num][0]==3 ? 2-scramble[num-1][1] : scramble[num-1][1]);
436
      }
437

    
438
    switch( rnd.nextInt(2) )
439
      {
440
      case 0: scramble[num][2] = -1; break;
441
      case 1: scramble[num][2] =  1; break;
442
      }
443
    }
444

    
445
///////////////////////////////////////////////////////////////////////////////////////////////////
446
// The Redi is solved if and only if:
447
//
448
// ??
449

    
450
  public boolean isSolved()
451
    {
452
    int q = CUBITS[0].mQuatIndex;
453

    
454
    return ( CUBITS[ 1].mQuatIndex == q &&
455
             CUBITS[ 2].mQuatIndex == q &&
456
             CUBITS[ 3].mQuatIndex == q &&
457
             CUBITS[ 4].mQuatIndex == q &&
458
             CUBITS[ 5].mQuatIndex == q &&
459
             CUBITS[ 6].mQuatIndex == q &&
460
             CUBITS[ 7].mQuatIndex == q &&
461
             CUBITS[ 8].mQuatIndex == q &&
462
             CUBITS[ 9].mQuatIndex == q &&
463
             CUBITS[10].mQuatIndex == q &&
464
             CUBITS[11].mQuatIndex == q &&
465
             CUBITS[12].mQuatIndex == q &&
466
             CUBITS[13].mQuatIndex == q &&
467
             CUBITS[14].mQuatIndex == q &&
468
             CUBITS[15].mQuatIndex == q &&
469
             CUBITS[16].mQuatIndex == q &&
470
             CUBITS[17].mQuatIndex == q &&
471
             CUBITS[18].mQuatIndex == q &&
472
             CUBITS[19].mQuatIndex == q  );
473
    }
474

    
475
///////////////////////////////////////////////////////////////////////////////////////////////////
476
// only needed for solvers - there are no Redi solvers ATM)
477

    
478
  public String retObjectString()
479
    {
480
    return "";
481
    }
482

    
483
///////////////////////////////////////////////////////////////////////////////////////////////////
484

    
485
  public int getObjectName(int numLayers)
486
    {
487
    return R.string.redi2;
488
    }
489

    
490
///////////////////////////////////////////////////////////////////////////////////////////////////
491

    
492
  public int getInventor(int numLayers)
493
    {
494
    return R.string.redi2_inventor;
495
    }
496

    
497
///////////////////////////////////////////////////////////////////////////////////////////////////
498

    
499
  public int getComplexity(int numLayers)
500
    {
501
    return 4;
502
    }
503
}
(33-33/37)