Project

General

Profile

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

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

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is proprietary software licensed under an EULA which you should have received      //
7
// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
8
///////////////////////////////////////////////////////////////////////////////////////////////////
9

    
10
package org.distorted.objectlib.objects;
11

    
12
import static org.distorted.objectlib.touchcontrol.TouchControl.TC_TETRAHEDRON;
13
import static org.distorted.objectlib.touchcontrol.TouchControl.TYPE_NOT_SPLIT;
14

    
15
import java.io.InputStream;
16

    
17
import org.distorted.library.type.Static3D;
18
import org.distorted.library.type.Static4D;
19

    
20
import org.distorted.objectlib.helpers.FactoryCubit;
21
import org.distorted.objectlib.helpers.ObjectFaceShape;
22
import org.distorted.objectlib.helpers.ObjectSignature;
23
import org.distorted.objectlib.helpers.ObjectVertexEffects;
24
import org.distorted.objectlib.main.InitData;
25
import org.distorted.objectlib.touchcontrol.TouchControlTetrahedron;
26
import org.distorted.objectlib.main.ObjectType;
27
import org.distorted.objectlib.helpers.ObjectShape;
28
import org.distorted.objectlib.shape.ShapeTetrahedron;
29

    
30
///////////////////////////////////////////////////////////////////////////////////////////////////
31

    
32
public class TwistyPyraminx extends ShapeTetrahedron
33
{
34
  static final Static3D[] ROT_AXIS = new Static3D[]
35
         {
36
           new Static3D(     0,-SQ3/3,-SQ6/3),
37
           new Static3D(     0,-SQ3/3, SQ6/3),
38
           new Static3D( SQ6/3, SQ3/3,     0),
39
           new Static3D(-SQ6/3, SQ3/3,     0),
40
         };
41

    
42
  private int[][] mEdges;
43
  private int[][] mBasicAngle;
44
  private float[][] mCuts;
45

    
46
///////////////////////////////////////////////////////////////////////////////////////////////////
47

    
48
  public TwistyPyraminx(InitData data, int meshState, int iconMode, Static4D quat, Static3D move, float scale, InputStream stream)
49
    {
50
    super(data, meshState, iconMode, data.getNumLayers()[0], quat, move, scale, stream);
51
    }
52

    
53
///////////////////////////////////////////////////////////////////////////////////////////////////
54

    
55
  public int[][] getScrambleEdges()
56
    {
57
    if( mEdges==null )
58
      {
59
      int numLayers = getNumLayers()[0];
60
      mEdges = new int[numLayers][];
61
      for(int i=0; i<numLayers-1; i++) mEdges[i] = generateEdge(numLayers-1-i,numLayers);
62
      mEdges[numLayers-1] = generateEdge(numLayers-2,numLayers);
63
      }
64

    
65
    return mEdges;
66
    }
67

    
68
///////////////////////////////////////////////////////////////////////////////////////////////////
69

    
70
  private int[] generateEdge(int end, int numLayers)
71
    {
72
    int[] ret = new int[8*end];
73

    
74
    for(int i=0; i<end; i++)
75
      {
76
      int s = ((i/2)%numLayers);
77

    
78
      ret[      2*i  ] = i;
79
      ret[      2*i+1] = s;
80
      ret[  end+2*i  ] = i;
81
      ret[  end+2*i+1] = s;
82
      ret[2*end+2*i  ] = i;
83
      ret[2*end+2*i+1] = s;
84
      ret[3*end+2*i  ] = i;
85
      ret[3*end+2*i+1] = s;
86
      }
87

    
88
    return ret;
89
    }
90

    
91
///////////////////////////////////////////////////////////////////////////////////////////////////
92

    
93
  private void addTetrahedralLattice(int size, int index, float[][] pos)
94
    {
95
    final float DX = 1.0f;
96
    final float DY = SQ2/2;
97
    final float DZ = 1.0f;
98

    
99
    float startX = 0.0f;
100
    float startY =-DY*(size-1)/2;
101
    float startZ = DZ*(size-1)/2;
102

    
103
    for(int layer=0; layer<size; layer++)
104
      {
105
      float currX = startX;
106
      float currY = startY;
107

    
108
      for(int x=0; x<layer+1; x++)
109
        {
110
        float currZ = startZ;
111

    
112
        for(int z=0; z<size-layer; z++)
113
          {
114
          pos[index] = new float[] {currX,currY,currZ};
115
          index++;
116
          currZ -= DZ;
117
          }
118

    
119
        currX += DX;
120
        }
121

    
122
      startX-=DX/2;
123
      startY+=DY;
124
      startZ-=DZ/2;
125
      }
126
    }
127

    
128
///////////////////////////////////////////////////////////////////////////////////////////////////
129

    
130
  private int getNumOctahedrons(int numLayers)
131
    {
132
    return (numLayers-1)*numLayers*(numLayers+1)/6;
133
    }
134

    
135
///////////////////////////////////////////////////////////////////////////////////////////////////
136

    
137
  public float[][] getCuts(int[] numLayers)
138
    {
139
    if( mCuts==null )
140
      {
141
      int numL = numLayers[0];
142
      mCuts = new float[4][numL-1];
143

    
144
      for(int i=0; i<numL-1; i++)
145
        {
146
        float cut = (1.0f+i-numL/4.0f)*(SQ6/3);
147
        mCuts[0][i] = cut;
148
        mCuts[1][i] = cut;
149
        mCuts[2][i] = cut;
150
        mCuts[3][i] = cut;
151
        }
152
      }
153

    
154
    return mCuts;
155
    }
156

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

    
159
  public boolean[][] getLayerRotatable(int[] numLayers)
160
    {
161
    int numAxis = ROT_AXIS.length;
162
    boolean[][] layerRotatable = new boolean[numAxis][];
163

    
164
    for(int i=0; i<numAxis; i++)
165
      {
166
      layerRotatable[i] = new boolean[numLayers[i]];
167
      for(int j=0; j<numLayers[i]; j++) layerRotatable[i][j] = true;
168
      }
169

    
170
    return layerRotatable;
171
    }
172

    
173
///////////////////////////////////////////////////////////////////////////////////////////////////
174

    
175
  public int getTouchControlType()
176
    {
177
    return TC_TETRAHEDRON;
178
    }
179

    
180
///////////////////////////////////////////////////////////////////////////////////////////////////
181

    
182
  public int getTouchControlSplit()
183
    {
184
    return TYPE_NOT_SPLIT;
185
    }
186

    
187
///////////////////////////////////////////////////////////////////////////////////////////////////
188

    
189
  public int[][][] getEnabled()
190
    {
191
    return new int[][][] { {{1,2,3}},{{0,2,3}},{{0,1,3}},{{0,1,2}} };
192
    }
193

    
194
///////////////////////////////////////////////////////////////////////////////////////////////////
195

    
196
  public float[] getDist3D(int[] numLayers)
197
    {
198
    return TouchControlTetrahedron.D3D;
199
    }
200

    
201
///////////////////////////////////////////////////////////////////////////////////////////////////
202

    
203
  public Static3D[] getFaceAxis()
204
    {
205
    return TouchControlTetrahedron.FACE_AXIS;
206
    }
207

    
208
///////////////////////////////////////////////////////////////////////////////////////////////////
209
// there are (n^3-n)/6 octahedrons and ((n+1)^3 - (n+1))/6 tetrahedrons
210

    
211
  public float[][] getCubitPositions(int[] numLayers)
212
    {
213
    int numL = numLayers[0];
214
    int numOcta = (numL-1)*numL*(numL+1)/6;
215
    int numTetra= numL*(numL+1)*(numL+2)/6;
216
    float[][] ret = new float[numOcta+numTetra][];
217

    
218
    addTetrahedralLattice(numL-1,      0,ret);
219
    addTetrahedralLattice(numL  ,numOcta,ret);
220

    
221
    return ret;
222
    }
223

    
224
///////////////////////////////////////////////////////////////////////////////////////////////////
225

    
226
  public Static4D getCubitQuats(int cubit, int[] numLayers)
227
    {
228
    return mObjectQuats[0];
229
    }
230

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

    
233
  private float[][] getVertices(int variant)
234
    {
235
    if( variant==0 )
236
      {
237
      return new float[][] { { 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} };
238
      }
239
    else
240
      {
241
      return new float[][] { {-0.5f, SQ2/4, 0.0f},{ 0.5f, SQ2/4, 0.0f},{ 0.0f,-SQ2/4, 0.5f},{ 0.0f,-SQ2/4,-0.5f} };
242
      }
243
    }
244

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

    
247
  public ObjectShape getObjectShape(int variant)
248
    {
249
    if( variant==0 )
250
      {
251
      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} };
252
      return new ObjectShape(getVertices(variant), indices);
253
      }
