Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyIvy.java @ c9c71c3f

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 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.TYPE_SPLIT_CORNER;
23
import static org.distorted.objectlib.touchcontrol.TouchControl.TC_HEXAHEDRON;
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.touchcontrol.TouchControlHexahedron;
31
import org.distorted.objectlib.main.ObjectControl;
32
import org.distorted.objectlib.main.ObjectType;
33
import org.distorted.objectlib.helpers.ObjectShape;
34
import org.distorted.objectlib.helpers.ObjectSticker;
35
import org.distorted.objectlib.helpers.ScrambleState;
36
import org.distorted.objectlib.main.ShapeHexahedron;
37

    
38
///////////////////////////////////////////////////////////////////////////////////////////////////
39

    
40
public class TwistyIvy extends ShapeHexahedron
41
{
42
  static final Static3D[] ROT_AXIS = new Static3D[]
43
         {
44
           new Static3D(+SQ3/3,+SQ3/3,+SQ3/3),
45
           new Static3D(+SQ3/3,+SQ3/3,-SQ3/3),
46
           new Static3D(+SQ3/3,-SQ3/3,+SQ3/3),
47
           new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
48
         };
49

    
50
  private static final int NUM_STICKERS = 2;
51
  public static final float IVY_D = 0.006f;
52
  private static final int  IVY_N = 8;
53

    
54
  private ScrambleState[] mStates;
55
  private int[] mBasicAngle;
56
  private Static4D[] mQuats;
57
  private float[][] mCuts;
58
  private int[][] mFaceMap;
59
  private ObjectSticker[] mStickers;
60

    
61
///////////////////////////////////////////////////////////////////////////////////////////////////
62

    
63
  public TwistyIvy(int[] numL, Static4D quat, Static3D move, float scale, InputStream stream)
64
    {
65
    super(numL, numL[0], quat, move, scale, stream);
66
    }
67

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

    
70
  public ScrambleState[] getScrambleStates()
71
    {
72
    if( mStates==null )
73
      {
74
      int[] tmp = {0,-1,0, 0,1,0, 1,-1,0, 1,1,0 };
75

    
76
      mStates = new ScrambleState[]
77
        {
78
        new ScrambleState( new int[][] {tmp,tmp,tmp,tmp} )
79
        };
80
      }
81

    
82
    return mStates;
83
    }
84

    
85
///////////////////////////////////////////////////////////////////////////////////////////////////
86

    
87
  private void initializeQuats()
88
    {
89
    mQuats = new Static4D[]
90
         {
91
         new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),
92
         new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
93
         new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
94
         new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
95

    
96
         new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),
97
         new Static4D(  0.5f,  0.5f,  0.5f, -0.5f ),
98
         new Static4D(  0.5f,  0.5f, -0.5f,  0.5f ),
99
         new Static4D(  0.5f,  0.5f, -0.5f, -0.5f ),
100
         new Static4D(  0.5f, -0.5f,  0.5f,  0.5f ),
101
         new Static4D(  0.5f, -0.5f,  0.5f, -0.5f ),
102
         new Static4D(  0.5f, -0.5f, -0.5f,  0.5f ),
103
         new Static4D(  0.5f, -0.5f, -0.5f, -0.5f )
104
         };
105
    }
106

    
107
///////////////////////////////////////////////////////////////////////////////////////////////////
108

    
109
  public int[] getSolvedQuats(int cubit, int[] numLayers)
110
    {
111
    if( mQuats==null ) initializeQuats();
112
    int status = retCubitSolvedStatus(cubit,numLayers);
113
    return status<0 ? null : buildSolvedQuats(TouchControlHexahedron.FACE_AXIS[status],mQuats);
114
    }
115

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

    
118
  public Static4D[] getQuats()
119
    {
120
    if( mQuats==null ) initializeQuats();
121
    return mQuats;
122
    }
123

    
124
///////////////////////////////////////////////////////////////////////////////////////////////////
125

    
126
  public int getSolvedFunctionIndex()
