Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyHelicopter.java @ cb137f36

1 ee35e63c 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 ee35e63c 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 ee35e63c Leszek Koltunski
import org.distorted.main.RubikSurfaceView;
37
38
import java.util.Random;
39
40
///////////////////////////////////////////////////////////////////////////////////////////////////
41
42 9c2f0c91 Leszek Koltunski
public class TwistyHelicopter extends TwistyObject
43 ee35e63c Leszek Koltunski
{
44
  private static final int FACES_PER_CUBIT =6;
45
46
  // the six rotation axis of a Helicopter. Must be normalized.
47
  static final Static3D[] ROT_AXIS = new Static3D[]
48
         {
49
           new Static3D(     0, +SQ2/2, -SQ2/2),
50
           new Static3D(     0, -SQ2/2, -SQ2/2),
51
           new Static3D(+SQ2/2,      0, -SQ2/2),
52
           new Static3D(-SQ2/2,      0, -SQ2/2),
53
           new Static3D(+SQ2/2, -SQ2/2,      0),
54
           new Static3D(-SQ2/2, -SQ2/2,      0)
55
         };
56
57
  private static final int[] FACE_COLORS = new int[]
58
         {
59 ece1b58d Leszek Koltunski
           COLOR_YELLOW, COLOR_WHITE,
60
           COLOR_BLUE  , COLOR_GREEN,
61 323b217c Leszek Koltunski
           COLOR_RED   , COLOR_ORANGE
62 ee35e63c Leszek Koltunski
         };
63
64
  // All legal rotation quats of a HELICOPTER (same as the Cube!)
65
  private static final Static4D[] QUATS = new Static4D[]
66
         {
67
           new Static4D( 0.00f,  0.00f,  0.00f,  1.00f ),
68
           new Static4D( 1.00f,  0.00f,  0.00f,  0.00f ),
69
           new Static4D( 0.00f,  1.00f,  0.00f,  0.00f ),
70
           new Static4D( 0.00f,  0.00f,  1.00f,  0.00f ),
71
72
           new Static4D( SQ2/2,  SQ2/2,  0.00f,  0.00f ),
73
           new Static4D( SQ2/2, -SQ2/2,  0.00f,  0.00f ),
74
           new Static4D( SQ2/2,  0.00f,  SQ2/2,  0.00f ),
75
           new Static4D( SQ2/2,  0.00f, -SQ2/2,  0.00f ),
76
           new Static4D( SQ2/2,  0.00f,  0.00f,  SQ2/2 ),
77
           new Static4D( SQ2/2,  0.00f,  0.00f, -SQ2/2 ),
78
           new Static4D( 0.00f,  SQ2/2,  SQ2/2,  0.00f ),
79
           new Static4D( 0.00f,  SQ2/2, -SQ2/2,  0.00f ),
80
           new Static4D( 0.00f,  SQ2/2,  0.00f,  SQ2/2 ),
81
           new Static4D( 0.00f,  SQ2/2,  0.00f, -SQ2/2 ),
82
           new Static4D( 0.00f,  0.00f,  SQ2/2,  SQ2/2 ),
83
           new Static4D( 0.00f,  0.00f,  SQ2/2, -SQ2/2 ),
84
85
           new Static4D( 0.50f,  0.50f,  0.50f,  0.50f ),
86
           new Static4D( 0.50f,  0.50f,  0.50f, -0.50f ),
87
           new Static4D( 0.50f,  0.50f, -0.50f,  0.50f ),
88
           new Static4D( 0.50f,  0.50f, -0.50f, -0.50f ),
89
           new Static4D( 0.50f, -0.50f,  0.50f,  0.50f ),
90
           new Static4D( 0.50f, -0.50f,  0.50f, -0.50f ),
91
           new Static4D( 0.50f, -0.50f, -0.50f,  0.50f ),
92
           new Static4D( 0.50f, -0.50f, -0.50f, -0.50f )
93
         };
94
95
  private static final float DIST_CORNER = 0.50f;
96 b0a56742 Leszek Koltunski
  private static final float DIST_CENTER = 0.50f;
97 ee35e63c Leszek Koltunski
  private static final float XY_CENTER   = DIST_CORNER/3;
98
99
  // centers of the 8 corners + 6*4 face triangles ( i.e. of the all 32 cubits)
100 e6cf7283 Leszek Koltunski
  private static final float[][] CENTERS = new float[][]
101 ee35e63c Leszek Koltunski
         {
102 e6cf7283 Leszek Koltunski
             {   DIST_CORNER,   DIST_CORNER,   DIST_CORNER },
103
             {   DIST_CORNER,   DIST_CORNER,  -DIST_CORNER },
104
             {   DIST_CORNER,  -DIST_CORNER,   DIST_CORNER },
105
             {   DIST_CORNER,  -DIST_CORNER,  -DIST_CORNER },
106
             {  -DIST_CORNER,   DIST_CORNER,   DIST_CORNER },
107
             {  -DIST_CORNER,   DIST_CORNER,  -DIST_CORNER },
108
             {  -DIST_CORNER,  -DIST_CORNER,   DIST_CORNER },
109
             {  -DIST_CORNER,  -DIST_CORNER,  -DIST_CORNER },
110
111
             {   DIST_CENTER,     XY_CENTER,     XY_CENTER },
112
             {   DIST_CENTER,     XY_CENTER,    -XY_CENTER },
113
             {   DIST_CENTER,    -XY_CENTER,     XY_CENTER },
114
             {   DIST_CENTER,    -XY_CENTER,    -XY_CENTER },
115
116
             {  -DIST_CENTER,     XY_CENTER,     XY_CENTER },
117
             {  -DIST_CENTER,     XY_CENTER,    -XY_CENTER },
118
             {  -DIST_CENTER,    -XY_CENTER,     XY_CENTER },
119
             {  -DIST_CENTER,    -XY_CENTER,    -XY_CENTER },
120
121
             {   XY_CENTER  ,   DIST_CENTER,     XY_CENTER },
122
             {   XY_CENTER  ,   DIST_CENTER,    -XY_CENTER },
123
             {  -XY_CENTER  ,   DIST_CENTER,     XY_CENTER },
124
             {  -XY_CENTER  ,   DIST_CENTER,    -XY_CENTER },
125
126
             {   XY_CENTER  ,  -DIST_CENTER,     XY_CENTER },
127
             {   XY_CENTER  ,  -DIST_CENTER,    -XY_CENTER },
128
             {  -XY_CENTER  ,  -DIST_CENTER,     XY_CENTER },
129
             {  -XY_CENTER  ,  -DIST_CENTER,    -XY_CENTER },
130
131
             {   XY_CENTER  ,     XY_CENTER,   DIST_CENTER },
132
             {   XY_CENTER  ,    -XY_CENTER,   DIST_CENTER },
133
             {  -XY_CENTER  ,     XY_CENTER,   DIST_CENTER },
134
             {  -XY_CENTER  ,    -XY_CENTER,   DIST_CENTER },
135
136
             {   XY_CENTER  ,     XY_CENTER,  -DIST_CENTER },
137
             {   XY_CENTER  ,    -XY_CENTER,  -DIST_CENTER },
138
             {  -XY_CENTER  ,     XY_CENTER,  -DIST_CENTER },
139
             {  -XY_CENTER  ,    -XY_CENTER,  -DIST_CENTER },
140 ee35e63c Leszek Koltunski
         };
141
142
  // Colors of the faces of cubits. Each cubit has 6 faces
143
  private static final int[][] mFaceMap = new int[][]
144
         {
145
           { 4,2,0, 6,6,6 },
146 20a0214b Leszek Koltunski
           { 0,2,5, 6,6,6 },
147
           { 4,0,3, 6,6,6 },
148 ee35e63c Leszek Koltunski
           { 5,3,0, 6,6,6 },
149
           { 1,2,4, 6,6,6 },
150
           { 5,2,1, 6,6,6 },
151
           { 4,3,1, 6,6,6 },
152
           { 1,3,5, 6,6,6 },
153
154
           { 0 , 6,6,6,6,6 },
155
           { 0 , 6,6,6,6,6 },
156
           { 0 , 6,6,6,6,6 },
157
           { 0 , 6,6,6,6,6 },
158
159
           { 1 , 6,6,6,6,6 },
160
           { 1 , 6,6,6,6,6 },
161
           { 1 , 6,6,6,6,6 },
162
           { 1 , 6,6,6,6,6 },
163
164
           { 2 , 6,6,6,6,6 },
165
           { 2 , 6,6,6,6,6 },
166
           { 2 , 6,6,6,6,6 },
167
           { 2 , 6,6,6,6,6 },
168
169
           { 3 , 6,6,6,6,6 },
170
           { 3 , 6,6,6,6,6 },
171
           { 3 , 6,6,6,6,6 },
172
           { 3 , 6,6,6,6,6 },
173
174
           { 4 , 6,6,6,6,6 },
175
           { 4 , 6,6,6,6,6 },
176
           { 4 , 6,6,6,6,6 },
177
           { 4 , 6,6,6,6,6 },
178
179
           { 5 , 6,6,6,6,6 },
180
           { 5 , 6,6,6,6,6 },
181
           { 5 , 6,6,6,6,6 },
182
           { 5 , 6,6,6,6,6 },
183
         };
184
185 a64e07d0 Leszek Koltunski
  private static final int[] QUAT_INDICES =
186 20a0214b Leszek Koltunski
      { 0,13,14,1,12,2,3,7,20,6,13,17,7,23,18,12,22,10,8,16,11,21,19,9,3,15,14,0,5,2,1,4 };
187
188 b1f2ccf5 Leszek Koltunski
  private final double[][] VERTICES_CORNER = new double[][]
189
          {
190
            // TODO
191
          };
192
193
  private final int[][] VERT_INDEXES_CORNER = new int[][]
194
          {
195
            // TODO
196
          };
197
198
  private final double[][] VERTICES_FACE = new double[][]
199
          {
200
            // TODO
201
          };
202
203
  private final int[][] VERT_INDEXES_FACE = new int[][]
204
          {
205
            // TODO
206
          };
207
208 ee35e63c Leszek Koltunski
  private static MeshBase mCornerMesh, mFaceMesh;
209
210
///////////////////////////////////////////////////////////////////////////////////////////////////
211
212 9c2f0c91 Leszek Koltunski
  TwistyHelicopter(int size, Static4D quat, DistortedTexture texture,
213
                   MeshSquare mesh, DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
214 ee35e63c Leszek Koltunski
    {
215 db875721 Leszek Koltunski
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.HELI, res, scrWidth);
216 ee35e63c Leszek Koltunski
    }
217
218 b1f2ccf5 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
219
220
  double[][] getVertices(int cubitType)
221
    {
222
     if( cubitType==0 )  // Corner
223
      {
224
      return VERTICES_CORNER;
225
      }
226
    if( cubitType==1 )  // Face
227
      {
228
      return VERTICES_FACE;
229
      }
230
231
    return null;
232
    }
233
234
///////////////////////////////////////////////////////////////////////////////////////////////////
235
236
  int[][] getVertIndexes(int cubitType)
237
    {
238
    if( cubitType==0 )  // Corner
239
      {
240
      return VERT_INDEXES_CORNER;
241
      }
242
    if( cubitType==1 )  // Face
243
      {
244
      return VERT_INDEXES_FACE;
245
      }
246
247
    return null;
248
    }
249
250
///////////////////////////////////////////////////////////////////////////////////////////////////
251
252
  int getNumCubitTypes(int numLayers)
253
    {
254
    return 1;
255
    }
256
257 ee35e63c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
258
259
  float getScreenRatio()
260
    {
261 e06e1b7e Leszek Koltunski
    return 1.6f;
262 ee35e63c Leszek Koltunski
    }
263
264
///////////////////////////////////////////////////////////////////////////////////////////////////
265
266
  Static4D[] getQuats()
267
    {
268
    return QUATS;
269
    }
270
271 eaee1ddc Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
272
273
  boolean shouldResetTextureMaps()
274
    {
275
    return false;
276
    }
277
278 ee35e63c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
279
280
  int getNumFaces()
281
    {
282
    return FACE_COLORS.length;
283
    }
284
285
///////////////////////////////////////////////////////////////////////////////////////////////////
286
287 a64e07d0 Leszek Koltunski
  int getNumStickerTypes(int numLayers)
288 ee35e63c Leszek Koltunski
    {
289
    return 1;
290
    }
291
292 7403cdfa Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
293
294 a97e02b7 Leszek Koltunski
  float[] getCuts(int size)
295 7403cdfa Leszek Koltunski
    {
296 a97e02b7 Leszek Koltunski
    float[] cuts = new float[2];
297
298
    cuts[0] = -SQ2/4;
299
    cuts[1] = +SQ2/4;
300
301
    return cuts;
302 7403cdfa Leszek Koltunski
    }
303
304 ee35e63c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
305
306
  int getNumCubitFaces()
307
    {
308
    return FACES_PER_CUBIT;
309
    }
310
311
///////////////////////////////////////////////////////////////////////////////////////////////////
312
313 e6cf7283 Leszek Koltunski
  float[][] getCubitPositions(int size)
314 ee35e63c Leszek Koltunski
    {
315
    return CENTERS;
316
    }
317
318
///////////////////////////////////////////////////////////////////////////////////////////////////
319
320 a64e07d0 Leszek Koltunski
  MeshBase createCubitMesh(int cubit, int numLayers)
321 ee35e63c Leszek Koltunski
    {
322
    MeshBase mesh;
323
324
    if( cubit<8 )
325
      {
326 b89898c5 Leszek Koltunski
      if( mCornerMesh==null ) mCornerMesh = FactoryCubit.getInstance().createHelicopterCornerMesh();
327 ee35e63c Leszek Koltunski
      mesh = mCornerMesh.copy(true);
328
      }
329
    else
330
      {
331 b89898c5 Leszek Koltunski
      if( mFaceMesh==null ) mFaceMesh = FactoryCubit.getInstance().createHelicopterFaceMesh();
332 ee35e63c Leszek Koltunski
      mesh = mFaceMesh.copy(true);
333
      }
334
335 20a0214b Leszek Koltunski
    int index = QUAT_INDICES[cubit];
336 ee35e63c Leszek Koltunski
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( QUATS[index], new Static3D(0,0,0) );
337
    mesh.apply(quat,0xffffffff,0);
338
339
    return mesh;
340
    }
341
342
///////////////////////////////////////////////////////////////////////////////////////////////////
343
344
  int getFaceColor(int cubit, int cubitface, int size)
345
    {
346
    return mFaceMap[cubit][cubitface];
347
    }
348
349
///////////////////////////////////////////////////////////////////////////////////////////////////
350
351 ae755eda Leszek Koltunski
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
352 ee35e63c Leszek Koltunski
    {
353 e06e1b7e Leszek Koltunski
    float R = 0.023f;
354 76c2bd07 Leszek Koltunski
    float S = 0.035f;
355
    float E = 0.5f;
356
    float[] vertices = { -E+E/4,E/4, E/4,-E+E/4, E/4,E/4};
357 ee35e63c Leszek Koltunski
358 b89898c5 Leszek Koltunski
    FactorySticker factory = FactorySticker.getInstance();
359 ae755eda Leszek Koltunski
    factory.drawRoundedPolygon(canvas, paint, left, top, vertices, S, FACE_COLORS[face], R);
360 ee35e63c Leszek Koltunski
    }
361
362
///////////////////////////////////////////////////////////////////////////////////////////////////
363
364
  float returnMultiplier()
365
    {
366
    return 2.0f;
367
    }
368
369
///////////////////////////////////////////////////////////////////////////////////////////////////
370
371 a64e07d0 Leszek Koltunski
  float[] getRowChances(int numLayers)
372 ee35e63c Leszek Koltunski
    {
373 475cbfe7 Leszek Koltunski
    float[] chances = new float[3];
374 ee35e63c Leszek Koltunski
375
    chances[0] = 0.5f;
376
    chances[1] = 0.5f;
377 475cbfe7 Leszek Koltunski
    chances[2] = 1.0f;
378 ee35e63c Leszek Koltunski
379
    return chances;
380
    }
381
382
///////////////////////////////////////////////////////////////////////////////////////////////////
383
// PUBLIC API
384
385
  public Static3D[] getRotationAxis()
386
    {
387
    return ROT_AXIS;
388
    }
389
390
///////////////////////////////////////////////////////////////////////////////////////////////////
391
392
  public int getBasicAngle()
393
    {
394
    return 2;
395
    }
396
397
///////////////////////////////////////////////////////////////////////////////////////////////////
398
399 5043d5d0 Leszek Koltunski
  public void randomizeNewScramble(int[][] scramble, Random rnd, int num)
400 ee35e63c Leszek Koltunski
    {
401 5043d5d0 Leszek Koltunski
    if( num==0 )
402 ee35e63c Leszek Koltunski
      {
403 5043d5d0 Leszek Koltunski
      scramble[num][0] = rnd.nextInt(ROTATION_AXIS.length);
404 ee35e63c Leszek Koltunski
      }
405
    else
406
      {
407 bbc6471c Leszek Koltunski
      int newVector = rnd.nextInt(ROTATION_AXIS.length-2);
408 ee35e63c Leszek Koltunski
409 5043d5d0 Leszek Koltunski
      switch(scramble[num-1][0])
410 ee35e63c Leszek Koltunski
        {
411
        case  0:
412 5043d5d0 Leszek Koltunski
        case  1: scramble[num][0] = newVector+2;
413 bbc6471c Leszek Koltunski
                 break;
414 ee35e63c Leszek Koltunski
        case  2:
415 5043d5d0 Leszek Koltunski
        case  3: scramble[num][0] = (newVector==0 || newVector==1) ? newVector:newVector+2;
416 bbc6471c Leszek Koltunski
                 break;
417 5043d5d0 Leszek Koltunski
        default: scramble[num][0] = newVector;
418 bbc6471c Leszek Koltunski
                 break;
419 ee35e63c Leszek Koltunski
        }
420
      }
421
422
    float rowFloat = rnd.nextFloat();
423
424
    for(int row=0; row<mRowChances.length; row++)
425
      {
426 bbc6471c Leszek Koltunski
      if( rowFloat<=mRowChances[row] )
427
        {
428 5043d5d0 Leszek Koltunski
        scramble[num][1] = row;
429 bbc6471c Leszek Koltunski
        break;
430
        }
431 ee35e63c Leszek Koltunski
      }
432
433 5043d5d0 Leszek Koltunski
    switch( rnd.nextInt(2) )
434
      {
435
      case 0: scramble[num][2] = -1; break;
436
      case 1: scramble[num][2] =  1; break;
437
      }
438 ee35e63c Leszek Koltunski
    }
439
440
///////////////////////////////////////////////////////////////////////////////////////////////////
441
// The Helicopter is solved if and only if:
442
//
443
// 1) all of its corner cubits are rotated with the same quat
444
// 2) all its face cubits are rotated with the same quat like the corner ones,
445
//    and optionally they also might be turned by a multiple of 90 degrees along
446
//    a vector perpendicular to the face they lie on.
447
//
448
// i.e.
449
// cubits  8, 9,10,11,12,13,14,15 - might be extra QUAT 1,8,9
450
// cubits 16,17,18,19,20,21,22,23 - might be extra QUAT 2,12,13
451
// cubits 24,25,26,27,28,29,30,31 - might be extra QUAT 3,14,15
452
453
  public boolean isSolved()
454
    {
455
    int q = CUBITS[0].mQuatIndex;
456
457
    if ( CUBITS[1].mQuatIndex == q &&
458
         CUBITS[2].mQuatIndex == q &&
459
         CUBITS[3].mQuatIndex == q &&
460
         CUBITS[4].mQuatIndex == q &&
461
         CUBITS[5].mQuatIndex == q &&
462
         CUBITS[6].mQuatIndex == q &&
463
         CUBITS[7].mQuatIndex == q  )
464
      {
465
      int q1 = mulQuat(q,1);
466
      int q2 = mulQuat(q,8);
467
      int q3 = mulQuat(q,9);
468
469
      for(int index=8; index<16; index++)
470
        {
471
        int qIndex = CUBITS[index].mQuatIndex;
472
        if( qIndex!=q && qIndex!=q1 && qIndex!=q2 && qIndex!=q3 ) return false;
473
        }
474
475
      q1 = mulQuat(q, 2);
476
      q2 = mulQuat(q,12);
477
      q3 = mulQuat(q,13);
478
479
      for(int index=16; index<24; index++)
480
        {
481
        int qIndex = CUBITS[index].mQuatIndex;
482
        if( qIndex!=q && qIndex!=q1 && qIndex!=q2 && qIndex!=q3 ) return false;
483
        }
484
485
      q1 = mulQuat(q, 3);
486
      q2 = mulQuat(q,14);
487
      q3 = mulQuat(q,15);
488
489
      for(int index=24; index<32; index++)
490
        {
491
        int qIndex = CUBITS[index].mQuatIndex;
492
        if( qIndex!=q && qIndex!=q1 && qIndex!=q2 && qIndex!=q3 ) return false;
493
        }
494
495
      return true;
496
      }
497
498
    return false;
499
    }
500
501
///////////////////////////////////////////////////////////////////////////////////////////////////
502
// only needed for solvers - there are no Helicopter solvers ATM)
503
504
  public String retObjectString()
505
    {
506
    return "";
507
    }
508 6fd4a72c Leszek Koltunski
509
///////////////////////////////////////////////////////////////////////////////////////////////////
510
511
  public int getObjectName(int numLayers)
512
    {
513
    return R.string.heli3;
514
    }
515
516
///////////////////////////////////////////////////////////////////////////////////////////////////
517
518
  public int getInventor(int numLayers)
519
    {
520
    return R.string.heli3_inventor;
521
    }
522
523
///////////////////////////////////////////////////////////////////////////////////////////////////
524
525
  public int getComplexity(int numLayers)
526
    {
527
    return 8;
528
    }
529 ee35e63c Leszek Koltunski
}