Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistySkewb.java @ 749ef882

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 749ef882 Leszek Koltunski
import org.distorted.helpers.FactoryCubit;
27
import org.distorted.helpers.FactorySticker;
28 3f3ff476 Leszek Koltunski
import org.distorted.library.effect.MatrixEffect;
29 fb52fae9 Leszek Koltunski
import org.distorted.library.effect.MatrixEffectQuaternion;
30 3f3ff476 Leszek Koltunski
import org.distorted.library.effect.MatrixEffectScale;
31 fb52fae9 Leszek Koltunski
import org.distorted.library.main.DistortedEffects;
32
import org.distorted.library.main.DistortedTexture;
33
import org.distorted.library.mesh.MeshBase;
34
import org.distorted.library.mesh.MeshSquare;
35
import org.distorted.library.type.Static3D;
36
import org.distorted.library.type.Static4D;
37 6fd4a72c Leszek Koltunski
import org.distorted.main.R;
38 fb52fae9 Leszek Koltunski
import org.distorted.main.RubikSurfaceView;
39
40
import java.util.Random;
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 db875721 Leszek Koltunski
    super(size, 2*size-2, 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 e6cf7283 Leszek Koltunski
  float[][] 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 e6cf7283 Leszek Koltunski
    final float[][] CENTERS = new float[numCorners+numEdges+numCenters][];
227 3f3ff476 Leszek Koltunski
228
    /// CORNERS //////////////////////////////////////////////
229
230 e6cf7283 Leszek Koltunski
    CENTERS[0] = new float[] { DIST_CORNER, DIST_CORNER, DIST_CORNER };
231
    CENTERS[1] = new float[] { DIST_CORNER, DIST_CORNER,-DIST_CORNER };
232
    CENTERS[2] = new float[] { DIST_CORNER,-DIST_CORNER, DIST_CORNER };
233
    CENTERS[3] = new float[] { DIST_CORNER,-DIST_CORNER,-DIST_CORNER };
234
    CENTERS[4] = new float[] {-DIST_CORNER, DIST_CORNER, DIST_CORNER };
235
    CENTERS[5] = new float[] {-DIST_CORNER, DIST_CORNER,-DIST_CORNER };
236
    CENTERS[6] = new float[] {-DIST_CORNER,-DIST_CORNER, DIST_CORNER };
237
    CENTERS[7] = new float[] {-DIST_CORNER,-DIST_CORNER,-DIST_CORNER };
238 3f3ff476 Leszek Koltunski
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 e6cf7283 Leszek Koltunski
        CENTERS[index] = new float[] { edges[0]==0 ? c : edges[0] ,
266 3f3ff476 Leszek Koltunski
                                       edges[1]==0 ? c : edges[1] ,
267 e6cf7283 Leszek Koltunski
                                       edges[2]==0 ? c : edges[2] };
268 3f3ff476 Leszek Koltunski
        }
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 e6cf7283 Leszek Koltunski
          CENTERS[index] = new float[] {cen0,cen1,cen2};
311 3f3ff476 Leszek Koltunski
          }
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 e6cf7283 Leszek Koltunski
          CENTERS[index] = new float[] {cen0,cen1,cen2};
335 3f3ff476 Leszek Koltunski
          }
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 5043d5d0 Leszek Koltunski
  public void randomizeNewScramble(int[][] scramble, Random rnd, int num)
545 fb52fae9 Leszek Koltunski
    {
546 5043d5d0 Leszek Koltunski
    if( num==0 )
547 fb52fae9 Leszek Koltunski
      {
548 5043d5d0 Leszek Koltunski
      scramble[num][0] = rnd.nextInt(ROTATION_AXIS.length);
549 fb52fae9 Leszek Koltunski
      }
550
    else
551
      {
552 bbc6471c Leszek Koltunski
      int newVector = rnd.nextInt(ROTATION_AXIS.length-1);
553 5043d5d0 Leszek Koltunski
      scramble[num][0] = (newVector>=scramble[num-1][0] ? newVector+1 : newVector);
554 fb52fae9 Leszek Koltunski
      }
555
556
    float rowFloat = rnd.nextFloat();
557
558
    for(int row=0; row<mRowChances.length; row++)
559
      {
560 bbc6471c Leszek Koltunski
      if( rowFloat<=mRowChances[row] )
561
        {
562 5043d5d0 Leszek Koltunski
        scramble[num][1] = row;
563 bbc6471c Leszek Koltunski
        break;
564
        }
565 fb52fae9 Leszek Koltunski
      }
566
567 5043d5d0 Leszek Koltunski
    switch( rnd.nextInt(2) )
568
      {
569
      case 0: scramble[num][2] = -1; break;
570
      case 1: scramble[num][2] =  1; break;
571
      }
572 fb52fae9 Leszek Koltunski
    }
573
574
///////////////////////////////////////////////////////////////////////////////////////////////////
575
// remember about the double cover or unit quaternions!
576
577
  private int mulQuat(int q1, int q2)
578
    {
579
    Static4D result = RubikSurfaceView.quatMultiply(QUATS[q1],QUATS[q2]);
580
581
    float rX = result.get0();
582
    float rY = result.get1();
583
    float rZ = result.get2();
584
    float rW = result.get3();
585
586
    final float MAX_ERROR = 0.1f;
587
    float dX,dY,dZ,dW;
588
589
    for(int i=0; i<QUATS.length; i++)
590
      {
591
      dX = QUATS[i].get0() - rX;
592
      dY = QUATS[i].get1() - rY;
593
      dZ = QUATS[i].get2() - rZ;
594
      dW = QUATS[i].get3() - rW;
595
596
      if( dX<MAX_ERROR && dX>-MAX_ERROR &&
597
          dY<MAX_ERROR && dY>-MAX_ERROR &&
598
          dZ<MAX_ERROR && dZ>-MAX_ERROR &&
599
          dW<MAX_ERROR && dW>-MAX_ERROR  ) return i;
600
601
      dX = QUATS[i].get0() + rX;
602
      dY = QUATS[i].get1() + rY;
603
      dZ = QUATS[i].get2() + rZ;
604
      dW = QUATS[i].get3() + rW;
605
606
      if( dX<MAX_ERROR && dX>-MAX_ERROR &&
607
          dY<MAX_ERROR && dY>-MAX_ERROR &&
608
          dZ<MAX_ERROR && dZ>-MAX_ERROR &&
609
          dW<MAX_ERROR && dW>-MAX_ERROR  ) return i;
610
      }
611
612
    return -1;
613
    }
614
615
///////////////////////////////////////////////////////////////////////////////////////////////////
616
// The Skewb is solved if and only if:
617
//
618 3f3ff476 Leszek Koltunski
// 1) all of its corner and edge cubits are rotated with the same quat
619 fb52fae9 Leszek Koltunski
// 2) all its face cubits are rotated with the same quat like the corner ones,
620
//    and optionally they also might be upside down.
621
//
622
// i.e.
623
// cubits [ 8] and [ 9] - might be extra QUAT[1]
624
// cubits [10] and [11] - might be extra QUAT[2]
625
// cubits [12] and [13] - might be extra QUAT[3]
626
627
  public boolean isSolved()
628
    {
629
    int q = CUBITS[0].mQuatIndex;
630
631 d92030e4 Leszek Koltunski
    int numLayers      = getNumLayers();
632
    int numCorners     = getNumCorners();
633
    int numEdges       = getNumEdges(numLayers);
634
    int cornersAndEdges= numCorners + numEdges;
635
    int centersPerFace = getNumCentersPerFace(numLayers);
636 b89898c5 Leszek Koltunski
    int cubit, q1=q;
637
638
    for(cubit=0; cubit<cornersAndEdges; cubit++)
639 fb52fae9 Leszek Koltunski
      {
640 b89898c5 Leszek Koltunski
      if( CUBITS[cubit].mQuatIndex != q ) return false;
641 fb52fae9 Leszek Koltunski
      }
642
643 b89898c5 Leszek Koltunski
    for(int face=0; face<6; face++)
644
      {
645
      if( face%2==0 ) q1 = mulQuat(q, (face/2)+1);
646
647 d92030e4 Leszek Koltunski
      for(int center=0; center<centersPerFace; center++)
648 b89898c5 Leszek Koltunski
        {
649
        if( CUBITS[cubit].mQuatIndex != q && CUBITS[cubit].mQuatIndex != q1 ) return false;
650
        cubit++;
651
        }
652
      }
653
654
    return true;
655 fb52fae9 Leszek Koltunski
    }
656
657
///////////////////////////////////////////////////////////////////////////////////////////////////
658 ee35e63c Leszek Koltunski
// only needed for solvers - there are no Skewb solvers ATM)
659 fb52fae9 Leszek Koltunski
660
  public String retObjectString()
661
    {
662
    return "";
663
    }
664 6fd4a72c Leszek Koltunski
665
///////////////////////////////////////////////////////////////////////////////////////////////////
666
667
  public int getObjectName(int numLayers)
668
    {
669
    switch(numLayers)
670
      {
671
      case 2: return R.string.skew2;
672
      case 3: return R.string.skew3;
673
      }
674
    return R.string.skew2;
675
    }
676
677
///////////////////////////////////////////////////////////////////////////////////////////////////
678
679
  public int getInventor(int numLayers)
680
    {
681
    switch(numLayers)
682
      {
683
      case 2: return R.string.skew2_inventor;
684
      case 3: return R.string.skew3_inventor;
685
      }
686
    return R.string.skew2_inventor;
687
    }
688
689
///////////////////////////////////////////////////////////////////////////////////////////////////
690
691
  public int getComplexity(int numLayers)
692
    {
693
    switch(numLayers)
694
      {
695
      case 2: return 5;
696
      case 3: return 9;
697
      }
698
    return 5;
699
    }
700 fb52fae9 Leszek Koltunski
}