Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistySkewb.java @ e4bf4d02

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 a64e07d0 Leszek Koltunski
  int getNumStickerTypes(int numLayers)
182 eab9d8f8 Leszek Koltunski
    {
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 a64e07d0 Leszek Koltunski
  MeshBase createCubitMesh(int cubit, int numLayers)
404 fb52fae9 Leszek Koltunski
    {
405
    MeshBase mesh;
406
407 d92030e4 Leszek Koltunski
    int numCorners = getNumCorners();
408 d99f3a48 Leszek Koltunski
    int numEdges   = getNumEdges(numLayers);
409 3f3ff476 Leszek Koltunski
410
    if( cubit<numCorners )
411 fb52fae9 Leszek Koltunski
      {
412 b89898c5 Leszek Koltunski
      if( mCornerMesh==null ) mCornerMesh = FactoryCubit.getInstance().createSkewbCornerMesh();
413 fb52fae9 Leszek Koltunski
      mesh = mCornerMesh.copy(true);
414
      }
415 3f3ff476 Leszek Koltunski
    else if( cubit<numCorners+numEdges )
416
      {
417
      if( mEdgeMesh==null )
418
        {
419 b89898c5 Leszek Koltunski
        mEdgeMesh = FactoryCubit.getInstance().createDinoMesh();
420 3f3ff476 Leszek Koltunski
        MatrixEffect effect = new MatrixEffectScale(1.0f/3);
421
        mEdgeMesh.apply(effect,-1,0);
422
        mEdgeMesh.addEmptyTexComponent();
423
        mEdgeMesh.addEmptyTexComponent();
424
        }
425
      mesh = mEdgeMesh.copy(true);
426
      }
427 fb52fae9 Leszek Koltunski
    else
428
      {
429 b89898c5 Leszek Koltunski
      if( mFaceMesh==null ) mFaceMesh = FactoryCubit.getInstance().createSkewbFaceMesh();
430 fb52fae9 Leszek Koltunski
      mesh = mFaceMesh.copy(true);
431
      }
432
433 d99f3a48 Leszek Koltunski
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( getQuat(cubit,numLayers), new Static3D(0,0,0) );
434 fb52fae9 Leszek Koltunski
    mesh.apply(quat,0xffffffff,0);
435
436
    return mesh;
437
    }
438
439
///////////////////////////////////////////////////////////////////////////////////////////////////
440
441 d92030e4 Leszek Koltunski
  int getFaceColor(int cubit, int cubitface, int numLayers)
442 fb52fae9 Leszek Koltunski
    {
443 d92030e4 Leszek Koltunski
    int numCorners = getNumCorners();
444
    int numEdges   = getNumEdges(numLayers);
445 3f3ff476 Leszek Koltunski
446
    if( cubit<numCorners )
447
      {
448
      return mCornerMap[cubit][cubitface];
449
      }
450
    else if( cubit<numCorners+numEdges )
451
      {
452 d92030e4 Leszek Koltunski
      int edge = (cubit-numCorners)/(numLayers-2);
453 3f3ff476 Leszek Koltunski
      return mEdgeMap[edge][cubitface];
454
      }
455
    else
456
      {
457 d92030e4 Leszek Koltunski
      int center = (cubit-numCorners-numEdges)/getNumCentersPerFace(numLayers);
458 3f3ff476 Leszek Koltunski
      return mCenterMap[center][cubitface];
459
      }
460 fb52fae9 Leszek Koltunski
    }
461
462
///////////////////////////////////////////////////////////////////////////////////////////////////
463
464 ae755eda Leszek Koltunski
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
465 fb52fae9 Leszek Koltunski
    {
466 eab9d8f8 Leszek Koltunski
    int COLORS = FACE_COLORS.length;
467 ae755eda Leszek Koltunski
    float R,S;
468
    float[] vertices;
469 eab9d8f8 Leszek Koltunski
470
    if( face<COLORS )
471
      {
472 76c2bd07 Leszek Koltunski
      float E = 0.5f;
473 ae755eda Leszek Koltunski
      R = 0.023f;
474
      S = 0.035f;
475
      vertices = new float[] { -E+E/4,E/4, E/4,-E+E/4, E/4,E/4};
476 eab9d8f8 Leszek Koltunski
      }
477 3f3ff476 Leszek Koltunski
    else if( face<2*COLORS )
478
      {
479 ae755eda Leszek Koltunski
      float E = 0.5f;
480
      R = 0.025f;
481
      S = 0.05f;
482
      vertices = new float[] { -E,E/3, 0,-2*E/3, +E,E/3 };
483 3f3ff476 Leszek Koltunski
      }
484 eab9d8f8 Leszek Koltunski
    else
485
      {
486 76c2bd07 Leszek Koltunski
      float E = SQ2/4;
487 ae755eda Leszek Koltunski
      R = 0.055f;
488
      S = 0.035f;
489
      vertices = new float[] { -E,-E, +E,-E, +E,+E, -E,+E };
490 eab9d8f8 Leszek Koltunski
      }
491 ae755eda Leszek Koltunski
492
    FactorySticker factory = FactorySticker.getInstance();
493
    factory.drawRoundedPolygon(canvas, paint, left, top, vertices, S, FACE_COLORS[face%COLORS], R);
494 fb52fae9 Leszek Koltunski
    }
495
496
///////////////////////////////////////////////////////////////////////////////////////////////////
497
498
  float returnMultiplier()
499
    {
500
    return 2.0f;
501
    }
502
503
///////////////////////////////////////////////////////////////////////////////////////////////////
504
505 a64e07d0 Leszek Koltunski
  float[] getRowChances(int numLayers)
506 fb52fae9 Leszek Koltunski
    {
507 d99f3a48 Leszek Koltunski
    float[] chances = new float[numLayers];
508 fb52fae9 Leszek Koltunski
509 b3da2f16 Leszek Koltunski
    switch(numLayers)
510 3f3ff476 Leszek Koltunski
      {
511 b3da2f16 Leszek Koltunski
      case 2: chances[0] = 0.5f;
512
              chances[1] = 1.0f;
513
              break;
514
      case 3: chances[0] = 0.5f;
515
              chances[1] = 0.5f;
516
              chances[2] = 1.0f;
517
              break;
518
      default:for(int i=0; i<numLayers; i++)
519
                {
520
                chances[i] = (float)(i+1)/numLayers;
521
                }
522 3f3ff476 Leszek Koltunski
      }
523 fb52fae9 Leszek Koltunski
524
    return chances;
525
    }
526
527
///////////////////////////////////////////////////////////////////////////////////////////////////
528
// PUBLIC API
529
530
  public Static3D[] getRotationAxis()
531
    {
532
    return ROT_AXIS;
533
    }
534
535
///////////////////////////////////////////////////////////////////////////////////////////////////
536
537
  public int getBasicAngle()
538
    {
539
    return 3;
540
    }
541
542
///////////////////////////////////////////////////////////////////////////////////////////////////
543
544
  public int randomizeNewRotAxis(Random rnd, int oldRotAxis)
545
    {
546
    int numAxis = ROTATION_AXIS.length;
547
548
    if( oldRotAxis == START_AXIS )
549
      {
550
      return rnd.nextInt(numAxis);
551
      }
552
    else
553
      {
554
      int newVector = rnd.nextInt(numAxis-1);
555
      return (newVector>=oldRotAxis ? newVector+1 : newVector);
556
      }
557
    }
558
559
///////////////////////////////////////////////////////////////////////////////////////////////////
560
561
  public int randomizeNewRow(Random rnd, int oldRotAxis, int oldRow, int newRotAxis)
562
    {
563
    float rowFloat = rnd.nextFloat();
564
565
    for(int row=0; row<mRowChances.length; row++)
566
      {
567
      if( rowFloat<=mRowChances[row] ) return row;
568
      }
569
570
    return 0;
571
    }
572
573
///////////////////////////////////////////////////////////////////////////////////////////////////
574
// remember about the double cover or unit quaternions!
575
576
  private int mulQuat(int q1, int q2)
577
    {
578
    Static4D result = RubikSurfaceView.quatMultiply(QUATS[q1],QUATS[q2]);
579
580
    float rX = result.get0();
581
    float rY = result.get1();
582
    float rZ = result.get2();
583
    float rW = result.get3();
584
585
    final float MAX_ERROR = 0.1f;
586
    float dX,dY,dZ,dW;
587
588
    for(int i=0; i<QUATS.length; i++)
589
      {
590
      dX = QUATS[i].get0() - rX;
591
      dY = QUATS[i].get1() - rY;
592
      dZ = QUATS[i].get2() - rZ;
593
      dW = QUATS[i].get3() - rW;
594
595
      if( dX<MAX_ERROR && dX>-MAX_ERROR &&
596
          dY<MAX_ERROR && dY>-MAX_ERROR &&
597
          dZ<MAX_ERROR && dZ>-MAX_ERROR &&
598
          dW<MAX_ERROR && dW>-MAX_ERROR  ) return i;
599
600
      dX = QUATS[i].get0() + rX;
601
      dY = QUATS[i].get1() + rY;
602
      dZ = QUATS[i].get2() + rZ;
603
      dW = QUATS[i].get3() + rW;
604
605
      if( dX<MAX_ERROR && dX>-MAX_ERROR &&
606
          dY<MAX_ERROR && dY>-MAX_ERROR &&
607
          dZ<MAX_ERROR && dZ>-MAX_ERROR &&
608
          dW<MAX_ERROR && dW>-MAX_ERROR  ) return i;
609
      }
610
611
    return -1;
612
    }
613
614
///////////////////////////////////////////////////////////////////////////////////////////////////
615
// The Skewb is solved if and only if:
616
//
617 3f3ff476 Leszek Koltunski
// 1) all of its corner and edge cubits are rotated with the same quat
618 fb52fae9 Leszek Koltunski
// 2) all its face cubits are rotated with the same quat like the corner ones,
619
//    and optionally they also might be upside down.
620
//
621
// i.e.
622
// cubits [ 8] and [ 9] - might be extra QUAT[1]
623
// cubits [10] and [11] - might be extra QUAT[2]
624
// cubits [12] and [13] - might be extra QUAT[3]
625
626
  public boolean isSolved()
627
    {
628
    int q = CUBITS[0].mQuatIndex;
629
630 d92030e4 Leszek Koltunski
    int numLayers      = getNumLayers();
631
    int numCorners     = getNumCorners();
632
    int numEdges       = getNumEdges(numLayers);
633
    int cornersAndEdges= numCorners + numEdges;
634
    int centersPerFace = getNumCentersPerFace(numLayers);
635 b89898c5 Leszek Koltunski
    int cubit, q1=q;
636
637
    for(cubit=0; cubit<cornersAndEdges; cubit++)
638 fb52fae9 Leszek Koltunski
      {
639 b89898c5 Leszek Koltunski
      if( CUBITS[cubit].mQuatIndex != q ) return false;
640 fb52fae9 Leszek Koltunski
      }
641
642 b89898c5 Leszek Koltunski
    for(int face=0; face<6; face++)
643
      {
644
      if( face%2==0 ) q1 = mulQuat(q, (face/2)+1);
645
646 d92030e4 Leszek Koltunski
      for(int center=0; center<centersPerFace; center++)
647 b89898c5 Leszek Koltunski
        {
648
        if( CUBITS[cubit].mQuatIndex != q && CUBITS[cubit].mQuatIndex != q1 ) return false;
649
        cubit++;
650
        }
651
      }
652
653
    return true;
654 fb52fae9 Leszek Koltunski
    }
655
656
///////////////////////////////////////////////////////////////////////////////////////////////////
657 ee35e63c Leszek Koltunski
// only needed for solvers - there are no Skewb solvers ATM)
658 fb52fae9 Leszek Koltunski
659
  public String retObjectString()
660
    {
661
    return "";
662
    }
663 6fd4a72c Leszek Koltunski
664
///////////////////////////////////////////////////////////////////////////////////////////////////
665
666
  public int getObjectName(int numLayers)
667
    {
668
    switch(numLayers)
669
      {
670
      case 2: return R.string.skew2;
671
      case 3: return R.string.skew3;
672
      }
673
    return R.string.skew2;
674
    }
675
676
///////////////////////////////////////////////////////////////////////////////////////////////////
677
678
  public int getInventor(int numLayers)
679
    {
680
    switch(numLayers)
681
      {
682
      case 2: return R.string.skew2_inventor;
683
      case 3: return R.string.skew3_inventor;
684
      }
685
    return R.string.skew2_inventor;
686
    }
687
688
///////////////////////////////////////////////////////////////////////////////////////////////////
689
690
  public int getComplexity(int numLayers)
691
    {
692
    switch(numLayers)
693
      {
694
      case 2: return 5;
695
      case 3: return 9;
696
      }
697
    return 5;
698
    }
699 fb52fae9 Leszek Koltunski
}