Project

General

Profile

Download (17 KB) Statistics
| Branch: | Revision:

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyPyraminx.java @ a8295031

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.objectlib.objects;
21

    
22
import static org.distorted.objectlib.touchcontrol.TouchControl.TC_TETRAHEDRON;
23
import static org.distorted.objectlib.touchcontrol.TouchControl.TYPE_NOT_SPLIT;
24

    
25
import java.io.InputStream;
26

    
27
import org.distorted.library.type.Static3D;
28
import org.distorted.library.type.Static4D;
29

    
30
import org.distorted.objectlib.helpers.ObjectFaceShape;
31
import org.distorted.objectlib.helpers.ObjectSignature;
32
import org.distorted.objectlib.main.InitData;
33
import org.distorted.objectlib.touchcontrol.TouchControlTetrahedron;
34
import org.distorted.objectlib.main.ObjectType;
35
import org.distorted.objectlib.helpers.ObjectShape;
36
import org.distorted.objectlib.scrambling.ScrambleState;
37
import org.distorted.objectlib.main.ShapeTetrahedron;
38

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

    
41
public class TwistyPyraminx extends ShapeTetrahedron
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 ScrambleState[] mStates;
52
  private int[][] mBasicAngle;
53
  private float[][] mCuts;
54

    
55
///////////////////////////////////////////////////////////////////////////////////////////////////
56

    
57
  public TwistyPyraminx(InitData data, int meshState, int iconMode, Static4D quat, Static3D move, float scale, InputStream stream)
58
    {
59
    super(data, meshState, iconMode, data.getNumLayers()[0], quat, move, scale, stream);
60
    }
61

    
62
///////////////////////////////////////////////////////////////////////////////////////////////////
63

    
64
  public ScrambleState[] getScrambleStates()
65
    {
66
    if( mStates==null )
67
      {
68
      int[] numLayers = getNumLayers();
69
      initializeScrambleStates(numLayers[0]);
70
      }
71

    
72
    return mStates;
73
    }
74

    
75
///////////////////////////////////////////////////////////////////////////////////////////////////
76

    
77
  private int[][] generateState(int start, int end)
78
    {
79
    int len = end-start+1;
80
    int[] tmp = new int[6*len];
81

    
82
    for(int i=0; i<len; i++)
83
      {
84
      tmp[6*i  ] = start;
85
      tmp[6*i+1] = -1;
86
      tmp[6*i+2] = start;
87
      tmp[6*i+3] = start;
88
      tmp[6*i+4] = +1;
89
      tmp[6*i+5] = start;
90

    
91
      start++;
92
      }
93

    
94
    return new int[][] {tmp,tmp,tmp,tmp};
95
    }
96

    
97
///////////////////////////////////////////////////////////////////////////////////////////////////
98

    
99
  private void initializeScrambleStates(int numLayers)
100
    {
101
    mStates = new ScrambleState[numLayers];
102

    
103
    for(int i=0; i<numLayers-1; i++)
104
      {
105
      mStates[i] = new ScrambleState( generateState(0,numLayers-1-i) );
106
      }
107

    
108
    mStates[numLayers-1] = new ScrambleState( generateState(1,numLayers-2) );
109
    }
110

    
111
///////////////////////////////////////////////////////////////////////////////////////////////////
112

    
113
  private void addTetrahedralLattice(int size, int index, float[][] pos)
114
    {
115
    final float DX = 1.0f;
116
    final float DY = SQ2/2;
117
    final float DZ = 1.0f;
118

    
119
    float startX = 0.0f;
120
    float startY =-DY*(size-1)/2;
121
    float startZ = DZ*(size-1)/2;
122

    
123
    for(int layer=0; layer<size; layer++)
124
      {
125
      float currX = startX;
126
      float currY = startY;
127

    
128
      for(int x=0; x<layer+1; x++)
129
        {
130
        float currZ = startZ;
131

    
132
        for(int z=0; z<size-layer; z++)
133
          {
134
          pos[index] = new float[] {currX,currY,currZ};
135
          index++;
136
          currZ -= DZ;
137
          }
138

    
139
        currX += DX;
140
        }
141

    
142
      startX-=DX/2;
143
      startY+=DY;
144
      startZ-=DZ/2;
145
      }
146
    }
