Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyPyraminx.java @ 221a4090

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
import android.graphics.Canvas;
24
import android.graphics.Paint;
25

    
26
import org.distorted.library.main.DistortedEffects;
27
import org.distorted.library.main.DistortedTexture;
28
import org.distorted.library.mesh.MeshBase;
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
import org.distorted.main.RubikSurfaceView;
34

    
35
import java.util.Random;
36

    
37
import static org.distorted.effects.scramble.ScrambleEffect.START_AXIS;
38

    
39
///////////////////////////////////////////////////////////////////////////////////////////////////
40

    
41
public class TwistyPyraminx extends TwistyObject
42
{
43
  static final Static3D[] ROT_AXIS = new Static3D[]
44
         {
45
           new Static3D(     0,-SQ3/3,-SQ6/3),
46
           new Static3D(     0,-SQ3/3,+SQ6/3),
47
           new Static3D(+SQ6/3,+SQ3/3,     0),
48
           new Static3D(-SQ6/3,+SQ3/3,     0),
49
         };
50

    
51
  private static final int[] FACE_COLORS = new int[]
52
         {
53
           COLOR_GREEN , COLOR_YELLOW,
54
           COLOR_BLUE  , COLOR_RED
55
         };
56

    
57
  // computed with res/raw/compute_quats.c
58
  private static final Static4D[] QUATS = new Static4D[]
59
         {
60
           new Static4D(  0.0f,   0.0f,   0.0f,  1.0f),
61
           new Static4D(  0.0f,   1.0f,   0.0f,  0.0f),
62
           new Static4D( SQ2/2,   0.5f,   0.0f,  0.5f),
63
           new Static4D(-SQ2/2,   0.5f,   0.0f,  0.5f),
64
           new Static4D(  0.0f,  -0.5f, -SQ2/2,  0.5f),
65
           new Static4D(  0.0f,  -0.5f,  SQ2/2,  0.5f),
66
           new Static4D( SQ2/2,   0.5f,   0.0f, -0.5f),
67
           new Static4D(-SQ2/2,   0.5f,   0.0f, -0.5f),
68
           new Static4D(  0.0f,  -0.5f, -SQ2/2, -0.5f),
69
           new Static4D(  0.0f,  -0.5f,  SQ2/2, -0.5f),
70
           new Static4D( SQ2/2,   0.0f,  SQ2/2,  0.0f),
71
           new Static4D(-SQ2/2,   0.0f,  SQ2/2,  0.0f)
72
         };
73

    
74
  private static MeshBase mOctaMesh, mTetraMesh;
75

    
76
///////////////////////////////////////////////////////////////////////////////////////////////////
77

    
78
  TwistyPyraminx(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
79
                 DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
80
    {
81
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.PYRA, res, scrWidth);
82
    }
83

    
84
///////////////////////////////////////////////////////////////////////////////////////////////////
85

    
86
  private void addTetrahedralLattice(int size, int index, Static3D[] pos)
87
    {
88
    final float DX = 1.0f;
89
    final float DY = SQ2/2;
90
    final float DZ = 1.0f;
91

    
92
    float startX = 0.0f;
93
    float startY =-DY*(size-1)/2;
94
    float startZ = DZ*(size-1)/2;
95

    
96
    for(int layer=0; layer<size; layer++)
97
      {
98
      float currX = startX;
99
      float currY = startY;
100

    
101
      for(int x=0; x<layer+1; x++)
102
        {
103
        float currZ = startZ;
104

    
105
        for(int z=0; z<size-layer; z++)
106
          {
107
          pos[index] = new Static3D(currX,currY,currZ);
108
          index++;
109
          currZ -= DZ;
110
          }
111

    
112
        currX += DX;
113
        }
114

    
115
      startX-=DX/2;
116
      startY+=DY;
117
      startZ-=DZ/2;
118
      }
119
    }
120

    
121
///////////////////////////////////////////////////////////////////////////////////////////////////
122
// there are (n^3-n)/6 octahedrons and ((n+1)^3 - (n+1))/6 tetrahedrons
123

    
124
  Static3D[] getCubitPositions(int size)
125
    {
126
    int numOcta = (size-1)*size*(size+1)/6;
127
    int numTetra= size*(size+1)*(size+2)/6;
128
    Static3D[] ret = new Static3D[numOcta+numTetra];
129

    
130
    addTetrahedralLattice(size-1,      0,ret);
131
    addTetrahedralLattice(size  ,numOcta,ret);
132

    
133
    return ret;
134
    }
135

    
136
///////////////////////////////////////////////////////////////////////////////////////////////////
137

    
138
  Static4D[] getQuats()
139
    {
140
    return QUATS;
141
    }
142

    
143
///////////////////////////////////////////////////////////////////////////////////////////////////
144

    
145
  int getNumFaces()
146
    {
147
    return FACE_COLORS.length;
148
    }
149

    
150
///////////////////////////////////////////////////////////////////////////////////////////////////
151

    
152
  int getNumStickerTypes(int numLayers)
153
    {
154
    return 1;
155
    }
156

    
157
///////////////////////////////////////////////////////////////////////////////////////////////////
158

    
159
  float[] getCuts(int size)
160
    {
161
    float[] cuts = new float[size-1];
162

    
163
    for(int i=0; i<size-1; i++)
164
      {
165
      cuts[i] = (1.0f-0.25f*size+i)*(SQ6/3);
166
      }
167

    
168
    return cuts;
169
    }
170

    
171
///////////////////////////////////////////////////////////////////////////////////////////////////
172

    
173
  int getNumCubitFaces()
174
    {
175
    return 8;
176
    }
177

    
178
///////////////////////////////////////////////////////////////////////////////////////////////////
179

    
180
  float getScreenRatio()
181
    {
182
    return 0.82f;
183
    }
184

    
185
///////////////////////////////////////////////////////////////////////////////////////////////////
186

    
187
  boolean shouldResetTextureMaps()
188
    {
189
    return false;
190
    }
191

    
192
///////////////////////////////////////////////////////////////////////////////////////////////////
193

    
194
  private int faceColor(int cubit, int axis)
195
    {
196
    return CUBITS[cubit].mRotationRow[axis] == 0 ? axis : NUM_FACES;
197
    }
198

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

    
201
  int getFaceColor(int cubit, int cubitface, int size)
202
    {
203
    if( cubit< (size-1)*size*(size+1)/6 )
204
      {
205
      switch( cubitface )
206
        {
207
        case 0: return faceColor(cubit,0);
208
        case 2: return faceColor(cubit,1);
209
        case 5: return faceColor(cubit,3);
210
        case 7: return faceColor(cubit,2);
211
        default:return NUM_FACES;
212
        }
213
      }
214
    else
215
      {
216
      return cubitface<NUM_FACES ? faceColor(cubit,cubitface) : NUM_FACES;
217
      }
218
    }
219

    
220
///////////////////////////////////////////////////////////////////////////////////////////////////
221

    
222
  MeshBase createCubitMesh(int cubit, int numLayers)
223
    {
224
    if( cubit< (numLayers-1)*numLayers*(numLayers+1)/6 )
225
      {
226
      if( mOctaMesh==null ) mOctaMesh = FactoryCubit.getInstance().createOctaMesh();
227
      return mOctaMesh.copy(true);
228
      }
229
    else
230
      {
231
      if( mTetraMesh==null ) mTetraMesh = FactoryCubit.getInstance().createTetraMesh();
232
      return mTetraMesh.copy(true);
233
      }
234
    }
235

    
236
///////////////////////////////////////////////////////////////////////////////////////////////////
237

    
238
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
239
    {
240
    float E = 0.75f;
241
    float F = 0.50f;
242
    float R = 0.06f;
243
    float S = 0.08f;
244
    float[] vertices = { -F,-E/3, +F,-E/3, 0.0f,2*E/3};
245

    
246
    FactorySticker factory = FactorySticker.getInstance();
247
    factory.drawRoundedPolygon(canvas, paint, left, top, vertices, S, FACE_COLORS[face], R);
248
    }
249

    
250
///////////////////////////////////////////////////////////////////////////////////////////////////
251
// SQ6/3 = height of the tetrahedron
252

    
253
  float returnMultiplier()
254
    {
255
    return getNumLayers()/(SQ6/3);
256
    }
257

    
258
///////////////////////////////////////////////////////////////////////////////////////////////////
259

    
260
  float[] getRowChances(int numLayers)
261
    {
262
    int total = numLayers*(numLayers+1)/2;
263
    float running=0.0f;
264
    float[] chances = new float[numLayers];
265

    
266
    for(int i=0; i<numLayers; i++)
267
      {
268
      running += (numLayers-i);
269
      chances[i] = running / total;
270
      }
271

    
272
    return chances;
273
    }
274

    
275
///////////////////////////////////////////////////////////////////////////////////////////////////
276
// PUBLIC API
277

    
278
  public Static3D[] getRotationAxis()
279
    {
280
    return ROT_AXIS;
281
    }
282

    
283
///////////////////////////////////////////////////////////////////////////////////////////////////
284

    
285
  public int getBasicAngle()
286
    {
287
    return 3;
288
    }
289

    
290
///////////////////////////////////////////////////////////////////////////////////////////////////
291

    
292
  public int randomizeNewRotAxis(Random rnd, int oldRotAxis)
293
    {
294
    int numAxis = ROTATION_AXIS.length;
295

    
296
    if( oldRotAxis == START_AXIS )
297
      {
298
      return rnd.nextInt(numAxis);
299
      }
300
    else
301
      {
302
      int newVector = rnd.nextInt(numAxis-1);
303
      return (newVector>=oldRotAxis ? newVector+1 : newVector);
304
      }
305
    }
306

    
307
///////////////////////////////////////////////////////////////////////////////////////////////////
308

    
309
  public int randomizeNewRow(Random rnd, int oldRotAxis, int oldRow, int newRotAxis)
310
    {
311
    float rowFloat = rnd.nextFloat();
312

    
313
    for(int row=0; row<mRowChances.length; row++)
314
      {
315
      if( rowFloat<=mRowChances[row] ) return row;
316
      }
317

    
318
    return 0;
319
    }
320

    
321
///////////////////////////////////////////////////////////////////////////////////////////////////
322

    
323
  public boolean isSolved()
324
    {
325
    int index = CUBITS[0].mQuatIndex;
326

    
327
    for(int i=1; i<NUM_CUBITS; i++)
328
      {
329
      if( !thereIsNoVisibleDifference(CUBITS[i], index) ) return false;
330
      }
331

    
332
    return true;
333
    }
334

    
335
////////////////////////////////////////////////////////////////////////
336
// only needed for solvers - there are no Pyraminx solvers ATM)
337

    
338
  public String retObjectString()
339
    {
340
    return "";
341
    }
342

    
343
///////////////////////////////////////////////////////////////////////////////////////////////////
344

    
345
  public int getObjectName(int numLayers)
346
    {
347
    switch(numLayers)
348
      {
349
      case 3: return R.string.pyra3;
350
      case 4: return R.string.pyra4;
351
      case 5: return R.string.pyra5;
352
      }
353
    return R.string.pyra3;
354
    }
355

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

    
358
  public int getInventor(int numLayers)
359
    {
360
    switch(numLayers)
361
      {
362
      case 3: return R.string.pyra3_inventor;
363
      case 4: return R.string.pyra4_inventor;
364
      case 5: return R.string.pyra5_inventor;
365
      }
366
    return R.string.pyra3_inventor;
367
    }
368

    
369
///////////////////////////////////////////////////////////////////////////////////////////////////
370

    
371
  public int getComplexity(int numLayers)
372
    {
373
    switch(numLayers)
374
      {
375
      case 3: return 4;
376
      case 4: return 6;
377
      case 5: return 8;
378
      }
379
    return 4;
380
    }
381
}
(32-32/35)