Project

General

Profile

« Previous | Next » 

Revision 1f656ca7

Added by Leszek Koltunski almost 2 years ago

Make the 4 built-in BandagedCuboids use the introduced InitData concept and remove all specific bandaged object classes.

View differences:

src/main/java/org/distorted/objectlib/json/JsonReader.java
32 32

  
33 33
import org.distorted.objectlib.helpers.ObjectFaceShape;
34 34
import org.distorted.objectlib.helpers.ObjectSignature;
35
import org.distorted.objectlib.objects.TwistyBandagedGeneric;
35
import org.distorted.objectlib.objects.TwistyBandagedCuboid;
36 36
import org.json.JSONArray;
37 37
import org.json.JSONException;
38 38
import org.json.JSONObject;
......
146 146
      long signature2 = object.getLong("signature2");
147 147
      long signature3 = object.getLong("signature3");
148 148

  
149
      if( mLongName.equals(TwistyBandagedGeneric.OBJECT_NAME) )
149
      switch( TwistyBandagedCuboid.getType(mShortName) )
150 150
        {
151
        mSignature = new ObjectSignature(mShortName,signature1,signature2,signature3);
152
        }
153
      else
154
        {
155
        mSignature = new ObjectSignature(signature1,signature2,signature3);
151
        case 0: mSignature = new ObjectSignature(signature1,signature2,signature3); break;
152
        case 1: mSignature = new ObjectSignature(mShortName,signature1,signature2,signature3); break;
153
        case 2: mSignature = new ObjectSignature("333",signature1,signature2,signature3); break;
156 154
        }
157 155
      }
158 156
    catch(JSONException ex)
src/main/java/org/distorted/objectlib/main/ObjectType.java
39 39
  CUBE_5 ( TwistyCuboid.class        , 28, R.drawable.cube_5, true, new InitData(new int[] {5,5,5})),
40 40
  CUBE_6 ( TwistyCuboid.class        , 35, R.drawable.cube_6, true, new InitData(new int[] {6,6,6})),
41 41
  CUBE_7 ( TwistyCuboid.class        , 42, R.drawable.cube_7, true, new InitData(new int[] {7,7,7})),
42
  BAN1_3 ( TwistyBandagedFused.class , 16, R.drawable.ban1_3, true, new InitData(new int[] {3,3,3})),
43
  BAN2_3 ( TwistyBandaged2Bar.class  , 20, R.drawable.ban2_3, true, new InitData(new int[] {3,3,3})),
44
  BAN3_3 ( TwistyBandaged3Plate.class, 16, R.drawable.ban3_3, true, new InitData(new int[] {3,3,3})),
45
  BAN4_3 ( TwistyBandagedBiCube.class, 22, R.drawable.ban4_3, true, new InitData(new int[] {3,3,3})),
42
  BAN1_3 ( TwistyBandagedCuboid.class, 16, R.drawable.ban1_3, true, new InitData(new int[] {3,3,3}, TwistyBandagedCuboid.POS_1)),
43
  BAN2_3 ( TwistyBandagedCuboid.class, 20, R.drawable.ban2_3, true, new InitData(new int[] {3,3,3}, TwistyBandagedCuboid.POS_2)),
44
  BAN3_3 ( TwistyBandagedCuboid.class, 16, R.drawable.ban3_3, true, new InitData(new int[] {3,3,3}, TwistyBandagedCuboid.POS_3)),
45
  BAN4_3 ( TwistyBandagedCuboid.class, 22, R.drawable.ban4_3, true, new InitData(new int[] {3,3,3}, TwistyBandagedCuboid.POS_4)),
46 46
  CU_323 ( TwistyCuboid.class        , 15, R.drawable.cu_323, true, new InitData(new int[] {3,2,3})),
47 47
  CU_232 ( TwistyCuboid.class        , 16, R.drawable.cu_232, true, new InitData(new int[] {2,3,2})),
48 48
  CU_343 ( TwistyCuboid.class        , 23, R.drawable.cu_343, true, new InitData(new int[] {3,4,3})),