147

    
148
///////////////////////////////////////////////////////////////////////////////////////////////////
149

    
150
  private int getNumOctahedrons(int numLayers)
151
    {
152
    return (numLayers-1)*numLayers*(numLayers+1)/6;
153
    }
154

    
155
///////////////////////////////////////////////////////////////////////////////////////////////////
156

    
157
  public float[][] getCuts(int[] numLayers)
158
    {
159
    if( mCuts==null )
160
      {
161
      int numL = numLayers[0];
162
      mCuts = new float[4][numL-1];
163

    
164
      for(int i=0; i<numL-1; i++)
165
        {
166
        float cut = (1.0f+i-numL/4.0f)*(SQ6/3);
167
        mCuts[0][i] = cut;
168
        mCuts[1][i] = cut;
169
        mCuts[2][i] = cut;
170
        mCuts[3][i] = cut;
171
        }
172
      }
173

    
174
    return mCuts;
175
    }
176

    
177
///////////////////////////////////////////////////////////////////////////////////////////////////
178

    
179
  public boolean[][] getLayerRotatable(int[] numLayers)
180
    {
181
    int numAxis = ROT_AXIS.length;
182
    boolean[][] layerRotatable = new boolean[numAxis][];
183

    
184
    for(int i=0; i<numAxis; i++)
185
      {
186
      layerRotatable[i] = new boolean[numLayers[i]];
187
      for(int j=0; j<numLayers[i]; j++) layerRotatable[i][j] = true;
188
      }
189

    
190
    return layerRotatable;
191
    }
192

    
193
///////////////////////////////////////////////////////////////////////////////////////////////////
194

    
195
  public int getTouchControlType()
196
    {
197
    return TC_TETRAHEDRON;
198
    }
199

    
200
///////////////////////////////////////////////////////////////////////////////////////////////////
201

    
202
  public int getTouchControlSplit()
203
    {
204
    return TYPE_NOT_SPLIT;
205
    }
206

    
207
///////////////////////////////////////////////////////////////////////////////////////////////////
208

    
209
  public int[][][] getEnabled()
210
    {
211
    return new int[][][] { {{1,2,3}},{{0,2,3}},{{0,1,3}},{{0,1,2}} };
212
    }
213

    
214
///////////////////////////////////////////////////////////////////////////////////////////////////
215

    
216
  public float[] getDist3D(int[] numLayers)
217
    {
218
    return TouchControlTetrahedron.D3D;
219
    }
220

    
221
///////////////////////////////////////////////////////////////////////////////////////////////////
222

    
223
  public Static3D[] getFaceAxis()
224
    {
225
    return TouchControlTetrahedron.FACE_AXIS;
226
    }
227

    
228
///////////////////////////////////////////////////////////////////////////////////////////////////
229
// there are (n^3-n)/6 octahedrons and ((n+1)^3 - (n+1))/6 tetrahedrons
230

    
231
  public float[][] getCubitPositions(int[] numLayers)
232
    {
233
    int numL = numLayers[0];
234
    int numOcta = (numL-1)*numL*(numL+1)/6;
235
    int numTetra= numL*(numL+1)*(numL+2)/6;
236
    float[][] ret = new float[numOcta+numTetra][];
237

    
238
    addTetrahedralLattice(numL-1,      0,ret);
239
    addTetrahedralLattice(numL  ,numOcta,ret);
240

    
241
    return ret;
242
    }
243

    
244
///////////////////////////////////////////////////////////////////////////////////////////////////
245

    
246
  public Static4D getCubitQuats(int cubit, int[] numLayers)
