Project

General

Profile

« Previous | Next » 

Revision 538ee7a6

Added by Leszek Koltunski over 3 years ago

Progress with bandaged cubes.

View differences:

src/main/java/org/distorted/objects/ObjectList.java
170 170
         5,
171 171
         60
172 172
       ),
173

  
174
  BAN2 (
175
         new int[][] {
176
                       {3 , 16, R.raw.mega3, R.drawable.ui_small_mega3, R.drawable.ui_medium_mega3, R.drawable.ui_big_mega3, R.drawable.ui_huge_mega3} ,
177
                     },
178
         TwistyBandaged2Bar.class,
179
         new MovementCube(),
180
         5,
181
         60
182
       ),
183

  
184
  BAN3 (
185
         new int[][] {
186
                       {3 , 16, R.raw.mega3, R.drawable.ui_small_mega3, R.drawable.ui_medium_mega3, R.drawable.ui_big_mega3, R.drawable.ui_huge_mega3} ,
187
                     },
188
         TwistyBandaged3Plate.class,
189
         new MovementCube(),
190
         5,
191
         60
192
       ),
193

  
194
  BAN4 (
195
         new int[][] {
196
                       {3 , 16, R.raw.mega3, R.drawable.ui_small_mega3, R.drawable.ui_medium_mega3, R.drawable.ui_big_mega3, R.drawable.ui_huge_mega3} ,
197
                     },
198
         TwistyBandagedEvil.class,
199
         new MovementCube(),
200
         5,
201
         60
202
       ),
173 203
  ;
174 204

  
175 205
  public static final int NUM_OBJECTS = values().length;
......
551 581

  
552 582
    switch(ordinal())
553 583
      {
554
      case  0: return new TwistyCube         (size, quat, texture, mesh, effects, moves, res, scrWidth);
555
      case  1: return new TwistyPyraminx     (size, quat, texture, mesh, effects, moves, res, scrWidth);
556
      case  2: return new TwistyDiamond      (size, quat, texture, mesh, effects, moves, res, scrWidth);
557
      case  3: return new TwistyDino6        (size, quat, texture, mesh, effects, moves, res, scrWidth);
558
      case  4: return new TwistyDino4        (size, quat, texture, mesh, effects, moves, res, scrWidth);
559
      case  5: return new TwistyRedi         (size, quat, texture, mesh, effects, moves, res, scrWidth);
560
      case  6: return new TwistyHelicopter   (size, quat, texture, mesh, effects, moves, res, scrWidth);
561
      case  7: return new TwistySkewb        (size, quat, texture, mesh, effects, moves, res, scrWidth);
562
      case  8: return new TwistyIvy          (size, quat, texture, mesh, effects, moves, res, scrWidth);
563
      case  9: return new TwistyRex          (size, quat, texture, mesh, effects, moves, res, scrWidth);
564
      case 10: return new TwistyKilominx     (size, quat, texture, mesh, effects, moves, res, scrWidth);
565
      case 11: return new TwistyMegaminx     (size, quat, texture, mesh, effects, moves, res, scrWidth);
566
      case 12: return new TwistyBandagedFused(size, quat, texture, mesh, effects, moves, res, scrWidth);
584
      case  0: return new TwistyCube          (size, quat, texture, mesh, effects, moves, res, scrWidth);
585
      case  1: return new TwistyPyraminx      (size, quat, texture, mesh, effects, moves, res, scrWidth);
586
      case  2: return new TwistyDiamond       (size, quat, texture, mesh, effects, moves, res, scrWidth);
587
      case  3: return new TwistyDino6         (size, quat, texture, mesh, effects, moves, res, scrWidth);
588
      case  4: return new TwistyDino4         (size, quat, texture, mesh, effects, moves, res, scrWidth);
589
      case  5: return new TwistyRedi          (size, quat, texture, mesh, effects, moves, res, scrWidth);
590
      case  6: return new TwistyHelicopter    (size, quat, texture, mesh, effects, moves, res, scrWidth);
591
      case  7: return new TwistySkewb         (size, quat, texture, mesh, effects, moves, res, scrWidth);
592
      case  8: return new TwistyIvy           (size, quat, texture, mesh, effects, moves, res, scrWidth);
593
      case  9: return new TwistyRex           (size, quat, texture, mesh, effects, moves, res, scrWidth);
594
      case 10: return new TwistyKilominx      (size, quat, texture, mesh, effects, moves, res, scrWidth);
595
      case 11: return new TwistyMegaminx      (size, quat, texture, mesh, effects, moves, res, scrWidth);
596
      case 12: return new TwistyBandagedFused (size, quat, texture, mesh, effects, moves, res, scrWidth);
597
      case 13: return new TwistyBandaged2Bar(size, quat, texture, mesh, effects, moves, res, scrWidth);
598
      case 14: return new TwistyBandaged3Plate(size, quat, texture, mesh, effects, moves, res, scrWidth);
599
      case 15: return new TwistyBandagedEvil  (size, quat, texture, mesh, effects, moves, res, scrWidth);
567 600
      }
568 601

  
569 602
    return null;