src/main/java/org/distorted/objectlib/objects/TwistyBandaged2Bar.java
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 java.io.InputStream;
23

  
24
import org.distorted.library.type.Static3D;
25
import org.distorted.library.type.Static4D;
26

  
27
import org.distorted.objectlib.helpers.ObjectSignature;
28
import org.distorted.objectlib.main.InitData;
29
import org.distorted.objectlib.main.ObjectType;
30

  
31
///////////////////////////////////////////////////////////////////////////////////////////////////
32

  
33
public class TwistyBandaged2Bar extends TwistyBandagedAbstract
34
{
35
  public TwistyBandaged2Bar(InitData data, int meshState, int iconMode, Static4D quat, Static3D move, float scale, InputStream stream)
36
    {
37
    super(data, meshState, iconMode, quat, move, scale, stream);
38
    }
39

  
40
///////////////////////////////////////////////////////////////////////////////////////////////////
41

  
42
  float[][] getPositions()
43
    {
44
    if( POSITIONS==null )
45
      {
46
      POSITIONS = new float[][]
47
        {
48
         { 0.0f, +1.0f,  1.0f, 0.0f, +1.0f,  0.0f, 0.0f, +1.0f, -1.0f},
49
         {-1.0f, -1.0f,  0.0f, 0.0f, -1.0f,  0.0f, 1.0f, -1.0f,  0.0f},
50
         {-1.0f, +1.0f, +1.0f},
51
         {-1.0f, +1.0f,  0.0f},
52
         {-1.0f, +1.0f, -1.0f},
53
         {-1.0f,  0.0f, +1.0f},
54
         {-1.0f,  0.0f,  0.0f},
55
         {-1.0f,  0.0f, -1.0f},
56
         {-1.0f, -1.0f, +1.0f},
57
         {-1.0f, -1.0f, -1.0f},
58
         {+1.0f, +1.0f, +1.0f},
59
         {+1.0f, +1.0f,  0.0f},
60
         {+1.0f, +1.0f, -1.0f},
61
         {+1.0f,  0.0f, +1.0f},
62
         {+1.0f,  0.0f,  0.0f},
63
         {+1.0f,  0.0f, -1.0f},
64
         {+1.0f, -1.0f, +1.0f},
65
         {+1.0f, -1.0f, -1.0f},
66
         { 0.0f,  0.0f, +1.0f},
67
         { 0.0f, -1.0f, +1.0f},
68
         { 0.0f,  0.0f, -1.0f},
69
         { 0.0f, -1.0f, -1.0f}
70
        };
71
      }
72

  
73
    return POSITIONS;
74
    }
75

  
76
///////////////////////////////////////////////////////////////////////////////////////////////////
77
// PUBLIC API
78

  
79
  public String getShortName()
80
    {
81
    return ObjectType.BAN2_3.name();
82
    }
83

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

  
86
  public ObjectSignature getSignature()
87
    {
88
    return new ObjectSignature(ObjectType.BAN2_3);
89
    }
90

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

  
93
  public String getObjectName()
94
    {
95
    return "2Bar Cube";
96
    }
97

  
98
///////////////////////////////////////////////////////////////////////////////////////////////////
99

  
100
  public String getInventor()
101
    {
102
    return "Unknown";
103
    }
104

  
105
///////////////////////////////////////////////////////////////////////////////////////////////////
106

  
107
  public int getYearOfInvention()
108
    {
109
    return 0;
110
    }
111

  
112
///////////////////////////////////////////////////////////////////////////////////////////////////
113

  
114
  public int getComplexity()
115
    {
116
    return 2;
117
    }
118

  
119
///////////////////////////////////////////////////////////////////////////////////////////////////
120

  
121
  public String[][] getTutorials()
122
    {
123
    return new String[][]{
124
                          {"ru","lS_EK0PMWI8","Как собрать 2-bar Cube","Алексей Ярыгин"},
125
                          {"pl","tX8ubTLh6p8","Bandaged 3x3 (Two bar)","MrUK"},
126
                          {"kr","NE6XuC1r8xw","밴디지 큐브","Denzel Washington"},
127
                         };
128
    }
129
}
src/main/java/org/distorted/objectlib/objects/TwistyBandaged3Plate.java
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 java.io.InputStream;
23

  
24
import org.distorted.library.type.Static3D;
25
import org.distorted.library.type.Static4D;
26

  
27
import org.distorted.objectlib.helpers.ObjectSignature;
28
import org.distorted.objectlib.main.InitData;
29
import org.distorted.objectlib.main.ObjectType;
30

  
31
///////////////////////////////////////////////////////////////////////////////////////////////////
32

  
33
public class TwistyBandaged3Plate extends TwistyBandagedAbstract
34
{
35
  public TwistyBandaged3Plate(InitData data, int meshState, int iconMode, Static4D quat, Static3D move, float scale, InputStream stream)
36
    {
37
    super(data, meshState, iconMode, quat, move, scale, stream);
38
    }
39

  
40
///////////////////////////////////////////////////////////////////////////////////////////////////
41

  
42
  float[][] getPositions()
43
    {
44
    if( POSITIONS==null )
45
      {
46
      POSITIONS = new float[][]
47
        {
48
          {-1.0f,  1.0f,  1.0f, -1.0f,  0.0f,  1.0f,  0.0f,  1.0f,  1.0f,  0.0f,  0.0f,  1.0f},
49
          { 1.0f,  0.0f, -1.0f,  1.0f,  0.0f,  0.0f,  1.0f,  1.0f, -1.0f,  1.0f,  1.0f,  0.0f},
50
          {-1.0f, -1.0f, -1.0f, -1.0f, -1.0f,  0.0f,  0.0f, -1.0f, -1.0f,  0.0f, -1.0f,  0.0f},
51
          { 1.0f,  1.0f,  1.0f},
52
          { 1.0f,  0.0f,  1.0f},
53
          { 1.0f, -1.0f,  1.0f},
54
          {-1.0f, -1.0f,  1.0f},
55
          { 0.0f, -1.0f,  1.0f},
56
          { 1.0f, -1.0f,  0.0f},
57
          { 1.0f, -1.0f, -1.0f},
58
          {-1.0f,  1.0f, -1.0f},
59
          {-1.0f,  1.0f,  0.0f},
60
          { 0.0f,  1.0f, -1.0f},
61
          { 0.0f,  1.0f,  0.0f},
62
          {-1.0f,  0.0f, -1.0f},
63
          {-1.0f,  0.0f,  0.0f},
64
          { 0.0f,  0.0f, -1.0f}
65
        };
66
      }
67
    return POSITIONS;
68
    }
69

  
70
///////////////////////////////////////////////////////////////////////////////////////////////////
71
// PUBLIC API
72

  
73
  public String getShortName()
74
    {
75
    return ObjectType.BAN3_3.name();
76
    }
77

  
78
///////////////////////////////////////////////////////////////////////////////////////////////////
79

  
80
  public ObjectSignature getSignature()
81
    {
82
    return new ObjectSignature(ObjectType.BAN3_3);
83
    }
84

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

  
87
  public String getObjectName()
88
    {
89
    return "Bandaged Cube C";
90
    }
91

  
92
///////////////////////////////////////////////////////////////////////////////////////////////////
93

  
94
  public String getInventor()
95
    {
96
    return "Andreas Nortmann";
97
    }
98

  
99
///////////////////////////////////////////////////////////////////////////////////////////////////
100

  
101
  public int getYearOfInvention()
102
    {
103
    return 2005;
104
    }
105

  
106
///////////////////////////////////////////////////////////////////////////////////////////////////
107

  
108
  public int getComplexity()
109
    {
110
    return 2;
111
    }
112

  
113
///////////////////////////////////////////////////////////////////////////////////////////////////
114

  
115
  public String[][] getTutorials()
116
    {
117
    return new String[][]{
118
                          {"gb","7UiCVGygUT4","Bandage Cube C Tutorial","PolyakB"},
119
                          {"ru","gXenRA92Wdc","Как собрать Bandaged 3x3 Type C","YG Cuber"},
120
                          {"pl","sKfdFLm79Zs","Bandaged 3x3 v.C cube","MrUK"},
121
                          {"kr","BcCFgeFy6Ec","밴디지 타입 C 해법","듀나메스 큐브 해법연구소"},
122
                          {"vn","9674LLkPSog","Tutorial N.2 - Bandaged VC","Duy Thích Rubik"},
123
                         };
124
    }
125
}
src/main/java/org/distorted/objectlib/objects/TwistyBandagedAbstract.java
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.helpers.ObjectSignature;
34
import org.distorted.objectlib.main.InitData;
35
import org.distorted.objectlib.scrambling.ScrambleStateBandaged3x3;
36
import org.distorted.objectlib.touchcontrol.TouchControlHexahedron;
37
import org.distorted.objectlib.helpers.ObjectShape;
38
import org.distorted.objectlib.scrambling.ScrambleState;
39
import org.distorted.objectlib.main.ShapeHexahedron;
40

  
41
///////////////////////////////////////////////////////////////////////////////////////////////////
42

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

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

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

  
69
  private int[][] mBasicAngle;
70
  private Static4D[] mInitQuats;
71
  private float[][] mCuts;
72
  private ScrambleState[] mStates;
73
  private int[] mCubitVariantMap;
74
  private int[] mTypeVariantMap;
75
  private int[][] mSolvedQuatsAbstract;
76

  
77
  float[][] POSITIONS;
78

  
79
///////////////////////////////////////////////////////////////////////////////////////////////////
80

  
81
  TwistyBandagedAbstract(InitData data, int meshState, int iconMode, Static4D quat, Static3D move, float scale, InputStream stream)
82
    {
83
    super(data, meshState, iconMode, (data.getNumLayers()[0]+data.getNumLayers()[1]+data.getNumLayers()[2])/3.0f, quat, move, scale, stream);
84
    }
85

  
86
///////////////////////////////////////////////////////////////////////////////////////////////////
87

  
88
  abstract float[][] getPositions();
89

  
90
///////////////////////////////////////////////////////////////////////////////////////////////////
91
// return 0 if cubit is 'external' (it has at least two walls which belong to two different faces
92
// of the cuboid, faces which do not both rotate along the same axis! So: it is an edge, a corner,
93
// or a bandaged cubit which 'comes out' in two different, non-opposite, faces.
94
// Otherwise, if the cubit only comes out in one face or in two faces which are opposite to each other,
95
// return the index of the first of the three quats which rotate stuff in this face (so right or left
96
// return 1 because quats 1,2,3 are the ones rotating along the X axis)
97

  
98
  private int cubitIsExternal(float[] pos, float dx, float dy, float dz)
