Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyRedi.java @ 0203be88

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  ORANGE 5
110
  // YELLOW 6 WHITE 7 BLUE 8 GREEN 9 RED 10 ORANGE 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
// PUBLIC API
411

    
412
  public Static3D[] getRotationAxis()
413
    {
414
    return ROT_AXIS;
415
    }
416

    
417
///////////////////////////////////////////////////////////////////////////////////////////////////
418

    
419
  public int getBasicAngle()
420
    {
421
    return 3;
422
    }
423

    
424
///////////////////////////////////////////////////////////////////////////////////////////////////
425

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

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

    
447
///////////////////////////////////////////////////////////////////////////////////////////////////
448
// The Redi is solved if and only if:
449
//
450
// ??
451

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

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

    
477
///////////////////////////////////////////////////////////////////////////////////////////////////
478
// only needed for solvers - there are no Redi solvers ATM)
479

    
480
  public String retObjectString()
481
    {
482
    return "";
483
    }
484

    
485
///////////////////////////////////////////////////////////////////////////////////////////////////
486

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

    
492
///////////////////////////////////////////////////////////////////////////////////////////////////
493

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

    
499
///////////////////////////////////////////////////////////////////////////////////////////////////
500

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