src/main/java/org/distorted/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.objects;
21

  
22
import android.content.res.Resources;
23

  
24
import org.distorted.library.main.DistortedEffects;
25
import org.distorted.library.main.DistortedTexture;
26
import org.distorted.library.mesh.MeshSquare;
27
import org.distorted.library.type.Static4D;
28
import org.distorted.main.R;
29

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

  
32
class TwistyBandaged2Bar extends TwistyBandagedAbstract
33
{
34
  TwistyBandaged2Bar(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
35
                     DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
36
    {
37
    super(size, quat, texture, mesh, effects, moves, ObjectList.BAN2, res, scrWidth);
38
    }
39

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

  
42
  int getCubitVariant(int cubit)
43
    {
44
    return cubit<=1 ? 2:0;
45
    }
46

  
47
///////////////////////////////////////////////////////////////////////////////////////////////////
48

  
49
  int getNumCubits()
50
    {
51
    return 22;
52
    }
53

  
54
///////////////////////////////////////////////////////////////////////////////////////////////////
55

  
56
  float[] getCubitPosition(int cubit)
57
    {
58
    switch(cubit)
59
      {
60
      case  0: return new float[] { 0.0f, +1.0f,  0.0f};
61
      case  1: return new float[] { 0.0f, -1.0f,  0.0f};
62
      case  2: return new float[] {-1.0f, +1.0f, +1.0f};
63
      case  3: return new float[] {-1.0f, +1.0f,  0.0f};
64
      case  4: return new float[] {-1.0f, +1.0f, -1.0f};
65
      case  5: return new float[] {-1.0f,  0.0f, +1.0f};
66
      case  6: return new float[] {-1.0f,  0.0f,  0.0f};
67
      case  7: return new float[] {-1.0f,  0.0f, -1.0f};
68
      case  8: return new float[] {-1.0f, -1.0f, +1.0f};
69
      case  9: return new float[] {-1.0f, -1.0f, -1.0f};
70
      case 10: return new float[] {+1.0f, +1.0f, +1.0f};
71
      case 11: return new float[] {+1.0f, +1.0f,  0.0f};
72
      case 12: return new float[] {+1.0f, +1.0f, -1.0f};
73
      case 13: return new float[] {+1.0f,  0.0f, +1.0f};
74
      case 14: return new float[] {+1.0f,  0.0f,  0.0f};
75
      case 15: return new float[] {+1.0f,  0.0f, -1.0f};
76
      case 16: return new float[] {+1.0f, -1.0f, +1.0f};
77
      case 17: return new float[] {+1.0f, -1.0f, -1.0f};
78
      case 18: return new float[] { 0.0f,  0.0f, +1.0f};
79
      case 19: return new float[] { 0.0f, -1.0f, +1.0f};
80
      case 20: return new float[] { 0.0f,  0.0f, -1.0f};
81
      case 21: return new float[] { 0.0f, -1.0f, -1.0f};
82
      }
83

  
84
    return null;
85
    }
86

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

  
89
  int getQuatIndex(int cubit)
90
    {
91
    return cubit==0 ? 2 : 0;
92
    }
93

  
94
///////////////////////////////////////////////////////////////////////////////////////////////////
95
// PUBLIC API
96

  
97
  public int getObjectName(int numLayers)
98
    {
99
    return R.string.bandaged_2bar;
100
    }
101

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

  
104
  public int getInventor(int numLayers)
105
    {
106
    return R.string.bandaged_2bar_inventor;
107
    }
108

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

  
111
  public int getComplexity(int numLayers)
112
    {
113
    return 8;
114
    }
115
}
src/main/java/org/distorted/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.objects;
21

  
22
import android.content.res.Resources;
23

  
24
import org.distorted.library.main.DistortedEffects;
25
import org.distorted.library.main.DistortedTexture;
26
import org.distorted.library.mesh.MeshSquare;
27
import org.distorted.library.type.Static4D;
28
import org.distorted.main.R;
29

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

  
32
class TwistyBandaged3Plate extends TwistyBandagedAbstract
33
{
34
  TwistyBandaged3Plate(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
35
                       DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
36
    {
37
    super(size, quat, texture, mesh, effects, moves, ObjectList.BAN1, res, scrWidth);
38
    }
39

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

  
42
  int getCubitVariant(int cubit)
43
    {
44
    return cubit<=2 ? 3:0;
45
    }
46

  
47
///////////////////////////////////////////////////////////////////////////////////////////////////
48

  
49
  int getNumCubits()
50
    {
51
    return 17;
52
    }
53

  
54
///////////////////////////////////////////////////////////////////////////////////////////////////
55

  
56
  float[] getCubitPosition(int cubit)
57
    {
58
    switch(cubit)
59
      {
60
      case  0: return new float[] {-0.5f,  0.5f,  1.0f};
61
      case  1: return new float[] { 1.0f,  0.5f, -0.5f};
62
      case  2: return new float[] {-0.5f, -1.0f, -0.5f};
63

  
64
      case  3: return new float[] { 1.0f,  1.0f,  1.0f};
65
      case  4: return new float[] { 1.0f,  0.0f,  1.0f};
66
      case  5: return new float[] { 1.0f, -1.0f,  1.0f};
67
      case  6: return new float[] {-1.0f, -1.0f,  1.0f};
68
      case  7: return new float[] { 0.0f, -1.0f,  1.0f};
69
      case  8: return new float[] { 1.0f, -1.0f,  0.0f};
70
      case  9: return new float[] { 1.0f, -1.0f, -1.0f};
71

  
72
      case 10: return new float[] {-1.0f,  1.0f, -1.0f};
73
      case 11: return new float[] {-1.0f,  1.0f,  0.0f};
74
      case 12: return new float[] { 0.0f,  1.0f, -1.0f};
75
      case 13: return new float[] { 0.0f,  1.0f,  0.0f};
76
      case 14: return new float[] {-1.0f,  0.0f, -1.0f};
77
      case 15: return new float[] {-1.0f,  0.0f,  0.0f};
78
      case 16: return new float[] { 0.0f,  0.0f, -1.0f};
79
      }
80

  
81
    return null;
82
    }
83

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

  
86
  int getQuatIndex(int cubit)
87
    {
88
    switch(cubit)
89
      {
90
      case 0: return 1;
91
      case 1: return 3;
92
      }
93

  
94
    return 0;
95
    }
96

  
97
///////////////////////////////////////////////////////////////////////////////////////////////////
98
// PUBLIC API
99

  
100
  public int getObjectName(int numLayers)
101
    {
102
    return R.string.bandaged_3plate;
103
    }
104

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

  
107
  public int getInventor(int numLayers)
108
    {
109
    return R.string.bandaged_3plate_inventor;
110
    }
111

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

  
114
  public int getComplexity(int numLayers)
115
    {
116
    return 8;
117
    }
118
}
src/main/java/org/distorted/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.objects;
21

  
22
import android.content.res.Resources;
23
import android.graphics.Canvas;
24
import android.graphics.Paint;
25

  
26
import org.distorted.library.effect.MatrixEffectQuaternion;
27
import org.distorted.library.main.DistortedEffects;
28
import org.distorted.library.main.DistortedTexture;
29
import org.distorted.library.mesh.MeshBase;
30
import org.distorted.library.mesh.MeshSquare;
31
import org.distorted.library.type.Static3D;
32
import org.distorted.library.type.Static4D;
33
import org.distorted.main.RubikSurfaceView;
34

  
35
import java.util.Random;
36

  
37
import static org.distorted.effects.scramble.ScrambleEffect.START_AXIS;
38

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

  
41
abstract class TwistyBandagedAbstract extends TwistyObject
42
{
43
  // the three rotation axis of a 3x3 Cube. Must be normalized.
44
  static final Static3D[] ROT_AXIS = new Static3D[]
45
         {
46
           new Static3D(1,0,0),
47
           new Static3D(0,1,0),
48
           new Static3D(0,0,1)
49
         };
50

  
51
  private static final int[] FACE_COLORS = new int[]
52
         {
53
           COLOR_YELLOW, COLOR_WHITE,
54
           COLOR_BLUE  , COLOR_GREEN,
55
           COLOR_RED   , COLOR_ORANGE
56
         };
57

  
58
  private static final Static4D[] QUATS = new Static4D[]
59
         {
60
         new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),
61
         new Static4D(  1.0f,   0.0f,   0.0f,   0.0f),
62
         new Static4D(  0.0f,   1.0f,   0.0f,   0.0f),
63
         new Static4D(  0.0f,   0.0f,   1.0f,   0.0f),
64

  
65
         new Static4D( SQ2/2,  SQ2/2,  0.0f ,   0.0f),
66
         new Static4D( SQ2/2, -SQ2/2,  0.0f ,   0.0f),
67
         new Static4D( SQ2/2,   0.0f,  SQ2/2,   0.0f),
68
         new Static4D(-SQ2/2,   0.0f,  SQ2/2,   0.0f),
69
         new Static4D( SQ2/2,   0.0f,   0.0f,  SQ2/2),
70
         new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),
71
         new Static4D(  0.0f,  SQ2/2,  SQ2/2,   0.0f),
72
         new Static4D(  0.0f,  SQ2/2, -SQ2/2,   0.0f),
73
         new Static4D(  0.0f,  SQ2/2,   0.0f,  SQ2/2),
74
         new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),
75
         new Static4D(  0.0f,   0.0f,  SQ2/2,  SQ2/2),
76
         new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),