99
    {
100
    int len = pos.length/3;
101
    int x=0, y=0, z=0;
102

  
103
    for(int i=0; i<len; i++)
104
      {
105
      float cx = pos[3*i  ];
106
      float cy = pos[3*i+1];
107
      float cz = pos[3*i+2];
108

  
109
      if( cx>dx || cx<-dx ) x=1;
110
      if( cy>dy || cy<-dy ) y=1;
111
      if( cz>dz || cz<-dz ) z=1;
112
      }
113

  
114
    if( x+y+z>=2 ) return 0;
115

  
116
    if( x==1 ) return 1;
117
    if( y==1 ) return 4;
118
    if( z==1 ) return 7;
119

  
120
    android.util.Log.e("D", "ERROR: unsupported: internal cubit! ");
121
    return 0;
122
    }
123

  
124
///////////////////////////////////////////////////////////////////////////////////////////////////
125
// If we have a flat cuboid than retCubitSolvedStatus() wrongly reports that the internal cubits
126
// are edges (they do have two non-black faces after all!) which leads to wrong solvedQuats and
127
// mis-detection of a solved status. Correct this manually here.
128
//
129
// Note that this is still not completely good in case of bandaged cuboids - there can be a 4x4x2
130
// bandaged cuboid whose 4 'internal' cubits from the 4x4 face are fused with the other 4 internal
131
// cubits from the other 4x4 face - and those would again get mis-detected as edges...
132

  
133
  @Override
134
  public int[][] getSolvedQuats()
135
    {
136
    if( mSolvedQuatsAbstract==null )
137
      {
138
      int[] numLayers = getNumLayers();
139
      float dx = 0.5f*(numLayers[0]-1) - 0.1f;
140
      float dy = 0.5f*(numLayers[1]-1) - 0.1f;
141
      float dz = 0.5f*(numLayers[2]-1) - 0.1f;
142

  
143
      float[][] pos = getPositions();
144
      int numTotal = pos.length;
145
      boolean[] isExternal = new boolean[numTotal];
146
      int[] internalQuat = new int[numTotal];
147
      int numExternal = 0;
148
      int pointer = 0;
149

  
150
      for(int cubit=0; cubit<numTotal; cubit++)
151
        {
152
        int q = cubitIsExternal(pos[cubit],dx,dy,dz);
153

  
154
        if( q<=0 )
155
          {
156
          isExternal[cubit] = true;
157
          numExternal++;
158
          }
159
        else
160
          {
161
          isExternal[cubit] = false;
162
          internalQuat[pointer] = q;
163
          pointer++;
164
          }
165
        }
166

  
167
      int numInternal = numTotal - numExternal;
168

  
169
      mSolvedQuatsAbstract = new int[numInternal+1][];
170
      mSolvedQuatsAbstract[0] = new int[numExternal+1];
171
      mSolvedQuatsAbstract[0][0] = numExternal;
172

  
173
      for(int i=0; i<numInternal; i++)
174
        {
175
        int q = internalQuat[i];
176
        mSolvedQuatsAbstract[i+1] = new int[5];
177
        mSolvedQuatsAbstract[i+1][0] = 1;
178
        mSolvedQuatsAbstract[i+1][2] = q;
179
        mSolvedQuatsAbstract[i+1][3] = q+1;
180
        mSolvedQuatsAbstract[i+1][4] = q+2;
181
        }
182

  
183
      int pointerExternal = 1;
184
      int pointerInternal = 1;
185

  
186
      for(int cubit=0; cubit<numTotal; cubit++)
187
        {
188
        if( isExternal[cubit] ) mSolvedQuatsAbstract[0][pointerExternal++] = cubit;
189
        else                    mSolvedQuatsAbstract[pointerInternal++][1] = cubit;
190
        }
191
      }
192

  
193
    return mSolvedQuatsAbstract;
194
    }
195

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

  
198
  public ObjectSignature getSignature()
199
    {
200
    long signature = 0;
201
    float[][] positions = getPositions();
202
    for(float[] pos : positions ) signature = markConnections(signature,pos);
203

  
204
    return new ObjectSignature(signature);
205
    }
206

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

  
209
  public ScrambleState[] getScrambleStates()
210
    {
211
    if( mStates==null && !isInIconMode() )
212
      {
213
      ObjectSignature signature = getSignature();
214
      mStates = ScrambleStateBandaged3x3.computeGraph(signature.getLong3());
215
      }
216

  
217
    return mStates;
218
    }
219

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

  
222
  private int getType(float[] pos)
223
    {
224
    switch(pos.length)
225
      {
226
      case  3: return CUBIT_111;
227
      case  6: return CUBIT_211;
228
      case  9: boolean x1 = (pos[0]==pos[3] && pos[0]==pos[6]);
229
               boolean y1 = (pos[1]==pos[4] && pos[1]==pos[7]);
230
               boolean z1 = (pos[2]==pos[5] && pos[2]==pos[8]);
231
               return ( (x1&&y1) || (x1&&z1) || (y1&&z1) ) ? CUBIT_311 : CUBIT_OTH;
232
      case 12: float x = (pos[0]+pos[3]+pos[6]+pos[ 9])/4;
233
               float y = (pos[1]+pos[4]+pos[7]+pos[10])/4;
234
               float z = (pos[2]+pos[5]+pos[8]+pos[11])/4;
235
               float d1 = (pos[0]-x)*(pos[0]-x) + (pos[ 1]-y)*(pos[ 1]-y) + (pos[ 2]-z)*(pos[ 2]-z);
236
               float d2 = (pos[3]-x)*(pos[3]-x) + (pos[ 4]-y)*(pos[ 4]-y) + (pos[ 5]-z)*(pos[ 5]-z);
237
               float d3 = (pos[6]-x)*(pos[6]-x) + (pos[ 7]-y)*(pos[ 7]-y) + (pos[ 8]-z)*(pos[ 8]-z);
238
               float d4 = (pos[9]-x)*(pos[9]-x) + (pos[10]-y)*(pos[10]-y) + (pos[11]-z)*(pos[11]-z);
239
               return ( d1==0.5f && d2==0.5f && d3==0.5f && d4==0.5f ) ? CUBIT_221 : CUBIT_OTH;
240
      case 24: float x3 = pos[0];
241
               float y3 = pos[1];
242
               float z3 = pos[2];
243
               float x4=-10,y4=-10,z4=-10;
244
               int i;
245

  
246
               for(i=0; i<8; i++)
247
                 {
248
                 if( pos[3*i]!=x3 && pos[3*i+1]!=y3 && pos[3*i+2]!=z3 )
249
                   {
250
                   x4 = pos[3*i  ];
251
                   y4 = pos[3*i+1];
252
                   z4 = pos[3*i+2];
253
                   break;
254
                   }
255
                 }
256
               if( i==9 ) return CUBIT_OTH;
257

  
258
               float dX = x4-x3;
259
               float dY = y4-y3;
260
               float dZ = z4-z3;
261

  
262
               if( (dX==1.0f || dX==-1.0f) && (dY==1.0f || dY==-1.0f) && (dZ==1.0f || dZ==-1.0f) )
263
                 {
264
                 for(i=0; i<8; i++)
265
                   {
266
                   if( (pos[3*i  ]!=x3 && pos[3*i  ]!=x4) ||
267
                       (pos[3*i+1]!=y3 && pos[3*i+1]!=y4) ||
268
                       (pos[3*i+2]!=z3 && pos[3*i+2]!=z4)  ) return CUBIT_OTH;
269
                   }
270

  
271
                 return CUBIT_222;
272
                 }
273

  
274
      default: return CUBIT_OTH;
275
      }
276
    }
