Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistySkewb.java @ 323b217c

1 fb52fae9 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 3f3ff476 Leszek Koltunski
import org.distorted.library.effect.MatrixEffect;
27 fb52fae9 Leszek Koltunski
import org.distorted.library.effect.MatrixEffectQuaternion;
28 3f3ff476 Leszek Koltunski
import org.distorted.library.effect.MatrixEffectScale;
29 fb52fae9 Leszek Koltunski
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 fb52fae9 Leszek Koltunski
import org.distorted.main.RubikSurfaceView;
37
38
import java.util.Random;
39
40
import static org.distorted.effects.scramble.ScrambleEffect.START_AXIS;
41
42
///////////////////////////////////////////////////////////////////////////////////////////////////
43
44 9c2f0c91 Leszek Koltunski
public class TwistySkewb extends TwistyObject
45 fb52fae9 Leszek Koltunski
{
46
  private static final int FACES_PER_CUBIT =6;
47
48
  // the four rotation axis of a RubikSkewb. Must be normalized.
49
  static final Static3D[] ROT_AXIS = new Static3D[]
50
         {
51
           new Static3D(+SQ3/3,+SQ3/3,+SQ3/3),
52
           new Static3D(+SQ3/3,+SQ3/3,-SQ3/3),
53
           new Static3D(+SQ3/3,-SQ3/3,+SQ3/3),
54
           new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
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 fb52fae9 Leszek Koltunski
         };
63
64
  // All legal rotation quats of a RubikSkewb
65
  private static final Static4D[] QUATS = new Static4D[]
66
         {
67
           new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),
68
           new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
69
           new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
70
           new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
71
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
           new Static4D(  0.5f, -0.5f, -0.5f, -0.5f )
80
         };
81
82 3f3ff476 Leszek Koltunski
  private static final int[][] mCornerMap =
83
         {
84
           {  4, 2, 0, 18,18,18 },
85
           {  2, 5, 0, 18,18,18 },
86
           {  3, 4, 0, 18,18,18 },
87
           {  5, 3, 0, 18,18,18 },
88
           {  1, 2, 4, 18,18,18 },
89
           {  5, 2, 1, 18,18,18 },
90
           {  4, 3, 1, 18,18,18 },
91
           {  1, 3, 5, 18,18,18 },
92
         };
93 63002261 Leszek Koltunski
94 3f3ff476 Leszek Koltunski
  private static final int[][] mEdgeMap =
95 fb52fae9 Leszek Koltunski
         {
96 3f3ff476 Leszek Koltunski
           { 10, 8, 18,18,18,18 },
97
           {  6,10, 18,18,18,18 },
98
           { 10, 9, 18,18,18,18 },
99
           {  7,10, 18,18,18,18 },
100
           {  8, 6, 18,18,18,18 },
101
           {  9, 6, 18,18,18,18 },
102
           {  9, 7, 18,18,18,18 },
103
           {  8, 7, 18,18,18,18 },
104
           { 11, 8, 18,18,18,18 },
105
           {  6,11, 18,18,18,18 },
106
           { 11, 9, 18,18,18,18 },
107
           {  7,11, 18,18,18,18 }
108 fb52fae9 Leszek Koltunski
         };
109
110 3f3ff476 Leszek Koltunski
  private static final int[][] mCenterMap =
111 fb52fae9 Leszek Koltunski
         {
112 3f3ff476 Leszek Koltunski
           { 12, 18,18,18,18,18 },
113
           { 13, 18,18,18,18,18 },
114
           { 14, 18,18,18,18,18 },
115
           { 15, 18,18,18,18,18 },
116
           { 16, 18,18,18,18,18 },
117
           { 17, 18,18,18,18,18 },
118 fb52fae9 Leszek Koltunski
         };
119
120 3f3ff476 Leszek Koltunski
  private static MeshBase mCornerMesh, mFaceMesh, mEdgeMesh;