77

  
78
         new Static4D(  0.5f,   0.5f,   0.5f,   0.5f),
79
         new Static4D(  0.5f,   0.5f,  -0.5f,   0.5f),
80
         new Static4D(  0.5f,   0.5f,  -0.5f,  -0.5f),
81
         new Static4D(  0.5f,  -0.5f,   0.5f,  -0.5f),
82
         new Static4D( -0.5f,  -0.5f,  -0.5f,   0.5f),
83
         new Static4D( -0.5f,   0.5f,  -0.5f,  -0.5f),
84
         new Static4D( -0.5f,   0.5f,   0.5f,  -0.5f),
85
         new Static4D( -0.5f,   0.5f,   0.5f,   0.5f)
86
         };
87

  
88
  private static final Static4D[] INIT_QUATS = new Static4D[]
89
        {
90
        new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),  // NULL
91
        new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),  // X
92
        new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),  // Y
93
        new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),  // Z
94
        new Static4D( -0.5f,  +0.5f,  -0.5f,  +0.5f),  // ZX
95
        new Static4D( +0.5f,  +0.5f,  +0.5f,  -0.5f),  // YX
96
        };
97

  
98
  private static final int[][] mDimensions = new int[][]
99
        {
100
         {1,1,1},  // has to be X>=Z>=Y so that all
101
         {2,1,1},  // the faces are horizontal
102
         {3,1,1},
103
         {2,1,2},
104
         {2,2,2}
105
        };
106

  
107
  private static final int[][] mStickerDimensions = new int[][]
108
        {
109
         {1,1},  // dimensions of the faces of
110
         {2,1},  // the cuboids defined above
111
         {3,1},
112
         {2,2}
113
        };
114

  
115
  private static final int[][] mFaceMap = new int[][] // cubitface=2 when rotated by
116
    {                                                 // quatIndex=1 gets moved to
117
        {0,0,5,2,4,2},                                // position mFaceMap[2][1]
118
        {1,1,4,3,5,3},
119
        {2,4,2,1,1,4},
120
        {3,5,3,0,0,5},
121
        {4,3,0,4,3,0},
122
        {5,2,1,5,2,1}
123
    };
124

  
125
  private static final int[][] mAxisMap = new int[][] // axis=1 when rotated by
126
    {                                                 // quatIndex=2 gets moved to
127
        {0,0,2,1,2,1},                                // axis mAxisMap[1][2]
128
        {1,2,1,0,0,2},
129
        {2,1,0,2,1,0}
130
    };
131

  
132
  private static final int NUM_STICKERS = mStickerDimensions.length;
133

  
134
  private static MeshBase[] mMeshes;
135

  
136
///////////////////////////////////////////////////////////////////////////////////////////////////
137

  
138
  TwistyBandagedAbstract(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
139
                         DistortedEffects effects, int[][] moves, ObjectList list, Resources res, int scrWidth)
140
    {
141
    super(size, size, quat, texture, mesh, effects, moves, list, res, scrWidth);
142
    }
143

  
144
///////////////////////////////////////////////////////////////////////////////////////////////////
145

  
146
  abstract int getCubitVariant(int cubit);
147
  abstract int getNumCubits();
148
  abstract int getQuatIndex(int cubit);
149
  abstract float[] getCubitPosition(int cubit);
150

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

  
153
  MeshBase createCubitMesh(int cubit, int numLayers)
154
    {
155
    if( mMeshes==null )
156
      {
157
      int LEN = mDimensions.length;
158
      mMeshes = new MeshBase[LEN];
159

  
160
      for(int i=0; i<LEN; i++)
161
        {
162
        mMeshes[i] = FactoryCubit.getInstance().createCuboidMesh(mDimensions[i]);
163
        }
164
      }
165

  
166
    int variant = getCubitVariant(cubit);
167
    MeshBase mesh = mMeshes[variant].copy(true);
168
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( INIT_QUATS[getQuatIndex(cubit)], new Static3D(0,0,0) );
169
    mesh.apply(quat,0xffffffff,0);
170

  
171
    return mesh;
172
    }
173

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

  
176
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
177
    {
178
    int numFaces = FACE_COLORS.length;
179
    int stickerType = face/numFaces;
180
    int color = face%numFaces;
181
    float X = mStickerDimensions[stickerType][0];
182
    float Y = mStickerDimensions[stickerType][1];
183
    float MAX = Math.max(X,Y);
184
    float R = 0.10f / MAX;
185
    float S = 0.08f / MAX;
186
    X /= (2*MAX);
187
    Y /= (2*MAX);
188

  
189
    float[] vertices = { -X,-Y, +X,-Y, +X,+Y, -X,+Y};
190

  
191
    FactorySticker factory = FactorySticker.getInstance();
192
    factory.drawRoundedPolygon(canvas, paint, left, top, vertices, S, FACE_COLORS[color], R);
193
    }
194

  
195
///////////////////////////////////////////////////////////////////////////////////////////////////
196

  
197
  Static3D[] getCubitPositions(int size)
198
    {
199
    int numCubits = getNumCubits();
200
    Static3D[] tmp = new Static3D[numCubits];
201

  
202
    for(int cubit=0; cubit<numCubits; cubit++)
203
      {
204
      float[] pos = getCubitPosition(cubit);
205
      tmp[cubit] = new Static3D(pos[0],pos[1],pos[2]);
206
      }
207

  
208
    return tmp;
209
    }
210

  
211
///////////////////////////////////////////////////////////////////////////////////////////////////
212

  
213
  Static4D[] getQuats()
214
    {
215
    return QUATS;
216
    }
217

  
218
///////////////////////////////////////////////////////////////////////////////////////////////////
219

  
220
  boolean shouldResetTextureMaps()
