Project

General

Profile

« Previous | Next » 

Revision ead91342

Added by Leszek Koltunski over 3 years ago

Progress with any size Kilominx.

View differences:

src/main/java/org/distorted/objects/TwistyKilominx.java
31 31
import org.distorted.library.type.Static3D;
32 32
import org.distorted.library.type.Static4D;
33 33
import org.distorted.main.R;
34
import org.distorted.main.RubikSurfaceView;
35

  
36
import static org.distorted.objects.FactoryCubit.COS18;
37
import static org.distorted.objects.FactoryCubit.COS54;
34 38

  
35 39
///////////////////////////////////////////////////////////////////////////////////////////////////
36 40

  
......
50 54

  
51 55
  private int numCubitsPerCorner(int numLayers)
52 56
    {
53
    return 3*((numLayers-3)/2)*((numLayers-5)/2) + (numLayers>=5 ? 1 : 0);
57
    return 3*((numLayers-3)/2)*((numLayers-5)/2) + (numLayers<5 ? 0:1);
54 58
    }
55 59

  
56 60
///////////////////////////////////////////////////////////////////////////////////////////////////
57 61

  
58 62
  private int numCubitsPerEdge(int numLayers)
59 63
    {
60
    return numLayers<5 ? 0 : numLayers-4;
64
    return numLayers<5 ? 0 : 2*(numLayers-4);
61 65
    }
62 66

  
63 67
///////////////////////////////////////////////////////////////////////////////////////////////////
64 68

  
65 69
  int getNumStickerTypes(int numLayers)
66 70
    {
67
    return numLayers == 3 ? 1 : numLayers/2 + 1;
71
    return numLayers<5 ? 1 : numLayers/2 + 1;
68 72
    }
69 73

  
70 74
///////////////////////////////////////////////////////////////////////////////////////////////////
......
75 79
    }
76 80

  
77 81
///////////////////////////////////////////////////////////////////////////////////////////////////
78
// TODO
79 82

  
80 83
  float[] getCuts(int numLayers)
81 84
    {
82
    return new float[] { -0.5f , 0.5f };
85
    float[] cuts = new float[numLayers-1];
86
    float D = numLayers*MovementMinx.DIST3D;
87
    float E = 2*C1;           // 2*cos(36 deg)
88
    float X = 2*D*E/(1+2*E);  // height of the 'upper' part of a dodecahedron, i.e. put it on a table,
89
                              // its height is then D*2*DIST3D, it has one 'lower' part of height X, one
90
                              // 'middle' part of height Y and one upper part of height X again.
91
                              // It's edge length = numLayers/3.0f.
92
    int num = (numLayers-1)/2;
93
    float G = X*0.5f/num;     // height of one Layer
94

  
95
    for(int i=0; i<num; i++)
96
      {
97
      cuts[        i] = -D + (i+0.5f)*G;
98
      cuts[2*num-1-i] = -cuts[i];
99
      }
100

  
101
    return cuts;
102
    }
103

  
104
///////////////////////////////////////////////////////////////////////////////////////////////////
105
// Fill out mCurrCorner{X,Y,Z} by applying appropriate Quat to mBasicCorner{X,Y,Z}
106
// Appropriate one: QUATS[QUAT_INDICES[corner]].
107

  
108
  private void computeBasicCornerVectors(int corner)
109
    {
110
    Static4D quat = QUATS[QUAT_CORNER_INDICES[corner]];
111

  
112
    mCurrCornerV[0] = RubikSurfaceView.rotateVectorByQuat(mBasicCornerV[0],quat);
113
    mCurrCornerV[1] = RubikSurfaceView.rotateVectorByQuat(mBasicCornerV[1],quat);
114
    mCurrCornerV[2] = RubikSurfaceView.rotateVectorByQuat(mBasicCornerV[2],quat);
115
    }
116

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

  
119
  private float[] computeCorner(int numCubitsPerCorner, int numLayers, int corner, int part)
120
    {
121
    float D = numLayers/3.0f;
122
    float[] corn = CORNERS[corner];
123

  
124
    if( part==0 )
125
      {
126
      return new float[] { corn[0]*D, corn[1]*D, corn[2]*D };
127
      }
128
    else
129
      {
130
      float E = D/(0.5f*(numLayers-1));   // ?? maybe 0.5*
131
      int N = (numCubitsPerCorner-1)/3;
132
      int block = (part-1) % N;
133
      int index = (part-1) / N;
134
      Static4D pri = mCurrCornerV[index];
135
      Static4D sec = mCurrCornerV[(index+2)%3];
136

  
137
      int layers= (numLayers-5)/2;
138
      int multP = (block % layers) + 1;
139
      int multS = (block / layers);
140

  
141
      return new float[] {
142
                          corn[0]*D + (pri.get0()*multP + sec.get0()*multS)*E,
143
                          corn[1]*D + (pri.get1()*multP + sec.get1()*multS)*E,
144
                          corn[2]*D + (pri.get2()*multP + sec.get2()*multS)*E
145
                         };
146
      }
147
    }
