Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyBandagedAbstract.java @ 95123ad0

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2021 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_CUBOID;
23
import static org.distorted.objectlib.touchcontrol.TouchControl.TYPE_NOT_SPLIT;
24

    
25
import java.io.InputStream;
26

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

    
31
import org.distorted.objectlib.helpers.FactoryBandagedCubit;
32
import org.distorted.objectlib.helpers.ObjectFaceShape;
33
import org.distorted.objectlib.scrambling.ScrambleStateBandagedCuboid;
34
import org.distorted.objectlib.touchcontrol.TouchControlHexahedron;
35
import org.distorted.objectlib.helpers.ObjectShape;
36
import org.distorted.objectlib.scrambling.ScrambleState;
37
import org.distorted.objectlib.main.ShapeHexahedron;
38

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

    
41
abstract class TwistyBandagedAbstract extends ShapeHexahedron
42
{
43
  private static final int CUBIT_111 = 0;
44
  private static final int CUBIT_211 = 1;
45
  private static final int CUBIT_311 = 2;
46
  private static final int CUBIT_221 = 3;
47
  private static final int CUBIT_222 = 4;
48
  private static final int CUBIT_OTH = 5;
49

    
50
  // the three rotation axis of a 3x3 Cube. Must be normalized.
51
  static final Static3D[] ROT_AXIS = new Static3D[]
52
         {
53
           new Static3D(1,0,0),
54
           new Static3D(0,1,0),
55
           new Static3D(0,0,1)
56
         };
57

    
58
  private static final int[][] mDims = new int[][]
59
        {
60
         {1,1,1},  // has to be X>=Z>=Y so that all
61
         {2,1,1},  // the faces are horizontal
62
         {3,1,1},
63
         {2,1,2},
64
         {2,2,2},
65
        };
66

    
67
  private int[][] mBasicAngle;
68
  private Static4D[] mInitQuats;
69
  private float[][] mCuts;
70
  private ScrambleState[] mStates;
71
  private int[] mCubitVariantMap;
72
  private int[] mTypeVariantMap;
73

    
74
  float[][] POSITIONS;
75

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

    
78
  TwistyBandagedAbstract(int[] numL, int meshState, int iconMode, Static4D quat, Static3D move, float scale, InputStream stream)
79
    {
80
    super(numL, meshState, iconMode, (numL[0]+numL[1]+numL[2])/3.0f, quat, move, scale, stream);
81
    }
82

    
83
///////////////////////////////////////////////////////////////////////////////////////////////////
84

    
85
  abstract float[][] getPositions();
86

    
87
///////////////////////////////////////////////////////////////////////////////////////////////////
88

    
89
  public ScrambleState[] getScrambleStates()
90
    {
91
    if( mStates==null && !isInIconMode() )
92
      {
93
      long signature = getSignature();
94
      mStates = ScrambleStateBandagedCuboid.computeGraph(signature);
95
      }
96

    
97
    return mStates;
98
    }
99

    
100
///////////////////////////////////////////////////////////////////////////////////////////////////
101

    
102
  private int getType(float[] pos)
103
    {
104
    switch(pos.length)
105
      {
106
      case  3: return CUBIT_111;
107
      case  6: return CUBIT_211;
108
      case  9: boolean x1 = (pos[0]==pos[3] && pos[0]==pos[6]);
109
               boolean y1 = (pos[1]==pos[4] && pos[1]==pos[7]);
110
               boolean z1 = (pos[2]==pos[5] && pos[2]==pos[8]);
111
               return ( (x1&&y1) || (x1&&z1) || (y1&&z1) ) ? CUBIT_311 : CUBIT_OTH;
112
      case 12: float x = (pos[0]+pos[3]+pos[6]+pos[ 9])/4;
113
               float y = (pos[1]+pos[4]+pos[7]+pos[10])/4;
114
               float z = (pos[2]+pos[5]+pos[8]+pos[11])/4;
115
               float d1 = (pos[0]-x)*(pos[0]-x) + (pos[ 1]-y)*(pos[ 1]-y) + (pos[ 2]-z)*(pos[ 2]-z);
116
               float d2 = (pos[3]-x)*(pos[3]-x) + (pos[ 4]-y)*(pos[ 4]-y) + (pos[ 5]-z)*(pos[ 5]-z);
117
               float d3 = (pos[6]-x)*(pos[6]-x) + (pos[ 7]-y)*(pos[ 7]-y) + (pos[ 8]-z)*(pos[ 8]-z);
118
               float d4 = (pos[9]-x)*(pos[9]-x) + (pos[10]-y)*(pos[10]-y) + (pos[11]-z)*(pos[11]-z);
119
               return ( d1==0.5f && d2==0.5f && d3==0.5f && d4==0.5f ) ? CUBIT_221 : CUBIT_OTH;
120
      case 24: float x3 = pos[0];
121
               float y3 = pos[1];
122
               float z3 = pos[2];
123
               float x4=-10,y4=-10,z4=-10;
124
               int i;
125

    
126
               for(i=0; i<8; i++)
127
                 {
128
                 if( pos[3*i]!=x3 && pos[3*i+1]!=y3 && pos[3*i+2]!=z3 )
129
                   {
130
                   x4 = pos[3*i  ];
131
                   y4 = pos[3*i+1];
132
                   z4 = pos[3*i+2];
133
                   break;
134
                   }
135
                 }
136
               if( i==9 ) return CUBIT_OTH;
137

    
138
               float dX = x4-x3;
139
               float dY = y4-y3;
140
               float dZ = z4-z3;
141

    
142
               if( (dX==1.0f || dX==-1.0f) && (dY==1.0f || dY==-1.0f) && (dZ==1.0f || dZ==-1.0f) )
143
                 {
144
                 for(i=0; i<8; i++)
145
                   {
146
                   if( (pos[3*i  ]!=x3 && pos[3*i  ]!=x4) ||
147
                       (pos[3*i+1]!=y3 && pos[3*i+1]!=y4) ||
148
                       (pos[3*i+2]!=z3 && pos[3*i+2]!=z4)  ) return CUBIT_OTH;
149
                   }
150

    
151
                 return CUBIT_222;
152
                 }
153

    
154
      default: return CUBIT_OTH;
155
      }
156
    }
157

    
158
///////////////////////////////////////////////////////////////////////////////////////////////////
159

    
160
  private int getQuatIndex(int cubit)
161
    {
162
    float[][] positions = getPositions();
163
    int len = positions.length;
164

    
165
    if( cubit>=0 && cubit<len )
166
      {
167
      float[] pos = positions[cubit];
168
      int type = getType(pos);
169

    
170
      switch(type)
171
        {
172
        case CUBIT_222:
173
        case CUBIT_111: return 0;
174
        case CUBIT_211:
175
        case CUBIT_311: return (pos[1]==pos[4]) ? (pos[0]==pos[3] ? 2 : 0) : 3;
176
        case CUBIT_221: if( pos[0]==pos[3] && pos[0]==pos[6] ) return 3;
177
                        if( pos[1]==pos[4] && pos[1]==pos[7] ) return 0;
178
                        if( pos[2]==pos[5] && pos[2]==pos[8] ) return 1;
179
        }
180
      }
181

    
182
    return 0;
183
    }
184

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

    
187
  private int getSigIndex(float x, float y, float z)
188
    {
189
    if( x==-1.0f )
190
      {
191
           if( y==-1.0f ) return z==0.5f ? 4:9;
192
      else if( y==-0.5f ) return z==1.0f ? 14 : (z==0.0f ? 17:20);
193
      else if( y== 0.0f ) return z==0.5f ? 25:30;
194
      else if( y== 0.5f ) return z==1.0f ? 35 : (z==0.0f ? 38:41);
195
      else if( y== 1.0f ) return z==0.5f ? 46:51;
196
      }
197
    else if( x==-0.5f )
198
      {
199
           if( y==-1.0f ) return z==1.0f ? 1  : (z==0.0f ?  6:11);
200
      else if( y== 0.0f ) return z==1.0f ? 22 : (z==0.0f ? 27:32);
201
      else if( y== 1.0f ) return z==1.0f ? 43 : (z==0.0f ? 48:53);
202
      }
203
    else if( x==0.0f )
204
      {
205
           if( y==-1.0f ) return z==0.5f ? 3:8;
206
      else if( y==-0.5f ) return z==1.0f ? 13 : (z==0.0f ? 16:19);
207
      else if( y== 0.0f ) return z==0.5f ? 24:29;
208
      else if( y== 0.5f ) return z==1.0f ? 34 : (z==0.0f ? 37:40);
209
      else if( y== 1.0f ) return z==0.5f ? 45:50;
210
      }
211
    else if( x==0.5f )
212
      {
213
           if( y==-1.0f ) return z==1.0f ? 0  : (z==0.0f ?  5:10);
214
      else if( y== 0.0f ) return z==1.0f ? 21 : (z==0.0f ? 26:31);
215
      else if( y== 1.0f ) return z==1.0f ? 42 : (z==0.0f ? 47:52);
216
      }
217
    else if( x==1.0f )
218
      {
219
           if( y==-1.0f ) return z==0.5f ? 2:7;
220
      else if( y==-0.5f ) return z==1.0f ? 12 : (z==0.0f ? 15:18);
221
      else if( y== 0.0f ) return z==0.5f ? 23:28;
222
      else if( y== 0.5f ) return z==1.0f ? 33 : (z==0.0f ? 36:39);
223
      else if( y== 1.0f ) return z==0.5f ? 44:49;
224
      }
225
    else
226
      {
227
      android.util.Log.e("D", "ERROR! mx="+x);
228
      }
229

    
230
    return -1;
231
    }
232

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

    
235
  private long markConnection(float x1, float y1, float z1, float x2, float y2, float z2)
236
    {
237
    float dx = x1-x2;
238
    float dy = y1-y2;
239
    float dz = z1-z2;
240

    
241
    if( (dx==0 && dy==0 && (dz==1 || dz==-1) ) ||
242
        (dz==0 && dx==0 && (dy==1 || dy==-1) ) ||
243
        (dy==0 && dz==0 && (dx==1 || dx==-1) )  )
244
      {
245
      float mx = (x1+x2)/2;
246
      float my = (y1+y2)/2;
247
      float mz = (z1+z2)/2;
248

    
249
      int index = getSigIndex(mx,my,mz);
250

    
251
      return (1L<<index);
252
      }
253

    
254
    return 0;
255
    }
256

    
257
///////////////////////////////////////////////////////////////////////////////////////////////////
258

    
259
  long markConnections(long signature, float[] position)
260
    {
261
    int len = position.length/3;
262

    
263
    for(int i=0; i<len; i++)
264
      {
265
      float x = position[3*i  ];
266
      float y = position[3*i+1];
267
      float z = position[3*i+2];
268

    
269
      for(int j=i+1; j<len; j++)
270
        {
271
        signature |= markConnection(x,y,z,position[3*j],position[3*j+1],position[3*j+2]);
272
        }
273
      }
274

    
275
    return signature;
276
    }
277

    
278
///////////////////////////////////////////////////////////////////////////////////////////////////
279

    
280
  public long getSignature()
281
    {
282
    long signature = 0;
283
    float[][] positions = getPositions();
284
    for(float[] pos : positions ) signature = markConnections(signature,pos);
285
    return signature;
286
    }
287

    
288
///////////////////////////////////////////////////////////////////////////////////////////////////
289

    
290
  public ObjectShape getObjectShape(int variant)
291
    {
292
    int type,numTypes = mDims.length;
293
    for(type=0; type<numTypes; type++) if( mTypeVariantMap[type]==variant ) break;
294

    
295
    if( type<numTypes )
296
      {
297
      int X = mDims[type][0];
298
      int Y = mDims[type][1];
299
      int Z = mDims[type][2];
300

    
301
      float[][] vertices =
302
        {
303
          {+0.5f*X,+0.5f*Y,+0.5f*Z},
304
          {+0.5f*X,+0.5f*Y,-0.5f*Z},
305
          {+0.5f*X,-0.5f*Y,+0.5f*Z},
306
          {+0.5f*X,-0.5f*Y,-0.5f*Z},
307
          {-0.5f*X,+0.5f*Y,+0.5f*Z},
308
          {-0.5f*X,+0.5f*Y,-0.5f*Z},
309
          {-0.5f*X,-0.5f*Y,+0.5f*Z},
310
          {-0.5f*X,-0.5f*Y,-0.5f*Z}
311
        };
312

    
313
      int[][] indices =
314
        {
315
          {2,3,1,0},
316
          {7,6,4,5},
317
          {4,0,1,5},
318
          {7,3,2,6},
319
          {6,2,0,4},
320
          {3,7,5,1},
321
        };
322

    
323
      return new ObjectShape(vertices, indices);
324
      }
325

    
326
    float[][] positions = getPositions();
327
    int cubit,numCubits = positions.length;
328

    
329
    for(cubit=0; cubit<numCubits; cubit++)
330
      {
331
      if( mCubitVariantMap[cubit]==variant ) break;
332
      }
333

    
334
    if( cubit>=numCubits )
335
      {
336
      android.util.Log.e("D", "unknown variant: "+variant);
337
      return null;
338
      }
339

    
340
    FactoryBandagedCubit factory = FactoryBandagedCubit.getInstance();
341
    return factory.createIrregularShape(variant,positions[cubit]);
342
    }
343

    
344
///////////////////////////////////////////////////////////////////////////////////////////////////
345

    
346
  public ObjectFaceShape getObjectFaceShape(int variant)
347
    {
348
    boolean roundCorners = DistortedLibrary.fastCompilationTF();
349
    int type,numTypes = mDims.length;
350
    for(type=0; type<numTypes; type++) if( mTypeVariantMap[type]==variant ) break;
351

    
352
    if( type<numTypes )
353
      {
354
      int val = roundCorners ? 0 : -1;
355
      int X = mDims[type][0];
356
      int Y = mDims[type][1];
357
      int Z = mDims[type][2];
358

    
359
      float height        = isInIconMode() ? 0.001f : 0.048f;
360
      int[] bandIndices   = { 0,0,1,1,2,2 };
361
      float[][] corners   = { {0.04f,0.15f} };
362
      int[] cornerIndices = { val,val,val,val,val,val,val,val };
363
      int[] centerIndices = { 0,1,2,3,4,5,6,7 };
364

    
365
      int maxXY = Math.max(X,Y);
366
      int maxXZ = Math.max(X,Z);
367
      int maxYZ = Math.max(Y,Z);
368

    
369
      int angle = 45;
370
      float R = 0.25f;
371
      float S = 0.50f;
372

    
373
      float[][] bands =
374
        {
375
          {height/maxYZ,angle,R,S,5,1,0},
376
          {height/maxXZ,angle,R,S,5,1,0},
377
          {height/maxXY,angle,R,S,5,1,0}
378
        };
379

    
380
      float[][] centers =
381
        {
382
          {+0.5f*(X-1),+0.5f*(Y-1),+0.5f*(Z-1)},
383
          {+0.5f*(X-1),+0.5f*(Y-1),-0.5f*(Z-1)},
384
          {+0.5f*(X-1),-0.5f*(Y-1),+0.5f*(Z-1)},
385
          {+0.5f*(X-1),-0.5f*(Y-1),-0.5f*(Z-1)},
386
          {-0.5f*(X-1),+0.5f*(Y-1),+0.5f*(Z-1)},
387
          {-0.5f*(X-1),+0.5f*(Y-1),-0.5f*(Z-1)},
388
          {-0.5f*(X-1),-0.5f*(Y-1),+0.5f*(Z-1)},
389
          {-0.5f*(X-1),-0.5f*(Y-1),-0.5f*(Z-1)}
390
        };
391

    
392
      return new ObjectFaceShape(bands,bandIndices,corners,cornerIndices,centers,centerIndices,null);
393
      }
394

    
395
    FactoryBandagedCubit factory = FactoryBandagedCubit.getInstance();
396
    return factory.createIrregularFaceShape(variant, isInIconMode(), roundCorners );
397
    }
398

    
399
///////////////////////////////////////////////////////////////////////////////////////////////////
400

    
401
  public float[][] getCubitPositions(int[] numLayers)
402
    {
403
    return getPositions();
404
    }
405

    
406
///////////////////////////////////////////////////////////////////////////////////////////////////
407

    
408
  public Static4D getCubitQuats(int cubit, int[] numLayers)
409
    {
410
    if( mInitQuats ==null )
411
      {
412
      mInitQuats = new Static4D[]
413
        {
414
        new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),  // NULL
415
        new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),  // X
416
        new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),  // Y
417
        new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),  // Z
418
        new Static4D( -0.5f,  +0.5f,  -0.5f,  +0.5f),  // ZX
419
        new Static4D( +0.5f,  +0.5f,  +0.5f,  -0.5f),  // YX
420
        };
421
      }
422

    
423
    return mInitQuats[getQuatIndex(cubit)];
424
    }
425

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

    
428
  public int getNumCubitVariants(int[] numLayers)
429
    {
430
    int numVariants = 0;
431
    float[][] positions = getPositions();
432
    boolean C111=false;
433
    boolean C211=false;
434
    boolean C311=false;
435
    boolean C221=false;
436
    boolean C222=false;
437

    
438
    int numCubits = positions.length;
439
    mCubitVariantMap = new int[numCubits];
440

    
441
    int numTypes = mDims.length;
442
    mTypeVariantMap = new int[numTypes];
443
    for(int i=0; i<numTypes; i++) mTypeVariantMap[i] = -1;
444

    
445
    for (int cubit=0; cubit<numCubits; cubit++)
446
      {
447
      int type = getType(positions[cubit]);
448

    
449
      switch (type)
450
        {
451
        case CUBIT_111: if (!C111) { C111 = true; mTypeVariantMap[CUBIT_111]=numVariants++; }
452
                        mCubitVariantMap[cubit]=mTypeVariantMap[CUBIT_111];
453
                        break;
454
        case CUBIT_211: if (!C211) { C211 = true; mTypeVariantMap[CUBIT_211]=numVariants++; }
455
                        mCubitVariantMap[cubit]=mTypeVariantMap[CUBIT_211];
456
                        break;
457
        case CUBIT_311: if (!C311) { C311 = true; mTypeVariantMap[CUBIT_311]=numVariants++; }
458
                        mCubitVariantMap[cubit]=mTypeVariantMap[CUBIT_311];
459
                        break;
460
        case CUBIT_221: if (!C221) { C221 = true; mTypeVariantMap[CUBIT_221]=numVariants++; }
461
                        mCubitVariantMap[cubit]=mTypeVariantMap[CUBIT_221];
462
                        break;
463
        case CUBIT_222: if (!C222) { C222 = true; mTypeVariantMap[CUBIT_222]=numVariants++; }
464
                        mCubitVariantMap[cubit]=mTypeVariantMap[CUBIT_222];
465
                        break;
466
        default       : mCubitVariantMap[cubit] = numVariants++;
467
        }
468
      }
469

    
470
    FactoryBandagedCubit factory = FactoryBandagedCubit.getInstance();
471
    factory.prepare(numVariants,numLayers[0],numLayers[1],numLayers[2]);
472

    
473
    return numVariants;
474
    }