247
    {
248
    return mObjectQuats[0];
249
    }
250

    
251
///////////////////////////////////////////////////////////////////////////////////////////////////
252

    
253
  public ObjectShape getObjectShape(int variant)
254
    {
255
    if( variant==0 )
256
      {
257
      float[][] vertices= { { 0.5f,0.0f,0.5f},{ 0.5f,0.0f,-0.5f},{-0.5f,0.0f,-0.5f},{-0.5f,0.0f,0.5f},{ 0.0f,SQ2/2,0.0f},{ 0.0f,-SQ2/2,0.0f} };
258
      int[][] indices   = { {3,0,4},{0,1,4},{1,2,4},{2,3,4},{5,0,3},{5,1,0},{5,2,1},{5,3,2} };
259
      return new ObjectShape(vertices, indices);
260
      }
261
    else
262
      {
263
      float[][] vertices= { {-0.5f, SQ2/4, 0.0f},{ 0.5f, SQ2/4, 0.0f},{ 0.0f,-SQ2/4, 0.5f},{ 0.0f,-SQ2/4,-0.5f} };
264
      int[][] indices   = { {2,1,0},{3,0,1},{3,2,0},{2,3,1} };
265
      return new ObjectShape(vertices, indices);
266
      }
267
    }
268

    
269
///////////////////////////////////////////////////////////////////////////////////////////////////
270

    
271
  public ObjectFaceShape getObjectFaceShape(int variant)
272
    {
273
    int numL = getNumLayers()[0];
274
    float height = isInIconMode() ? 0.001f : 0.05f;
275

    
276
    if( variant==0 )
277
      {
278
      int N = numL==3? 6 : 5;
279
      int E = numL==3? 2 : 1;
280
      float[][] bands     = { {height,20,0.5f,0.8f,N,E,E} };
281
      int[] bandIndices   = { 0,0,0,0,0,0,0,0 };
282
      float[][] corners   = { {0.04f,0.20f} };
283
      int[] cornerIndices = { 0,0,0,0,0,0 };
284
      float[][] centers   = { {0.0f, 0.0f, 0.0f} };
285
      int[] centerIndices = { 0,0,0,0,0,0 };
286
      return new ObjectFaceShape(bands,bandIndices,corners,cornerIndices,centers,centerIndices,null);
287
      }
288
    else
289
      {
290
      int N = numL==3? 6 : 5;
291
      int E = numL==3? 2 : 1;
292
      float[][] bands     = { {height,35,0.5f,0.8f,N,E,E} };
293
      int[] bandIndices   = { 0,0,0,0 };
294
      float[][] corners   = { {0.06f,0.15f} };
295
      int[] cornerIndices = { 0,0,0,0 };
296
      float[][] centers   = { {0.0f, 0.0f, 0.0f} };
297
      int[] centerIndices = { 0,0,0,0 };
298
      return new ObjectFaceShape(bands,bandIndices,corners,cornerIndices,centers,centerIndices,null);
299
      }
300
    }
301

    
302
///////////////////////////////////////////////////////////////////////////////////////////////////
303

    
304
  public int getNumCubitVariants(int[] numLayers)
305
    {
306
    return 2;
307
    }
308

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

    
311
  public int getCubitVariant(int cubit, int[] numLayers)
312
    {
313
    return cubit<getNumOctahedrons(numLayers[0]) ? 0:1;
314
    }
315

    
316
///////////////////////////////////////////////////////////////////////////////////////////////////
317

    
318
  public float getStickerRadius()
319
    {
320
    return 0.08f;
321
    }
322

    
323
///////////////////////////////////////////////////////////////////////////////////////////////////
324

    
325
  public float getStickerStroke()
