Revision ead91342
Added by Leszek Koltunski about 3 years ago
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 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
Also available in: Unified diff
Progress with any size Kilominx.