127
    {
128
    return 0;
129
    }
130

    
131
///////////////////////////////////////////////////////////////////////////////////////////////////
132

    
133
  public int getNumStickerTypes(int[] numLayers)
134
    {
135
    return NUM_STICKERS;
136
    }
137

    
138
///////////////////////////////////////////////////////////////////////////////////////////////////
139

    
140
  public float[][] getCuts(int[] numLayers)
141
    {
142
    if( mCuts==null )
143
      {
144
      float[] cut = new float[] {0.0f};
145
      mCuts = new float[][] { cut,cut,cut,cut };
146
      }
147

    
148
    return mCuts;
149
    }
150

    
151
///////////////////////////////////////////////////////////////////////////////////////////////////
152

    
153
  public boolean[][] getLayerRotatable(int[] numLayers)
154
    {
155
    int numAxis = ROT_AXIS.length;
156
    boolean[][] layerRotatable = new boolean[numAxis][];
157

    
158
    for(int i=0; i<numAxis; i++)
159
      {
160
      layerRotatable[i] = new boolean[numLayers[i]];
161
      for(int j=0; j<numLayers[i]; j++) layerRotatable[i][j] = true;
162
      }
163

    
164
    return layerRotatable;
165
    }
166

    
167
///////////////////////////////////////////////////////////////////////////////////////////////////
168

    
169
  public int getMovementType()
170
    {
171
    return TC_HEXAHEDRON;
172
    }
173

    
174
///////////////////////////////////////////////////////////////////////////////////////////////////
175

    
176
  public int getMovementSplit()
177
    {
178
    return TYPE_SPLIT_CORNER;
179
    }
180

    
181
///////////////////////////////////////////////////////////////////////////////////////////////////
182

    
183
  public int[][][] getEnabled()
184
    {
185
    return new int[][][]
186
      {
187
          {{0},{3},{3},{0}},
188
          {{2},{1},{1},{2}},
189
          {{2},{0},{0},{2}},
190
          {{1},{3},{3},{1}},
191
          {{0},{0},{1},{1}},
192
          {{2},{2},{3},{3}},
193
      };
194
    }
195

    
196
///////////////////////////////////////////////////////////////////////////////////////////////////
197

    
198
  public float[] getDist3D(int[] numLayers)
199
    {
200
    return null;
201
    }
202

    
203
///////////////////////////////////////////////////////////////////////////////////////////////////
204

    
205
  public int getNumCubitFaces()
206
    {
207
    return 6;
208
    }
209

    
210
///////////////////////////////////////////////////////////////////////////////////////////////////
211

    
212
  public float[][] getCubitPositions(int[] numLayers)
213
    {
214
    final float DIST_CORNER = numLayers[0]-1;
215
    final float DIST_CENTER = numLayers[0]-1;
216

    
217
    final float[][] CENTERS = new float[10][];
218

    
219
    CENTERS[0] = new float[] { DIST_CORNER, DIST_CORNER, DIST_CORNER };
220
    CENTERS[1] = new float[] {-DIST_CORNER, DIST_CORNER,-DIST_CORNER };
221
    CENTERS[2] = new float[] {-DIST_CORNER,-DIST_CORNER, DIST_CORNER };
222
    CENTERS[3] = new float[] { DIST_CORNER,-DIST_CORNER,-DIST_CORNER };
223
    CENTERS[4] = new float[] { DIST_CENTER,           0,           0 };
224
    CENTERS[5] = new float[] {-DIST_CENTER,           0,           0 };
225
    CENTERS[6] = new float[] {           0, DIST_CENTER,           0 };
226
    CENTERS[7] = new float[] {           0,-DIST_CENTER,           0 };
227
    CENTERS[8] = new float[] {           0,           0, DIST_CENTER };
228
    CENTERS[9] = new float[] {           0,           0,-DIST_CENTER };
229

    
230
    return CENTERS;
231
    }
