Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyIvy.java @ 7a606778

1 49cd8581 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
import org.distorted.library.effect.MatrixEffectQuaternion;
27
import org.distorted.library.main.DistortedEffects;
28
import org.distorted.library.main.DistortedTexture;
29
import org.distorted.library.mesh.MeshBase;
30
import org.distorted.library.mesh.MeshSquare;
31
import org.distorted.library.type.Static3D;
32
import org.distorted.library.type.Static4D;
33 6fd4a72c Leszek Koltunski
import org.distorted.main.R;
34 49cd8581 Leszek Koltunski
import org.distorted.main.RubikSurfaceView;
35
36
import java.util.Random;
37
38
///////////////////////////////////////////////////////////////////////////////////////////////////
39
40
public class TwistyIvy extends TwistyObject
41
{
42 18a5f95f Leszek Koltunski
  private static final int FACES_PER_CUBIT =6;
43 49cd8581 Leszek Koltunski
44
  // the four rotation axis of a RubikIvy. Must be normalized.
45
  static final Static3D[] ROT_AXIS = new Static3D[]
46
         {
47
           new Static3D(+SQ3/3,+SQ3/3,+SQ3/3),
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
         };
52
53
  private static final int[] FACE_COLORS = new int[]
54
         {
55
           COLOR_YELLOW, COLOR_WHITE,
56
           COLOR_BLUE  , COLOR_GREEN,
57 323b217c Leszek Koltunski
           COLOR_RED   , COLOR_ORANGE
58 49cd8581 Leszek Koltunski
         };
59
60
  // All legal rotation quats of a RubikIvy
61
  private static final Static4D[] QUATS = new Static4D[]
62
         {
63
           new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),
64
           new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
65
           new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
66
           new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
67
68
           new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),
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
         };
77
78 18a5f95f Leszek Koltunski
  private static final int[][] mFaceMap =
79 49cd8581 Leszek Koltunski
         {
80 18a5f95f Leszek Koltunski
           {  4, 2, 0, 12,12,12 },
81
           {  5, 2, 1, 12,12,12 },
82
           {  4, 3, 1, 12,12,12 },
83
           {  5, 3, 0, 12,12,12 },
84
85
           {  6, 12,12,12,12,12 },
86
           {  7, 12,12,12,12,12 },
87
           {  8, 12,12,12,12,12 },
88
           {  9, 12,12,12,12,12 },
89
           { 10, 12,12,12,12,12 },
90
           { 11, 12,12,12,12,12 },
91 49cd8581 Leszek Koltunski
         };
92
93
  private static MeshBase mCornerMesh, mFaceMesh;
94
95
///////////////////////////////////////////////////////////////////////////////////////////////////
96
97
  TwistyIvy(int size, Static4D quat, DistortedTexture texture,
98
            MeshSquare mesh, DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
99
    {
100 db875721 Leszek Koltunski
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.IVY, res, scrWidth);
101 49cd8581 Leszek Koltunski
    }
102
103
///////////////////////////////////////////////////////////////////////////////////////////////////
104
105
  float getScreenRatio()
106
    {
107
    return 1.0f;
108
    }
109
110
///////////////////////////////////////////////////////////////////////////////////////////////////
111
112
  Static4D[] getQuats()
113
    {
114
    return QUATS;
115
    }
116
117
///////////////////////////////////////////////////////////////////////////////////////////////////
118
119
  int getNumFaces()
120
    {
121
    return FACE_COLORS.length;
122
    }
123
124
///////////////////////////////////////////////////////////////////////////////////////////////////
125
126
  boolean shouldResetTextureMaps()
127
    {
128
    return false;
129
    }
130
131
///////////////////////////////////////////////////////////////////////////////////////////////////
132
133 a64e07d0 Leszek Koltunski
  int getNumStickerTypes(int numLayers)
134 49cd8581 Leszek Koltunski
    {
135
    return 2;
136
    }
