Project

General

Profile

« Previous | Next » 

Revision 94ad5a8f

Added by Leszek Koltunski about 4 years ago

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.

View differences:

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