221
    {
222
    return false;
223
    }
224

  
225
///////////////////////////////////////////////////////////////////////////////////////////////////
226

  
227
  int getNumFaces()
228
    {
229
    return FACE_COLORS.length;
230
    }
231

  
232
///////////////////////////////////////////////////////////////////////////////////////////////////
233

  
234
  float[] getCuts(int numLayers)
235
    {
236
    float[] cuts = new float[numLayers-1];
237

  
238
    for(int i=0; i<numLayers-1; i++)
239
      {
240
      cuts[i] = (2-numLayers)*0.5f + i;
241
      }
242

  
243
    return cuts;
244
    }
245

  
246
///////////////////////////////////////////////////////////////////////////////////////////////////
247

  
248
  int getNumStickerTypes(int numLayers)
249
    {
250
    return NUM_STICKERS;
251
    }
252

  
253
///////////////////////////////////////////////////////////////////////////////////////////////////
254

  
255
  int getNumCubitFaces()
256
    {
257
    return FACE_COLORS.length;
258
    }
259

  
260
///////////////////////////////////////////////////////////////////////////////////////////////////
261

  
262
  float getScreenRatio()
263
    {
264
    return 0.5f;
265
    }
266

  
267
///////////////////////////////////////////////////////////////////////////////////////////////////
268

  
269
  private int retStickerIndex(int horzSize, int vertSize)
270
    {
271
    switch(horzSize)
272
      {
273
      case 1: return 0;
274
      case 2: return vertSize==1 ? 1:3;
275
      case 3: return 2;
276
      }
277

  
278
    return 0;
279
    }
280

  
281
///////////////////////////////////////////////////////////////////////////////////////////////////
282

  
283
  private int getStickerIndex(int cubitface, int[] dim)
284
    {
285
    switch(cubitface)
286
      {
287
      case 0: case 1: return retStickerIndex(dim[2],dim[1]);
288
      case 2: case 3: return retStickerIndex(dim[0],dim[2]);
289
      case 4: case 5: return retStickerIndex(dim[0],dim[1]);
290
      }
291

  
292
    return 0;
293
    }
294

  
295
///////////////////////////////////////////////////////////////////////////////////////////////////
296

  
297
  int getFaceColor(int cubit, int cubitface, int numLayers)
298
    {
299
    int variant      = getCubitVariant(cubit);
300
    int[] dim        = mDimensions[variant];
301
    float[] pos      = getCubitPosition(cubit);
302
    int stickerIndex = getStickerIndex(cubitface,dim);
303
    int quatIndex    = getQuatIndex(cubit);
304
    int face         = mFaceMap[cubitface][quatIndex];
305
    int multiplier   = (face%2)==0 ? 1:-1;
306
    int posIndex     = face/2;
307
    int dimIndex     = mAxisMap[posIndex][quatIndex];
308
    boolean reaches  = multiplier*pos[posIndex] + dim[dimIndex]*0.5f > (numLayers-1)*0.5f;
309

  
310
    int ret=  reaches ? stickerIndex*NUM_FACES + face : NUM_STICKERS*NUM_FACES;
311

  
312
if( cubit==0 )
313
  {
314
android.util.Log.e("DISTORTED", "cubit="+cubit+" cubitface="+cubitface+" ret="+ret+" stickerIndex="+stickerIndex+" face="+face);
315
android.util.Log.e("DISTORTED", "reaches="+reaches+" border="+((numLayers-1)*0.5f)+" left="+(multiplier*pos[posIndex] + dim[dimIndex]*0.5f));
316
android.util.Log.e("DISTORTED", "posIndex="+posIndex+" dimIndex="+dimIndex);
317

  
318
  }
319
    return ret;
320
    }
321

  
322
///////////////////////////////////////////////////////////////////////////////////////////////////
323

  
324
  float returnMultiplier()
325
    {
326
    return getNumLayers();
327
    }
328

  
329
///////////////////////////////////////////////////////////////////////////////////////////////////
330

  
331
  float[] getRowChances(int numLayers)
332
    {
333
    float[] chances = new float[numLayers];
334

  
335
    for(int i=0; i<numLayers; i++)
336
      {
337
      chances[i] = (i+1.0f) / numLayers;
338
      }
339

  
340
    return chances;
341
    }
342

  
343
///////////////////////////////////////////////////////////////////////////////////////////////////
344
// PUBLIC API
345

  
346
  public Static3D[] getRotationAxis()
347
    {
348
    return ROT_AXIS;
349
    }
350

  
351
///////////////////////////////////////////////////////////////////////////////////////////////////
352

  
353
  public int getBasicAngle()
354
    {
355
    return 4;
356
    }
357

  
358
///////////////////////////////////////////////////////////////////////////////////////////////////
359
// TODO
360

  
361
  public int randomizeNewRotAxis(Random rnd, int oldRotAxis)
362
    {
363
    int numAxis = ROTATION_AXIS.length;
364

  
365
    if( oldRotAxis == START_AXIS )
366
      {
367
      return rnd.nextInt(numAxis);
368
      }
369
    else
370
      {
371
      int newVector = rnd.nextInt(numAxis-1);
372
      return (newVector>=oldRotAxis ? newVector+1 : newVector);
373
      }
374
    }
375

  
376
///////////////////////////////////////////////////////////////////////////////////////////////////
377
// TODO
378

  
379
  public int randomizeNewRow(Random rnd, int oldRotAxis, int oldRow, int newRotAxis)
380
    {
381
    float rowFloat = rnd.nextFloat();
382

  
383
    for(int row=0; row<mRowChances.length; row++)
384
      {
385
      if( rowFloat<=mRowChances[row] ) return row;
386
      }
387

  
388
    return 0;
389
    }
390

  
391
///////////////////////////////////////////////////////////////////////////////////////////////////
392

  
393
  public boolean isSolved()
394
    {
395
    int index = CUBITS[0].mQuatIndex;
396

  
397
    for(int i=1; i<NUM_CUBITS; i++)
398
      {
399
      if( !thereIsNoVisibleDifference(CUBITS[i], index) ) return false;
400
      }
401

  
402
    return true;
403
    }
404

  
405
///////////////////////////////////////////////////////////////////////////////////////////////////
406
// return if the Cubit, when rotated with its own mQuatScramble, would have looked any different
407
// then if it were rotated by quaternion 'quat'.
408
// No it is not so simple as the quats need to be the same - imagine a 4x4x4 cube where the two
409
// middle squares get interchanged. No visible difference!
410
//
411
// So: this is true iff the cubit
412
// a) is a corner or edge and the quaternions are the same
413
// b) is inside one of the faces and after rotations by both quats it ends up on the same face.
414

  
415
  private boolean thereIsNoVisibleDifference(Cubit cubit, int quatIndex)