137
138
///////////////////////////////////////////////////////////////////////////////////////////////////
139
140
  float[] getCuts(int numLayers)
141
    {
142
    float[] cuts = new float[1];
143
    cuts[0] = 0.0f;
144
145
    return cuts;
146
    }
147
148
///////////////////////////////////////////////////////////////////////////////////////////////////
149
150
  int getNumCubitFaces()
151
    {
152
    return FACES_PER_CUBIT;
153
    }
154
155
///////////////////////////////////////////////////////////////////////////////////////////////////
156
157 e6cf7283 Leszek Koltunski
  float[][] getCubitPositions(int numLayers)
158 49cd8581 Leszek Koltunski
    {
159
    final float DIST_CORNER = (numLayers-1)*0.50f;
160
    final float DIST_CENTER = (numLayers-1)*0.50f;
161
162 e6cf7283 Leszek Koltunski
    final float[][] CENTERS = new float[10][];
163
164
    CENTERS[0] = new float[] { DIST_CORNER, DIST_CORNER, DIST_CORNER };
165
    CENTERS[1] = new float[] {-DIST_CORNER, DIST_CORNER,-DIST_CORNER };
166
    CENTERS[2] = new float[] {-DIST_CORNER,-DIST_CORNER, DIST_CORNER };
167
    CENTERS[3] = new float[] { DIST_CORNER,-DIST_CORNER,-DIST_CORNER };
168
    CENTERS[4] = new float[] { DIST_CENTER,           0,           0 };
169
    CENTERS[5] = new float[] {-DIST_CENTER,           0,           0 };
170
    CENTERS[6] = new float[] {           0, DIST_CENTER,           0 };
171
    CENTERS[7] = new float[] {           0,-DIST_CENTER,           0 };
172
    CENTERS[8] = new float[] {           0,           0, DIST_CENTER };
173
    CENTERS[9] = new float[] {           0,           0,-DIST_CENTER };
174 49cd8581 Leszek Koltunski
175
    return CENTERS;
176
    }
177
178
///////////////////////////////////////////////////////////////////////////////////////////////////
179
180
  private int getQuat(int cubit)
181
    {
182
    switch(cubit)
183
      {
184
      case  0: return 0;
185
      case  1: return 2;
186
      case  2: return 3;
187
      case  3: return 1;
188
189
      case  4: return 8;
190
      case  5: return 11;
191
      case  6: return 10;
192
      case  7: return 9;
193
      case  8: return 0;
194
      case  9: return 2;
195
      }
196
197
    return 0;
198
    }
199
200
///////////////////////////////////////////////////////////////////////////////////////////////////
201
202 a64e07d0 Leszek Koltunski
  MeshBase createCubitMesh(int cubit, int numLayers)
203 49cd8581 Leszek Koltunski
    {
204
    MeshBase mesh;
205
206
    if( cubit<4 )
207
      {
208
      if( mCornerMesh==null ) mCornerMesh = FactoryCubit.getInstance().createIvyCornerMesh();
209
      mesh = mCornerMesh.copy(true);
210
      }
211
    else
212
      {
213
      if( mFaceMesh==null ) mFaceMesh = FactoryCubit.getInstance().createIvyFaceMesh();
214
      mesh = mFaceMesh.copy(true);
215
      }
216
217
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( QUATS[getQuat(cubit)], new Static3D(0,0,0) );
218
    mesh.apply(quat,0xffffffff,0);
219
220
    return mesh;
221
    }
222
223
///////////////////////////////////////////////////////////////////////////////////////////////////
224
225
  int getFaceColor(int cubit, int cubitface, int numLayers)
226
    {
227 18a5f95f Leszek Koltunski
    return mFaceMap[cubit][cubitface];
228 49cd8581 Leszek Koltunski
    }