254
    else
255
      {
256
      int[][] indices   = { {2,1,0},{3,0,1},{3,2,0},{2,3,1} };
257
      return new ObjectShape(getVertices(variant), indices);
258
      }
259
    }
260

    
261
///////////////////////////////////////////////////////////////////////////////////////////////////
262

    
263
  public ObjectFaceShape getObjectFaceShape(int variant)
264
    {
265
    int numL = getNumLayers()[0];
266
    float height = isInIconMode() ? 0.001f : 0.05f;
267

    
268
    if( variant==0 )
269
      {
270
      int N = numL==3? 6 : 5;
271
      int E = numL==3? 2 : 1;
272
      float[][] bands = { {height,20,0.5f,0.8f,N,E,E} };
273
      int[] indices   = { 0,0,0,0,0,0,0,0 };
274
      return new ObjectFaceShape(bands,indices,null);
275
      }
276
    else
277
      {
278
      int N = numL==3? 6 : 5;
279
      int E = numL==3? 2 : 1;
280
      float[][] bands = { {height,35,0.5f,0.8f,N,E,E} };
281
      int[] indices   = { 0,0,0,0 };
282
      return new ObjectFaceShape(bands,indices,null);
283
      }
284
    }
285

    
286
///////////////////////////////////////////////////////////////////////////////////////////////////
287

    
288
  public ObjectVertexEffects getVertexEffects(int variant)