475

    
476
///////////////////////////////////////////////////////////////////////////////////////////////////
477

    
478
  public int getCubitVariant(int cubit, int[] numLayers)
479
    {
480
    return mCubitVariantMap[cubit];
481
    }
482

    
483
///////////////////////////////////////////////////////////////////////////////////////////////////
484

    
485
  public float[][] getCuts(int[] numLayers)
486
    {
487
    if( mCuts==null )
488
      {
489
      mCuts = new float[3][];
490

    
491
      for(int axis=0; axis<3; axis++)
492
        {
493
        int len = numLayers[axis];
494
        float start = (2-len)*0.5f;
495

    
496
        if( len>=2 )
497
          {
498
          mCuts[axis] = new float[len-1];
499
          for(int i=0; i<len-1; i++) mCuts[axis][i] = start+i;
500
          }
501
        }
502
      }
503

    
504
    return mCuts;
505
    }
506

    
507
///////////////////////////////////////////////////////////////////////////////////////////////////
508

    
509
  public boolean[][] getLayerRotatable(int[] numLayers)
510
    {
511
    int numAxis = ROT_AXIS.length;
512
    boolean[][] layerRotatable = new boolean[numAxis][];
513

    
514
    for(int i=0; i<numAxis; i++)
515
      {
516
      layerRotatable[i] = new boolean[numLayers[i]];
517
      for(int j=0; j<numLayers[i]; j++) layerRotatable[i][j] = true;
518
      }
519

    
520
    return layerRotatable;
521
    }
