Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyRedi.java @ 925ed78f

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[] cuts = new float[2];
254

    
255
    cuts[0] = -SQ3/3 -0.05f;
256
    cuts[1] = +SQ3/3 +0.05f;
257

    
258
    return cuts;
259
    }
260

    
261
///////////////////////////////////////////////////////////////////////////////////////////////////
262

    
263
  int getNumCubitFaces()
264
    {
265
    return FACES_PER_CUBIT;
266
    }
267

    
268
///////////////////////////////////////////////////////////////////////////////////////////////////
269

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

    
275
///////////////////////////////////////////////////////////////////////////////////////////////////
276

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

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

    
304
    return null;
305
    }
306

    
307
///////////////////////////////////////////////////////////////////////////////////////////////////
308

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

    
318
    MeshBase mesh;
319

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

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

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

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

    
375
    return mesh;
376
    }
377

    
378
///////////////////////////////////////////////////////////////////////////////////////////////////
379

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

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

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

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

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

    
404
///////////////////////////////////////////////////////////////////////////////////////////////////
405

    
406
  float returnMultiplier()
407
    {
408
    return 2.0f;
409
    }
410

    
411
///////////////////////////////////////////////////////////////////////////////////////////////////
412
// PUBLIC API
413

    
414
  public Static3D[] getRotationAxis()
415
    {
416
    return ROT_AXIS;
417
    }
418

    
419
///////////////////////////////////////////////////////////////////////////////////////////////////
420

    
421
  public int[] getBasicAngle()
422
    {
423
    return BASIC_ANGLE;
424
    }
425

    
426
///////////////////////////////////////////////////////////////////////////////////////////////////
427

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

    
442
    switch( rnd.nextInt(2) )
443
      {
444
      case 0: scramble[num][2] = -1; break;
445
      case 1: scramble[num][2] =  1; break;
446
      }
447
    }
448

    
449
///////////////////////////////////////////////////////////////////////////////////////////////////
450
// The Redi is solved if and only if:
451
//
452
// ??
453

    
454
  public boolean isSolved()
455
    {
456
    int q = CUBITS[0].mQuatIndex;
457

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

    
479
///////////////////////////////////////////////////////////////////////////////////////////////////
480
// only needed for solvers - there are no Redi solvers ATM)
481

    
482
  public String retObjectString()
483
    {
484
    return "";
485
    }
486

    
487
///////////////////////////////////////////////////////////////////////////////////////////////////
488

    
489
  public int getObjectName(int numLayers)
490
    {
491
    return R.string.redi2;
492
    }
493

    
494
///////////////////////////////////////////////////////////////////////////////////////////////////
495

    
496
  public int getInventor(int numLayers)
497
    {
498
    return R.string.redi2_inventor;
499
    }
500

    
501
///////////////////////////////////////////////////////////////////////////////////////////////////
502

    
503
  public int getComplexity(int numLayers)
504
    {
505
    return 4;
506
    }
507
}
(33-33/37)