232

    
233
///////////////////////////////////////////////////////////////////////////////////////////////////
234

    
235
  public ObjectShape getObjectShape(int variant)
236
    {
237
    if( variant==0 )
238
      {
239
      final float angle = (float)Math.PI/(2*IVY_N);
240
      final float CORR  = 1.0f - 2*IVY_D;
241

    
242
      float[][] centers= new float[][] { {-1.0f,-1.0f,-1.0f} };
243
      float[][] corners= new float[][] { {0.05f,0.20f}, {0.04f,0.20f} };
244
      int[] cornerIndices= new int[3*(IVY_N+1)+4];
245
      int[] centerIndices= new int[3*(IVY_N+1)+4];
246
      double[][] vertices= new double[3*(IVY_N+1)+4][3];
247
      int[][] vertIndices= new int[6][IVY_N+4];
248
      int[] bandIndices  = new int[] { 0,0,0,1,1,1 };
249

    
250
      float[][] bands =
251
        {
252
          {+0.015f,20,0.2f,0.5f,7,1,2},
253
          {-0.100f,20,0.2f,0.0f,2,1,2}
254
        };
255

    
256
      for(int i=0; i<3*(IVY_N+1); i++)
257
        {
258
        cornerIndices[i+4] = -1;
259
        centerIndices[i+4] = -1;
260
        }
261

    
262
      cornerIndices[0] = 1;
263
      cornerIndices[1] = 0;
264
      cornerIndices[2] = 0;
265
      cornerIndices[3] = 0;
266

    
267
      centerIndices[0] = 0;
268
      centerIndices[1] = 0;
269
      centerIndices[2] = 0;
270
      centerIndices[3] = 0;
271

    
272
      vertices[0][0] = 0.0;
273
      vertices[0][1] = 0.0;
274
      vertices[0][2] = 0.0;
275
      vertices[1][0] =-2.0;
276
      vertices[1][1] = 0.0;
277
      vertices[1][2] = 0.0;
278
      vertices[2][0] = 0.0;
279
      vertices[2][1] =-2.0;
280
      vertices[2][2] = 0.0;
281
      vertices[3][0] = 0.0;
282
      vertices[3][1] = 0.0;
283
      vertices[3][2] =-2.0;
284

    
285
      vertIndices[0][0] = 2;
286
      vertIndices[0][1] = 0;
287
      vertIndices[0][2] = 1;
288
      vertIndices[3][0] = 2;
289
      vertIndices[3][1] = 0;
290
      vertIndices[3][2] = 1;
291

    
292
      vertIndices[1][0] = 3;
293
      vertIndices[1][1] = 0;
294
      vertIndices[1][2] = 2;
295
      vertIndices[4][0] = 3;
296
      vertIndices[4][1] = 0;
297
      vertIndices[4][2] = 2;
298

    
299
      vertIndices[2][0] = 1;
300
      vertIndices[2][1] = 0;
301
      vertIndices[2][2] = 3;
302
      vertIndices[5][0] = 1;
303
      vertIndices[5][1] = 0;
304
      vertIndices[5][2] = 3;
305

    
306
      int N1 = 4;
307
      int N2 = N1 + IVY_N + 1;
308
      int N3 = N2 + IVY_N + 1;
309

    
310
      for(int i=0; i<=IVY_N; i++)
311
        {
312
        double cos1 = Math.cos((IVY_N-i)*angle);
313
        double sin1 = Math.sin((IVY_N-i)*angle);
314
        double cos2 = Math.cos((      i)*angle);
315
        double sin2 = Math.sin((      i)*angle);
316

    
317
        vertices[N1+i][0] = CORR*(2*cos1-1.0) - 1.0;
318
        vertices[N1+i][1] = CORR*(2*sin1-1.0) - 1.0;
319
        vertices[N1+i][2] = 0.0;
320

    
321
        vertices[N2+i][0] = 0.0;
322
        vertices[N2+i][1] = CORR*(2*sin2-1.0) - 1.0;
323
        vertices[N2+i][2] = CORR*(2*cos2-1.0) - 1.0;
324

    
325
        vertices[N3+i][0] = CORR*(2*cos2-1.0) - 1.0;
326
        vertices[N3+i][1] = 0.0;
327
        vertices[N3+i][2] = CORR*(2*sin2-1.0) - 1.0;
328

    
329
        vertIndices[0][i+3] = N1 + i;
330
        vertIndices[1][i+3] = N2 + i;
331
        vertIndices[2][i+3] = N3 + i;
332
        vertIndices[3][i+3] = N1 + i;
333
        vertIndices[4][i+3] = N2 + i;
334
        vertIndices[5][i+3] = N3 + i;
335
        }
336

    
337
      float C = 1.0f - SQ2/2;
338
      float[] convexCenter = new float[] {-C,-C,-C};
339
      return new ObjectShape(vertices,vertIndices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), convexCenter);
340
      }
