Project

General

Profile

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

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

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