416
    {
417
    if ( cubit.mQuatIndex == quatIndex ) return true;
418

  
419
    int belongsToHowManyFaces = 0;
420
    int lastLayer = getNumLayers()-1;
421
    float row;
422
    final float MAX_ERROR = 0.01f;
423

  
424
    for(int i=0; i<NUM_AXIS; i++)
425
      {
426
      row = cubit.mRotationRow[i];
427
      if( (row          <MAX_ERROR && row          >-MAX_ERROR) ||
428
          (row-lastLayer<MAX_ERROR && row-lastLayer>-MAX_ERROR)  ) belongsToHowManyFaces++;
429
      }
430

  
431
    switch(belongsToHowManyFaces)
432
      {
433
      case 0 : return true ;  // 'inside' cubit that does not lie on any face
434
      case 1 :                // cubit that lies inside one of the faces
435
               Static3D orig = cubit.getOrigPosition();
436
               Static4D quat1 = QUATS[quatIndex];
437
               Static4D quat2 = QUATS[cubit.mQuatIndex];
438

  
439
               Static4D cubitCenter = new Static4D( orig.get0(), orig.get1(), orig.get2(), 0);
440
               Static4D rotated1 = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat1 );
441
               Static4D rotated2 = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat2 );
442

  
443
               float row1, row2;
444
               float x1 = rotated1.get0();
445
               float y1 = rotated1.get1();
446
               float z1 = rotated1.get2();
447
               float x2 = rotated2.get0();
448
               float y2 = rotated2.get1();
449
               float z2 = rotated2.get2();
450

  
451
               for(int i=0; i<NUM_AXIS; i++)
452
                 {
453
                 row1 = computeRow(x1,y1,z1,i);
454
                 row2 = computeRow(x2,y2,z2,i);
455

  
456
                 if( (row1==0 && row2==0) || (row1==lastLayer && row2==lastLayer) ) return true;
457
                 }
458
               return false;
459

  
460
      default: return false;  // edge or corner
461
      }
462
    }
463

  
464
///////////////////////////////////////////////////////////////////////////////////////////////////
465
// only needed for solvers - there are no Bandaged solvers ATM)
466

  
467
  public String retObjectString()
468
    {
469
    return "";
470
    }
471
}
src/main/java/org/distorted/objects/TwistyBandagedCube.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.objects;
21

  
22
import android.content.res.Resources;
23
import android.graphics.Canvas;
24
import android.graphics.Paint;
25

  
26
import org.distorted.library.effect.MatrixEffectQuaternion;
27
import org.distorted.library.main.DistortedEffects;
28
import org.distorted.library.main.DistortedTexture;
29
import org.distorted.library.mesh.MeshBase;
30
import org.distorted.library.mesh.MeshSquare;
31
import org.distorted.library.type.Static3D;
32
import org.distorted.library.type.Static4D;
33
import org.distorted.main.RubikSurfaceView;
34

  
35
import java.util.Random;
36

  
37
import static org.distorted.effects.scramble.ScrambleEffect.START_AXIS;
38

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

  
41
abstract class TwistyBandagedCube extends TwistyObject
42
{
43
  // the three rotation axis of a 3x3 Cube. Must be normalized.
44
  static final Static3D[] ROT_AXIS = new Static3D[]
45
         {
46
           new Static3D(1,0,0),
47
           new Static3D(0,1,0),
48
           new Static3D(0,0,1)
49
         };
50

  
51
  private static final int[] FACE_COLORS = new int[]
52
         {
53
           COLOR_YELLOW, COLOR_WHITE,
54
           COLOR_BLUE  , COLOR_GREEN,
55
           COLOR_RED   , COLOR_ORANGE
56
         };
57

  
58
  private static final Static4D[] QUATS = new Static4D[]
59
         {
60
         new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),
61
         new Static4D(  1.0f,   0.0f,   0.0f,   0.0f),
62
         new Static4D(  0.0f,   1.0f,   0.0f,   0.0f),
63
         new Static4D(  0.0f,   0.0f,   1.0f,   0.0f),
64

  
65
         new Static4D( SQ2/2,  SQ2/2,  0.0f ,   0.0f),
66
         new Static4D( SQ2/2, -SQ2/2,  0.0f ,   0.0f),
67
         new Static4D( SQ2/2,   0.0f,  SQ2/2,   0.0f),
68
         new Static4D(-SQ2/2,   0.0f,  SQ2/2,   0.0f),
69
         new Static4D( SQ2/2,   0.0f,   0.0f,  SQ2/2),
70
         new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),
71
         new Static4D(  0.0f,  SQ2/2,  SQ2/2,   0.0f),
72
         new Static4D(  0.0f,  SQ2/2, -SQ2/2,   0.0f),
73
         new Static4D(  0.0f,  SQ2/2,   0.0f,  SQ2/2),
74
         new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),
75
         new Static4D(  0.0f,   0.0f,  SQ2/2,  SQ2/2),
76
         new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),
77

  
78
         new Static4D(  0.5f,   0.5f,   0.5f,   0.5f),
79
         new Static4D(  0.5f,   0.5f,  -0.5f,   0.5f),
80
         new Static4D(  0.5f,   0.5f,  -0.5f,  -0.5f),
81
         new Static4D(  0.5f,  -0.5f,   0.5f,  -0.5f),
82
         new Static4D( -0.5f,  -0.5f,  -0.5f,   0.5f),
83
         new Static4D( -0.5f,   0.5f,  -0.5f,  -0.5f),
84
         new Static4D( -0.5f,   0.5f,   0.5f,  -0.5f),
85
         new Static4D( -0.5f,   0.5f,   0.5f,   0.5f)
86
         };
87

  
88
  // possible aspectRatios of cubit faces in case of a bandaged 3x3:
89
  // 1/3, 1/2, 2/3, 1, 3/2, 2, 3. Numerator = (1/3)*3!, (1/2)*3!, ...
90
  private static final int[] mAspectNumerator3 = new int[] {2,3,4,6,9,12,18};
91
  private static final int[] mAspectRatio3     = new int[] {0,0,0,0,0,0,0};
92

  
93
  static final Static4D[] INIT_QUATS = new Static4D[]
94
        {
95
        new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),  // NULL
96
        new Static4D( SQ2/2,   0.0f,   0.0f,  SQ2/2),  // X
97
        new Static4D(  0.0f,  SQ2/2,   0.0f,  SQ2/2),  // Y
98
        new Static4D(  0.0f,   0.0f,  SQ2/2,  SQ2/2),  // Z
99
        new Static4D( -0.5f,  +0.5f,  -0.5f,  -0.5f),  // ZX
100
        new Static4D( +0.5f,  +0.5f,  +0.5f,  +0.5f),  // YX
101
        };