289
    {
290
    if( variant==0 )
291
      {
292
      float[][] corners = { {0.04f,0.20f} };
293
      int[] indices     = { 0,0,0,0,0,0 };
294
      float[][] centers = { {0.0f, 0.0f, 0.0f} };
295
      return FactoryCubit.generateVertexEffect(getVertices(variant),corners,indices,centers,indices);
296
      }
297
    else
298
      {
299
      float[][] corners = { {0.06f,0.15f} };
300
      int[] indices     = { 0,0,0,0 };
301
      float[][] centers = { {0.0f, 0.0f, 0.0f} };
302
      return FactoryCubit.generateVertexEffect(getVertices(variant),corners,indices,centers,indices);
303
      }
304
    }
305

    
306
///////////////////////////////////////////////////////////////////////////////////////////////////
307

    
308
  public int getNumCubitVariants(int[] numLayers)
309
    {
310
    return 2;
311
    }
312

    
313
///////////////////////////////////////////////////////////////////////////////////////////////////
314

    
315
  public int getCubitVariant(int cubit, int[] numLayers)
316
    {
317
    return cubit<getNumOctahedrons(numLayers[0]) ? 0:1;
318
    }
319

    
320
///////////////////////////////////////////////////////////////////////////////////////////////////
321

    
322
  public float getStickerRadius()
323
    {
324
    return 0.08f;
325
    }
326

    
327
///////////////////////////////////////////////////////////////////////////////////////////////////
328

    
329
  public float getStickerStroke()
330
    {
331
    float stroke = 0.08f;
332

    
333
    if( isInIconMode() )
334
      {
335
      int[] numLayers = getNumLayers();
336

    
337
      switch(numLayers[0])
338
        {
339
        case 2: stroke*=1.0f; break;
340
        case 3: stroke*=1.4f; break;
341
        case 4: stroke*=1.7f; break;
342
        default:stroke*=1.9f; break;
343
        }
344
      }
345

    
346
    return stroke;
347
    }
348

    
349
///////////////////////////////////////////////////////////////////////////////////////////////////
350

    
351
  public float[][] getStickerAngles()
352
    {
353
    return null;
354
    }
355

    
356
///////////////////////////////////////////////////////////////////////////////////////////////////
357
// public API
358

    
359
  public Static3D[] getRotationAxis()
360
    {
361
    return ROT_AXIS;
362
    }
363

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

    
366
  public int[][] getBasicAngles()
367
    {
368
    if( mBasicAngle ==null )
369
      {
370
      int num = getNumLayers()[0];
371
      int[] tmp = new int[num];
372
      for(int i=0; i<num; i++) tmp[i] = 3;
373
      mBasicAngle = new int[][] { tmp,tmp,tmp,tmp };
374
      }
375

    
376
    return mBasicAngle;
377
    }
378

    
379
///////////////////////////////////////////////////////////////////////////////////////////////////
380

    
381
  public String getShortName()
382
    {
383
    switch(getNumLayers()[0])
384
      {
385
      case 3: return ObjectType.PYRA_3.name();
386
      case 4: return ObjectType.PYRA_4.name();
387
      case 5: return ObjectType.PYRA_5.name();
388
      }
389

    
390
    return ObjectType.PYRA_3.name();
391
    }
392

    
393
///////////////////////////////////////////////////////////////////////////////////////////////////
394

    
395
  public ObjectSignature getSignature()
396
    {
397
    switch(getNumLayers()[0])
398
      {
399
      case 3: return new ObjectSignature(ObjectType.PYRA_3);
400
      case 4: return new ObjectSignature(ObjectType.PYRA_4);
401
      case 5: return new ObjectSignature(ObjectType.PYRA_5);
402
      }
403

    
404
    return null;
405
    }
406

    
407
///////////////////////////////////////////////////////////////////////////////////////////////////
408

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

    
420
///////////////////////////////////////////////////////////////////////////////////////////////////
421

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

    
433
///////////////////////////////////////////////////////////////////////////////////////////////////
434

    
435
  public int getYearOfInvention()
436
    {
437
    switch(getNumLayers()[0])
438
      {
439
      case 3: return 1970;
440
      case 4: return 2002;
441
      case 5: return 2011;
442
      }
443
    return 1970;
444
    }
445

    
446
///////////////////////////////////////////////////////////////////////////////////////////////////
447

    
448
  public int getComplexity()
449
    {
450
    switch(getNumLayers()[0])
451
      {
452
      case 3: return 1;
453
      case 4: return 2;
454
      case 5: return 3;
455
      }
456
    return 4;
457
    }
458

    
459
///////////////////////////////////////////////////////////////////////////////////////////////////
460

    
461
  public String[][] getTutorials()
462
    {
463
    int[] numLayers = getNumLayers();
464

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