277

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

  
280
  private int getQuatIndex(int cubit)
281
    {
282
    float[][] positions = getPositions();
283
    int len = positions.length;
284

  
285
    if( cubit>=0 && cubit<len )
286
      {
287
      float[] pos = positions[cubit];
288
      int type = getType(pos);
289

  
290
      switch(type)
291
        {
292
        case CUBIT_222:
293
        case CUBIT_111: return 0;
294
        case CUBIT_211:
295
        case CUBIT_311: return (pos[1]==pos[4]) ? (pos[0]==pos[3] ? 2 : 0) : 3;
296
        case CUBIT_221: if( pos[0]==pos[3] && pos[0]==pos[6] ) return 3;
297
                        if( pos[1]==pos[4] && pos[1]==pos[7] ) return 0;
298
                        if( pos[2]==pos[5] && pos[2]==pos[8] ) return 1;
299
        }
300
      }
301

  
302
    return 0;
303
    }
304

  
305
///////////////////////////////////////////////////////////////////////////////////////////////////
306

  
307
  private int getSigIndex(float x, float y, float z)
308
    {
309
    if( x==-1.0f )
310
      {
311
           if( y==-1.0f ) return z==0.5f ? 4:9;
312
      else if( y==-0.5f ) return z==1.0f ? 14 : (z==0.0f ? 17:20);
313
      else if( y== 0.0f ) return z==0.5f ? 25:30;
314
      else if( y== 0.5f ) return z==1.0f ? 35 : (z==0.0f ? 38:41);
315
      else if( y== 1.0f ) return z==0.5f ? 46:51;
316
      }
317
    else if( x==-0.5f )
318
      {
319
           if( y==-1.0f ) return z==1.0f ? 1  : (z==0.0f ?  6:11);
320
      else if( y== 0.0f ) return z==1.0f ? 22 : (z==0.0f ? 27:32);
321
      else if( y== 1.0f ) return z==1.0f ? 43 : (z==0.0f ? 48:53);
322
      }
323
    else if( x==0.0f )
324
      {
325
           if( y==-1.0f ) return z==0.5f ? 3:8;
326
      else if( y==-0.5f ) return z==1.0f ? 13 : (z==0.0f ? 16:19);
327
      else if( y== 0.0f ) return z==0.5f ? 24:29;
328
      else if( y== 0.5f ) return z==1.0f ? 34 : (z==0.0f ? 37:40);
329
      else if( y== 1.0f ) return z==0.5f ? 45:50;
330
      }
331
    else if( x==0.5f )
332
      {
333
           if( y==-1.0f ) return z==1.0f ? 0  : (z==0.0f ?  5:10);
334
      else if( y== 0.0f ) return z==1.0f ? 21 : (z==0.0f ? 26:31);
335
      else if( y== 1.0f ) return z==1.0f ? 42 : (z==0.0f ? 47:52);
336
      }
337
    else if( x==1.0f )
338
      {
339
           if( y==-1.0f ) return z==0.5f ? 2:7;
340
      else if( y==-0.5f ) return z==1.0f ? 12 : (z==0.0f ? 15:18);
341
      else if( y== 0.0f ) return z==0.5f ? 23:28;
342
      else if( y== 0.5f ) return z==1.0f ? 33 : (z==0.0f ? 36:39);
343
      else if( y== 1.0f ) return z==0.5f ? 44:49;
344
      }
345
    else
346
      {
347
      android.util.Log.e("D", "ERROR! mx="+x);
348
      }
349

  
350
    return -1;
351
    }
352

  
353
///////////////////////////////////////////////////////////////////////////////////////////////////
354

  
355
  private long markConnection(float x1, float y1, float z1, float x2, float y2, float z2)
356
    {
357
    float dx = x1-x2;
358
    float dy = y1-y2;
359
    float dz = z1-z2;
360

  
361
    if( (dx==0 && dy==0 && (dz==1 || dz==-1) ) ||
362
        (dz==0 && dx==0 && (dy==1 || dy==-1) ) ||
363
        (dy==0 && dz==0 && (dx==1 || dx==-1) )  )
364
      {
365
      float mx = (x1+x2)/2;
366
      float my = (y1+y2)/2;
367
      float mz = (z1+z2)/2;
368

  
369
      int index = getSigIndex(mx,my,mz);
370

  
371
      return (1L<<index);
372
      }
373

  
374
    return 0;
375
    }
376

  
377
///////////////////////////////////////////////////////////////////////////////////////////////////
378

  
379
  long markConnections(long signature, float[] position)
380
    {
381
    int len = position.length/3;
382

  
383
    for(int i=0; i<len; i++)
384
      {
385
      float x = position[3*i  ];
386
      float y = position[3*i+1];
387
      float z = position[3*i+2];
388

  
389
      for(int j=i+1; j<len; j++)
390
        {
391
        signature |= markConnection(x,y,z,position[3*j],position[3*j+1],position[3*j+2]);
392
        }
393
      }
394

  
395
    return signature;
396
    }
397

  
398
///////////////////////////////////////////////////////////////////////////////////////////////////
399

  
400
  public ObjectShape getObjectShape(int variant)
401
    {
402
    int type,numTypes = mDims.length;
403
    for(type=0; type<numTypes; type++) if( mTypeVariantMap[type]==variant ) break;
404

  
405
    if( type<numTypes )
406
      {
407
      int X = mDims[type][0];
408
      int Y = mDims[type][1];
409
      int Z = mDims[type][2];
410

  
411
      float[][] vertices =
412
        {
413
          {+0.5f*X,+0.5f*Y,+0.5f*Z},
414
          {+0.5f*X,+0.5f*Y,-0.5f*Z},
415
          {+0.5f*X,-0.5f*Y,+0.5f*Z},
416
          {+0.5f*X,-0.5f*Y,-0.5f*Z},
417
          {-0.5f*X,+0.5f*Y,+0.5f*Z},
418
          {-0.5f*X,+0.5f*Y,-0.5f*Z},
419
          {-0.5f*X,-0.5f*Y,+0.5f*Z},
420
          {-0.5f*X,-0.5f*Y,-0.5f*Z}
421
        };
422

  
423
      int[][] indices =
424
        {
425
          {2,3,1,0},
426
          {7,6,4,5},
427
          {4,0,1,5},
428
          {7,3,2,6},
429
          {6,2,0,4},
430
          {3,7,5,1},
431
        };
432

  
433
      return new ObjectShape(vertices, indices);
434
      }
435

  
436
    float[][] positions = getPositions();
437
    int cubit,numCubits = positions.length;
438

  
439
    for(cubit=0; cubit<numCubits; cubit++)
440
      {
441
      if( mCubitVariantMap[cubit]==variant ) break;
442
      }
443

  
444
    if( cubit>=numCubits )
445
      {
446
      android.util.Log.e("D", "unknown variant: "+variant);
447
      return null;
448
      }
449

  
450
    FactoryBandagedCubit factory = FactoryBandagedCubit.getInstance();
451
    return factory.createIrregularShape(variant,positions[cubit]);
452
    }