229
230
///////////////////////////////////////////////////////////////////////////////////////////////////
231
232
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
233
    {
234
    int COLORS = FACE_COLORS.length;
235
    FactorySticker factory = FactorySticker.getInstance();
236 9e5b990e Leszek Koltunski
    float S = 0.08f;
237 886d1ebb Leszek Koltunski
    float R = 0.12f;
238 49cd8581 Leszek Koltunski
239
    if( face<COLORS )
240
      {
241 9e5b990e Leszek Koltunski
      factory.drawIvyCornerSticker(canvas, paint, left, top, FACE_COLORS[face%COLORS], S, R);
242 49cd8581 Leszek Koltunski
      }
243
    else
244
      {
245 9e5b990e Leszek Koltunski
      factory.drawIvyCenterSticker(canvas, paint, left, top, FACE_COLORS[face%COLORS], S, R);
246 49cd8581 Leszek Koltunski
      }
247
    }
248
249
///////////////////////////////////////////////////////////////////////////////////////////////////
250
251
  float returnMultiplier()
252
    {
253
    return 2.0f;
254
    }
255
256
///////////////////////////////////////////////////////////////////////////////////////////////////
257
258 a64e07d0 Leszek Koltunski
  float[] getRowChances(int numLayers)
259 49cd8581 Leszek Koltunski
    {
260
    float[] chances = new float[2];
261
    chances[0] = 0.5f;
262
    chances[1] = 1.0f;
263
264
    return chances;
265
    }
266
267
///////////////////////////////////////////////////////////////////////////////////////////////////
268
// PUBLIC API
269
270
  public Static3D[] getRotationAxis()
271
    {
272
    return ROT_AXIS;
273
    }
274
275
///////////////////////////////////////////////////////////////////////////////////////////////////
276
277
  public int getBasicAngle()
278
    {
279
    return 3;
280
    }
281
282
///////////////////////////////////////////////////////////////////////////////////////////////////
283
284 5043d5d0 Leszek Koltunski
  public void randomizeNewScramble(int[][] scramble, Random rnd, int num)
285 49cd8581 Leszek Koltunski
    {
286 5043d5d0 Leszek Koltunski
    if( num==0 )
287 49cd8581 Leszek Koltunski
      {
288 5043d5d0 Leszek Koltunski
      scramble[num][0] = rnd.nextInt(ROTATION_AXIS.length);
289 49cd8581 Leszek Koltunski
      }
290
    else
291
      {
292 bbc6471c Leszek Koltunski
      int newVector = rnd.nextInt(ROTATION_AXIS.length-1);
293 5043d5d0 Leszek Koltunski
      scramble[num][0] = (newVector>=scramble[num-1][0] ? newVector+1 : newVector);
294 49cd8581 Leszek Koltunski
      }
295
296
    float rowFloat = rnd.nextFloat();
297
298
    for(int row=0; row<mRowChances.length; row++)
299
      {
300 bbc6471c Leszek Koltunski
      if( rowFloat<=mRowChances[row] )
301
        {
302 5043d5d0 Leszek Koltunski
        scramble[num][1] = row;
303 bbc6471c Leszek Koltunski
        break;
304
        }
305 49cd8581 Leszek Koltunski
      }
306
307 5043d5d0 Leszek Koltunski
    switch( rnd.nextInt(2) )
308
      {
309
      case 0: scramble[num][2] = -1; break;
310
      case 1: scramble[num][2] =  1; break;
311
      }
312 49cd8581 Leszek Koltunski
    }
313
314
///////////////////////////////////////////////////////////////////////////////////////////////////
315
// remember about the double cover or unit quaternions!
316
317
  private int mulQuat(int q1, int q2)