102

  
103
  private static MeshBase[] mMeshes;
104

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

  
107
  TwistyBandagedCube(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
108
                     DistortedEffects effects, int[][] moves, ObjectList list, Resources res, int scrWidth)
109
    {
110
    super(size, size, quat, texture, mesh, effects, moves, list, res, scrWidth);
111
    }
112

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

  
115
  abstract int getNumCubitVariants();
116
  abstract int getCubitVariant(int cubit);
117
  abstract int getNumCubits();
118
  abstract int[] getCubitDimensions(int variant);
119
  abstract Static3D getCubitPosition(int cubit);
120
  abstract int getQuatIndex(int cubit);
121

  
122
///////////////////////////////////////////////////////////////////////////////////////////////////
123

  
124
  MeshBase createCubitMesh(int cubit, int numLayers)
125
    {
126
    if( mMeshes==null )
127
      {
128
      mMeshes = new MeshBase[getNumCubitVariants()];
129
      }
130

  
131
    int variant = getCubitVariant(cubit);
132

  
133
    if( mMeshes[variant]==null )
134
      {
135
      int[] dimensions = getCubitDimensions(variant);
136
      mMeshes[variant] = FactoryCubit.getInstance().createCuboidMesh(dimensions);
137
      }
138

  
139
    MeshBase mesh = mMeshes[variant].copy(true);
140
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( INIT_QUATS[getQuatIndex(cubit)], new Static3D(0,0,0) );
141
    mesh.apply(quat,0xffffffff,0);
142

  
143
    return mesh;
144
    }
145

  
146
///////////////////////////////////////////////////////////////////////////////////////////////////
147

  
148
  private int getAspectNumerator(int stickerType)
149
    {
150
    int type=-1;
151
    int len = mAspectRatio3.length;
152

  
153
    for(int i=0; i<len; i++)
154
      {
155
      if( mAspectRatio3[i] != 0 ) type++;
156
      if( type==stickerType ) return mAspectNumerator3[i];
157
      }
158

  
159
    return 0;
160
    }
161

  
162
///////////////////////////////////////////////////////////////////////////////////////////////////
163

  
164
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
165
    {
166
    float R = 0.10f;
167
    float S = 0.08f;
168
    int numFaces = FACE_COLORS.length;
169
    int stickerType = face/numFaces;
170
    float ratio = getAspectNumerator(stickerType)/6.0f;
171
    float X,Y;
172

  
173
    if( ratio<1.0f )
174
      {
175
      X = ratio/2;
176
      Y = 0.5f;
177
      }
178
    else
179
      {
180
      X = 0.5f;
181
      Y = 0.5f/ratio;
182
      }
183

  
184
    float[] vertices = { -X,-Y, +X,-Y, +X,+Y, -X,+Y};
185

  
186
    FactorySticker factory = FactorySticker.getInstance();
187
    factory.drawRoundedPolygon(canvas, paint, left, top, vertices, S, FACE_COLORS[face%numFaces], R);
188
    }
189

  
190
///////////////////////////////////////////////////////////////////////////////////////////////////
191

  
192
  Static3D[] getCubitPositions(int size)
193
    {
194
    int numCubits = getNumCubits();
195
    Static3D[] tmp = new Static3D[numCubits];
196

  
197
    for(int cubit=0; cubit<numCubits; cubit++)
198
      {
199
      tmp[cubit] = getCubitPosition(cubit);
200
      }
201

  
202
    return tmp;
203
    }
204

  
205
///////////////////////////////////////////////////////////////////////////////////////////////////
206

  
207
  Static4D[] getQuats()
208
    {
209
    return QUATS;
210
    }
211

  
212
///////////////////////////////////////////////////////////////////////////////////////////////////
213

  
214
  boolean shouldResetTextureMaps()
215
    {
216
    return false;
217
    }
218

  
219
///////////////////////////////////////////////////////////////////////////////////////////////////
220

  
221
  int getNumFaces()
222
    {
223
    return FACE_COLORS.length;
224
    }
225

  
226
///////////////////////////////////////////////////////////////////////////////////////////////////
227

  
228
  float[] getCuts(int numLayers)
229
    {
230
    float[] cuts = new float[numLayers-1];
231

  
232
    for(int i=0; i<numLayers-1; i++)
233
      {
234
      cuts[i] = (2-numLayers)*0.5f + i;
235
      }
236

  
237
    return cuts;
238
    }
239

  
240
///////////////////////////////////////////////////////////////////////////////////////////////////
241

  
242
  int getNumStickerTypes(int numLayers)
243
    {
244
    if( numLayers==3 )
245
      {
246
      int numVariants = getNumCubitVariants();
247
      int len = mAspectNumerator3.length;
248

  
249
      for(int variant=0; variant<numVariants; variant++)
250
        {
251
        int[] dimensions = getCubitDimensions(variant);
252

  
253
        int ratio0 = 6*dimensions[0]/dimensions[1];
254
        int ratio1 = 6*dimensions[0]/dimensions[2];
255
        int ratio2 = 6*dimensions[2]/dimensions[1];
256

  
257
        for(int i=0; i<len; i++)
258
          {
259
          if( mAspectNumerator3[i]==ratio0 ||
260
              mAspectNumerator3[i]==ratio1 ||
261
              mAspectNumerator3[i]==ratio2  ) mAspectRatio3[i]++;
262
          }
263
        }
264

  
265
      int result=0;
266

  
267
      for(int i=0; i<len; i++)
268
        {
269
        if( mAspectRatio3[i]>0 ) result++;
270
        }
271

  
272
      return result;
273
      }
274

  
275
    return 1;
276
    }
277

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

  
280
  int getNumCubitFaces()
281
    {
282
    return FACE_COLORS.length;
283
    }
284

  
285
///////////////////////////////////////////////////////////////////////////////////////////////////
286

  
287
  float getScreenRatio()
288
    {
289
    return 0.5f;
290
    }
291

  
292
///////////////////////////////////////////////////////////////////////////////////////////////////
293

  
294
  int getFaceColor(int cubit, int cubitface, int numLayers)