453

  
454
///////////////////////////////////////////////////////////////////////////////////////////////////
455

  
456
  public ObjectFaceShape getObjectFaceShape(int variant)
457
    {
458
    boolean roundCorners = DistortedLibrary.fastCompilationTF();
459
    int type,numTypes = mDims.length;
460
    for(type=0; type<numTypes; type++) if( mTypeVariantMap[type]==variant ) break;
461

  
462
    if( type<numTypes )
463
      {
464
      int val = roundCorners ? 0 : -1;
465
      int X = mDims[type][0];
466
      int Y = mDims[type][1];
467
      int Z = mDims[type][2];
468

  
469
      float height        = isInIconMode() ? 0.001f : 0.048f;
470
      int[] bandIndices   = { 0,0,1,1,2,2 };
471
      float[][] corners   = { {0.04f,0.15f} };
472
      int[] cornerIndices = { val,val,val,val,val,val,val,val };
473
      int[] centerIndices = { 0,1,2,3,4,5,6,7 };
474

  
475
      int maxXY = Math.max(X,Y);
476
      int maxXZ = Math.max(X,Z);
477
      int maxYZ = Math.max(Y,Z);
478

  
479
      int angle = 45;
480
      float R = 0.25f;
481
      float S = 0.50f;
482

  
483
      float[][] bands =
484
        {
485
          {height/maxYZ,angle,R,S,5,0,0},
486
          {height/maxXZ,angle,R,S,5,0,0},
487
          {height/maxXY,angle,R,S,5,0,0}
488
        };
489

  
490
      float[][] centers =
491
        {
492
          {+0.5f*(X-1),+0.5f*(Y-1),+0.5f*(Z-1)},
493
          {+0.5f*(X-1),+0.5f*(Y-1),-0.5f*(Z-1)},
494
          {+0.5f*(X-1),-0.5f*(Y-1),+0.5f*(Z-1)},
495
          {+0.5f*(X-1),-0.5f*(Y-1),-0.5f*(Z-1)},
496
          {-0.5f*(X-1),+0.5f*(Y-1),+0.5f*(Z-1)},
497
          {-0.5f*(X-1),+0.5f*(Y-1),-0.5f*(Z-1)},
498
          {-0.5f*(X-1),-0.5f*(Y-1),+0.5f*(Z-1)},
499
          {-0.5f*(X-1),-0.5f*(Y-1),-0.5f*(Z-1)}
500
        };
501

  
502
      return new ObjectFaceShape(bands,bandIndices,corners,cornerIndices,centers,centerIndices,null);
503
      }
504

  
505
    FactoryBandagedCubit factory = FactoryBandagedCubit.getInstance();
506
    return factory.createIrregularFaceShape(variant, isInIconMode(), roundCorners );
507
    }
508

  
509
///////////////////////////////////////////////////////////////////////////////////////////////////
510

  
511
  public float[][] getCubitPositions(int[] numLayers)
512
    {
513
    return getPositions();
514
    }
515

  
516
///////////////////////////////////////////////////////////////////////////////////////////////////
517

  
518
  public Static4D getCubitQuats(int cubit, int[] numLayers)
519
    {
520
    if( mInitQuats ==null )
521
      {
522
      mInitQuats = new Static4D[]
523
        {
524
        new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),  // NULL
525
        new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),  // X
526
        new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),  // Y
527
        new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),  // Z
528
        new Static4D( -0.5f,  +0.5f,  -0.5f,  +0.5f),  // ZX
529
        new Static4D( +0.5f,  +0.5f,  +0.5f,  -0.5f),  // YX
530
        };
531
      }
532

  
533
    return mInitQuats[getQuatIndex(cubit)];
534
    }
535

  
536
///////////////////////////////////////////////////////////////////////////////////////////////////
537

  
538
  public int getNumCubitVariants(int[] numLayers)
539
    {
540
    int numVariants = 0;
541
    float[][] positions = getPositions();
542
    boolean C111=false;
543
    boolean C211=false;
544
    boolean C311=false;
545
    boolean C221=false;
546
    boolean C222=false;
547

  
548
    int numCubits = positions.length;
549
    mCubitVariantMap = new int[numCubits];
550

  
551
    int numTypes = mDims.length;
552
    mTypeVariantMap = new int[numTypes];
553
    for(int i=0; i<numTypes; i++) mTypeVariantMap[i] = -1;
554

  
555
    for (int cubit=0; cubit<numCubits; cubit++)
556
      {
557
      int type = getType(positions[cubit]);
558

  
559
      switch (type)
560
        {
561
        case CUBIT_111: if (!C111) { C111 = true; mTypeVariantMap[CUBIT_111]=numVariants++; }
562
                        mCubitVariantMap[cubit]=mTypeVariantMap[CUBIT_111];
563
                        break;
564
        case CUBIT_211: if (!C211) { C211 = true; mTypeVariantMap[CUBIT_211]=numVariants++; }
565
                        mCubitVariantMap[cubit]=mTypeVariantMap[CUBIT_211];
566
                        break;
567
        case CUBIT_311: if (!C311) { C311 = true; mTypeVariantMap[CUBIT_311]=numVariants++; }
568
                        mCubitVariantMap[cubit]=mTypeVariantMap[CUBIT_311];
569
                        break;
570
        case CUBIT_221: if (!C221) { C221 = true; mTypeVariantMap[CUBIT_221]=numVariants++; }
571
                        mCubitVariantMap[cubit]=mTypeVariantMap[CUBIT_221];
572
                        break;
573
        case CUBIT_222: if (!C222) { C222 = true; mTypeVariantMap[CUBIT_222]=numVariants++; }
574
                        mCubitVariantMap[cubit]=mTypeVariantMap[CUBIT_222];
575
                        break;
576
        default       : mCubitVariantMap[cubit] = numVariants++;
577
        }
578
      }
579

  
580
    FactoryBandagedCubit factory = FactoryBandagedCubit.getInstance();
581
    factory.prepare(numVariants,numLayers[0],numLayers[1],numLayers[2]);
582

  
583
    return numVariants;
584
    }
585

  
586
///////////////////////////////////////////////////////////////////////////////////////////////////
587

  
588
  public int getCubitVariant(int cubit, int[] numLayers)
589
    {
590
    return mCubitVariantMap[cubit];
591
    }
592

  
593
///////////////////////////////////////////////////////////////////////////////////////////////////
594

  
595
  public float[][] getCuts(int[] numLayers)
596
    {
597
    if( mCuts==null )
598
      {
599
      mCuts = new float[3][];
600

  
601
      for(int axis=0; axis<3; axis++)
602
        {
603
        int len = numLayers[axis];
604
        float start = (2-len)*0.5f;
605

  
606
        if( len>=2 )
607
          {
608
          mCuts[axis] = new float[len-1];
609
          for(int i=0; i<len-1; i++) mCuts[axis][i] = start+i;
610
          }
611
        }
612
      }
613

  
614
    return mCuts;
615
    }