326
    {
327
    float stroke = 0.08f;
328

    
329
    if( isInIconMode() )
330
      {
331
      int[] numLayers = getNumLayers();
332

    
333
      switch(numLayers[0])
334
        {
335
        case 2: stroke*=1.0f; break;
336
        case 3: stroke*=1.4f; break;
337
        case 4: stroke*=1.7f; break;
338
        default:stroke*=1.9f; break;
339
        }
340
      }
341

    
342
    return stroke;
343
    }
344

    
345
///////////////////////////////////////////////////////////////////////////////////////////////////
346

    
347
  public float[][] getStickerAngles()
348
    {
349
    return null;
350
    }
351

    
352
///////////////////////////////////////////////////////////////////////////////////////////////////
353
// public API
354

    
355
  public Static3D[] getRotationAxis()
356
    {
357
    return ROT_AXIS;
358
    }
359

    
360
///////////////////////////////////////////////////////////////////////////////////////////////////
361

    
362
  public int[][] getBasicAngles()
363
    {
364
    if( mBasicAngle ==null )
365
      {
366
      int num = getNumLayers()[0];
367
      int[] tmp = new int[num];
368
      for(int i=0; i<num; i++) tmp[i] = 3;
369
      mBasicAngle = new int[][] { tmp,tmp,tmp,tmp };
370
      }
371

    
372
    return mBasicAngle;
373
    }
374

    
375
///////////////////////////////////////////////////////////////////////////////////////////////////
376

    
377
  public String getShortName()
378
    {
379
    switch(getNumLayers()[0])
380
      {
381
      case 3: return ObjectType.PYRA_3.name();
382
      case 4: return ObjectType.PYRA_4.name();
383
      case 5: return ObjectType.PYRA_5.name();
384
      }
385

    
386
    return ObjectType.PYRA_3.name();
387
    }
388

    
389
///////////////////////////////////////////////////////////////////////////////////////////////////
390

    
391
  public ObjectSignature getSignature()
392
    {
393
    switch(getNumLayers()[0])
394
      {
395
      case 3: return new ObjectSignature(ObjectType.PYRA_3);
396
      case 4: return new ObjectSignature(ObjectType.PYRA_4);
397
      case 5: return new ObjectSignature(ObjectType.PYRA_5);
398
      }
399

    
400
    return null;
401
    }
402

    
403
///////////////////////////////////////////////////////////////////////////////////////////////////
404

    
405
  public String getObjectName()
406
    {
407
    switch(getNumLayers()[0])
408
      {
409
      case 3: return "Pyraminx";
410
      case 4: return "Master Pyraminx";
411
      case 5: return "Professor's Pyraminx";
412
      }
413
    return null;
414
    }
415

    
416
///////////////////////////////////////////////////////////////////////////////////////////////////
417

    
418
  public String getInventor()
419
    {
420
    switch(getNumLayers()[0])
421
      {
422
      case 3: return "Uwe Meffert";
423
      case 4: return "Katsuhiko Okamoto";
424
      case 5: return "Timur Evbatyrov";
425
      }
426
    return null;
427
    }
428

    
429
///////////////////////////////////////////////////////////////////////////////////////////////////
430

    
431
  public int getYearOfInvention()
432
    {
433
    switch(getNumLayers()[0])
434
      {
435
      case 3: return 1970;
436
      case 4: return 2002;
437
      case 5: return 2011;
438
      }
439
    return 1970;
440
    }
441

    
442
///////////////////////////////////////////////////////////////////////////////////////////////////
443

    
444
  public int getComplexity()
445
    {
446
    switch(getNumLayers()[0])
447
      {
448
      case 3: return 1;
449
      case 4: return 2;
450
      case 5: return 3;
451
      }
452
    return 4;
453
    }
454

    
455
///////////////////////////////////////////////////////////////////////////////////////////////////
456

    
457
  public String[][] getTutorials()