522

    
523
///////////////////////////////////////////////////////////////////////////////////////////////////
524

    
525
  public int getTouchControlType()
526
    {
527
    return TC_CUBOID;
528
    }
529

    
530
///////////////////////////////////////////////////////////////////////////////////////////////////
531

    
532
  public int getTouchControlSplit()
533
    {
534
    return TYPE_NOT_SPLIT;
535
    }
536

    
537
///////////////////////////////////////////////////////////////////////////////////////////////////
538

    
539
  public int[][][] getEnabled()
540
    {
541
    return new int[][][] { {{1,2}},{{1,2}},{{0,2}},{{0,2}},{{0,1}},{{0,1}} };
542
    }
543

    
544
///////////////////////////////////////////////////////////////////////////////////////////////////
545

    
546
  public float[] getDist3D(int[] numLayers)
547
    {
548
    float x = numLayers[0];
549
    float y = numLayers[1];
550
    float z = numLayers[2];
551
    float a = (x+y+z)/1.5f;
552

    
553
    return new float[] {x/a,x/a,y/a,y/a,z/a,z/a};
554
    }
555

    
556
///////////////////////////////////////////////////////////////////////////////////////////////////
557

    
558
  public Static3D[] getFaceAxis()
559
    {
560
    return TouchControlHexahedron.FACE_AXIS;
561
    }
