Project

General

Profile

« Previous | Next » 

Revision 6b6504fe

Added by Leszek Koltunski almost 4 years ago

Finally fix the Dino's 'isSolved()' - Dino can be mirrored and then it is also solved!

View differences:

src/main/java/org/distorted/objects/RubikCube.java
394 394
    return 0;
395 395
    }
396 396

  
397
///////////////////////////////////////////////////////////////////////////////////////////////////
398

  
399
  public boolean isSolved()
400
    {
401
    int index = CUBITS[0].mQuatIndex;
402

  
403
    for(int i=1; i<NUM_CUBITS; i++)
404
      {
405
      if( !thereIsNoVisibleDifference(CUBITS[i], index) ) return false;
406
      }
407

  
408
    return true;
409
    }
410

  
397 411
///////////////////////////////////////////////////////////////////////////////////////////////////
398 412
// return if the Cubit, when rotated with its own mQuatScramble, would have looked any different
399 413
// then if it were rotated by quaternion 'quat'.
......
404 418
// a) is a corner or edge and the quaternions are the same
405 419
// b) is inside one of the faces and after rotations by both quats it ends up on the same face.
406 420

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

  
src/main/java/org/distorted/objects/RubikDino.java
41 41
import org.distorted.library.type.Static1D;
42 42
import org.distorted.library.type.Static3D;
43 43
import org.distorted.library.type.Static4D;
44
import org.distorted.main.RubikSurfaceView;
44 45

  
45 46
import java.util.Random;
46 47

  
......
442 443
    }
443 444

  
444 445
///////////////////////////////////////////////////////////////////////////////////////////////////
445
// here it's simple - all cubits have to be rotated with the same quaretnion for the whole thing
446
// to be solved.
446
// remember about the double cover or unit quaternions!
447 447

  
448
  boolean thereIsNoVisibleDifference(Cubit cubit, int quatIndex)
448
  private int mulQuat(int q1, int q2)
449 449
    {
450
    return cubit.mQuatIndex == quatIndex;
450
    Static4D result = RubikSurfaceView.quatMultiply(QUATS[q1],QUATS[q2]);
451

  
452
    float rX = result.get0();
453
    float rY = result.get1();
454
    float rZ = result.get2();
455
    float rW = result.get3();
456

  
457
    final float MAX_ERROR = 0.1f;
458
    float dX,dY,dZ,dW;
459

  
460
    for(int i=0; i<QUATS.length; i++)
461
      {
462
      dX = QUATS[i].get0() - rX;
463
      dY = QUATS[i].get1() - rY;
464
      dZ = QUATS[i].get2() - rZ;
465
      dW = QUATS[i].get3() - rW;
466

  
467
      if( dX<MAX_ERROR && dX>-MAX_ERROR &&
468
          dY<MAX_ERROR && dY>-MAX_ERROR &&
469
          dZ<MAX_ERROR && dZ>-MAX_ERROR &&
470
          dW<MAX_ERROR && dW>-MAX_ERROR  ) return i;
471

  
472
      dX = QUATS[i].get0() + rX;
473
      dY = QUATS[i].get1() + rY;
474
      dZ = QUATS[i].get2() + rZ;
475
      dW = QUATS[i].get3() + rW;
476

  
477
      if( dX<MAX_ERROR && dX>-MAX_ERROR &&
478
          dY<MAX_ERROR && dY>-MAX_ERROR &&
479
          dZ<MAX_ERROR && dZ>-MAX_ERROR &&
480
          dW<MAX_ERROR && dW>-MAX_ERROR  ) return i;
481
      }
482

  
483
    return -1;
484
    }
485

  
486
///////////////////////////////////////////////////////////////////////////////////////////////////
487
// Dino is solved if and only if:
488
//
489
// All four 'X' cubits (i.e. those whose longest edge goes along the X axis) are rotated
490
// by the same quaternion qX, similarly all four 'Y' cubits by the same qY and all four 'Z'
491
// by the same qZ, and then either:
492
//
493
// a) qX = qY = qZ
494
// b) qY = qX*Q2 and qZ = qX*Q8  (i.e. swap of WHITE and YELLOW faces)
495
// c) qX = qY*Q2 and qZ = qY*Q10 (i.e. swap of BLUE and GREEN faces)
496
// d) qX = qZ*Q8 and qY = qZ*Q10 (i.e. swap of RED and BROWN faces)
497
//
498
// BUT: cases b), c) and d) are really the same - it's all just a mirror image of the original.
499
//
500
// X cubits: 0, 2, 8, 10
501
// Y cubits: 1, 3, 9, 11
502
// Z cubits: 4, 5, 6, 7
503

  
504
  public boolean isSolved()
505
    {
506
    int qX = CUBITS[0].mQuatIndex;
507
    int qY = CUBITS[1].mQuatIndex;
508
    int qZ = CUBITS[4].mQuatIndex;
509

  
510
    if( CUBITS[2].mQuatIndex != qX || CUBITS[8].mQuatIndex != qX || CUBITS[10].mQuatIndex != qX ||
511
        CUBITS[3].mQuatIndex != qY || CUBITS[9].mQuatIndex != qY || CUBITS[11].mQuatIndex != qY ||
512
        CUBITS[5].mQuatIndex != qZ || CUBITS[6].mQuatIndex != qZ || CUBITS[ 7].mQuatIndex != qZ  )
513
      {
514
      return false;
515
      }
516

  
517
    return ( qX==qY && qX==qZ ) || ( qY==mulQuat(qX,2) && qZ==mulQuat(qX,8) );
451 518
    }
452 519

  
453 520
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/objects/RubikObject.java
68 68

  
69 69
  final Static3D[] ROTATION_AXIS;
70 70
  final Static4D[] QUATS;
71
  final Cubit[] CUBITS;
71 72
  final int NUM_FACES;
72 73
  final int NUM_CUBIT_FACES;
73 74
  final int NUM_AXIS;
75
  final int NUM_CUBITS;
74 76

  
75 77
  private static float mInitScreenRatio,mObjectScreenRatio;
76 78

  
77
  private final int NUM_CUBITS;
78 79
  private final int mNodeSize;
79 80
  private int mRotRowBitmap;
80 81
  private int mRotAxis;
81 82
  private Static3D[] mOrigPos;
82 83
  private Static3D mNodeScale;
83 84
  private Static4D mQuat;
84
  private Cubit[] mCubits;
85 85
  private int mSize;
86 86
  private RubikObjectList mList;
87 87
  private MeshBase mMesh;
......
146 146
    MatrixEffectScale nodeScaleEffect = new MatrixEffectScale(mNodeScale);
147 147
    nodeEffects.apply(nodeScaleEffect);
148 148

  
149
    CUBITS = new Cubit[NUM_CUBITS];
149 150
    createMeshAndCubits(list,res);
150 151

  
151 152
    mTexture = new DistortedTexture();
......
174 175

  
175 176
  private void createMeshAndCubits(RubikObjectList list, Resources res)
176 177
    {
177
    mCubits = new Cubit[NUM_CUBITS];
178

  
179 178
    if( mCreateFromDMesh )
180 179
      {
181 180
      int sizeIndex = RubikObjectList.getSizeIndex(list.ordinal(),mSize);
......
196 195

  
197 196
      for(int i=0; i<NUM_CUBITS; i++)
198 197
        {
199
        mCubits[i] = new Cubit(this,mOrigPos[i]);
200
        mMesh.setEffectAssociation(i, mCubits[i].computeAssociation(), 0);
198
        CUBITS[i] = new Cubit(this,mOrigPos[i]);
199
        mMesh.setEffectAssociation(i, CUBITS[i].computeAssociation(), 0);
201 200
        }
202 201
      }
203 202
    else
......
206 205

  
207 206
      for(int i=0; i<NUM_CUBITS; i++)
208 207
        {
209
        mCubits[i] = new Cubit(this,mOrigPos[i]);
208
        CUBITS[i] = new Cubit(this,mOrigPos[i]);
210 209
        cubitMesh[i] = createCubitMesh(i);
211 210
        cubitMesh[i].apply(new MatrixEffectMove(mOrigPos[i]),1,0);
212
        cubitMesh[i].setEffectAssociation(0, mCubits[i].computeAssociation(), 0);
211
        cubitMesh[i].setEffectAssociation(0, CUBITS[i].computeAssociation(), 0);
213 212
        }
214 213

  
215 214
      mMesh = new MeshJoined(cubitMesh);
......
276 275

  
277 276
  private boolean belongsToRotation( int cubit, int axis, int rowBitmap)
278 277
    {
279
    int cubitRow = (int)(mCubits[cubit].mRotationRow[axis]+0.5f);
278
    int cubitRow = (int)(CUBITS[cubit].mRotationRow[axis]+0.5f);
280 279
    return ((1<<cubitRow)&rowBitmap)!=0;
281 280
    }
282 281

  
......
317 316
        for(int j=0; j<NUM_CUBITS; j++)
318 317
          if( belongsToRotation(j,axis,rowBitmap) )
319 318
            {
320
            index = mCubits[j].removeRotationNow(quat);
321
            mMesh.setEffectAssociation(j,mCubits[j].computeAssociation(),index);
319
            index = CUBITS[j].removeRotationNow(quat);
320
            mMesh.setEffectAssociation(j, CUBITS[j].computeAssociation(),index);
322 321
            }
323 322
        }
324 323
      }
......
332 331
  boolean isOnFace( int cubit, int axis, int row)
333 332
    {
334 333
    final float MAX_ERROR = 0.0001f;
335
    float diff = mCubits[cubit].mRotationRow[axis] - row;
334
    float diff = CUBITS[cubit].mRotationRow[axis] - row;
336 335
    return diff*diff < MAX_ERROR;
337 336
    }
338 337

  
......
433 432

  
434 433
  public void savePreferences(SharedPreferences.Editor editor)
435 434
    {
436
    for(int i=0; i<NUM_CUBITS; i++) mCubits[i].savePreferences(editor);
435
    for(int i=0; i<NUM_CUBITS; i++) CUBITS[i].savePreferences(editor);
437 436
    }
438 437

  
439 438
///////////////////////////////////////////////////////////////////////////////////////////////////
......
442 441
    {
443 442
    for(int i=0; i<NUM_CUBITS; i++)
444 443
      {
445
      int index = mCubits[i].restorePreferences(preferences);
446
      mMesh.setEffectAssociation(i,mCubits[i].computeAssociation(),index);
444
      int index = CUBITS[i].restorePreferences(preferences);
445
      mMesh.setEffectAssociation(i, CUBITS[i].computeAssociation(),index);
447 446
      }
448 447
    }
449 448

  
......
474 473
    {
475 474
    for(int i=0; i<NUM_CUBITS; i++)
476 475
      {
477
      mCubits[i].solve();
478
      mMesh.setEffectAssociation(i, mCubits[i].computeAssociation(), 0);
479
      }
480
    }
481

  
482
///////////////////////////////////////////////////////////////////////////////////////////////////
483

  
484
  public boolean isSolved()
485
    {
486
    int index = mCubits[0].mQuatIndex;
487

  
488
    for(int i=1; i<NUM_CUBITS; i++)
489
      {
490
      if( !thereIsNoVisibleDifference(mCubits[i], index) ) return false;
476
      CUBITS[i].solve();
477
      mMesh.setEffectAssociation(i, CUBITS[i].computeAssociation(), 0);
491 478
      }
492

  
493
    return true;
494 479
    }
495 480

  
496 481
///////////////////////////////////////////////////////////////////////////////////////////////////
......
625 610
    for(int i=0; i<NUM_CUBITS; i++)
626 611
      if( belongsToRotation(i,mRotAxis,mRotRowBitmap) )
627 612
        {
628
        int index = mCubits[i].removeRotationNow(quat);
629
        mMesh.setEffectAssociation(i,mCubits[i].computeAssociation(),index);
613
        int index = CUBITS[i].removeRotationNow(quat);
614
        mMesh.setEffectAssociation(i, CUBITS[i].computeAssociation(),index);
630 615
        }
631 616
    }
632 617

  
......
652 637

  
653 638
    for(int i=0; i<NUM_CUBITS; i++)
654 639
      {
655
      dist = mCubits[i].getDistSquared(point3D);
640
      dist = CUBITS[i].getDistSquared(point3D);
656 641
      if( dist<minDist )
657 642
        {
658 643
        minDist = dist;
......
703 688
  abstract int getFaceColor(int cubit, int cubitface, int size);
704 689
  abstract float returnMultiplier();
705 690
  abstract float[] getRowChances();
706
  abstract boolean thereIsNoVisibleDifference(Cubit cubit, int quatIndex);
707 691

  
692
  public abstract boolean isSolved();
708 693
  public abstract Static3D[] getRotationAxis();
709 694
  public abstract int getBasicAngle();
710 695
  public abstract int computeRowFromOffset(float offset);
src/main/java/org/distorted/objects/RubikPyraminx.java
486 486
    return 0;
487 487
    }
488 488

  
489
///////////////////////////////////////////////////////////////////////////////////////////////////
490

  
491
  public boolean isSolved()
492
    {
493
    int index = CUBITS[0].mQuatIndex;
494

  
495
    for(int i=1; i<NUM_CUBITS; i++)
496
      {
497
      if( !thereIsNoVisibleDifference(CUBITS[i], index) ) return false;
498
      }
499

  
500
    return true;
501
    }
502

  
489 503
///////////////////////////////////////////////////////////////////////////////////////////////////
490 504
// return if the Cubit, when rotated with its own mQuatScramble, would have looked any different
491 505
// then if it were rotated by quaternion 'quat'.
......
496 510
// a) is a corner or edge and the quaternions are the same
497 511
// b) is inside one of the faces and after rotations by both quats it ends up on the same face.
498 512

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

  

Also available in: Unified diff