Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyPyraminx.java @ efa81f0c

1
///////////////////////////////////////////////////////////////////////////////////////////////////
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
package org.distorted.objects;
21

    
22
import android.content.res.Resources;
23

    
24
import org.distorted.helpers.ObjectShape;
25
import org.distorted.helpers.ObjectSticker;
26
import org.distorted.helpers.ScrambleState;
27
import org.distorted.library.main.DistortedEffects;
28
import org.distorted.library.main.DistortedTexture;
29
import org.distorted.library.mesh.MeshSquare;
30
import org.distorted.library.type.Static3D;
31
import org.distorted.library.type.Static4D;
32
import org.distorted.main.R;
33

    
34
///////////////////////////////////////////////////////////////////////////////////////////////////
35

    
36
public class TwistyPyraminx extends Twisty4
37
{
38
  static final Static3D[] ROT_AXIS = new Static3D[]
39
         {
40
           new Static3D(     0,-SQ3/3,-SQ6/3),
41
           new Static3D(     0,-SQ3/3,+SQ6/3),
42
           new Static3D(+SQ6/3,+SQ3/3,     0),
43
           new Static3D(-SQ6/3,+SQ3/3,     0),
44
         };
45

    
46
  private ScrambleState[] mStates;
47
  private int[] mBasicAngle;
48
  private Static4D[] mQuats;
49
  private ObjectSticker[] mStickers;
50
  private Movement mMovement;
51

    
52
///////////////////////////////////////////////////////////////////////////////////////////////////
53

    
54
  TwistyPyraminx(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
55
                 DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
56
    {
57
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.PYRA, res, scrWidth);
58
    }
59

    
60
///////////////////////////////////////////////////////////////////////////////////////////////////
61

    
62
  ScrambleState[] getScrambleStates()
63
    {
64
    if( mStates==null )
65
      {
66
      int numLayers = getNumLayers();
67
      initializeScrambleStates(numLayers);
68
      }
69

    
70
    return mStates;
71
    }
72

    
73
///////////////////////////////////////////////////////////////////////////////////////////////////
74

    
75
  private void initializeQuats()
76
    {
77
    mQuats = new Static4D[]
78
         {
79
         new Static4D(  0.0f,   0.0f,   0.0f,  1.0f),
80
         new Static4D(  0.0f,   1.0f,   0.0f,  0.0f),
81
         new Static4D( SQ2/2,   0.5f,   0.0f,  0.5f),
82
         new Static4D(-SQ2/2,   0.5f,   0.0f,  0.5f),
83
         new Static4D(  0.0f,  -0.5f, -SQ2/2,  0.5f),
84
         new Static4D(  0.0f,  -0.5f,  SQ2/2,  0.5f),
85
         new Static4D( SQ2/2,   0.5f,   0.0f, -0.5f),
86
         new Static4D(-SQ2/2,   0.5f,   0.0f, -0.5f),
87
         new Static4D(  0.0f,  -0.5f, -SQ2/2, -0.5f),
88
         new Static4D(  0.0f,  -0.5f,  SQ2/2, -0.5f),
89
         new Static4D( SQ2/2,   0.0f,  SQ2/2,  0.0f),
90
         new Static4D(-SQ2/2,   0.0f,  SQ2/2,  0.0f)
91
         };
92
    }
93

    
94
///////////////////////////////////////////////////////////////////////////////////////////////////
95

    
96
  private int[][] generateState(int start, int end)
97
    {
98
    int len = end-start+1;
99
    int[] tmp = new int[6*len];
100

    
101
    for(int i=0; i<len; i++)
102
      {
103
      tmp[6*i  ] = start;
104
      tmp[6*i+1] = -1;
105
      tmp[6*i+2] = start;
106
      tmp[6*i+3] = start;
107
      tmp[6*i+4] = +1;
108
      tmp[6*i+5] = start;
109

    
110
      start++;
111
      }
112

    
113
    return new int[][] {tmp,tmp,tmp,tmp};
114
    }
115

    
116
///////////////////////////////////////////////////////////////////////////////////////////////////
117

    
118
  private void initializeScrambleStates(int numLayers)
119
    {
120
    mStates = new ScrambleState[numLayers];
121

    
122
    for(int i=0; i<numLayers-1; i++)
123
      {
124
      mStates[i] = new ScrambleState( generateState(0,numLayers-1-i) );
125
      }
126

    
127
    mStates[numLayers-1] = new ScrambleState( generateState(1,numLayers-2) );
128
    }
129

    
130
///////////////////////////////////////////////////////////////////////////////////////////////////
131

    
132
  int[] getSolvedQuats(int cubit, int numLayers)
133
    {
134
    if( mQuats==null ) initializeQuats();
135
    int status = retCubitSolvedStatus(cubit,numLayers);
136
    return status<0 ? null : buildSolvedQuats(MovementPyraminx.FACE_AXIS[status],mQuats);
137
    }
138

    
139
///////////////////////////////////////////////////////////////////////////////////////////////////
140

    
141
  private void addTetrahedralLattice(int size, int index, float[][] pos)
142
    {
143
    final float DX = 1.0f;
144
    final float DY = SQ2/2;
145
    final float DZ = 1.0f;
146

    
147
    float startX = 0.0f;
148
    float startY =-DY*(size-1)/2;
149
    float startZ = DZ*(size-1)/2;
150

    
151
    for(int layer=0; layer<size; layer++)
152
      {
153
      float currX = startX;
154
      float currY = startY;
155

    
156
      for(int x=0; x<layer+1; x++)
157
        {
158
        float currZ = startZ;
159

    
160
        for(int z=0; z<size-layer; z++)
161
          {
162
          pos[index] = new float[] {currX,currY,currZ};
163
          index++;
164
          currZ -= DZ;
165
          }
166

    
167
        currX += DX;
168
        }
169

    
170
      startX-=DX/2;
171
      startY+=DY;
172
      startZ-=DZ/2;
173
      }
174
    }
175

    
176
///////////////////////////////////////////////////////////////////////////////////////////////////
177
// there are (n^3-n)/6 octahedrons and ((n+1)^3 - (n+1))/6 tetrahedrons
178

    
179
  float[][] getCubitPositions(int size)
180
    {
181
    int numOcta = (size-1)*size*(size+1)/6;
182
    int numTetra= size*(size+1)*(size+2)/6;
183
    float[][] ret = new float[numOcta+numTetra][];
184

    
185
    addTetrahedralLattice(size-1,      0,ret);
186
    addTetrahedralLattice(size  ,numOcta,ret);
187

    
188
    return ret;
189
    }
190

    
191
///////////////////////////////////////////////////////////////////////////////////////////////////
192

    
193
  Static4D[] getQuats()
194
    {
195
    if( mQuats==null ) initializeQuats();
196
    return mQuats;
197
    }
198

    
199
///////////////////////////////////////////////////////////////////////////////////////////////////
200

    
201
  int getSolvedFunctionIndex()
202
    {
203
    return 0;
204
    }
205

    
206
///////////////////////////////////////////////////////////////////////////////////////////////////
207

    
208
  int getNumStickerTypes(int numLayers)
209
    {
210
    return 1;
211
    }
212

    
213
///////////////////////////////////////////////////////////////////////////////////////////////////
214

    
215
  float[][] getCuts(int numLayers)
216
    {
217
    float[][] cuts = new float[4][numLayers-1];
218

    
219
    for(int i=0; i<numLayers-1; i++)
220
      {
221
      float cut = (1.0f+i-numLayers/3.0f)*(SQ6/3);
222
      cuts[0][i] = cut;
223
      cuts[1][i] = cut;
224
      cuts[2][i] = cut;
225
      cuts[3][i] = cut;
226
      }
227

    
228
    return cuts;
229
    }
230

    
231
///////////////////////////////////////////////////////////////////////////////////////////////////
232

    
233
  int getNumCubitFaces()
234
    {
235
    return 8;
236
    }
237

    
238
///////////////////////////////////////////////////////////////////////////////////////////////////
239

    
240
  private int getNumOctahedrons(int numLayers)
241
    {
242
    return (numLayers-1)*numLayers*(numLayers+1)/6;
243
    }
244

    
245
///////////////////////////////////////////////////////////////////////////////////////////////////
246

    
247
  private int faceColor(int cubit, int axis)
248
    {
249
    return CUBITS[cubit].mRotationRow[axis] == 1 ? axis : NUM_TEXTURES;
250
    }
251

    
252
///////////////////////////////////////////////////////////////////////////////////////////////////
253

    
254
  int getFaceColor(int cubit, int cubitface, int size)
255
    {
256
    if( cubit< (size-1)*size*(size+1)/6 )
257
      {
258
      switch( cubitface )
259
        {
260
        case 0: return faceColor(cubit,0);
261
        case 2: return faceColor(cubit,1);
262
        case 5: return faceColor(cubit,3);
263
        case 7: return faceColor(cubit,2);
264
        default:return NUM_TEXTURES;
265
        }
266
      }
267
    else
268
      {
269
      return cubitface<NUM_TEXTURES ? faceColor(cubit,cubitface) : NUM_TEXTURES;
270
      }
271
    }
272

    
273
///////////////////////////////////////////////////////////////////////////////////////////////////
274

    
275
  ObjectShape getObjectShape(int cubit, int numLayers)
276
    {
277
    int variant = getCubitVariant(cubit,numLayers);
278

    
279
    if( variant==0 )
280
      {
281
      double[][] vertices = new double[][] { { 0.5,0.0,0.5},{ 0.5,0.0,-0.5},{-0.5,0.0,-0.5},{-0.5,0.0,0.5},{ 0.0,SQ2/2,0.0},{ 0.0,-SQ2/2,0.0} };
282
      int[][] vert_indices = new int[][] { {3,0,4},{0,1,4},{1,2,4},{2,3,4},{5,0,3},{5,1,0},{5,2,1},{5,3,2} };
283
      int N = numLayers==3? 6 : 5;
284
      int E = numLayers==3? 2 : 1;
285
      float[][] bands     = new float[][] { {0.05f,35,0.5f,0.8f,N,E,E} };
286
      int[] bandIndices   = new int[] { 0,0,0,0,0,0,0,0 };
287
      float[][] corners   = new float[][] { {0.04f,0.20f} };
288
      int[] cornerIndices = new int[] { 0,0,0,0,0,0 };
289
      float[][] centers   = new float[][] { {0.0f, 0.0f, 0.0f} };
290
      int[] centerIndices = new int[] { 0,0,0,0,0,0 };
291
      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
292
      }
293
    else
294
      {
295
      double[][] vertices = new double[][] { {-0.5, SQ2/4, 0.0},{ 0.5, SQ2/4, 0.0},{ 0.0,-SQ2/4, 0.5},{ 0.0,-SQ2/4,-0.5} };
296
      int[][] vert_indices = new int[][] { {2,1,0},{3,0,1},{3,2,0},{2,3,1} };
297
      int N = numLayers==3? 6 : 5;
298
      int E = numLayers==3? 2 : 1;
299
      float[][] bands     = new float[][] { {0.05f,35,0.5f,0.8f,N,E,E} };
300
      int[] bandIndices   = new int[] { 0,0,0,0 };
301
      float[][] corners   = new float[][] { {0.06f,0.15f} };
302
      int[] cornerIndices = new int[] { 0,0,0,0 };
303
      float[][] centers   = new float[][] { {0.0f, 0.0f, 0.0f} };
304
      int[] centerIndices = new int[] { 0,0,0,0 };
305
      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
306
      }
307
    }
308

    
309
///////////////////////////////////////////////////////////////////////////////////////////////////
310

    
311
  Static4D getQuat(int cubit, int numLayers)
312
    {
313
    if( mQuats==null ) initializeQuats();
314
    return mQuats[0];
315
    }
316

    
317
///////////////////////////////////////////////////////////////////////////////////////////////////
318

    
319
  int getNumCubitVariants(int numLayers)
320
    {
321
    return 2;
322
    }
323

    
324
///////////////////////////////////////////////////////////////////////////////////////////////////
325

    
326
  int getCubitVariant(int cubit, int numLayers)
327
    {
328
    return cubit<getNumOctahedrons(numLayers) ? 0:1;
329
    }
330

    
331
///////////////////////////////////////////////////////////////////////////////////////////////////
332

    
333
  ObjectSticker retSticker(int face)
334
    {
335
    if( mStickers==null )
336
      {
337
      float[][] STICKERS = new float[][] { { -0.4330127f, -0.25f, 0.4330127f, -0.25f, 0.0f, 0.5f } };
338
      final float stroke = 0.08f;
339
      final float radius = 0.06f;
340
      final float[] radii= {radius,radius,radius};
341
      mStickers = new ObjectSticker[STICKERS.length];
342
      mStickers[0] = new ObjectSticker(STICKERS[0],null,radii,stroke);
343
      }
344

    
345
    return mStickers[face/NUM_FACE_COLORS];
346
    }
347

    
348
///////////////////////////////////////////////////////////////////////////////////////////////////
349
// public API
350

    
351
  public Static3D[] getRotationAxis()
352
    {
353
    return ROT_AXIS;
354
    }
355

    
356
///////////////////////////////////////////////////////////////////////////////////////////////////
357

    
358
  public Movement getMovement()
359
    {
360
    if( mMovement==null ) mMovement = new MovementPyraminx();
361
    return mMovement;
362
    }
363

    
364
///////////////////////////////////////////////////////////////////////////////////////////////////
365

    
366
  public int[] getBasicAngle()
367
    {
368
    if( mBasicAngle ==null ) mBasicAngle = new int[] { 3,3,3,3 };
369
    return mBasicAngle;
370
    }
371

    
372
///////////////////////////////////////////////////////////////////////////////////////////////////
373

    
374
  public int getObjectName(int numLayers)
375
    {
376
    switch(numLayers)
377
      {
378
      case 3: return R.string.pyra3;
379
      case 4: return R.string.pyra4;
380
      case 5: return R.string.pyra5;
381
      }
382
    return R.string.pyra3;
383
    }
384

    
385
///////////////////////////////////////////////////////////////////////////////////////////////////
386

    
387
  public int getInventor(int numLayers)
388
    {
389
    switch(numLayers)
390
      {
391
      case 3: return R.string.pyra3_inventor;
392
      case 4: return R.string.pyra4_inventor;
393
      case 5: return R.string.pyra5_inventor;
394
      }
395
    return R.string.pyra3_inventor;
396
    }
397

    
398
///////////////////////////////////////////////////////////////////////////////////////////////////
399

    
400
  public int getComplexity(int numLayers)
401
    {
402
    switch(numLayers)
403
      {
404
      case 3: return 4;
405
      case 4: return 6;
406
      case 5: return 8;
407
      }
408
    return 4;
409
    }
410
}
(41-41/48)