295
    {
296
    int X=0,Y=0,Z=0;
297
    int variant = getCubitVariant(cubit);
298
    int[] dim = getCubitDimensions(variant);
299
    Static3D pos = getCubitPosition(cubit);
300

  
301
    switch( getQuatIndex(cubit) )
302
      {
303
      case 0: X= dim[0]; Y=dim[1]; Z=dim[2]; break;
304
      case 1: X= dim[0]; Y=dim[2]; Z=dim[1]; break;
305
      case 2: X= dim[2]; Y=dim[1]; Z=dim[0]; break;
306
      case 3: X= dim[1]; Y=dim[0]; Z=dim[2]; break;
307
      case 4: X= dim[1]; Y=dim[2]; Z=dim[0]; break;
308
      case 5: X= dim[2]; Y=dim[0]; Z=dim[1]; break;
309
      }
310

  
311
    float posX = pos.get0();
312
    float posY = pos.get1();
313
    float posZ = pos.get2();
314
    float border = (numLayers-1)*0.5f;
315
    int ret = NUM_FACES;
316

  
317
    switch(cubitface)
318
      {
319
      case 0: ret = posX + X*0.5f > border ? cubitface : NUM_FACES; break;
320
      case 1: ret = posX - X*0.5f <-border ? cubitface : NUM_FACES; break;
321
      case 2: ret = posY + Y*0.5f > border ? cubitface : NUM_FACES; break;
322
      case 3: ret = posY - Y*0.5f <-border ? cubitface : NUM_FACES; break;
323
      case 4: ret = posZ + Z*0.5f > border ? cubitface : NUM_FACES; break;
324
      case 5: ret = posZ - Z*0.5f <-border ? cubitface : NUM_FACES; break;
325
      }
326

  
327
    return ret;
328
    }
329

  
330
///////////////////////////////////////////////////////////////////////////////////////////////////
331

  
332
  float returnMultiplier()
333
    {
334
    return getNumLayers();
335
    }
336

  
337
///////////////////////////////////////////////////////////////////////////////////////////////////
338

  
339
  float[] getRowChances(int numLayers)
340
    {
341
    float[] chances = new float[numLayers];
342

  
343
    for(int i=0; i<numLayers; i++)
344
      {
345
      chances[i] = (i+1.0f) / numLayers;
346
      }
347

  
348
    return chances;
349
    }
350

  
351
///////////////////////////////////////////////////////////////////////////////////////////////////
352
// PUBLIC API
353

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

  
359
///////////////////////////////////////////////////////////////////////////////////////////////////
360

  
361
  public int getBasicAngle()
362
    {
363
    return 4;
364
    }
365

  
366
///////////////////////////////////////////////////////////////////////////////////////////////////
367
// TODO
368

  
369
  public int randomizeNewRotAxis(Random rnd, int oldRotAxis)
370
    {
371
    int numAxis = ROTATION_AXIS.length;
372

  
373
    if( oldRotAxis == START_AXIS )
374
      {
375
      return rnd.nextInt(numAxis);
376
      }
377
    else
378
      {
379
      int newVector = rnd.nextInt(numAxis-1);
380
      return (newVector>=oldRotAxis ? newVector+1 : newVector);
381
      }
382
    }
383

  
384
///////////////////////////////////////////////////////////////////////////////////////////////////
385
// TODO
386

  
387
  public int randomizeNewRow(Random rnd, int oldRotAxis, int oldRow, int newRotAxis)
388
    {
389
    float rowFloat = rnd.nextFloat();
390

  
391
    for(int row=0; row<mRowChances.length; row++)
392
      {
393
      if( rowFloat<=mRowChances[row] ) return row;
394
      }
395

  
396
    return 0;
397
    }
398

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

  
401
  public boolean isSolved()
402
    {
403
    int index = CUBITS[0].mQuatIndex;
404

  
405
    for(int i=1; i<NUM_CUBITS; i++)
406
      {
407
      if( !thereIsNoVisibleDifference(CUBITS[i], index) ) return false;
408
      }
409

  
410
    return true;
411
    }
412

  
413
///////////////////////////////////////////////////////////////////////////////////////////////////
414
// return if the Cubit, when rotated with its own mQuatScramble, would have looked any different
415
// then if it were rotated by quaternion 'quat'.
416
// No it is not so simple as the quats need to be the same - imagine a 4x4x4 cube where the two
417
// middle squares get interchanged. No visible difference!
418
//
419
// So: this is true iff the cubit
420
// a) is a corner or edge and the quaternions are the same
421
// b) is inside one of the faces and after rotations by both quats it ends up on the same face.
422

  
423
  private boolean thereIsNoVisibleDifference(Cubit cubit, int quatIndex)
424
    {
425
    if ( cubit.mQuatIndex == quatIndex ) return true;
426

  
427
    int belongsToHowManyFaces = 0;
428
    int lastLayer = getNumLayers()-1;
429
    float row;
430
    final float MAX_ERROR = 0.01f;
431

  
432
    for(int i=0; i<NUM_AXIS; i++)
433
      {
434
      row = cubit.mRotationRow[i];
435
      if( (row          <MAX_ERROR && row          >-MAX_ERROR) ||
436
          (row-lastLayer<MAX_ERROR && row-lastLayer>-MAX_ERROR)  ) belongsToHowManyFaces++;
437
      }
438

  
439
    switch(belongsToHowManyFaces)
440
      {
441
      case 0 : return true ;  // 'inside' cubit that does not lie on any face
442
      case 1 :                // cubit that lies inside one of the faces
443
               Static3D orig = cubit.getOrigPosition();
444
               Static4D quat1 = QUATS[quatIndex];
445
               Static4D quat2 = QUATS[cubit.mQuatIndex];
446

  
447
               Static4D cubitCenter = new Static4D( orig.get0(), orig.get1(), orig.get2(), 0);
448
               Static4D rotated1 = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat1 );
449
               Static4D rotated2 = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat2 );
450

  
451
               float row1, row2;
452
               float x1 = rotated1.get0();
453
               float y1 = rotated1.get1();
454
               float z1 = rotated1.get2();
455
               float x2 = rotated2.get0();
456
               float y2 = rotated2.get1();
457
               float z2 = rotated2.get2();
458

  
459
               for(int i=0; i<NUM_AXIS; i++)
460
                 {
461
                 row1 = computeRow(x1,y1,z1,i);
462
                 row2 = computeRow(x2,y2,z2,i);
463

  
464
                 if( (row1==0 && row2==0) || (row1==lastLayer && row2==lastLayer) ) return true;
465
                 }
466
               return false;
467

  
468
      default: return false;  // edge or corner
469
      }
470
    }
471

  
472
///////////////////////////////////////////////////////////////////////////////////////////////////
473
// only needed for solvers - there are no Ivy solvers ATM)
474

  
475
  public String retObjectString()
476
    {
477
    return "";
478
    }
