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