318
    {
319
    Static4D result = RubikSurfaceView.quatMultiply(QUATS[q1],QUATS[q2]);
320
321
    float rX = result.get0();
322
    float rY = result.get1();
323
    float rZ = result.get2();
324
    float rW = result.get3();
325
326
    final float MAX_ERROR = 0.1f;
327
    float dX,dY,dZ,dW;
328
329
    for(int i=0; i<QUATS.length; i++)
330
      {
331
      dX = QUATS[i].get0() - rX;
332
      dY = QUATS[i].get1() - rY;
333
      dZ = QUATS[i].get2() - rZ;
334
      dW = QUATS[i].get3() - rW;
335
336
      if( dX<MAX_ERROR && dX>-MAX_ERROR &&
337
          dY<MAX_ERROR && dY>-MAX_ERROR &&
338
          dZ<MAX_ERROR && dZ>-MAX_ERROR &&
339
          dW<MAX_ERROR && dW>-MAX_ERROR  ) return i;
340
341
      dX = QUATS[i].get0() + rX;
342
      dY = QUATS[i].get1() + rY;
343
      dZ = QUATS[i].get2() + rZ;
344
      dW = QUATS[i].get3() + rW;
345
346
      if( dX<MAX_ERROR && dX>-MAX_ERROR &&
347
          dY<MAX_ERROR && dY>-MAX_ERROR &&
348
          dZ<MAX_ERROR && dZ>-MAX_ERROR &&
349
          dW<MAX_ERROR && dW>-MAX_ERROR  ) return i;
350
      }
351
352
    return -1;
353
    }
354
355
///////////////////////////////////////////////////////////////////////////////////////////////////
356
// The Ivy is solved if and only if:
357
//
358
// 1) all 4 of its corner cubits are rotated with the same quat
359
// 2) all its face cubits are rotated with the same quat like the corner ones,
360
//    and optionally they also might be upside down.
361
//
362
// i.e.
363
// cubits [4] and [5] - might be extra QUAT[1]
364
// cubits [6] and [7] - might be extra QUAT[2]
365
// cubits [8] and [9] - might be extra QUAT[3]
366
367
  public boolean isSolved()
368
    {
369
    int q1,q = CUBITS[0].mQuatIndex;
370
371
    if( CUBITS[1].mQuatIndex == q &&
372
        CUBITS[2].mQuatIndex == q &&
373
        CUBITS[3].mQuatIndex == q  )
374
      {
375
      q1 = mulQuat(q,1);
376
      if( CUBITS[4].mQuatIndex != q && CUBITS[4].mQuatIndex != q1 ) return false;
377
      if( CUBITS[5].mQuatIndex != q && CUBITS[5].mQuatIndex != q1 ) return false;
378
379
      q1 = mulQuat(q,2);
380
      if( CUBITS[6].mQuatIndex != q && CUBITS[6].mQuatIndex != q1 ) return false;
381
      if( CUBITS[7].mQuatIndex != q && CUBITS[7].mQuatIndex != q1 ) return false;
382
383
      q1 = mulQuat(q,3);
384
      if( CUBITS[8].mQuatIndex != q && CUBITS[8].mQuatIndex != q1 ) return false;
385
      if( CUBITS[9].mQuatIndex != q && CUBITS[9].mQuatIndex != q1 ) return false;
386
387
      return true;
388
      }
389
390
    return false;
391
    }
392
393
///////////////////////////////////////////////////////////////////////////////////////////////////
394
// only needed for solvers - there are no Ivy solvers ATM)
395
396
  public String retObjectString()
397
    {
398
    return "";
399
    }
400 6fd4a72c Leszek Koltunski
401
///////////////////////////////////////////////////////////////////////////////////////////////////
402
403
  public int getObjectName(int numLayers)
404
    {
405
    return R.string.ivy2;
406
    }
407
408
///////////////////////////////////////////////////////////////////////////////////////////////////
409
410
  public int getInventor(int numLayers)
411
    {
412
    return R.string.ivy2_inventor;
413
    }
414
415
///////////////////////////////////////////////////////////////////////////////////////////////////
416
417
  public int getComplexity(int numLayers)
418
    {
419
    return 1;
420
    }
421 49cd8581 Leszek Koltunski
}