148

  
149
///////////////////////////////////////////////////////////////////////////////////////////////////
150

  
151
  private float[] computeCenter(int numLayers, int center, int part)
152
    {
153
    int corner = mCenterMap[center][part];
154
    float[] cent = mCenterCoords[center];
155
    float[] corn = CORNERS[corner];
156
    float D = numLayers/3.0f;
157
    float F = 1.0f - (2.0f*numLayers-6.0f)/(numLayers-1)*COS54*COS54;
158

  
159
    return new float[]
160
      {
161
        D * ( cent[0] + (corn[0]-cent[0])*F),
162
        D * ( cent[1] + (corn[1]-cent[1])*F),
163
        D * ( cent[2] + (corn[2]-cent[2])*F)
164
      };
165
    }
166

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

  
169
  private int computeEdgeType(int cubit, int numCubitsPerCorner, int numCubitsPerEdge)
170
    {
171
    int part = (cubit - NUM_CORNERS*numCubitsPerCorner) % numCubitsPerEdge;
172
    return (part+1)/2;
173
    }
174

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

  
177
  private float[] computeEdge(int numLayers, int edge, int part)
178
    {
179
    float D = numLayers/3.0f;
180

  
181
    float[] c1 = CORNERS[ mEdgeMap[edge][0] ];
182
    float[] c2 = CORNERS[ mEdgeMap[edge][1] ];
183
    float x = D * (c1[0]+c2[0]) / 2;
184
    float y = D * (c1[1]+c2[1]) / 2;
185
    float z = D * (c1[2]+c2[2]) / 2;
186

  
187
    part /= 2;
188

  
189
    if( part==0 )
190
      {
191
      return new float[] { x, y, z };
192
      }
193
    else
194
      {
195
      int mult = (part+1)/2;
196
      int dir  = (part+1)%2;
197
      float[] center = mCenterCoords[ mEdgeMap[edge][dir+2] ];
198

  
199
      float vX = D*center[0] - x;
200
      float vY = D*center[1] - y;
201
      float vZ = D*center[2] - z;
202

  
203
      float A = mult*D*COS18/(numLayers-1);
204
      A /= (float)Math.sqrt(vX*vX+vY*vY+vZ*vZ);
205

  
206
      return new float[] { x+A*vX, y+A*vY, z+A*vZ };
207
      }
83 208
    }
84 209

  
85 210
///////////////////////////////////////////////////////////////////////////////////////////////////
86
// TODO
87 211

  
88 212
  float[][] getCubitPositions(int numLayers)
89 213
    {
90
    return CORNERS;
214
    if( numLayers<5 ) return CORNERS;
215

  
216
    int numCubitsPerCorner = numCubitsPerCorner(numLayers);
217
    int numCubitsPerEdge   = numCubitsPerEdge(numLayers);
218
    int numCubitsPerCenter = 5;
219
    int numCubits = NUM_CORNERS*numCubitsPerCorner + NUM_EDGES*numCubitsPerEdge + NUM_CENTERS*numCubitsPerCenter;
220
    int index=0;
221

  
222
    final float[][] CENTERS = new float[numCubits][];
223

  
224
    for(int corner=0; corner<NUM_CORNERS; corner++)
225
      {
226
      computeBasicCornerVectors(corner);
227

  
228
      for(int part=0; part<numCubitsPerCorner; part++, index++)
229
        {
230
        CENTERS[index] = computeCorner(numCubitsPerCorner,numLayers,corner,part);
231
        }
232
      }
233

  
234
    for(int edge=0; edge<NUM_EDGES; edge++)
235
      {
236
      for(int part=0; part<numCubitsPerEdge; part++, index++)
237
        {
238
        CENTERS[index] = computeEdge(numLayers, edge, part );
239
        }
240
      }
241

  
242
    for(int center=0; center<NUM_CENTERS; center++, index++)
243
      {
244
      for(int part=0; part<numCubitsPerCenter; part++, index++)
245
        {
246
        CENTERS[index] = computeCenter(numLayers,center, part);
247
        }
248
      }
249

  
250
    return CENTERS;
91 251
    }