616

  
617
///////////////////////////////////////////////////////////////////////////////////////////////////
618

  
619
  public boolean[][] getLayerRotatable(int[] numLayers)
620
    {
621
    int numAxis = ROT_AXIS.length;
622
    boolean[][] layerRotatable = new boolean[numAxis][];
623

  
624
    for(int i=0; i<numAxis; i++)
625
      {
626
      layerRotatable[i] = new boolean[numLayers[i]];
627
      for(int j=0; j<numLayers[i]; j++) layerRotatable[i][j] = true;
628
      }
629

  
630
    return layerRotatable;
631
    }
632

  
633
///////////////////////////////////////////////////////////////////////////////////////////////////
634

  
635
  public int getTouchControlType()
636
    {
637
    return TC_CUBOID;
638
    }
639

  
640
///////////////////////////////////////////////////////////////////////////////////////////////////
641

  
642
  public int getTouchControlSplit()
643
    {
644
    return TYPE_NOT_SPLIT;
645
    }
646

  
647
///////////////////////////////////////////////////////////////////////////////////////////////////
648

  
649
  public int[][][] getEnabled()
650
    {
651
    return new int[][][] { {{1,2}},{{1,2}},{{0,2}},{{0,2}},{{0,1}},{{0,1}} };
652
    }
653

  
654
///////////////////////////////////////////////////////////////////////////////////////////////////
655

  
656
  public float[] getDist3D(int[] numLayers)
657
    {
658
    float x = numLayers[0];
659
    float y = numLayers[1];
660
    float z = numLayers[2];
661
    float a = (x+y+z)/1.5f;
662

  
663
    return new float[] {x/a,x/a,y/a,y/a,z/a,z/a};
664
    }
665

  
666
///////////////////////////////////////////////////////////////////////////////////////////////////
667

  
668
  public Static3D[] getFaceAxis()
669
    {
670
    return TouchControlHexahedron.FACE_AXIS;
671
    }
672

  
673
///////////////////////////////////////////////////////////////////////////////////////////////////
674

  
675
  public float getStickerRadius()
676
    {
677
    return 0.10f;
678
    }
679

  
680
///////////////////////////////////////////////////////////////////////////////////////////////////
681

  
682
  public float getStickerStroke()
683
    {
684
    return isInIconMode() ? 0.16f : 0.08f;
685
    }
686

  
687
///////////////////////////////////////////////////////////////////////////////////////////////////
688

  
689
  public float[][] getStickerAngles()
690
    {
691
    return null;
692
    }
693

  
694
///////////////////////////////////////////////////////////////////////////////////////////////////
695
// PUBLIC API
696

  
697
  public Static3D[] getRotationAxis()
698
    {
699
    return ROT_AXIS;
700
    }
701

  
702
///////////////////////////////////////////////////////////////////////////////////////////////////
703

  
704
  public int[][] getBasicAngles()
705
    {
706
     if( mBasicAngle==null )
707
      {
708
      int[] num = getNumLayers();
709
      int numX = num[0];
710
      int numY = num[1];
711
      int numZ = num[2];
712

  
713
      int x = numY==numZ ? 4 : 2;
714
      int y = numX==numZ ? 4 : 2;
715
      int z = numX==numY ? 4 : 2;
716

  
717
      int[] tmpX = new int[numX];
718
      for(int i=0; i<numX; i++) tmpX[i] = x;
719
      int[] tmpY = new int[numY];
720
      for(int i=0; i<numY; i++) tmpY[i] = y;
721
      int[] tmpZ = new int[numZ];
722
      for(int i=0; i<numZ; i++) tmpZ[i] = z;
723

  
724
      mBasicAngle = new int[][] { tmpX,tmpY,tmpZ };
725
      }
726

  
727
    return mBasicAngle;
728
    }