562

    
563
///////////////////////////////////////////////////////////////////////////////////////////////////
564

    
565
  public float getStickerRadius()
566
    {
567
    return 0.10f;
568
    }
569

    
570
///////////////////////////////////////////////////////////////////////////////////////////////////
571

    
572
  public float getStickerStroke()
573
    {
574
    return isInIconMode() ? 0.16f : 0.08f;
575
    }
576

    
577
///////////////////////////////////////////////////////////////////////////////////////////////////
578

    
579
  public float[][] getStickerAngles()
580
    {
581
    return null;
582
    }
583

    
584
///////////////////////////////////////////////////////////////////////////////////////////////////
585
// PUBLIC API
586

    
587
  public Static3D[] getRotationAxis()
588
    {
589
    return ROT_AXIS;
590
    }
591

    
592
///////////////////////////////////////////////////////////////////////////////////////////////////
593

    
594
  public int[][] getBasicAngles()
595
    {
596
     if( mBasicAngle==null )
597
      {
598
      int[] num = getNumLayers();
599
      int numX = num[0];
600
      int numY = num[1];
601
      int numZ = num[2];
602

    
603
      int x = numY==numZ ? 4 : 2;
604
      int y = numX==numZ ? 4 : 2;
605
      int z = numX==numY ? 4 : 2;
606

    
607
      int[] tmpX = new int[numX];
608
      for(int i=0; i<numX; i++) tmpX[i] = x;
609
      int[] tmpY = new int[numY];
610
      for(int i=0; i<numY; i++) tmpY[i] = y;
611
      int[] tmpZ = new int[numZ];
612
      for(int i=0; i<numZ; i++) tmpZ[i] = z;
613

    
614
      mBasicAngle = new int[][] { tmpX,tmpY,tmpZ };
615
      }
616

    
617
    return mBasicAngle;
618
    }
619
}
(4-4/36)