92 252

  
93 253
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/objects/TwistyMegaminx.java
44 44
{
45 45
  static final float MEGA_D = 0.04f;
46 46

  
47
  private static final int NUM_CORNERS = 20;
48
  private static final int NUM_CENTERS = 12;
49
  private static final int NUM_EDGES   = 30;
50

  
51
  // the five vertices that form a given face. Order: the same as colors
52
  // of the faces in TwistyMinx.
53
  private static final int[][] mCenterMap =
54
         {
55
           { 0, 12,  4, 14,  2},
56
           { 0,  2, 18,  6, 16},
57
           { 6, 18, 11, 19,  7},
58
           { 3, 15,  9, 11, 19},
59
           { 4,  5, 15,  9, 14},
60
           { 1, 13,  5, 15,  3},
61
           { 1,  3, 19,  7, 17},
62
           {10, 16,  6,  7, 17},
63
           { 0, 12,  8, 10, 16},
64
           { 8, 13,  5,  4, 12},
65
           { 1, 13,  8, 10, 17},
66
           { 2, 14,  9, 11, 18},
67
         };
68

  
69
  // the quadruple ( vertex1, vertex2, face1, face2 ) defining an edge.
70
  // In fact the 2 vertices already define it, the faces only provide easy
71
  // way to get to know the colors. Order: arbitrary. Face1 arbitrarily on
72
  // the 'left' or right of vector vertex1 --> vertex2, according to Quat.
73
  private static final int[][] mEdgeMap =
74
         {
75
           {  0, 12,  0,  8},
76
           { 12,  4,  0,  9},
77
           {  4, 14,  0,  4},
78
           { 14,  2,  0, 11},
79
           {  2,  0,  0,  1},
80
           { 14,  9,  4, 11},
81
           {  9, 11,  3, 11},
82
           { 11, 18,  2, 11},
83
           { 18,  2,  1, 11},
84
           { 18,  6,  1,  2},
85
           {  6, 16,  1,  7},
86
           { 16,  0,  8,  1},
87
           { 16, 10,  7,  8},
88
           { 10,  8, 10,  8},
89
           {  8, 12,  9,  8},
90
           {  8, 13,  9, 10},
91
           { 13,  5,  9,  5},
92
           {  5,  4,  9,  4},
93
           {  5, 15,  5,  4},
94
           { 15,  9,  3,  4},
95
           { 11, 19,  2,  3},
96
           { 19,  7,  2,  6},
97
           {  7,  6,  2,  7},
98
           {  7, 17,  7,  6},
99
           { 17, 10,  7, 10},
100
           { 17,  1, 10,  6},
101
           {  1,  3,  5,  6},
102
           {  3, 19,  3,  6},
103
           {  1, 13, 10,  5},
104
           {  3, 15,  3,  5},
105
         };
106

  
107

  
108 47
  private static final int[] QUAT_EDGE_INDICES =
109 48
      {
110 49
        56, 40, 43, 59,  0, 55, 10, 17, 25, 49,
......
117 56
        16, 18, 22,  1, 20, 13, 14, 15,  0, 12,  2,  3
118 57
      };
119 58

  
120
  private static final float[][] mCenterCoords = new float[NUM_CENTERS][3];
121

  
122
  static
123
    {
124
    for(int center=0; center<NUM_CENTERS; center++)
125
      {
126
      int[] map = mCenterMap[center];
127

  
128
      float x = CORNERS[map[0]][0] +
129
                CORNERS[map[1]][0] +
130
                CORNERS[map[2]][0] +
131
                CORNERS[map[3]][0] +
132
                CORNERS[map[4]][0] ;
133

  
134
      float y = CORNERS[map[0]][1] +
135
                CORNERS[map[1]][1] +
136
                CORNERS[map[2]][1] +
137
                CORNERS[map[3]][1] +
138
                CORNERS[map[4]][1] ;
139

  
140
      float z = CORNERS[map[0]][2] +
141
                CORNERS[map[1]][2] +
142
                CORNERS[map[2]][2] +
143
                CORNERS[map[3]][2] +
144
                CORNERS[map[4]][2] ;
145

  
146
      mCenterCoords[center][0] = x/5;
147
      mCenterCoords[center][1] = y/5;
148
      mCenterCoords[center][2] = z/5;
149
      }
150
    }
151

  
152 59
  private static MeshBase[] mCenterMeshes, mCornerMeshes;
153 60
  private static MeshBase[][] mEdgeMeshes;
154 61

  
155
  private static final Static4D[] mBasicCornerV, mCurrCornerV;
156

  
157
  static
158
    {
159
    mBasicCornerV = new Static4D[3];
160
    mCurrCornerV  = new Static4D[3];
161

  
162
    mBasicCornerV[0] = new Static4D( (SQ5+1)*0.125f, (SQ5-1)*0.125f, -0.250f, 0.0f );
163
    mBasicCornerV[1] = new Static4D(-(SQ5+1)*0.125f, (SQ5-1)*0.125f, -0.250f, 0.0f );
164
    mBasicCornerV[2] = new Static4D(              0,        -0.500f,    0.0f, 0.0f );
165
    }
166

  
167 62
///////////////////////////////////////////////////////////////////////////////////////////////////
168 63

  
169 64
  TwistyMegaminx(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
......
259 154
      }
260 155
    else
261 156
      {
262
      float E = 2.0f*(numLayers/3.0f)*(0.5f-MEGA_D)/(0.5f*(numLayers-1));
157
      float E = 2.0f*D*(0.5f-MEGA_D)/(0.5f*(numLayers-1));
263 158
      int N = (numCubitsPerCorner-1)/3;
264 159
      int block = (part-1) % N;
265 160
      int index = (part-1) / N;
266 161
      Static4D pri = mCurrCornerV[index];
267 162
      Static4D sec = mCurrCornerV[(index+2)%3];
268 163

  
269
      int multP = (block % ((numLayers-3)/2)) + 1;
270
      int multS = (block / ((numLayers-3)/2));
164
      int layers= (numLayers-5)/2;
165
      int multP = (block % layers) + 1;
166
      int multS = (block / layers);
271 167

  
272 168
      return new float[] {
273 169
                          corn[0]*D + (pri.get0()*multP + sec.get0()*multS)*E,
......
289 185

  
290 186
  private float[] computeEdge(int numLayers, int edge, int part)
291 187
    {
292
    float corr = numLayers/3.0f;
188
    float D = numLayers/3.0f;
293 189

  
294 190
    float[] c1 = CORNERS[ mEdgeMap[edge][0] ];
295 191
    float[] c2 = CORNERS[ mEdgeMap[edge][1] ];
296
    float x = corr * (c1[0]+c2[0]) / 2;
297
    float y = corr * (c1[1]+c2[1]) / 2;
298
    float z = corr * (c1[2]+c2[2]) / 2;
192
    float x = D * (c1[0]+c2[0]) / 2;
193
    float y = D * (c1[1]+c2[1]) / 2;
194
    float z = D * (c1[2]+c2[2]) / 2;
299 195

  
300 196
    if( part==0 )
301 197
      {
......
307 203
      int dir  = (part+1)%2;
308 204
      float[] center = mCenterCoords[ mEdgeMap[edge][dir+2] ];
309 205

  
310
      float vX = corr*center[0] - x;
311
      float vY = corr*center[1] - y;
312
      float vZ = corr*center[2] - z;
206
      float vX = D*center[0] - x;
207
      float vY = D*center[1] - y;
208
      float vZ = D*center[2] - z;
313 209

  
314
      float len = (float)Math.sqrt(vX*vX+vY*vY+vZ*vZ);
315
      float A = mult*corr*(0.5f-MEGA_D)*COS18/((numLayers-1)*0.5f)/len;
210
      float A = mult*D*(0.5f-MEGA_D)*COS18/((numLayers-1)*0.5f);
211
      A /= (float)Math.sqrt(vX*vX+vY*vY+vZ*vZ);
316 212

  
317 213
      return new float[] { x+A*vX, y+A*vY, z+A*vZ };
318 214
      }
src/main/java/org/distorted/objects/TwistyMinx.java
35 35
{
36 36
  private static final int FACES_PER_CUBIT =6;
37 37

  
38
  static final int NUM_CORNERS = 20;
39
  static final int NUM_CENTERS = 12;
40
  static final int NUM_EDGES   = 30;
41

  
38 42
  static final float C0 = (SQ5-1)/4;                       // cos(72 deg)
39 43
  static final float C1 = (SQ5+1)/4;                       // cos(36 deg)
40 44
  static final float C2 = (SQ5+3)/4;
......
206 210
          {false,  true,  true,  true,  true, false}
207 211
      };
208 212

  
213
  // the quadruple ( vertex1, vertex2, face1, face2 ) defining an edge.
214
  // In fact the 2 vertices already define it, the faces only provide easy
215
  // way to get to know the colors. Order: arbitrary. Face1 arbitrarily on
216
  // the 'left' or right of vector vertex1 --> vertex2, according to Quat.
217
  static final int[][] mEdgeMap =
218
         {
219
           {  0, 12,  0,  8},
220
           { 12,  4,  0,  9},
221
           {  4, 14,  0,  4},
222
           { 14,  2,  0, 11},
223
           {  2,  0,  0,  1},
224
           { 14,  9,  4, 11},
225
           {  9, 11,  3, 11},
226
           { 11, 18,  2, 11},
227
           { 18,  2,  1, 11},
228
           { 18,  6,  1,  2},
229
           {  6, 16,  1,  7},
230
           { 16,  0,  8,  1},
231
           { 16, 10,  7,  8},
232
           { 10,  8, 10,  8},
233
           {  8, 12,  9,  8},
234
           {  8, 13,  9, 10},
235
           { 13,  5,  9,  5},
236
           {  5,  4,  9,  4},
237
           {  5, 15,  5,  4},
238
           { 15,  9,  3,  4},
239
           { 11, 19,  2,  3},
240
           { 19,  7,  2,  6},
241
           {  7,  6,  2,  7},
242
           {  7, 17,  7,  6},
243
           { 17, 10,  7, 10},
244
           { 17,  1, 10,  6},
245
           {  1,  3,  5,  6},
246
           {  3, 19,  3,  6},
247
           {  1, 13, 10,  5},
248
           {  3, 15,  3,  5},
249
         };
250

  
251
  // the five vertices that form a given face. Order: the same as colors
252
  // of the faces in TwistyMinx.
253
  static final int[][] mCenterMap =
254
         {
255
           { 0, 12,  4, 14,  2},
256
           { 0,  2, 18,  6, 16},
257
           { 6, 18, 11, 19,  7},
258
           { 3, 15,  9, 11, 19},
259
           { 4,  5, 15,  9, 14},
260
           { 1, 13,  5, 15,  3},
261
           { 1,  3, 19,  7, 17},
262
           {10, 16,  6,  7, 17},
263
           { 0, 12,  8, 10, 16},
264
           { 8, 13,  5,  4, 12},
265
           { 1, 13,  8, 10, 17},
266
           { 2, 14,  9, 11, 18},
267
         };
268

  
269
  static final float[][] mCenterCoords = new float[NUM_CENTERS][3];
270

  
271
  static
272
    {
273
    for(int center=0; center<NUM_CENTERS; center++)
274
      {
275
      int[] map = mCenterMap[center];
276

  
277
      float x = CORNERS[map[0]][0] +
278
                CORNERS[map[1]][0] +
279
                CORNERS[map[2]][0] +
280
                CORNERS[map[3]][0] +
281
                CORNERS[map[4]][0] ;
282

  
283
      float y = CORNERS[map[0]][1] +
284
                CORNERS[map[1]][1] +
285
                CORNERS[map[2]][1] +
286
                CORNERS[map[3]][1] +
287
                CORNERS[map[4]][1] ;
288

  
289
      float z = CORNERS[map[0]][2] +
290
                CORNERS[map[1]][2] +
291
                CORNERS[map[2]][2] +
292
                CORNERS[map[3]][2] +
293
                CORNERS[map[4]][2] ;
294

  
295
      mCenterCoords[center][0] = x/5;
296
      mCenterCoords[center][1] = y/5;
297
      mCenterCoords[center][2] = z/5;
298
      }
299
    }
300

  
301
  static final Static4D[] mBasicCornerV, mCurrCornerV;
302

  
303
  static
304
    {
305
    mBasicCornerV = new Static4D[3];
306
    mCurrCornerV  = new Static4D[3];
307

  
308
    mBasicCornerV[0] = new Static4D( (SQ5+1)*0.125f, (SQ5-1)*0.125f, -0.250f, 0.0f );
309
    mBasicCornerV[1] = new Static4D(-(SQ5+1)*0.125f, (SQ5-1)*0.125f, -0.250f, 0.0f );
310
    mBasicCornerV[2] = new Static4D(              0,        -0.500f,    0.0f, 0.0f );
311
    }
312

  
313

  
209 314
///////////////////////////////////////////////////////////////////////////////////////////////////
210 315

  
211 316
  TwistyMinx(int numLayers, int realSize, Static4D quat, DistortedTexture texture, MeshSquare mesh,

Also available in: Unified diff