458
    {
459
    int[] numLayers = getNumLayers();
460

    
461
    switch(numLayers[0])
462
      {
463
      case 3: return new String[][] {
464
                          {"gb","xIQtn2qazvg","Pyraminx Layer By Layer","Z3"},
465
                          {"es","4cJJe9RAzAU","Resolver Pyraminx","Cuby"},
466
                          {"ru","F4_bhfWyVRQ","Как собрать ПИРАМИДКУ","Е Бондаренко"},
467
                          {"fr","Z2h1YI6jPes","Comment résoudre le Pyraminx","ValentinoCube"},
468
                          {"de","x_DMA8htJpY","Pyraminx lösen","Pezcraft"},
469
                          {"pl","uNpKpJfAa5I","Jak ułożyć: Pyraminx","DżoDżo"},
470
                          {"br","dtC0GNGyXqw","Como resolver o Pyraminx","Pedro Filho"},
471
                          {"kr","mO3excjvvoA","피라밍크스 맞추는 방법","iamzoone"},
472
                          {"vn","p9LUWUW5iYg","Tutorial N.4 - Pyraminx","Duy Thích Rubik"},
473
                    //    {"tw","YS3cDcP6Aro","金字塔方塊解法","1hrBLD"},
474
                         };
475
      case 4: return new String[][] {
476
                          {"gb","tGQDqDcSa6U","How to Solve the Master Pyraminx","Z3"},
477
                          {"es","74PIPm9-uPg","Resolver Master Pyraminx 4x4","Cuby"},
478
                          {"ru","-F_xJAwkobU","Как собрать Мастер Пираминкс"," Алексей Ярыгин"},
479
                          {"fr","F3gzBs7uvmw","Tuto: résoudre le Master Pyraminx","Spaghetti Cubing"},
480
                          {"de","3Q_bO7_FfAI","Master Pyraminx lösen","CubaroCubing"},
481
                          {"pl","EamwvhmHC7Q","4x4 (Master) Pyraminx PL","MrUk"},
482
                          {"br","cKql6YZ7yAg","Como resolver o Pyraminx 4x4 1/3","Rafael Cinoto"},
483
                          {"br","gtNQDPsN2Dg","Como resolver o Pyraminx 4x4 2/3","Rafael Cinoto"},
484
                          {"br","j8_-s4rd8mw","Como resolver o Pyraminx 4x4 3/3","Rafael Cinoto"},
485
                          {"kr","JlmBKaHESyY","마스터 피라밍크스 해법","주누후누"},
486
                          {"vn","AMCll82WcJY","Tutorial N.13 - Master Pyraminx","Duy Thích Rubik"},
487
                         };
488
      case 5: return new String[][] {
489
                          {"gb","2nsPEECDdN0","Professor Pyraminx Solve","RedKB"},
490
                          {"es","cSDj8OQK3TU","Tutorial del Professor Pyraminx","QBAndo"},
491
                          {"ru","gMp1tbDyDWg","Как собрать Professor Pyraminx","RBcuber"},
492
                          {"de","pCHx9bVMSgI","Professor Pyraminx Teil 1","Arvid Bollmann"},
493
                          {"de","iiNXJMVNmCM","Professor Pyraminx Teil 2","Arvid Bollmann"},
494
                          {"br","t2QJSSjNxPw","Resolver o Professor Pyraminx 1/4","Rafael Cinoto"},
495
                          {"br","mI6W6IFyVv0","Resolver o Professor Pyraminx 2/4","Rafael Cinoto"},
496
                          {"br","0HoOp6JlLSs","Resolver o Professor Pyraminx 3/4","Rafael Cinoto"},
497
                          {"br","Xg1jnCRsw_I","Resolver o Professor Pyraminx 4/4","Rafael Cinoto"},
498
                          {"vn","OHwPqp3kQdE","Professor Pyraminx làm chậm","TRẦN QUANG HÙNG"},
499
                         };
500
      }
501
    return null;
502
    }
503
}
(29-29/40)