121 fb52fae9 Leszek Koltunski
122
///////////////////////////////////////////////////////////////////////////////////////////////////
123
124 9c2f0c91 Leszek Koltunski
  TwistySkewb(int size, Static4D quat, DistortedTexture texture,
125
              MeshSquare mesh, DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
126 fb52fae9 Leszek Koltunski
    {
127 d99f3a48 Leszek Koltunski
    super(size, 2*size-2, 60, quat, texture, mesh, effects, moves, ObjectList.SKEW, res, scrWidth);
128 fb52fae9 Leszek Koltunski
    }
129
130 3f3ff476 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
131
132 d92030e4 Leszek Koltunski
  private int getNumCorners()
133 3f3ff476 Leszek Koltunski
    {
134
    return 8;
135
    }
136
137
///////////////////////////////////////////////////////////////////////////////////////////////////
138
139 b89898c5 Leszek Koltunski
  private int getNumEdges(int layers)
140 3f3ff476 Leszek Koltunski
    {
141 b89898c5 Leszek Koltunski
    return (layers-2)*12;
142 3f3ff476 Leszek Koltunski
    }
143
144
///////////////////////////////////////////////////////////////////////////////////////////////////
145
146 d92030e4 Leszek Koltunski
  private int getNumCentersPerFace(int layers)
147 3f3ff476 Leszek Koltunski
    {
148 d92030e4 Leszek Koltunski
    return ((layers-2)*(layers-2) + (layers-1)*(layers-1));
149 3f3ff476 Leszek Koltunski
    }
150
151 fb52fae9 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
152
153
  float getScreenRatio()
154
    {
155 d99f3a48 Leszek Koltunski
    return 1.0f;
156 fb52fae9 Leszek Koltunski
    }
157
158
///////////////////////////////////////////////////////////////////////////////////////////////////
159
160
  Static4D[] getQuats()
161
    {
162
    return QUATS;
163
    }
164
165
///////////////////////////////////////////////////////////////////////////////////////////////////
166
167
  int getNumFaces()
168
    {
169
    return FACE_COLORS.length;
170
    }
171
172 eaee1ddc Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
173
174
  boolean shouldResetTextureMaps()
175
    {
176
    return false;
177
    }
178
179 eab9d8f8 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
180
181
  int getNumStickerTypes()
182
    {
183 3f3ff476 Leszek Koltunski
    return 3;
184 eab9d8f8 Leszek Koltunski
    }
185
186 7403cdfa Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
187
188 b89898c5 Leszek Koltunski
  float[] getCuts(int numLayers)
189 7403cdfa Leszek Koltunski
    {
190 b89898c5 Leszek Koltunski
    float[] cuts = new float[numLayers-1];
191 a97e02b7 Leszek Koltunski
192 b89898c5 Leszek Koltunski
    switch(numLayers)
193 a97e02b7 Leszek Koltunski
      {
194
      case 2: cuts[0] = 0;
195
              break;
196
      case 3: cuts[0] = -SQ3/12;
197
              cuts[1] = +SQ3/12;
198
              break;
199 c7e23561 Leszek Koltunski
      case 4: cuts[0] = -SQ3/9;
200
              cuts[1] = 0;
201
              cuts[2] = +SQ3/9;
202
              break;
203 a97e02b7 Leszek Koltunski
      }
204
    return cuts;
205 7403cdfa Leszek Koltunski
    }
206
207 fb52fae9 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
208
209
  int getNumCubitFaces()
210
    {
211
    return FACES_PER_CUBIT;
212
    }
213
214
///////////////////////////////////////////////////////////////////////////////////////////////////
215
216 b89898c5 Leszek Koltunski
  Static3D[] getCubitPositions(int numLayers)
217 fb52fae9 Leszek Koltunski
    {
218 b89898c5 Leszek Koltunski
    final float DIST_CORNER = (numLayers-1)*0.50f;
219
    final float DIST_EDGE   = (numLayers-1)*0.50f;
220
    final float DIST_CENTER = (numLayers-1)*0.50f;
221 3f3ff476 Leszek Koltunski
222 d92030e4 Leszek Koltunski
    final int numCorners = getNumCorners();
223 b89898c5 Leszek Koltunski
    final int numEdges   = getNumEdges(numLayers);
224 d92030e4 Leszek Koltunski
    final int numCenters = 6*getNumCentersPerFace(numLayers);
225 3f3ff476 Leszek Koltunski
226
    final Static3D[] CENTERS = new Static3D[numCorners+numEdges+numCenters];
227
228
    /// CORNERS //////////////////////////////////////////////
229
230
    CENTERS[0] = new Static3D( DIST_CORNER, DIST_CORNER, DIST_CORNER );
231
    CENTERS[1] = new Static3D( DIST_CORNER, DIST_CORNER,-DIST_CORNER );
232
    CENTERS[2] = new Static3D( DIST_CORNER,-DIST_CORNER, DIST_CORNER );
233
    CENTERS[3] = new Static3D( DIST_CORNER,-DIST_CORNER,-DIST_CORNER );
234
    CENTERS[4] = new Static3D(-DIST_CORNER, DIST_CORNER, DIST_CORNER );
235
    CENTERS[5] = new Static3D(-DIST_CORNER, DIST_CORNER,-DIST_CORNER );
236
    CENTERS[6] = new Static3D(-DIST_CORNER,-DIST_CORNER, DIST_CORNER );
237
    CENTERS[7] = new Static3D(-DIST_CORNER,-DIST_CORNER,-DIST_CORNER );
238
239
    /// EDGES ///////////////////////////////////////////////
240
241
    final float[][]  edgeTable =
242
        {
243
            {0,+DIST_EDGE,+DIST_EDGE},
244
            {+DIST_EDGE,0,+DIST_EDGE},
245
            {0,-DIST_EDGE,+DIST_EDGE},
246
            {-DIST_EDGE,0,+DIST_EDGE},
247
            {+DIST_EDGE,+DIST_EDGE,0},
248
            {+DIST_EDGE,-DIST_EDGE,0},
249
            {-DIST_EDGE,-DIST_EDGE,0},
250
            {-DIST_EDGE,+DIST_EDGE,0},
251
            {0,+DIST_EDGE,-DIST_EDGE},
252
            {+DIST_EDGE,0,-DIST_EDGE},
253
            {0,-DIST_EDGE,-DIST_EDGE},
254
            {-DIST_EDGE,0,-DIST_EDGE}
255
        };
256
257
    int index=8;
258
259
    for (float[] edges : edgeTable)
260
      {
261 b89898c5 Leszek Koltunski
      float c = (3-numLayers)*0.5f;
262 3f3ff476 Leszek Koltunski
263 b89898c5 Leszek Koltunski
      for (int j=0; j<numLayers-2; j++, c+=1.0f, index++)
264 3f3ff476 Leszek Koltunski
        {
265
        CENTERS[index] = new Static3D( edges[0]==0 ? c : edges[0] ,
266
                                       edges[1]==0 ? c : edges[1] ,
267
                                       edges[2]==0 ? c : edges[2] );
268
        }
269
      }
270
271
    /// CENTERS //////////////////////////////////////////////
272
273
    final float X= -1000.0f;
274
    final float Y= -1001.0f;
275
276
    final float[][]  centerTable =
277
        {
278
            {+DIST_CENTER,X,Y},
279
            {-DIST_CENTER,X,Y},
280
            {X,+DIST_CENTER,Y},
281
            {X,-DIST_CENTER,Y},
282
            {X,Y,+DIST_CENTER},
283
            {X,Y,-DIST_CENTER}
284
        };
285
286
    float x,y, cen0, cen1, cen2;
287
288
    for( float[] centers : centerTable )
289
      {
290 b89898c5 Leszek Koltunski
      x = (2-numLayers)*0.5f;
291 3f3ff476 Leszek Koltunski
292 b89898c5 Leszek Koltunski
      for(int i=0; i<numLayers-1; i++, x+=1.0f)
293 3f3ff476 Leszek Koltunski
        {
294 b89898c5 Leszek Koltunski
        y = (2-numLayers)*0.5f;
295 3f3ff476 Leszek Koltunski
296 b89898c5 Leszek Koltunski
        for(int j=0; j<numLayers-1; j++, y+=1.0f, index++)
297 3f3ff476 Leszek Koltunski
          {
298
               if( centers[0]==Y ) cen0 = y;
299
          else if( centers[0]==X ) cen0 = x;
300
          else                     cen0 = centers[0];
301
302
               if( centers[1]==Y ) cen1 = y;
303
          else if( centers[1]==X ) cen1 = x;
304
          else                     cen1 = centers[1];
305
306
               if( centers[2]==Y ) cen2 = y;
307
          else if( centers[2]==X ) cen2 = x;
308
          else                     cen2 = centers[2];
309
310
          CENTERS[index] = new Static3D(cen0,cen1,cen2);
311
          }
312
        }
313
314 b89898c5 Leszek Koltunski
      x = (3-numLayers)*0.5f;
315 3f3ff476 Leszek Koltunski
316 b89898c5 Leszek Koltunski
      for(int i=0; i<numLayers-2; i++, x+=1.0f)
317 3f3ff476 Leszek Koltunski
        {
318 b89898c5 Leszek Koltunski
        y = (3-numLayers)*0.5f;
319 3f3ff476 Leszek Koltunski
320 b89898c5 Leszek Koltunski
        for(int j=0; j<numLayers-2; j++, y+=1.0f, index++)
321 3f3ff476 Leszek Koltunski
          {
322
               if( centers[0]==Y ) cen0 = y;
323
          else if( centers[0]==X ) cen0 = x;
324
          else                     cen0 = centers[0];
325
326
               if( centers[1]==Y ) cen1 = y;
327
          else if( centers[1]==X ) cen1 = x;
328
          else                     cen1 = centers[1];
329
330
               if( centers[2]==Y ) cen2 = y;
331
          else if( centers[2]==X ) cen2 = x;
332
          else                     cen2 = centers[2];
333
334
          CENTERS[index] = new Static3D(cen0,cen1,cen2);
335
          }
336
        }
337
      }
338
339 fb52fae9 Leszek Koltunski
    return CENTERS;
340
    }
341
342
///////////////////////////////////////////////////////////////////////////////////////////////////
343
344 d92030e4 Leszek Koltunski
  private Static4D getQuat(int cubit, int numLayers)
345 fb52fae9 Leszek Koltunski
    {
346 d92030e4 Leszek Koltunski
    int numCorners = getNumCorners();
347
    int numEdges   = getNumEdges(numLayers);
348 3f3ff476 Leszek Koltunski
349
    if( cubit<numCorners )
350
      {
351
      switch(cubit)
352
        {
353
        case  0: return QUATS[0];                          //  unit quat
354
        case  1: return new Static4D( SQ2/2,0,0,SQ2/2);    //  90 along X
355
        case  2: return new Static4D(-SQ2/2,0,0,SQ2/2);    // -90 along X
356
        case  3: return QUATS[1];                          // 180 along X
357
        case  4: return new Static4D(0, SQ2/2,0,SQ2/2);    //  90 along Y
358
        case  5: return QUATS[2];                          // 180 along Y
359
        case  6: return QUATS[3];                          // 180 along Z
360
        case  7: return new Static4D(SQ2/2,0,-SQ2/2,0);    // 180 along (SQ2/2,0,-SQ2/2)
361
        }
362
      }
363
    else if( cubit<numCorners+numEdges )
364
      {
365 d92030e4 Leszek Koltunski
      int edge = (cubit-numCorners)/(numLayers-2);
366 3f3ff476 Leszek Koltunski
367
      switch(edge)
368
        {
369
        case  0: return QUATS[ 0];
370
        case  1: return QUATS[ 5];
371
        case  2: return QUATS[ 3];
372
        case  3: return QUATS[11];
373
        case  4: return QUATS[ 4];
374
        case  5: return QUATS[ 7];
375
        case  6: return QUATS[ 9];
376
        case  7: return QUATS[10];
377
        case  8: return QUATS[ 2];
378
        case  9: return QUATS[ 8];
379
        case 10: return QUATS[ 1];
380
        case 11: return QUATS[ 6];
381
        }
382
      }
383
    else
384 fb52fae9 Leszek Koltunski
      {
385 d92030e4 Leszek Koltunski
      int center = (cubit-numCorners-numEdges)/getNumCentersPerFace(numLayers);
386 3f3ff476 Leszek Koltunski
387
      switch(center)
388
        {
389
        case 0: return new Static4D(0,-SQ2/2,0,SQ2/2);    // -90 along Y
390
        case 1: return new Static4D(0, SQ2/2,0,SQ2/2);    //  90 along Y
391
        case 2: return new Static4D( SQ2/2,0,0,SQ2/2);    //  90 along X
392
        case 3: return new Static4D(-SQ2/2,0,0,SQ2/2);    // -90 along X
393
        case 4: return QUATS[0];                          //  unit quaternion
394
        case 5: return QUATS[1];                          // 180 along X
395
        }
396 fb52fae9 Leszek Koltunski
      }
397
398
    return null;
399
    }
400
401
///////////////////////////////////////////////////////////////////////////////////////////////////
402
403
  MeshBase createCubitMesh(int cubit)
404
    {
405
    MeshBase mesh;
406
407 d92030e4 Leszek Koltunski
    int numLayers  = getNumLayers();
408
    int numCorners = getNumCorners();
409 d99f3a48 Leszek Koltunski
    int numEdges   = getNumEdges(numLayers);
410 3f3ff476 Leszek Koltunski
411
    if( cubit<numCorners )
412 fb52fae9 Leszek Koltunski
      {
413 b89898c5 Leszek Koltunski
      if( mCornerMesh==null ) mCornerMesh = FactoryCubit.getInstance().createSkewbCornerMesh();
414 fb52fae9 Leszek Koltunski
      mesh = mCornerMesh.copy(true);
415
      }
416 3f3ff476 Leszek Koltunski
    else if( cubit<numCorners+numEdges )
417
      {
418
      if( mEdgeMesh==null )
419
        {
420 b89898c5 Leszek Koltunski
        mEdgeMesh = FactoryCubit.getInstance().createDinoMesh();
421 3f3ff476 Leszek Koltunski
        MatrixEffect effect = new MatrixEffectScale(1.0f/3);
422
        mEdgeMesh.apply(effect,-1,0);
423
        mEdgeMesh.addEmptyTexComponent();
424
        mEdgeMesh.addEmptyTexComponent();
425
        }
426
      mesh = mEdgeMesh.copy(true);
427
      }
428 fb52fae9 Leszek Koltunski
    else
429
      {
430 b89898c5 Leszek Koltunski
      if( mFaceMesh==null ) mFaceMesh = FactoryCubit.getInstance().createSkewbFaceMesh();
431 fb52fae9 Leszek Koltunski
      mesh = mFaceMesh.copy(true);
432
      }
433
434 d99f3a48 Leszek Koltunski
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( getQuat(cubit,numLayers), new Static3D(0,0,0) );
435 fb52fae9 Leszek Koltunski
    mesh.apply(quat,0xffffffff,0);
436
437
    return mesh;
438
    }
439
440
///////////////////////////////////////////////////////////////////////////////////////////////////
441
442 d92030e4 Leszek Koltunski
  int getFaceColor(int cubit, int cubitface, int numLayers)
443 fb52fae9 Leszek Koltunski
    {
444 d92030e4 Leszek Koltunski
    int numCorners = getNumCorners();
445
    int numEdges   = getNumEdges(numLayers);
446 3f3ff476 Leszek Koltunski
447
    if( cubit<numCorners )
448
      {
449
      return mCornerMap[cubit][cubitface];
450
      }
451
    else if( cubit<numCorners+numEdges )
452
      {
453 d92030e4 Leszek Koltunski
      int edge = (cubit-numCorners)/(numLayers-2);
454 3f3ff476 Leszek Koltunski
      return mEdgeMap[edge][cubitface];
455
      }
456
    else
457
      {
458 d92030e4 Leszek Koltunski
      int center = (cubit-numCorners-numEdges)/getNumCentersPerFace(numLayers);
459 3f3ff476 Leszek Koltunski
      return mCenterMap[center][cubitface];
460
      }
461 fb52fae9 Leszek Koltunski
    }
462
463
///////////////////////////////////////////////////////////////////////////////////////////////////
464
465 ae755eda Leszek Koltunski
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
466 fb52fae9 Leszek Koltunski
    {
467 eab9d8f8 Leszek Koltunski
    int COLORS = FACE_COLORS.length;
468 ae755eda Leszek Koltunski
    float R,S;
469
    float[] vertices;
470 eab9d8f8 Leszek Koltunski
471
    if( face<COLORS )
472
      {
473 76c2bd07 Leszek Koltunski
      float E = 0.5f;
474 ae755eda Leszek Koltunski
      R = 0.023f;
475
      S = 0.035f;
476
      vertices = new float[] { -E+E/4,E/4, E/4,-E+E/4, E/4,E/4};
477 eab9d8f8 Leszek Koltunski
      }
478 3f3ff476 Leszek Koltunski
    else if( face<2*COLORS )
479
      {
480 ae755eda Leszek Koltunski
      float E = 0.5f;
481
      R = 0.025f;
482
      S = 0.05f;
483
      vertices = new float[] { -E,E/3, 0,-2*E/3, +E,E/3 };
484 3f3ff476 Leszek Koltunski
      }
485 eab9d8f8 Leszek Koltunski
    else
486
      {
487 76c2bd07 Leszek Koltunski
      float E = SQ2/4;
488 ae755eda Leszek Koltunski
      R = 0.055f;
489
      S = 0.035f;
490
      vertices = new float[] { -E,-E, +E,-E, +E,+E, -E,+E };
491 eab9d8f8 Leszek Koltunski
      }
492 ae755eda Leszek Koltunski
493
    FactorySticker factory = FactorySticker.getInstance();
494
    factory.drawRoundedPolygon(canvas, paint, left, top, vertices, S, FACE_COLORS[face%COLORS], R);
495 fb52fae9 Leszek Koltunski
    }
496
497
///////////////////////////////////////////////////////////////////////////////////////////////////
498
499
  float returnMultiplier()
500
    {
501
    return 2.0f;
502
    }
503
504
///////////////////////////////////////////////////////////////////////////////////////////////////
505
506
  float[] getRowChances()
507
    {
508 d99f3a48 Leszek Koltunski
    int numLayers = getNumLayers();
509
    float[] chances = new float[numLayers];
510 fb52fae9 Leszek Koltunski
511 b3da2f16 Leszek Koltunski
    switch(numLayers)
512 3f3ff476 Leszek Koltunski
      {
513 b3da2f16 Leszek Koltunski
      case 2: chances[0] = 0.5f;
514
              chances[1] = 1.0f;
515
              break;
516
      case 3: chances[0] = 0.5f;
517
              chances[1] = 0.5f;
518
              chances[2] = 1.0f;
519
              break;
520
      default:for(int i=0; i<numLayers; i++)
521
                {
522
                chances[i] = (float)(i+1)/numLayers;
523
                }
524 3f3ff476 Leszek Koltunski
      }
525 fb52fae9 Leszek Koltunski
526
    return chances;
527
    }
528
529
///////////////////////////////////////////////////////////////////////////////////////////////////
530
// PUBLIC API
531
532
  public Static3D[] getRotationAxis()
533
    {
534
    return ROT_AXIS;
535
    }
536
537
///////////////////////////////////////////////////////////////////////////////////////////////////
538
539
  public int getBasicAngle()
540
    {
541
    return 3;
542
    }
543
544
///////////////////////////////////////////////////////////////////////////////////////////////////
545
546
  public int randomizeNewRotAxis(Random rnd, int oldRotAxis)
547
    {
548
    int numAxis = ROTATION_AXIS.length;
549
550
    if( oldRotAxis == START_AXIS )
551
      {
552
      return rnd.nextInt(numAxis);
553
      }
554
    else
555
      {
556
      int newVector = rnd.nextInt(numAxis-1);
557
      return (newVector>=oldRotAxis ? newVector+1 : newVector);
558
      }
559
    }
560
561
///////////////////////////////////////////////////////////////////////////////////////////////////
562
563
  public int randomizeNewRow(Random rnd, int oldRotAxis, int oldRow, int newRotAxis)
564
    {
565
    float rowFloat = rnd.nextFloat();
566
567
    for(int row=0; row<mRowChances.length; row++)
568
      {
569
      if( rowFloat<=mRowChances[row] ) return row;
570
      }
571
572
    return 0;
573
    }
574
575
///////////////////////////////////////////////////////////////////////////////////////////////////
576
// remember about the double cover or unit quaternions!
577
578
  private int mulQuat(int q1, int q2)
579
    {
580
    Static4D result = RubikSurfaceView.quatMultiply(QUATS[q1],QUATS[q2]);
581
582
    float rX = result.get0();
583
    float rY = result.get1();
584
    float rZ = result.get2();
585
    float rW = result.get3();
586
587
    final float MAX_ERROR = 0.1f;
588
    float dX,dY,dZ,dW;
589
590
    for(int i=0; i<QUATS.length; i++)
591
      {
592
      dX = QUATS[i].get0() - rX;
593
      dY = QUATS[i].get1() - rY;
594
      dZ = QUATS[i].get2() - rZ;
595
      dW = QUATS[i].get3() - rW;
596
597
      if( dX<MAX_ERROR && dX>-MAX_ERROR &&
598
          dY<MAX_ERROR && dY>-MAX_ERROR &&
599
          dZ<MAX_ERROR && dZ>-MAX_ERROR &&
600
          dW<MAX_ERROR && dW>-MAX_ERROR  ) return i;
601
602
      dX = QUATS[i].get0() + rX;
603
      dY = QUATS[i].get1() + rY;
604
      dZ = QUATS[i].get2() + rZ;
605
      dW = QUATS[i].get3() + rW;
606
607
      if( dX<MAX_ERROR && dX>-MAX_ERROR &&
608
          dY<MAX_ERROR && dY>-MAX_ERROR &&
609
          dZ<MAX_ERROR && dZ>-MAX_ERROR &&
610
          dW<MAX_ERROR && dW>-MAX_ERROR  ) return i;
611
      }
612
613
    return -1;
614
    }
615
616
///////////////////////////////////////////////////////////////////////////////////////////////////
617
// The Skewb is solved if and only if:
618
//
619 3f3ff476 Leszek Koltunski
// 1) all of its corner and edge cubits are rotated with the same quat
620 fb52fae9 Leszek Koltunski
// 2) all its face cubits are rotated with the same quat like the corner ones,
621
//    and optionally they also might be upside down.
622
//
623
// i.e.
624
// cubits [ 8] and [ 9] - might be extra QUAT[1]
625
// cubits [10] and [11] - might be extra QUAT[2]
626
// cubits [12] and [13] - might be extra QUAT[3]
627
628
  public boolean isSolved()
629
    {
630
    int q = CUBITS[0].mQuatIndex;
631
632 d92030e4 Leszek Koltunski
    int numLayers      = getNumLayers();
633
    int numCorners     = getNumCorners();
634
    int numEdges       = getNumEdges(numLayers);
635
    int cornersAndEdges= numCorners + numEdges;
636
    int centersPerFace = getNumCentersPerFace(numLayers);
637 b89898c5 Leszek Koltunski
    int cubit, q1=q;
638
639
    for(cubit=0; cubit<cornersAndEdges; cubit++)
640 fb52fae9 Leszek Koltunski
      {
641 b89898c5 Leszek Koltunski
      if( CUBITS[cubit].mQuatIndex != q ) return false;
642 fb52fae9 Leszek Koltunski
      }
643
644 b89898c5 Leszek Koltunski
    for(int face=0; face<6; face++)
645
      {
646
      if( face%2==0 ) q1 = mulQuat(q, (face/2)+1);
647
648 d92030e4 Leszek Koltunski
      for(int center=0; center<centersPerFace; center++)
649 b89898c5 Leszek Koltunski
        {
650
        if( CUBITS[cubit].mQuatIndex != q && CUBITS[cubit].mQuatIndex != q1 ) return false;
651
        cubit++;
652
        }
653
      }
654
655
    return true;
656 fb52fae9 Leszek Koltunski
    }
657
658
///////////////////////////////////////////////////////////////////////////////////////////////////
659 ee35e63c Leszek Koltunski
// only needed for solvers - there are no Skewb solvers ATM)
660 fb52fae9 Leszek Koltunski
661
  public String retObjectString()
662
    {
663
    return "";
664
    }
665 6fd4a72c Leszek Koltunski
666
///////////////////////////////////////////////////////////////////////////////////////////////////
667
668
  public int getObjectName(int numLayers)
669
    {
670
    switch(numLayers)
671
      {
672
      case 2: return R.string.skew2;
673
      case 3: return R.string.skew3;
674
      }
675
    return R.string.skew2;
676
    }
677
678
///////////////////////////////////////////////////////////////////////////////////////////////////
679
680
  public int getInventor(int numLayers)
681
    {
682
    switch(numLayers)
683
      {
684
      case 2: return R.string.skew2_inventor;
685
      case 3: return R.string.skew3_inventor;
686
      }
687
    return R.string.skew2_inventor;
688
    }
689
690
///////////////////////////////////////////////////////////////////////////////////////////////////
691
692
  public int getComplexity(int numLayers)
693
    {
694
    switch(numLayers)
695
      {
696
      case 2: return 5;
697
      case 3: return 9;
698
      }
699
    return 5;
700
    }
701 fb52fae9 Leszek Koltunski
}