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 |
///////////////////////////////////////////////////////////////////////////////////////////////////
|
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.