Project

General

Profile

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

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

1 68f6046c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
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 749ef882 Leszek Koltunski
import org.distorted.helpers.FactoryCubit;
27
import org.distorted.helpers.FactorySticker;
28 68f6046c Leszek Koltunski
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 6fd4a72c Leszek Koltunski
import org.distorted.main.R;
36 68f6046c Leszek Koltunski
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 323b217c Leszek Koltunski
           COLOR_RED   , COLOR_ORANGE
59 68f6046c Leszek Koltunski
         };
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 e6cf7283 Leszek Koltunski
  private static final float[][] CENTERS = new float[][]
84 68f6046c Leszek Koltunski
         {
85 e6cf7283 Leszek Koltunski
             { 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 68f6046c Leszek Koltunski
         };
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 962437b5 Leszek Koltunski
           {  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 68f6046c Leszek Koltunski
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 680469e6 Leszek Koltunski
  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 68f6046c Leszek Koltunski
204
///////////////////////////////////////////////////////////////////////////////////////////////////
205
206
  TwistyRedi(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
207
             DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
208
    {
209 db875721 Leszek Koltunski
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.REDI, res, scrWidth);
210 68f6046c Leszek Koltunski
    }
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 a64e07d0 Leszek Koltunski
  int getNumStickerTypes(int numLayers)
243 68f6046c Leszek Koltunski
    {
244
    return 2;
245
    }
246
247
///////////////////////////////////////////////////////////////////////////////////////////////////
248
249 a97e02b7 Leszek Koltunski
  float[] getCuts(int size)
250 68f6046c Leszek Koltunski
    {
251 a97e02b7 Leszek Koltunski
    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 68f6046c Leszek Koltunski
    }
258
259
///////////////////////////////////////////////////////////////////////////////////////////////////
260
261
  int getNumCubitFaces()
262
    {
263
    return FACES_PER_CUBIT;
264
    }
265
266
///////////////////////////////////////////////////////////////////////////////////////////////////
267
268 e6cf7283 Leszek Koltunski
  float[][] getCubitPositions(int size)
269 68f6046c Leszek Koltunski
    {
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 a64e07d0 Leszek Koltunski
  MeshBase createCubitMesh(int cubit, int numLayers)
308 68f6046c Leszek Koltunski
    {
309 680469e6 Leszek Koltunski
    if( mMeshes==null )
310
      {
311
      FactoryCubit factory = FactoryCubit.getInstance();
312
      factory.clear();
313
      mMeshes = new MeshBase[2];
314
      }
315
316 68f6046c Leszek Koltunski
    MeshBase mesh;
317
318
    if( cubit<8 )
319
      {
320 680469e6 Leszek Koltunski
      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 68f6046c Leszek Koltunski
      }
343
    else
344
      {
345 680469e6 Leszek Koltunski
      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 68f6046c Leszek Koltunski
      }
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 ae755eda Leszek Koltunski
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
386 68f6046c Leszek Koltunski
    {
387
    int COLORS = FACE_COLORS.length;
388 680469e6 Leszek Koltunski
    int stickerType = face/COLORS;
389
    float R,S;
390 68f6046c Leszek Koltunski
391 680469e6 Leszek Koltunski
    switch(stickerType)
392 68f6046c Leszek Koltunski
      {
393 680469e6 Leszek Koltunski
      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 68f6046c Leszek Koltunski
      }
397
398 680469e6 Leszek Koltunski
    FactorySticker factory = FactorySticker.getInstance();
399
    factory.drawRoundedPolygon(canvas, paint, left, top, STICKERS[stickerType], S, FACE_COLORS[face%COLORS], R);
400 68f6046c Leszek Koltunski
    }
401
402
///////////////////////////////////////////////////////////////////////////////////////////////////
403
404
  float returnMultiplier()
405
    {
406
    return 2.0f;
407
    }
408
409
///////////////////////////////////////////////////////////////////////////////////////////////////
410
411 a64e07d0 Leszek Koltunski
  float[] getRowChances(int numLayers)
412 68f6046c Leszek Koltunski
    {
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 5043d5d0 Leszek Koltunski
  public void randomizeNewScramble(int[][] scramble, Random rnd, int num)
440 68f6046c Leszek Koltunski
    {
441 5043d5d0 Leszek Koltunski
    if( num==0 )
442 68f6046c Leszek Koltunski
      {
443 5043d5d0 Leszek Koltunski
      scramble[num][0] = rnd.nextInt(ROTATION_AXIS.length);
444
      scramble[num][1] = rnd.nextFloat()<=0.5f ? 0:2;
445 68f6046c Leszek Koltunski
      }
446
    else
447
      {
448 bbc6471c Leszek Koltunski
      int newVector = rnd.nextInt(ROTATION_AXIS.length-1);
449 5043d5d0 Leszek Koltunski
      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 68f6046c Leszek Koltunski
      }
452
453 5043d5d0 Leszek Koltunski
    switch( rnd.nextInt(2) )
454
      {
455
      case 0: scramble[num][2] = -1; break;
456
      case 1: scramble[num][2] =  1; break;
457
      }
458 68f6046c Leszek Koltunski
    }
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 fcd8226a Leszek Koltunski
    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 68f6046c Leszek Koltunski
    }
489
490
///////////////////////////////////////////////////////////////////////////////////////////////////
491
// only needed for solvers - there are no Redi solvers ATM)
492
493
  public String retObjectString()
494
    {
495
    return "";
496
    }
497 6fd4a72c Leszek Koltunski
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 68f6046c Leszek Koltunski
}