729
}
src/main/java/org/distorted/objectlib/objects/TwistyBandagedBiCube.java
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 java.io.InputStream;
23

  
24
import org.distorted.library.type.Static3D;
25
import org.distorted.library.type.Static4D;
26

  
27
import org.distorted.objectlib.helpers.ObjectSignature;
28
import org.distorted.objectlib.main.InitData;
29
import org.distorted.objectlib.main.ObjectType;
30

  
31
///////////////////////////////////////////////////////////////////////////////////////////////////
32

  
33
public class TwistyBandagedBiCube extends TwistyBandagedAbstract
34
{
35
  public TwistyBandagedBiCube(InitData data, int meshState, int iconMode, Static4D quat, Static3D move, float scale, InputStream stream)
36
    {
37
    super(data, meshState, iconMode, quat, move, scale, stream);
38
    }
39

  
40
///////////////////////////////////////////////////////////////////////////////////////////////////
41

  
42
  float[][] getPositions()
43
    {
44
    if( POSITIONS==null )
45
      {
46
      POSITIONS = new float[][]
47
        {
48
          { 1.0f,  1.0f, -1.0f},
49
          {-1.0f, -1.0f,  0.0f, -1.0f,  0.0f,  0.0f, 0.0f, -1.0f,  0.0f,  0.0f,  0.0f,  0.0f},
50
          {-1.0f,  1.0f, -1.0f,  0.0f,  1.0f, -1.0f},
51
          {-1.0f,  0.0f, -1.0f,  0.0f,  0.0f, -1.0f},
52
          {-1.0f, -1.0f, -1.0f,  0.0f, -1.0f, -1.0f},
53
          {-1.0f,  1.0f,  0.0f, -1.0f,  1.0f,  1.0f},
54
          { 0.0f,  1.0f,  0.0f,  0.0f,  1.0f,  1.0f},
55
          { 1.0f,  1.0f,  0.0f,  1.0f,  1.0f,  1.0f},
56
          {-1.0f, -1.0f,  1.0f, -1.0f,  0.0f,  1.0f},
57
          { 0.0f, -1.0f,  1.0f,  0.0f,  0.0f,  1.0f},
58
          { 1.0f, -1.0f,  1.0f,  1.0f,  0.0f,  1.0f},
59
          { 1.0f, -1.0f,  0.0f,  1.0f,  0.0f,  0.0f},
60
          { 1.0f, -1.0f, -1.0f,  1.0f,  0.0f, -1.0f}
61
        };
62
      }
63
    return POSITIONS;
64
    }
65

  
66
///////////////////////////////////////////////////////////////////////////////////////////////////
67
// PUBLIC API
68

  
69
  public String getShortName()
70
    {
71
    return ObjectType.BAN4_3.name();
72
    }
73

  
74
///////////////////////////////////////////////////////////////////////////////////////////////////
75

  
76
  public ObjectSignature getSignature()
77
    {
78
    return new ObjectSignature(ObjectType.BAN4_3);
79
    }
80

  
81
///////////////////////////////////////////////////////////////////////////////////////////////////
82

  
83
  public String getObjectName()
84
    {
85
    return "BiCube";
86
    }
87

  
88
///////////////////////////////////////////////////////////////////////////////////////////////////
89

  
90
  public String getInventor()
91
    {
92
    return "Uwe Meffert";
93
    }
94

  
95
///////////////////////////////////////////////////////////////////////////////////////////////////
96

  
97
  public int getYearOfInvention()
98
    {
99
    return 1999;
100
    }
101

  
102
///////////////////////////////////////////////////////////////////////////////////////////////////
103

  
104
  public int getComplexity()
105
    {
106
    return 3;
107
    }
108

  
109
///////////////////////////////////////////////////////////////////////////////////////////////////
110

  
111
  public String[][] getTutorials()
112
    {
113
    return new String[][]{
114
                          {"gb","AnpdIKICBpM","Trying to Solve a Bandaged Cube","RedKB"},
115
                          {"es","cUyo5fycrvI","Tutorial Bandaged Cube en español","Rafa Garcia Benacazon"},
116
                          {"ru","-MTzeEJptsg","Как собрать bandaged Cube B","стратегия знаний"},
117
                          {"fr","3rsfIJ3roT0","Tutoriel: résolution du Bicube","Skieur Cubb"},
118
                          {"de","sqWVRwkXX9w","Bandaged Cube - Tutorial","GerCubing"},
119
                          {"pl","XcHzTvVR6Po","Bandaged 3x3 v.B cube","MrUK"},
120
                          {"kr","1gsoijF_5q0","BiCube Tutorial (해법)","듀나메스 큐브 해법연구소"},
121
                          {"vn","ZCJDaF4jEbc","Tutorial N.3 - BiCube","Duy Thích Rubik"},
122
                         };
123
    }
124
}
src/main/java/org/distorted/objectlib/objects/TwistyBandagedCuboid.java
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.helpers.ObjectSignature;
34
import org.distorted.objectlib.main.InitData;
35
import org.distorted.objectlib.main.ObjectType;
36
import org.distorted.objectlib.touchcontrol.TouchControlHexahedron;
37
import org.distorted.objectlib.helpers.ObjectShape;
38
import org.distorted.objectlib.scrambling.ScrambleState;
39
import org.distorted.objectlib.main.ShapeHexahedron;
40

  
41
///////////////////////////////////////////////////////////////////////////////////////////////////
42

  
43
public class TwistyBandagedCuboid extends ShapeHexahedron
44
{
45
  private static final String OBJECT_NAME = "LOCAL_BANDAGED";
46

  
47
  private static final int CUBIT_111 = 0;
48
  private static final int CUBIT_211 = 1;
49
  private static final int CUBIT_311 = 2;
50
  private static final int CUBIT_221 = 3;
51
  private static final int CUBIT_222 = 4;
52
  private static final int CUBIT_OTH = 5;
53

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

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

  
71
  public static final float[][] POS_1 = new float[][]
72
        {
73
          {-1.0f, -1.0f, +0.0f,
74
           -1.0f, -1.0f, +1.0f,
75
           -1.0f,  0.0f, +0.0f,
76
           -1.0f,  0.0f, +1.0f,
77
            0.0f, -1.0f, +0.0f,
78
            0.0f, -1.0f, +1.0f,
79
            0.0f,  0.0f, +0.0f,
80
            0.0f,  0.0f, +1.0f},
81
          {-1.0f, +1.0f, +1.0f},
82
          {-1.0f, +1.0f, +0.0f},
83
          {-1.0f, +1.0f, -1.0f},
84
          { 0.0f, +1.0f, +1.0f},
85
          { 0.0f, +1.0f, +0.0f},
86
          { 0.0f, +1.0f, -1.0f},
87
          { 1.0f, +1.0f, +1.0f},
88
          { 1.0f, +1.0f, +0.0f},
89
          { 1.0f, +1.0f, -1.0f},
90
          { 1.0f,  0.0f, +1.0f},
91
          { 1.0f,  0.0f, +0.0f},
92
          { 1.0f,  0.0f, -1.0f},
93
          { 1.0f, -1.0f, +1.0f},
94
          { 1.0f, -1.0f, +0.0f},
95
          { 1.0f, -1.0f, -1.0f},
96
          {-1.0f, -1.0f, -1.0f},
97
          {-1.0f,  0.0f, -1.0f},
98
          { 0.0f, -1.0f, -1.0f},
99
          { 0.0f,  0.0f, -1.0f}
100
        };
101

  
102
  public static final float[][] POS_2 = new float[][]
103
        {
104
          { 0.0f, +1.0f,  1.0f, 0.0f, +1.0f,  0.0f, 0.0f, +1.0f, -1.0f},
105
          {-1.0f, -1.0f,  0.0f, 0.0f, -1.0f,  0.0f, 1.0f, -1.0f,  0.0f},
106
          {-1.0f, +1.0f, +1.0f},
107
          {-1.0f, +1.0f,  0.0f},
108
          {-1.0f, +1.0f, -1.0f},
109
          {-1.0f,  0.0f, +1.0f},
110
          {-1.0f,  0.0f,  0.0f},
111
          {-1.0f,  0.0f, -1.0f},
112
          {-1.0f, -1.0f, +1.0f},
113
          {-1.0f, -1.0f, -1.0f},
114
          {+1.0f, +1.0f, +1.0f},
115
          {+1.0f, +1.0f,  0.0f},
116
          {+1.0f, +1.0f, -1.0f},
117
          {+1.0f,  0.0f, +1.0f},
118
          {+1.0f,  0.0f,  0.0f},
119
          {+1.0f,  0.0f, -1.0f},
120
          {+1.0f, -1.0f, +1.0f},
121
          {+1.0f, -1.0f, -1.0f},
122
          { 0.0f,  0.0f, +1.0f},
123
          { 0.0f, -1.0f, +1.0f},
124
          { 0.0f,  0.0f, -1.0f},
125
          { 0.0f, -1.0f, -1.0f}
126
        };
127

  
128
  public static final float[][] POS_3 = new float[][]
129
        {
130
          {-1.0f,  1.0f,  1.0f, -1.0f,  0.0f,  1.0f,  0.0f,  1.0f,  1.0f,  0.0f,  0.0f,  1.0f},
131
          { 1.0f,  0.0f, -1.0f,  1.0f,  0.0f,  0.0f,  1.0f,  1.0f, -1.0f,  1.0f,  1.0f,  0.0f},
132
          {-1.0f, -1.0f, -1.0f, -1.0f, -1.0f,  0.0f,  0.0f, -1.0f, -1.0f,  0.0f, -1.0f,  0.0f},
133
          { 1.0f,  1.0f,  1.0f},
134
          { 1.0f,  0.0f,  1.0f},
135
          { 1.0f, -1.0f,  1.0f},
136
          {-1.0f, -1.0f,  1.0f},
137
          { 0.0f, -1.0f,  1.0f},
138
          { 1.0f, -1.0f,  0.0f},
139
          { 1.0f, -1.0f, -1.0f},
140
          {-1.0f,  1.0f, -1.0f},
141
          {-1.0f,  1.0f,  0.0f},
142
          { 0.0f,  1.0f, -1.0f},
143
          { 0.0f,  1.0f,  0.0f},
144
          {-1.0f,  0.0f, -1.0f},
145
          {-1.0f,  0.0f,  0.0f},
146
          { 0.0f,  0.0f, -1.0f}
147
        };
148

  
149
  public static final float[][] POS_4 = new float[][]
150
        {
151
          { 1.0f,  1.0f, -1.0f},
152
          {-1.0f, -1.0f,  0.0f, -1.0f,  0.0f,  0.0f, 0.0f, -1.0f,  0.0f,  0.0f,  0.0f,  0.0f},
153
          {-1.0f,  1.0f, -1.0f,  0.0f,  1.0f, -1.0f},
154
          {-1.0f,  0.0f, -1.0f,  0.0f,  0.0f, -1.0f},
155
          {-1.0f, -1.0f, -1.0f,  0.0f, -1.0f, -1.0f},
156
          {-1.0f,  1.0f,  0.0f, -1.0f,  1.0f,  1.0f},
157
          { 0.0f,  1.0f,  0.0f,  0.0f,  1.0f,  1.0f},
158
          { 1.0f,  1.0f,  0.0f,  1.0f,  1.0f,  1.0f},
159
          {-1.0f, -1.0f,  1.0f, -1.0f,  0.0f,  1.0f},
160
          { 0.0f, -1.0f,  1.0f,  0.0f,  0.0f,  1.0f},
161
          { 1.0f, -1.0f,  1.0f,  1.0f,  0.0f,  1.0f},
162
          { 1.0f, -1.0f,  0.0f,  1.0f,  0.0f,  0.0f},
163
          { 1.0f, -1.0f, -1.0f,  1.0f,  0.0f, -1.0f}
164
        };
165

  
166
  private int[][] mBasicAngle;
167
  private Static4D[] mInitQuats;
168
  private float[][] mCuts;
169
  private int[] mCubitVariantMap;
170
  private int[] mTypeVariantMap;
171
  private int[][] mSolvedQuatsAbstract;
172
  private float[][] mPosition;
173
  private ObjectSignature mSignature;
174

  
175
///////////////////////////////////////////////////////////////////////////////////////////////////
176

  
177
  public TwistyBandagedCuboid(InitData data, int meshState, int iconMode, Static4D quat, Static3D move, float scale, InputStream stream)
178
    {
179
    super(data, meshState, iconMode, (data.getNumLayers()[0]+data.getNumLayers()[1]+data.getNumLayers()[2])/3.0f, quat, move, scale, stream);
180
    }
181

  
182
///////////////////////////////////////////////////////////////////////////////////////////////////
183
// return 0 if cubit is 'external' (it has at least two walls which belong to two different faces
184
// of the cuboid, faces which do not both rotate along the same axis! So: it is an edge, a corner,
185
// or a bandaged cubit which 'comes out' in two different, non-opposite, faces.
186
// Otherwise, if the cubit only comes out in one face or in two faces which are opposite to each other,
187
// return the index of the first of the three quats which rotate stuff in this face (so right or left
188
// return 1 because quats 1,2,3 are the ones rotating along the X axis)
189

  
190
  private int cubitIsExternal(float[] pos, float dx, float dy, float dz)
191
    {
192
    int len = pos.length/3;
193
    int x=0, y=0, z=0;
194

  
195
    for(int i=0; i<len; i++)
196
      {
197
      float cx = pos[3*i  ];
198
      float cy = pos[3*i+1];
199
      float cz = pos[3*i+2];
200

  
201
      if( cx>dx || cx<-dx ) x=1;
202
      if( cy>dy || cy<-dy ) y=1;
203
      if( cz>dz || cz<-dz ) z=1;
204
      }
205

  
206
    if( x+y+z>=2 ) return 0;
207

  
208
    if( x==1 ) return 1;
209
    if( y==1 ) return 4;
210
    if( z==1 ) return 7;
211

  
212
    android.util.Log.e("D", "ERROR: unsupported: internal cubit! ");
213
    return 0;
214
    }
215

  
216
///////////////////////////////////////////////////////////////////////////////////////////////////
217
// If we have a flat cuboid than retCubitSolvedStatus() wrongly reports that the internal cubits
218
// are edges (they do have two non-black faces after all!) which leads to wrong solvedQuats and
219
// mis-detection of a solved status. Correct this manually here.
220
//
221
// Note that this is still not completely good in case of bandaged cuboids - there can be a 4x4x2
222
// bandaged cuboid whose 4 'internal' cubits from the 4x4 face are fused with the other 4 internal
223
// cubits from the other 4x4 face - and those would again get mis-detected as edges...
224

  
225
  @Override
226
  public int[][] getSolvedQuats()
227
    {
228
    if( mSolvedQuatsAbstract==null )
229
      {
230
      int[] numLayers = getNumLayers();
231
      float dx = 0.5f*(numLayers[0]-1) - 0.1f;
232
      float dy = 0.5f*(numLayers[1]-1) - 0.1f;
233
      float dz = 0.5f*(numLayers[2]-1) - 0.1f;
234

  
235
      float[][] pos = getPositions();
236
      int numTotal = pos.length;
237
      boolean[] isExternal = new boolean[numTotal];
238
      int[] internalQuat = new int[numTotal];
239
      int numExternal = 0;
240
      int pointer = 0;
241

  
242
      for(int cubit=0; cubit<numTotal; cubit++)
243
        {
244
        int q = cubitIsExternal(pos[cubit],dx,dy,dz);
245

  
246
        if( q<=0 )
247
          {
248
          isExternal[cubit] = true;
249
          numExternal++;
250
          }
251
        else
252
          {
253
          isExternal[cubit] = false;
254
          internalQuat[pointer] = q;
255
          pointer++;
256
          }
257
        }
258

  
259
      int numInternal = numTotal - numExternal;
260

  
261
      mSolvedQuatsAbstract = new int[numInternal+1][];
262
      mSolvedQuatsAbstract[0] = new int[numExternal+1];
263
      mSolvedQuatsAbstract[0][0] = numExternal;
264

  
265
      for(int i=0; i<numInternal; i++)
266
        {
267
        int q = internalQuat[i];
268
        mSolvedQuatsAbstract[i+1] = new int[5];
269
        mSolvedQuatsAbstract[i+1][0] = 1;
270
        mSolvedQuatsAbstract[i+1][2] = q;
271
        mSolvedQuatsAbstract[i+1][3] = q+1;
272
        mSolvedQuatsAbstract[i+1][4] = q+2;
273
        }
274

  
275
      int pointerExternal = 1;
276
      int pointerInternal = 1;
277

  
278
      for(int cubit=0; cubit<numTotal; cubit++)
279
        {
280
        if( isExternal[cubit] ) mSolvedQuatsAbstract[0][pointerExternal++] = cubit;
281
        else                    mSolvedQuatsAbstract[pointerInternal++][1] = cubit;
282
        }
283
      }
284

  
285
    return mSolvedQuatsAbstract;
286
    }
287

  
288
///////////////////////////////////////////////////////////////////////////////////////////////////
289
// Computing scramble states of many a bandaged cubes takes way too long time and too much space.
290
// Return null here and turn to construction of scramble tables just-in-time.
291

  
292
  @Override
293
  public ScrambleState[] getScrambleStates()
294
    {
295
    return null;
296
    }
297

  
298
///////////////////////////////////////////////////////////////////////////////////////////////////
299

  
300
  @Override
301
  public int getScrambleType()
302
    {
303
    return 2;
304
    }
305

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

  
308
  private int getType(float[] pos)
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff