Project

General

Profile

« Previous | Next » 

Revision 1ebc4767

Added by Leszek Koltunski over 4 years ago

Fix detecting if an Object is solved. Before, the generic Cubit.thereIsNoVisibleDifference(0 would not work correctly in case of the Dino.

View differences:

src/main/java/org/distorted/objects/Cubit.java
150 150
      }
151 151
    }
152 152

  
153
///////////////////////////////////////////////////////////////////////////////////////////////////
154

  
155
  Static3D getOrigPosition()
156
    {
157
    return mOrigPosition;
158
    }
159

  
153 160
///////////////////////////////////////////////////////////////////////////////////////////////////
154 161

  
155 162
  int computeAssociation()
......
185 192
    return mQuatIndex;
186 193
    }
187 194

  
188
///////////////////////////////////////////////////////////////////////////////////////////////////
189
// return if the Cubit, when rotated with its own mQuatScramble, would have looked any different
190
// then if it were rotated by quaternion 'quat'.
191
// No it is not so simple as the quats need to be the same - imagine a 4x4x4 cube where the two
192
// middle squares get interchanged. No visible difference!
193
//
194
// So: this is true iff the cubit
195
// a) is a corner or edge and the quaternions are the same
196
// b) is inside one of the faces and after rotations by both quats it ends up on the same face.
197

  
198
  boolean thereIsNoVisibleDifference(int quatIndex)
199
    {
200
    if ( mQuatIndex == quatIndex ) return true;
201

  
202
    int belongsToHowManyFaces = 0;
203
    int size = mParent.getSize()-1;
204
    float row;
205
    final float MAX_ERROR = 0.01f;
206

  
207
    for(int i=0; i<mNumAxis; i++)
208
      {
209
      row = mRotationRow[i];
210
      if( (row     <MAX_ERROR && row     >-MAX_ERROR) ||
211
          (row-size<MAX_ERROR && row-size>-MAX_ERROR)  ) belongsToHowManyFaces++;
212
      }
213

  
214
    switch(belongsToHowManyFaces)
215
      {
216
      case 0 : return true ;  // 'inside' cubit that does not lie on any face
217
      case 1 :                // cubit that lies inside one of the faces
218
               float cubitCenterX = mOrigPosition.get0();
219
               float cubitCenterY = mOrigPosition.get1();
220
               float cubitCenterZ = mOrigPosition.get2();
221

  
222
               Static4D quat1 = mParent.QUATS[quatIndex];
223
               Static4D quat2 = mParent.QUATS[mQuatIndex];
224

  
225
               Static4D cubitCenter = new Static4D(cubitCenterX, cubitCenterY, cubitCenterZ, 0);
226
               Static4D rotated1 = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat1 );
227
               Static4D rotated2 = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat2 );
228

  
229
               float row1, row2, row3, row4;
230
               float ax,ay,az;
231
               Static3D axis;
232
               float x1 = rotated1.get0();
233
               float y1 = rotated1.get1();
234
               float z1 = rotated1.get2();
235
               float x2 = rotated2.get0();
236
               float y2 = rotated2.get1();
237
               float z2 = rotated2.get2();
238

  
239
               for(int i=0; i<mNumAxis; i++)
240
                 {
241
                 axis = mParent.ROTATION_AXIS[i];
242
                 ax = axis.get0();
243
                 ay = axis.get1();
244
                 az = axis.get2();
245

  
246
                 row1 = ((x1*ax + y1*ay + z1*az) - mParent.mStart) / mParent.mStep;
247
                 row2 = ((x2*ax + y2*ay + z2*az) - mParent.mStart) / mParent.mStep;
248
                 row3 = row1 - size;
249
                 row4 = row2 - size;
250

  
251
                 if( (row1<MAX_ERROR && row1>-MAX_ERROR && row2<MAX_ERROR && row2>-MAX_ERROR) ||
252
                     (row3<MAX_ERROR && row3>-MAX_ERROR && row4<MAX_ERROR && row4>-MAX_ERROR)  )
253
                   {
254
                   return true;
255
                   }
256
                 }
257
               return false;
258

  
259
      default: return false;  // edge or corner
260
      }
261
    }
262

  
263 195
///////////////////////////////////////////////////////////////////////////////////////////////////
264 196

  
265 197
  int removeRotationNow(Static4D quat)
src/main/java/org/distorted/objects/RubikCube.java
35 35
import org.distorted.library.type.Static1D;
36 36
import org.distorted.library.type.Static3D;
37 37
import org.distorted.library.type.Static4D;
38
import org.distorted.main.RubikSurfaceView;
38 39

  
39 40
import java.util.Random;
40 41

  
......
393 394
    return 0;
394 395
    }
395 396

  
397
///////////////////////////////////////////////////////////////////////////////////////////////////
398
// return if the Cubit, when rotated with its own mQuatScramble, would have looked any different
399
// then if it were rotated by quaternion 'quat'.
400
// No it is not so simple as the quats need to be the same - imagine a 4x4x4 cube where the two
401
// middle squares get interchanged. No visible difference!
402
//
403
// So: this is true iff the cubit
404
// a) is a corner or edge and the quaternions are the same
405
// b) is inside one of the faces and after rotations by both quats it ends up on the same face.
406

  
407
  boolean thereIsNoVisibleDifference(Cubit cubit, int quatIndex)
408
    {
409
    if ( cubit.mQuatIndex == quatIndex ) return true;
410

  
411
    int belongsToHowManyFaces = 0;
412
    int size = getSize()-1;
413
    float row;
414
    final float MAX_ERROR = 0.01f;
415

  
416
    for(int i=0; i<NUM_AXIS; i++)
417
      {
418
      row = cubit.mRotationRow[i];
419
      if( (row     <MAX_ERROR && row     >-MAX_ERROR) ||
420
          (row-size<MAX_ERROR && row-size>-MAX_ERROR)  ) belongsToHowManyFaces++;
421
      }
422

  
423
    switch(belongsToHowManyFaces)
424
      {
425
      case 0 : return true ;  // 'inside' cubit that does not lie on any face
426
      case 1 :                // cubit that lies inside one of the faces
427
               Static3D orig = cubit.getOrigPosition();
428
               Static4D quat1 = QUATS[quatIndex];
429
               Static4D quat2 = QUATS[cubit.mQuatIndex];
430

  
431
               Static4D cubitCenter = new Static4D( orig.get0(), orig.get1(), orig.get2(), 0);
432
               Static4D rotated1 = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat1 );
433
               Static4D rotated2 = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat2 );
434

  
435
               float row1, row2, row3, row4;
436
               float ax,ay,az;
437
               Static3D axis;
438
               float x1 = rotated1.get0();
439
               float y1 = rotated1.get1();
440
               float z1 = rotated1.get2();
441
               float x2 = rotated2.get0();
442
               float y2 = rotated2.get1();
443
               float z2 = rotated2.get2();
444

  
445
               for(int i=0; i<NUM_AXIS; i++)
446
                 {
447
                 axis = ROTATION_AXIS[i];
448
                 ax = axis.get0();
449
                 ay = axis.get1();
450
                 az = axis.get2();
451

  
452
                 row1 = ((x1*ax + y1*ay + z1*az) - mStart) / mStep;
453
                 row2 = ((x2*ax + y2*ay + z2*az) - mStart) / mStep;
454
                 row3 = row1 - size;
455
                 row4 = row2 - size;
456

  
457
                 if( (row1<MAX_ERROR && row1>-MAX_ERROR && row2<MAX_ERROR && row2>-MAX_ERROR) ||
458
                     (row3<MAX_ERROR && row3>-MAX_ERROR && row4<MAX_ERROR && row4>-MAX_ERROR)  )
459
                   {
460
                   return true;
461
                   }
462
                 }
463
               return false;
464

  
465
      default: return false;  // edge or corner
466
      }
467
    }
468

  
396 469
///////////////////////////////////////////////////////////////////////////////////////////////////
397 470
// order: Up --> Right --> Front --> Down --> Left --> Back
398 471
// (because the first implemented Solver - the two-phase Cube3 one - expects such order)
src/main/java/org/distorted/objects/RubikDino.java
441 441
      }
442 442
    }
443 443

  
444
///////////////////////////////////////////////////////////////////////////////////////////////////
445
// here it's simple - all cubits have to be rotated with the same quaretnion for the whole thing
446
// to be solved.
447

  
448
  boolean thereIsNoVisibleDifference(Cubit cubit, int quatIndex)
449
    {
450
    return cubit.mQuatIndex == quatIndex;
451
    }
452

  
444 453
///////////////////////////////////////////////////////////////////////////////////////////////////
445 454
// TODO  (only needed for solvers - there are no Dino solvers ATM)
446 455

  
src/main/java/org/distorted/objects/RubikObject.java
70 70
  final Static4D[] QUATS;
71 71
  final int NUM_FACES;
72 72
  final int NUM_CUBIT_FACES;
73
  final int NUM_AXIS;
73 74

  
74 75
  private static float mInitScreenRatio,mObjectScreenRatio;
75 76

  
......
116 117
    QUATS = getQuats();
117 118
    NUM_CUBITS  = mOrigPos.length;
118 119
    ROTATION_AXIS = getRotationAxis();
120
    NUM_AXIS = ROTATION_AXIS.length;
119 121
    mObjectScreenRatio = getScreenRatio();
120 122
    mInitScreenRatio = mObjectScreenRatio;
121 123
    NUM_FACES = getNumFaces();
......
485 487

  
486 488
    for(int i=1; i<NUM_CUBITS; i++)
487 489
      {
488
      if( !mCubits[i].thereIsNoVisibleDifference(index) ) return false;
490
      if( !thereIsNoVisibleDifference(mCubits[i], index) ) return false;
489 491
      }
490 492

  
491 493
    return true;
......
701 703
  abstract int getFaceColor(int cubit, int cubitface, int size);
702 704
  abstract float returnMultiplier();
703 705
  abstract float[] getRowChances();
706
  abstract boolean thereIsNoVisibleDifference(Cubit cubit, int quatIndex);
704 707

  
705 708
  public abstract Static3D[] getRotationAxis();
706 709
  public abstract int getBasicAngle();
src/main/java/org/distorted/objects/RubikPyraminx.java
37 37
import org.distorted.library.type.Static1D;
38 38
import org.distorted.library.type.Static3D;
39 39
import org.distorted.library.type.Static4D;
40
import org.distorted.main.RubikSurfaceView;
40 41

  
41 42
import java.util.Random;
42 43

  
......
485 486
    return 0;
486 487
    }
487 488

  
489
///////////////////////////////////////////////////////////////////////////////////////////////////
490
// return if the Cubit, when rotated with its own mQuatScramble, would have looked any different
491
// then if it were rotated by quaternion 'quat'.
492
// No it is not so simple as the quats need to be the same - imagine a 4x4x4 cube where the two
493
// middle squares get interchanged. No visible difference!
494
//
495
// So: this is true iff the cubit
496
// a) is a corner or edge and the quaternions are the same
497
// b) is inside one of the faces and after rotations by both quats it ends up on the same face.
498

  
499
  boolean thereIsNoVisibleDifference(Cubit cubit, int quatIndex)
500
    {
501
    if ( cubit.mQuatIndex == quatIndex ) return true;
502

  
503
    int belongsToHowManyFaces = 0;
504
    int size = getSize()-1;
505
    float row;
506
    final float MAX_ERROR = 0.01f;
507

  
508
    for(int i=0; i<NUM_AXIS; i++)
509
      {
510
      row = cubit.mRotationRow[i];
511
      if( (row     <MAX_ERROR && row     >-MAX_ERROR) ||
512
          (row-size<MAX_ERROR && row-size>-MAX_ERROR)  ) belongsToHowManyFaces++;
513
      }
514

  
515
    switch(belongsToHowManyFaces)
516
      {
517
      case 0 : return true ;  // 'inside' cubit that does not lie on any face
518
      case 1 :                // cubit that lies inside one of the faces
519
               Static3D orig = cubit.getOrigPosition();
520
               Static4D quat1 = QUATS[quatIndex];
521
               Static4D quat2 = QUATS[cubit.mQuatIndex];
522

  
523
               Static4D cubitCenter = new Static4D( orig.get0(), orig.get1(), orig.get2(), 0);
524
               Static4D rotated1 = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat1 );
525
               Static4D rotated2 = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat2 );
526

  
527
               float row1, row2, row3, row4;
528
               float ax,ay,az;
529
               Static3D axis;
530
               float x1 = rotated1.get0();
531
               float y1 = rotated1.get1();
532
               float z1 = rotated1.get2();
533
               float x2 = rotated2.get0();
534
               float y2 = rotated2.get1();
535
               float z2 = rotated2.get2();
536

  
537
               for(int i=0; i<NUM_AXIS; i++)
538
                 {
539
                 axis = ROTATION_AXIS[i];
540
                 ax = axis.get0();
541
                 ay = axis.get1();
542
                 az = axis.get2();
543

  
544
                 row1 = ((x1*ax + y1*ay + z1*az) - mStart) / mStep;
545
                 row2 = ((x2*ax + y2*ay + z2*az) - mStart) / mStep;
546
                 row3 = row1 - size;
547
                 row4 = row2 - size;
548

  
549
                 if( (row1<MAX_ERROR && row1>-MAX_ERROR && row2<MAX_ERROR && row2>-MAX_ERROR) ||
550
                     (row3<MAX_ERROR && row3>-MAX_ERROR && row4<MAX_ERROR && row4>-MAX_ERROR)  )
551
                   {
552
                   return true;
553
                   }
554
                 }
555
               return false;
556

  
557
      default: return false;  // edge or corner
558
      }
559
    }
560

  
488 561
///////////////////////////////////////////////////////////////////////////////////////////////////
489 562
// TODO  (only needed for solvers - there are no Pyraminx solvers ATM)
490 563

  

Also available in: Unified diff