Revision 94ad5a8f
Added by Leszek Koltunski about 4 years ago
src/main/java/org/distorted/object/Cubit.java | ||
---|---|---|
134 | 134 |
|
135 | 135 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
136 | 136 |
|
137 |
private void modifyCurrentPosition(Static3D currentPosition, Static4D quat)
|
|
137 |
private void modifyCurrentPosition(Static4D quat) |
|
138 | 138 |
{ |
139 |
float cubitCenterX = currentPosition.get0();
|
|
140 |
float cubitCenterY = currentPosition.get1();
|
|
141 |
float cubitCenterZ = currentPosition.get2();
|
|
139 |
float cubitCenterX = mCurrentPosition.get0();
|
|
140 |
float cubitCenterY = mCurrentPosition.get1();
|
|
141 |
float cubitCenterZ = mCurrentPosition.get2();
|
|
142 | 142 |
|
143 | 143 |
Static4D cubitCenter = new Static4D(cubitCenterX, cubitCenterY, cubitCenterZ, 0); |
144 | 144 |
Static4D rotatedCenter = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat); |
... | ... | |
147 | 147 |
float rotatedY = rotatedCenter.get1(); |
148 | 148 |
float rotatedZ = rotatedCenter.get2(); |
149 | 149 |
|
150 |
currentPosition.set(rotatedX, rotatedY, rotatedZ);
|
|
151 |
mParent.clampPos(currentPosition);
|
|
150 |
mCurrentPosition.set(rotatedX, rotatedY, rotatedZ);
|
|
151 |
mParent.clampPos(mCurrentPosition);
|
|
152 | 152 |
|
153 | 153 |
computeRotationRow(); |
154 | 154 |
} |
155 | 155 |
|
156 |
|
|
157 | 156 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
158 | 157 |
// cast current position on axis; use mStart and mStep to compute the rotation row for each axis. |
159 | 158 |
|
... | ... | |
232 | 231 |
float qw = preferences.getFloat("qw_"+number, 1.0f); |
233 | 232 |
|
234 | 233 |
mQuatScramble.set(qx,qy,qz,qw); |
235 |
modifyCurrentPosition( mCurrentPosition, mQuatScramble); |
|
234 |
modifyCurrentPosition(mQuatScramble); |
|
235 |
} |
|
236 |
|
|
237 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
238 |
// return if the Cubit, when rotated with its own mQuatScramble, would have looked any different |
|
239 |
// then if it were rotated by quaternion 'quat'. |
|
240 |
// No it is not so simple as the quats need to be the same - imagine a 4x4x4 cube where the two |
|
241 |
// middle squares get interchanged. No visible difference! |
|
242 |
// |
|
243 |
// So: this is true iff the cubit |
|
244 |
// a) is a corner or edge and the quaternions are the same |
|
245 |
// b) is inside one of the faces and after rotations by both quats it ends up on the same face. |
|
246 |
|
|
247 |
boolean thereIsNoVisibleDifference(Static4D quat) |
|
248 |
{ |
|
249 |
if ( mQuatScramble.get0()==quat.get0() && |
|
250 |
mQuatScramble.get1()==quat.get1() && |
|
251 |
mQuatScramble.get2()==quat.get2() && |
|
252 |
mQuatScramble.get3()==quat.get3() ) return true; |
|
253 |
|
|
254 |
int belongsToHowManyFaces = 0; |
|
255 |
int size = mParent.getSize()-1; |
|
256 |
int row; |
|
257 |
|
|
258 |
for(int i=0; i<mNumAxis; i++) |
|
259 |
{ |
|
260 |
row = (int)(mRotationRow[i]+0.5f); |
|
261 |
if( row==0 || row==size ) belongsToHowManyFaces++; |
|
262 |
} |
|
263 |
|
|
264 |
switch(belongsToHowManyFaces) |
|
265 |
{ |
|
266 |
case 0 : return true ; // 'inside' cubit that does not lie on any face |
|
267 |
case 1 : // cubit that lies inside one of the faces |
|
268 |
float cubitCenterX = mCurrentPosition.get0(); |
|
269 |
float cubitCenterY = mCurrentPosition.get1(); |
|
270 |
float cubitCenterZ = mCurrentPosition.get2(); |
|
271 |
|
|
272 |
Static4D cubitCenter = new Static4D(cubitCenterX, cubitCenterY, cubitCenterZ, 0); |
|
273 |
Static4D rotated1 = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat); |
|
274 |
Static4D rotated2 = RubikSurfaceView.rotateVectorByQuat( cubitCenter, mQuatScramble ); |
|
275 |
|
|
276 |
int row1, row2; |
|
277 |
float ax,ay,az; |
|
278 |
Static3D axis; |
|
279 |
float x1 = rotated1.get0(); |
|
280 |
float y1 = rotated1.get1(); |
|
281 |
float z1 = rotated1.get2(); |
|
282 |
float x2 = rotated2.get0(); |
|
283 |
float y2 = rotated2.get1(); |
|
284 |
float z2 = rotated2.get2(); |
|
285 |
|
|
286 |
for(int i=0; i<mNumAxis; i++) |
|
287 |
{ |
|
288 |
axis = mParent.ROTATION_AXIS[i]; |
|
289 |
ax = axis.get0(); |
|
290 |
ay = axis.get1(); |
|
291 |
az = axis.get2(); |
|
292 |
|
|
293 |
row1 = (int)(( (x1*ax + y1*ay + z1*az) - mParent.mStart)/mParent.mStep + 0.5f); |
|
294 |
row2 = (int)(( (x2*ax + y2*ay + z2*az) - mParent.mStart)/mParent.mStep + 0.5f); |
|
295 |
|
|
296 |
if( (row1==0 && row2==0) || (row1==size && row2==size) ) |
|
297 |
{ |
|
298 |
return true; |
|
299 |
} |
|
300 |
} |
|
301 |
return false; |
|
302 |
default: return false; // edge or corner |
|
303 |
|
|
304 |
|
|
305 |
} |
|
236 | 306 |
} |
237 | 307 |
|
238 | 308 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
284 | 354 |
mRotationAngle.removeAll(); |
285 | 355 |
mQuatScramble.set(RubikSurfaceView.quatMultiply(quat,mQuatScramble)); |
286 | 356 |
normalizeScrambleQuat( mQuatScramble ); |
287 |
modifyCurrentPosition( mCurrentPosition,quat);
|
|
357 |
modifyCurrentPosition(quat); |
|
288 | 358 |
} |
289 | 359 |
|
290 | 360 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
Also available in: Unified diff
Fix the way we detect if an Object is solved.
Previous way would not detect situations when the object looks solved, but one of the cubits inside its faces - a non-corner and non-edge - is rotated and ends up on the same face.