341
    else
342
      {
343
      final float angle = (float)Math.PI/(2*IVY_N);
344
      final float CORR  = 1.0f - 2*IVY_D;
345
      double[][] vertices = new double[2*IVY_N][3];
346
      int[][] vert_indices = new int[2][2*IVY_N];
347

    
348
      int[] bandIndices= new int[] { 0,1 };
349
      int[] indexes    = new int[2*IVY_N];
350
      float[][] corners= new float[][] { {0.05f,0.20f} };
351
      float[][] centers= new float[][] { {-0.0f,-0.0f,-1.0f} };
352

    
353
      for(int i=0; i<IVY_N; i++)
354
        {
355
        double sin = Math.sin(i*angle);
356
        double cos = Math.cos(i*angle);
357

    
358
        vertices[i      ][0] = CORR*(1.0f-2*cos);
359
        vertices[i      ][1] = CORR*(1.0f-2*sin);
360
        vertices[i      ][2] = 0;
361
        vertices[i+IVY_N][0] = CORR*(2*cos-1.0f);
362
        vertices[i+IVY_N][1] = CORR*(2*sin-1.0f);
363
        vertices[i+IVY_N][2] = 0;
364
        }
365

    
366
      for(int i=0; i<2*IVY_N; i++)
367
        {
368
        vert_indices[0][i] = i;
369
        vert_indices[1][i] = 2*IVY_N-1-i;
370
        }
371

    
372
      for(int i=0; i<2*IVY_N; i++)
373
        {
374
        indexes[i] = -1;
375
        }
376
      indexes[0] = indexes[IVY_N] = 0;
377

    
378
      float[][] bands =
379
        {
380
          {+0.03f,35,0.5f,0.5f,5,0,0},
381
          {+0.10f,45,0.5f,0.0f,2,0,0}
382
        };
383

    
384
      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,indexes,centers,indexes,getNumCubitFaces(), null);
385
      }
386
    }
387

    
388
///////////////////////////////////////////////////////////////////////////////////////////////////
389

    
390
  public Static4D getQuat(int cubit, int[] numLayers)
391
    {
392
    if( mQuats==null ) initializeQuats();
393

    
394
    switch(cubit)
395
      {
396
      case  0: return mQuats[0];
397
      case  1: return mQuats[2];
398
      case  2: return mQuats[3];
399
      case  3: return mQuats[1];
400

    
401
      case  4: return mQuats[8];
402
      case  5: return mQuats[11];
403
      case  6: return mQuats[10];
404
      case  7: return mQuats[9];
405
      case  8: return mQuats[0];
406
      case  9: return mQuats[2];
407
      }
408

    
409
    return mQuats[0];
410
    }
411

    
412
///////////////////////////////////////////////////////////////////////////////////////////////////
413

    
414
  public int getNumCubitVariants(int[] numLayers)
415
    {
416
    return 2;
417
    }
418

    
419
///////////////////////////////////////////////////////////////////////////////////////////////////
420

    
421
  public int getCubitVariant(int cubit, int[] numLayers)
422
    {
423
    return cubit<4 ? 0:1;
424
    }
425

    
426
///////////////////////////////////////////////////////////////////////////////////////////////////
427

    
428
  public int getVariantFaceColor(int variant, int face, int[] numLayers)
429
    {
430
    if( variant==0 ) return face<3 ? 0 : -1;
431
    else             return face<1 ? 1 : -1;
432
    }
433

    
434
///////////////////////////////////////////////////////////////////////////////////////////////////
435

    
436
  public int getCubitFaceColor(int cubit, int face, int[] numLayers)
437
    {
438
    if( mFaceMap==null )
439
      {
440
      mFaceMap = new int[][]
441
         {
442
           { 4, 0, 2, -1,-1,-1 },
443
           { 5, 1, 2, -1,-1,-1 },
444
           { 4, 1, 3, -1,-1,-1 },
445
           { 5, 0, 3, -1,-1,-1 },
446

    
447
           { 0, -1,-1,-1,-1,-1 },
448
           { 1, -1,-1,-1,-1,-1 },
449
           { 2, -1,-1,-1,-1,-1 },
450
           { 3, -1,-1,-1,-1,-1 },
451
           { 4, -1,-1,-1,-1,-1 },
452
           { 5, -1,-1,-1,-1,-1 },
453
         };
454
      }
455

    
456
    return mFaceMap[cubit][face];
457
    }
458

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

    
461
  public ObjectSticker retSticker(int sticker)
462
    {
463
    if( mStickers==null )
464
      {
465
      float[][] STICKERS = new float[][] { { 0.29258922f, -0.5f, 0.29258922f, 0.29258922f, -0.5f, 0.29258922f }, { -0.5f, 0.5f, 0.5f, -0.5f } };
466
      mStickers = new ObjectSticker[NUM_STICKERS];
467
      float D = (float)(Math.PI/4);
468
      final float[][] angles = { { 0,0,D },{ D,D } };
469
      final float[][] radii  = { { 0,0.04f,0 },{ 0.06f,0.06f } };
470
      final float[] strokes = { 0.03f, 0.08f };
471

    
472
      if( ObjectControl.isInIconMode() )
473
        {
474
        float mult = 1.5f;
475
        strokes[0]*=mult;
476
        strokes[1]*=mult;
477
        }
478

    
479
      for(int s=0; s<NUM_STICKERS; s++) mStickers[s] = new ObjectSticker(STICKERS[s], angles[s],radii[s],strokes[s]);
480
      }
481

    
482
    return mStickers[sticker];
483
    }
484

    
485
///////////////////////////////////////////////////////////////////////////////////////////////////
486
// PUBLIC API
487

    
488
  public Static3D[] getRotationAxis()
489
    {
490
    return ROT_AXIS;
491
    }
492

    
493
///////////////////////////////////////////////////////////////////////////////////////////////////
494

    
495
  public int[] getBasicAngle()
496
    {
497
    if( mBasicAngle ==null ) mBasicAngle = new int[] { 3,3,3,3 };
498
    return mBasicAngle;
499
    }
500

    
501
///////////////////////////////////////////////////////////////////////////////////////////////////
502

    
503
  public ObjectType intGetObjectType(int[] numLayers)
504
    {
505
    return ObjectType.IVY_2;
506
    }
507

    
508
///////////////////////////////////////////////////////////////////////////////////////////////////
509

    
510
  public String getObjectName()
511
    {
512
    return "Ivy Cube";
513
    }
514

    
515
///////////////////////////////////////////////////////////////////////////////////////////////////
516

    
517
  public String getInventor()
518
    {
519
    return "Eitan Cher";
520
    }
521

    
522
///////////////////////////////////////////////////////////////////////////////////////////////////
523

    
524
  public int getYearOfInvention()
525
    {
526
    return 2009;
527
    }
528

    
529
///////////////////////////////////////////////////////////////////////////////////////////////////
530

    
531
  public int getComplexity()
532
    {
533
    return 1;
534
    }
535
}
(12-12/25)