479
}
src/main/java/org/distorted/objects/TwistyBandagedEvil.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.objects;
21

  
22
import android.content.res.Resources;
23

  
24
import org.distorted.library.main.DistortedEffects;
25
import org.distorted.library.main.DistortedTexture;
26
import org.distorted.library.mesh.MeshSquare;
27
import org.distorted.library.type.Static4D;
28
import org.distorted.main.R;
29

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

  
32
class TwistyBandagedEvil extends TwistyBandagedAbstract
33
{
34
  TwistyBandagedEvil(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
35
                     DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
36
    {
37
    super(size, quat, texture, mesh, effects, moves, ObjectList.BAN1, res, scrWidth);
38
    }
39

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

  
42
  int getCubitVariant(int cubit)
43
    {
44
    switch(cubit)
45
      {
46
      case 0: return 0;
47
      case 1: return 3;
48
      }
49

  
50
    return 1;
51
    }
52

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

  
55
  int getNumCubits()
56
    {
57
    return 13;
58
    }
59

  
60
///////////////////////////////////////////////////////////////////////////////////////////////////
61

  
62
  float[] getCubitPosition(int cubit)
63
    {
64
    switch(cubit)
65
      {
66
      case  0: return new float[] { 1.0f,  1.0f, -1.0f};
67
      case  1: return new float[] {-0.5f, -0.5f,  0.0f};
68
      case  2: return new float[] {-0.5f,  1.0f, -1.0f};
69
      case  3: return new float[] {-0.5f,  0.0f, -1.0f};
70
      case  4: return new float[] {-0.5f, -1.0f, -1.0f};
71
      case  5: return new float[] {-1.0f,  1.0f,  0.5f};
72
      case  6: return new float[] { 0.0f,  1.0f,  0.5f};
73
      case  7: return new float[] { 1.0f,  1.0f,  0.5f};
74
      case  8: return new float[] {-1.0f, -0.5f,  1.0f};
75
      case  9: return new float[] { 0.0f, -0.5f,  1.0f};
76
      case 10: return new float[] { 1.0f, -0.5f,  1.0f};
77
      case 11: return new float[] { 1.0f, -0.5f,  0.0f};
78
      case 12: return new float[] { 1.0f, -0.5f, -1.0f};
79
      }
80

  
81
    return null;
82
    }
83

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

  
86
  int getQuatIndex(int cubit)
87
    {
88
    switch(cubit)
89
      {
90
      case 1: return 1;
91
      case 0:
92
      case 2:
93
      case 3:
94
      case 4: return 0;
95
      case 5:
96
      case 6:
97
      case 7: return 2;
98
      default:return 3;
99
      }
100
    }
101

  
102
///////////////////////////////////////////////////////////////////////////////////////////////////
103
// PUBLIC API
104

  
105
  public int getObjectName(int numLayers)
106
    {
107
    return R.string.bandaged_evil;
108
    }
109

  
110
///////////////////////////////////////////////////////////////////////////////////////////////////
111

  
112
  public int getInventor(int numLayers)
113
    {
114
    return R.string.bandaged_evil_inventor;
115
    }
116

  
117
///////////////////////////////////////////////////////////////////////////////////////////////////
118

  
119
  public int getComplexity(int numLayers)
120
    {
121
    return 8;
122
    }
123
}
src/main/java/org/distorted/objects/TwistyBandagedFused.java
24 24
import org.distorted.library.main.DistortedEffects;
25 25
import org.distorted.library.main.DistortedTexture;
26 26
import org.distorted.library.mesh.MeshSquare;
27
import org.distorted.library.type.Static3D;
28 27
import org.distorted.library.type.Static4D;
29 28
import org.distorted.main.R;
30 29

  
31 30
///////////////////////////////////////////////////////////////////////////////////////////////////
32 31

  
33
class TwistyBandagedFused extends TwistyBandagedCube
32
class TwistyBandagedFused extends TwistyBandagedAbstract
34 33
{
35 34
  TwistyBandagedFused(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
36 35
                      DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
......
38 37
    super(size, quat, texture, mesh, effects, moves, ObjectList.BAN1, res, scrWidth);
39 38
    }
40 39

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

  
43
  int getNumCubitVariants()
44
    {
45
    return 2;
46
    }
47

  
48 40
///////////////////////////////////////////////////////////////////////////////////////////////////
49 41

  
50 42
  int getCubitVariant(int cubit)
51 43
    {
52
    return cubit==0 ? 0:1;
44
    return cubit==0 ? 4:0;
53 45
    }
54 46

  
55 47
///////////////////////////////////////////////////////////////////////////////////////////////////
......
61 53

  
62 54
///////////////////////////////////////////////////////////////////////////////////////////////////
63 55

  
64
  int[] getCubitDimensions(int variant)
65
    {
66
    return variant==0 ? new int[] {2,2,2} : new int[] {1,1,1};
67
    }
68

  
69
///////////////////////////////////////////////////////////////////////////////////////////////////
70

  
71
  Static3D getCubitPosition(int cubit)
56
  float[] getCubitPosition(int cubit)
72 57
    {
73 58
    switch(cubit)
74 59
      {
75
      case  0: return new Static3D(-0.5f, -0.5f, +0.5f);
76
      case  1: return new Static3D(-1.0f, +1.0f, +1.0f);
77
      case  2: return new Static3D(-1.0f, +1.0f, +0.0f);
78
      case  3: return new Static3D(-1.0f, +1.0f, -1.0f);
79
      case  4: return new Static3D( 0.0f, +1.0f, +1.0f);
80
      case  5: return new Static3D( 0.0f, +1.0f, +0.0f);
81
      case  6: return new Static3D( 0.0f, +1.0f, -1.0f);
82
      case  7: return new Static3D( 1.0f, +1.0f, +1.0f);
83
      case  8: return new Static3D( 1.0f, +1.0f, +0.0f);
84
      case  9: return new Static3D( 1.0f, +1.0f, -1.0f);
85
      case 10: return new Static3D( 1.0f,  0.0f, +1.0f);
86
      case 11: return new Static3D( 1.0f,  0.0f, +0.0f);
87
      case 12: return new Static3D( 1.0f,  0.0f, -1.0f);
88
      case 13: return new Static3D( 1.0f, -1.0f, +1.0f);
89
      case 14: return new Static3D( 1.0f, -1.0f, +0.0f);
90
      case 15: return new Static3D( 1.0f, -1.0f, -1.0f);
91
      case 16: return new Static3D(-1.0f, -1.0f, -1.0f);
92
      case 17: return new Static3D(-1.0f,  0.0f, -1.0f);
93
      case 18: return new Static3D( 0.0f, -1.0f, -1.0f);
94
      case 19: return new Static3D( 0.0f,  0.0f, -1.0f);
60
      case  0: return new float[] {-0.5f, -0.5f, +0.5f};
61
      case  1: return new float[] {-1.0f, +1.0f, +1.0f};
62
      case  2: return new float[] {-1.0f, +1.0f, +0.0f};
63
      case  3: return new float[] {-1.0f, +1.0f, -1.0f};
64
      case  4: return new float[] { 0.0f, +1.0f, +1.0f};
65
      case  5: return new float[] { 0.0f, +1.0f, +0.0f};
66
      case  6: return new float[] { 0.0f, +1.0f, -1.0f};
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff