Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyPyraminx.java @ 7d8cc029

1 e844c116 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 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 1f9772f3 Leszek Koltunski
package org.distorted.objects;
21 e844c116 Leszek Koltunski
22 ccf9fec5 Leszek Koltunski
import android.content.res.Resources;
23 e844c116 Leszek Koltunski
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 e844c116 Leszek Koltunski
import org.distorted.library.main.DistortedEffects;
29
import org.distorted.library.main.DistortedTexture;
30
import org.distorted.library.mesh.MeshBase;
31 efa8aa48 Leszek Koltunski
import org.distorted.library.mesh.MeshSquare;
32 e844c116 Leszek Koltunski
import org.distorted.library.type.Static3D;
33
import org.distorted.library.type.Static4D;
34 6fd4a72c Leszek Koltunski
import org.distorted.main.R;
35 e844c116 Leszek Koltunski
36 7c969a6d Leszek Koltunski
import java.util.Random;
37
38 e844c116 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
39
40 9c2f0c91 Leszek Koltunski
public class TwistyPyraminx extends TwistyObject
41 e844c116 Leszek Koltunski
{
42 ad38d800 Leszek Koltunski
  static final Static3D[] ROT_AXIS = new Static3D[]
43 e844c116 Leszek Koltunski
         {
44 ac940e24 Leszek Koltunski
           new Static3D(     0,-SQ3/3,-SQ6/3),
45
           new Static3D(     0,-SQ3/3,+SQ6/3),
46
           new Static3D(+SQ6/3,+SQ3/3,     0),
47
           new Static3D(-SQ6/3,+SQ3/3,     0),
48 ad38d800 Leszek Koltunski
         };
49
50 e844c116 Leszek Koltunski
  private static final int[] FACE_COLORS = new int[]
51
         {
52 ece1b58d Leszek Koltunski
           COLOR_GREEN , COLOR_YELLOW,
53
           COLOR_BLUE  , COLOR_RED
54 e844c116 Leszek Koltunski
         };
55
56 9f4c44fe Leszek Koltunski
  // computed with res/raw/compute_quats.c
57 10585385 Leszek Koltunski
  private static final Static4D[] QUATS = new Static4D[]
58 e844c116 Leszek Koltunski
         {
59 10585385 Leszek Koltunski
           new Static4D(  0.0f,   0.0f,   0.0f,  1.0f),
60 ac940e24 Leszek Koltunski
           new Static4D(  0.0f,   1.0f,   0.0f,  0.0f),
61
           new Static4D( SQ2/2,   0.5f,   0.0f,  0.5f),
62
           new Static4D(-SQ2/2,   0.5f,   0.0f,  0.5f),
63
           new Static4D(  0.0f,  -0.5f, -SQ2/2,  0.5f),
64
           new Static4D(  0.0f,  -0.5f,  SQ2/2,  0.5f),
65
           new Static4D( SQ2/2,   0.5f,   0.0f, -0.5f),
66
           new Static4D(-SQ2/2,   0.5f,   0.0f, -0.5f),
67
           new Static4D(  0.0f,  -0.5f, -SQ2/2, -0.5f),
68
           new Static4D(  0.0f,  -0.5f,  SQ2/2, -0.5f),
69
           new Static4D( SQ2/2,   0.0f,  SQ2/2,  0.0f),
70
           new Static4D(-SQ2/2,   0.0f,  SQ2/2,  0.0f)
71 e844c116 Leszek Koltunski
         };
72
73 31cd7256 Leszek Koltunski
  private static final double[][] VERTICES_TETRA = new double[][]
74 b1f2ccf5 Leszek Koltunski
          {
75
             {-0.5, SQ2/4, 0.0},
76
             { 0.5, SQ2/4, 0.0},
77
             { 0.0,-SQ2/4, 0.5},
78
             { 0.0,-SQ2/4,-0.5}
79
          };
80
81 31cd7256 Leszek Koltunski
  private static final int[][] VERT_INDEXES_TETRA = new int[][]
82 b1f2ccf5 Leszek Koltunski
          {
83
             {2,1,0},   // counterclockwise!
84 31cd7256 Leszek Koltunski
             {3,0,1},
85 b1f2ccf5 Leszek Koltunski
             {3,2,0},
86 31cd7256 Leszek Koltunski
             {2,3,1}
87 b1f2ccf5 Leszek Koltunski
          };
88
89 31cd7256 Leszek Koltunski
  private static final double[][] VERTICES_OCTA = new double[][]
90 b1f2ccf5 Leszek Koltunski
          {
91
             { 0.5,   0.0, 0.5},
92
             { 0.5,   0.0,-0.5},
93
             {-0.5,   0.0,-0.5},
94
             {-0.5,   0.0, 0.5},
95
             { 0.0, SQ2/2, 0.0},
96
             { 0.0,-SQ2/2, 0.0}
97
          };
98
99 31cd7256 Leszek Koltunski
  private static final int[][] VERT_INDEXES_OCTA = new int[][]
100 b1f2ccf5 Leszek Koltunski
          {
101
             {3,0,4},   // counterclockwise!
102
             {0,1,4},
103
             {1,2,4},
104
             {2,3,4},
105
             {5,0,3},
106
             {5,1,0},
107
             {5,2,1},
108
             {5,3,2}
109
          };
110
111 31cd7256 Leszek Koltunski
  private static final float[][] STICKERS = new float[][]
112
          {
113
             { -0.4330127f, -0.25f, 0.4330127f, -0.25f, 0.0f, 0.5f }
114
          };
115
116
  private static MeshBase[] mMeshes;
117 49f67f9b Leszek Koltunski
118 e844c116 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
119
120 ac940e24 Leszek Koltunski
  TwistyPyraminx(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
121
                 DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
122 e844c116 Leszek Koltunski
    {
123 db875721 Leszek Koltunski
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.PYRA, res, scrWidth);
124 e844c116 Leszek Koltunski
    }
125
126
///////////////////////////////////////////////////////////////////////////////////////////////////
127
128 e6cf7283 Leszek Koltunski
  private void addTetrahedralLattice(int size, int index, float[][] pos)
129 49f67f9b Leszek Koltunski
    {
130 ac940e24 Leszek Koltunski
    final float DX = 1.0f;
131
    final float DY = SQ2/2;
132
    final float DZ = 1.0f;
133 49f67f9b Leszek Koltunski
134 ac940e24 Leszek Koltunski
    float startX = 0.0f;
135
    float startY =-DY*(size-1)/2;
136
    float startZ = DZ*(size-1)/2;
137 769409d2 Leszek Koltunski
138 ac940e24 Leszek Koltunski
    for(int layer=0; layer<size; layer++)
139 49f67f9b Leszek Koltunski
      {
140 ac940e24 Leszek Koltunski
      float currX = startX;
141
      float currY = startY;
142
143
      for(int x=0; x<layer+1; x++)
144
        {
145
        float currZ = startZ;
146
147
        for(int z=0; z<size-layer; z++)
148
          {
149 e6cf7283 Leszek Koltunski
          pos[index] = new float[] {currX,currY,currZ};
150 ac940e24 Leszek Koltunski
          index++;
151
          currZ -= DZ;
152
          }
153
154
        currX += DX;
155
        }
156
157
      startX-=DX/2;
158
      startY+=DY;
159
      startZ-=DZ/2;
160 49f67f9b Leszek Koltunski
      }
161
    }
162
163
///////////////////////////////////////////////////////////////////////////////////////////////////
164 ac940e24 Leszek Koltunski
// there are (n^3-n)/6 octahedrons and ((n+1)^3 - (n+1))/6 tetrahedrons
165 49f67f9b Leszek Koltunski
166 e6cf7283 Leszek Koltunski
  float[][] getCubitPositions(int size)
167 e844c116 Leszek Koltunski
    {
168 ac940e24 Leszek Koltunski
    int numOcta = (size-1)*size*(size+1)/6;
169
    int numTetra= size*(size+1)*(size+2)/6;
170 e6cf7283 Leszek Koltunski
    float[][] ret = new float[numOcta+numTetra][];
171 49f67f9b Leszek Koltunski
172 ac940e24 Leszek Koltunski
    addTetrahedralLattice(size-1,      0,ret);
173
    addTetrahedralLattice(size  ,numOcta,ret);
174 49f67f9b Leszek Koltunski
175 ac940e24 Leszek Koltunski
    return ret;
176 e844c116 Leszek Koltunski
    }
177
178
///////////////////////////////////////////////////////////////////////////////////////////////////
179
180 10585385 Leszek Koltunski
  Static4D[] getQuats()
181 e844c116 Leszek Koltunski
    {
182 10585385 Leszek Koltunski
    return QUATS;
183 e844c116 Leszek Koltunski
    }
184
185
///////////////////////////////////////////////////////////////////////////////////////////////////
186
187
  int getNumFaces()
188
    {
189
    return FACE_COLORS.length;
190
    }
191
192 eab9d8f8 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
193
194 a64e07d0 Leszek Koltunski
  int getNumStickerTypes(int numLayers)
195 eab9d8f8 Leszek Koltunski
    {
196 31cd7256 Leszek Koltunski
    return STICKERS.length;
197 eab9d8f8 Leszek Koltunski
    }
198
199 7403cdfa Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
200
201 a97e02b7 Leszek Koltunski
  float[] getCuts(int size)
202 7403cdfa Leszek Koltunski
    {
203 a97e02b7 Leszek Koltunski
    float[] cuts = new float[size-1];
204
205
    for(int i=0; i<size-1; i++)
206
      {
207
      cuts[i] = (1.0f-0.25f*size+i)*(SQ6/3);
208
      }
209
210
    return cuts;
211 7403cdfa Leszek Koltunski
    }
212
213 8f53e513 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
214
215
  int getNumCubitFaces()
216
    {
217 ac940e24 Leszek Koltunski
    return 8;
218 8f53e513 Leszek Koltunski
    }
219
220 f0fa83ae Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
221
222
  float getScreenRatio()
223
    {
224 7381193e Leszek Koltunski
    return 0.82f;
225 f0fa83ae Leszek Koltunski
    }
226
227 eaee1ddc Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
228
229
  boolean shouldResetTextureMaps()
230
    {
231
    return false;
232
    }
233
234 31cd7256 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
235
236
  private int getNumOctahedrons(int numLayers)
237
    {
238
    return (numLayers-1)*numLayers*(numLayers+1)/6;
239
    }
240
241 f6d06256 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
242
243 ac940e24 Leszek Koltunski
  private int faceColor(int cubit, int axis)
244 f6d06256 Leszek Koltunski
    {
245 f0450fcc Leszek Koltunski
    return CUBITS[cubit].mRotationRow[axis] == 1 ? axis : NUM_FACES;
246 f6d06256 Leszek Koltunski
    }
247
248 f0fa83ae Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
249
250 ac940e24 Leszek Koltunski
  int getFaceColor(int cubit, int cubitface, int size)
251 e844c116 Leszek Koltunski
    {
252 ac940e24 Leszek Koltunski
    if( cubit< (size-1)*size*(size+1)/6 )
253 40ab026e Leszek Koltunski
      {
254 ac940e24 Leszek Koltunski
      switch( cubitface )
255
        {
256
        case 0: return faceColor(cubit,0);
257
        case 2: return faceColor(cubit,1);
258
        case 5: return faceColor(cubit,3);
259
        case 7: return faceColor(cubit,2);
260
        default:return NUM_FACES;
261
        }
262 40ab026e Leszek Koltunski
      }
263 ac940e24 Leszek Koltunski
    else
264 89a11f7b Leszek Koltunski
      {
265 ac940e24 Leszek Koltunski
      return cubitface<NUM_FACES ? faceColor(cubit,cubitface) : NUM_FACES;
266 89a11f7b Leszek Koltunski
      }
267 e844c116 Leszek Koltunski
    }
268
269 40ab026e Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
270
271 a64e07d0 Leszek Koltunski
  MeshBase createCubitMesh(int cubit, int numLayers)
272 40ab026e Leszek Koltunski
    {
273 31cd7256 Leszek Koltunski
    if( mMeshes==null )
274 40ab026e Leszek Koltunski
      {
275 31cd7256 Leszek Koltunski
      FactoryCubit factory = FactoryCubit.getInstance();
276
      factory.clear();
277
      mMeshes = new MeshBase[2];
278
      }
279
280
    MeshBase mesh;
281
    int numO = getNumOctahedrons(numLayers);
282
283
    if( cubit<numO )
284
      {
285
      if( mMeshes[0]==null )
286
        {
287
        float[][] bands     = new float[][] { {0.05f,35,0.5f,0.8f,6,2,2} };
288
        int[] bandIndexes   = new int[] { 0,0,0,0,0,0,0,0 };
289
        float[][] corners   = new float[][] { {0.04f,0.20f} };
290
        int[] cornerIndexes = new int[] { 0,0,0,0,0,0 };
291 b3c9061a Leszek Koltunski
        float[][] centers   = new float[][] { {0.0f, 0.0f, 0.0f} };
292
        int[] centerIndexes = new int[] { 0,0,0,0,0,0 };
293 31cd7256 Leszek Koltunski
294
        FactoryCubit factory = FactoryCubit.getInstance();
295
296
        factory.createNewFaceTransform(VERTICES_OCTA,VERT_INDEXES_OCTA);
297
        mMeshes[0] = factory.createRoundedSolid(VERTICES_OCTA, VERT_INDEXES_OCTA,
298
                                                bands, bandIndexes,
299
                                                corners, cornerIndexes,
300 b3c9061a Leszek Koltunski
                                                centers, centerIndexes,
301 31cd7256 Leszek Koltunski
                                                getNumCubitFaces() );
302
        }
303
      mesh = mMeshes[0].copy(true);
304 40ab026e Leszek Koltunski
      }
305
    else
306
      {
307 31cd7256 Leszek Koltunski
      if( mMeshes[1]==null )
308
        {
309
        float[][] bands     = new float[][] { {0.05f,35,0.5f,0.8f,6,2,2} };
310
        int[] bandIndexes   = new int[] { 0,0,0,0 };
311
        float[][] corners   = new float[][] { {0.06f,0.15f} };
312
        int[] cornerIndexes = new int[] { 0,0,0,0 };
313 b3c9061a Leszek Koltunski
        float[][] centers   = new float[][] { {0.0f, 0.0f, 0.0f} };
314
        int[] centerIndexes = new int[] { 0,0,0,0 };
315 31cd7256 Leszek Koltunski
316
        FactoryCubit factory = FactoryCubit.getInstance();
317
318
        factory.createNewFaceTransform(VERTICES_TETRA,VERT_INDEXES_TETRA);
319
        mMeshes[1] = factory.createRoundedSolid(VERTICES_TETRA, VERT_INDEXES_TETRA,
320
                                                bands, bandIndexes,
321
                                                corners, cornerIndexes,
322 b3c9061a Leszek Koltunski
                                                centers, centerIndexes,
323 31cd7256 Leszek Koltunski
                                                getNumCubitFaces() );
324
325
        factory.printStickerCoords();
326
        }
327
      mesh = mMeshes[1].copy(true);
328 40ab026e Leszek Koltunski
      }
329 31cd7256 Leszek Koltunski
330
    return mesh;
331 40ab026e Leszek Koltunski
    }
332
333 7289fd6c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
334
335 ae755eda Leszek Koltunski
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
336 7289fd6c Leszek Koltunski
    {
337 76c2bd07 Leszek Koltunski
    float R = 0.06f;
338
    float S = 0.08f;
339
340 b89898c5 Leszek Koltunski
    FactorySticker factory = FactorySticker.getInstance();
341 31cd7256 Leszek Koltunski
    factory.drawRoundedPolygon(canvas, paint, left, top, STICKERS[0], S, FACE_COLORS[face], R);
342 7289fd6c Leszek Koltunski
    }
343
344 fb377dae Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
345 7403cdfa Leszek Koltunski
// SQ6/3 = height of the tetrahedron
346 fb377dae Leszek Koltunski
347
  float returnMultiplier()
348
    {
349 d99f3a48 Leszek Koltunski
    return getNumLayers()/(SQ6/3);
350 fb377dae Leszek Koltunski
    }
351
352 7c969a6d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
353
354 a64e07d0 Leszek Koltunski
  float[] getRowChances(int numLayers)
355 7c969a6d Leszek Koltunski
    {
356 d99f3a48 Leszek Koltunski
    int total = numLayers*(numLayers+1)/2;
357 7c969a6d Leszek Koltunski
    float running=0.0f;
358 d99f3a48 Leszek Koltunski
    float[] chances = new float[numLayers];
359 7c969a6d Leszek Koltunski
360 d99f3a48 Leszek Koltunski
    for(int i=0; i<numLayers; i++)
361 7c969a6d Leszek Koltunski
      {
362 d99f3a48 Leszek Koltunski
      running += (numLayers-i);
363 7c969a6d Leszek Koltunski
      chances[i] = running / total;
364
      }
365
366
    return chances;
367
    }
368
369 e844c116 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
370
// PUBLIC API
371
372 12ad3fca Leszek Koltunski
  public Static3D[] getRotationAxis()
373
    {
374 ad38d800 Leszek Koltunski
    return ROT_AXIS;
375 12ad3fca Leszek Koltunski
    }
376
377
///////////////////////////////////////////////////////////////////////////////////////////////////
378
379 e844c116 Leszek Koltunski
  public int getBasicAngle()
380
    {
381
    return 3;
382
    }
383 39e74052 Leszek Koltunski
384 7c969a6d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
385
386 5043d5d0 Leszek Koltunski
  public void randomizeNewScramble(int[][] scramble, Random rnd, int num)
387 7c969a6d Leszek Koltunski
    {
388 5043d5d0 Leszek Koltunski
    if( num==0 )
389 5cf34c5f Leszek Koltunski
      {
390 5043d5d0 Leszek Koltunski
      scramble[num][0] = rnd.nextInt(ROTATION_AXIS.length);
391 7c969a6d Leszek Koltunski
      }
392
    else
393
      {
394 bbc6471c Leszek Koltunski
      int newVector = rnd.nextInt(ROTATION_AXIS.length-1);
395 5043d5d0 Leszek Koltunski
      scramble[num][0] = (newVector>=scramble[num-1][0] ? newVector+1 : newVector);
396 5cf34c5f Leszek Koltunski
      }
397 e46e17fb Leszek Koltunski
398 7c969a6d Leszek Koltunski
    float rowFloat = rnd.nextFloat();
399 e46e17fb Leszek Koltunski
400 7c969a6d Leszek Koltunski
    for(int row=0; row<mRowChances.length; row++)
401
      {
402 bbc6471c Leszek Koltunski
      if( rowFloat<=mRowChances[row] )
403
        {
404 5043d5d0 Leszek Koltunski
        scramble[num][1] = row;
405 bbc6471c Leszek Koltunski
        break;
406
        }
407 7c969a6d Leszek Koltunski
      }
408
409 5043d5d0 Leszek Koltunski
    switch( rnd.nextInt(2) )
410
      {
411
      case 0: scramble[num][2] = -1; break;
412
      case 1: scramble[num][2] =  1; break;
413
      }
414 e46e17fb Leszek Koltunski
    }
415 f0336037 Leszek Koltunski
416 6b6504fe Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
417
418
  public boolean isSolved()
419
    {
420
    int index = CUBITS[0].mQuatIndex;
421
422
    for(int i=1; i<NUM_CUBITS; i++)
423
      {
424 722b2512 Leszek Koltunski
      if( thereIsVisibleDifference(CUBITS[i], index) ) return false;
425 6b6504fe Leszek Koltunski
      }
426
427
    return true;
428
    }
429
430 221a4090 Leszek Koltunski
////////////////////////////////////////////////////////////////////////
431 ee35e63c Leszek Koltunski
// only needed for solvers - there are no Pyraminx solvers ATM)
432 f0336037 Leszek Koltunski
433 20931cf6 Leszek Koltunski
  public String retObjectString()
434 f0336037 Leszek Koltunski
    {
435
    return "";
436
    }
437 6fd4a72c Leszek Koltunski
438
///////////////////////////////////////////////////////////////////////////////////////////////////
439
440
  public int getObjectName(int numLayers)
441
    {
442
    switch(numLayers)
443
      {
444
      case 3: return R.string.pyra3;
445
      case 4: return R.string.pyra4;
446
      case 5: return R.string.pyra5;
447
      }
448
    return R.string.pyra3;
449
    }
450
451
///////////////////////////////////////////////////////////////////////////////////////////////////
452
453
  public int getInventor(int numLayers)
454
    {
455
    switch(numLayers)
456
      {
457
      case 3: return R.string.pyra3_inventor;
458
      case 4: return R.string.pyra4_inventor;
459
      case 5: return R.string.pyra5_inventor;
460
      }
461
    return R.string.pyra3_inventor;
462
    }
463
464
///////////////////////////////////////////////////////////////////////////////////////////////////
465
466
  public int getComplexity(int numLayers)
467
    {
468
    switch(numLayers)
469
      {
470
      case 3: return 4;
471
      case 4: return 6;
472
      case 5: return 8;
473
      }
474
    return 4;
475
    }
476 e844c116 Leszek Koltunski
}