Revision a480ee80
Added by Leszek Koltunski about 4 years ago
| src/main/java/org/distorted/objects/MovementSquare.java | ||
|---|---|---|
| 46 | 46 |
|
| 47 | 47 |
int computeRowFromOffset(int face, int axisIndex, int numLayers, float offset) |
| 48 | 48 |
{
|
| 49 |
//android.util.Log.e("D", "face="+face+" size="+numLayers+" offset="+offset);
|
|
| 50 |
|
|
| 51 | 49 |
return offset>DIST2D? 2-axisIndex : 0; |
| 52 | 50 |
} |
| 53 | 51 |
|
| src/main/java/org/distorted/objects/TwistyBandagedAbstract.java | ||
|---|---|---|
| 161 | 161 |
abstract float[][] getPositions(); |
| 162 | 162 |
abstract int[] getQuatIndices(); |
| 163 | 163 |
|
| 164 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 165 |
|
|
| 166 |
int[] getSolvedQuats(int cubit, int numLayers) |
|
| 167 |
{
|
|
| 168 |
int status = retCubitSolvedStatus(cubit,numLayers); |
|
| 169 |
return status<0 ? null : buildSolvedQuats(MovementCube.FACE_AXIS[status],QUATS); |
|
| 170 |
} |
|
| 171 |
|
|
| 164 | 172 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 165 | 173 |
|
| 166 | 174 |
int getNumCubits() |
| ... | ... | |
| 461 | 469 |
{
|
| 462 | 470 |
return BASIC_ANGLE; |
| 463 | 471 |
} |
| 464 |
|
|
| 465 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 466 |
|
|
| 467 |
public boolean isSolved() |
|
| 468 |
{
|
|
| 469 |
int index = CUBITS[0].mQuatIndex; |
|
| 470 |
|
|
| 471 |
for(int i=1; i<NUM_CUBITS; i++) |
|
| 472 |
{
|
|
| 473 |
if( thereIsVisibleDifference(CUBITS[i], index) ) return false; |
|
| 474 |
} |
|
| 475 |
|
|
| 476 |
return true; |
|
| 477 |
} |
|
| 478 | 472 |
} |
| src/main/java/org/distorted/objects/TwistyCube.java | ||
|---|---|---|
| 136 | 136 |
super(size, size, quat, texture, mesh, effects, moves, ObjectList.CUBE, res, scrWidth); |
| 137 | 137 |
} |
| 138 | 138 |
|
| 139 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 140 |
|
|
| 141 |
int[] getSolvedQuats(int cubit, int numLayers) |
|
| 142 |
{
|
|
| 143 |
int status = retCubitSolvedStatus(cubit,numLayers); |
|
| 144 |
return status<0 ? null : buildSolvedQuats(MovementCube.FACE_AXIS[status],QUATS); |
|
| 145 |
} |
|
| 146 |
|
|
| 139 | 147 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 140 | 148 |
|
| 141 | 149 |
ObjectShape getObjectShape(int cubit, int numLayers) |
| ... | ... | |
| 356 | 364 |
} |
| 357 | 365 |
} |
| 358 | 366 |
|
| 359 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 360 |
|
|
| 361 |
public boolean isSolved() |
|
| 362 |
{
|
|
| 363 |
int index = CUBITS[0].mQuatIndex; |
|
| 364 |
|
|
| 365 |
for(int i=1; i<NUM_CUBITS; i++) |
|
| 366 |
{
|
|
| 367 |
if( thereIsVisibleDifference(CUBITS[i], index) ) return false; |
|
| 368 |
} |
|
| 369 |
|
|
| 370 |
return true; |
|
| 371 |
} |
|
| 372 |
|
|
| 373 | 367 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 374 | 368 |
|
| 375 | 369 |
public int getObjectName(int numLayers) |
| src/main/java/org/distorted/objects/TwistyDiamond.java | ||
|---|---|---|
| 57 | 57 |
COLOR_GREEN , COLOR_GREY |
| 58 | 58 |
}; |
| 59 | 59 |
|
| 60 |
private static final int[] mFaceMap = new int[] {4,0,6,2,7,3,5,1};
|
|
| 61 |
|
|
| 60 | 62 |
// All legal rotation quats of a Diamond: unit + three 180 deg turns + 8 generators |
| 61 | 63 |
private static final Static4D[] QUATS = new Static4D[] |
| 62 | 64 |
{
|
| ... | ... | |
| 77 | 79 |
|
| 78 | 80 |
private static final float DIST = 0.50f; |
| 79 | 81 |
|
| 80 |
private static final int[][] mFaceNeutralQuatIndex = new int[][] |
|
| 81 |
{
|
|
| 82 |
{6,10},
|
|
| 83 |
{4, 8},
|
|
| 84 |
{7,11},
|
|
| 85 |
{5, 9},
|
|
| 86 |
{7,11},
|
|
| 87 |
{5, 9},
|
|
| 88 |
{6,10},
|
|
| 89 |
{4, 8}
|
|
| 90 |
}; |
|
| 91 |
|
|
| 92 | 82 |
private static final int[] mTetraToFaceMap = new int[] {1,2,3,0,5,6,7,4};
|
| 93 | 83 |
|
| 94 | 84 |
private static final double[][] VERTICES_TETRA = new double[][] |
| ... | ... | |
| 153 | 143 |
super(size, size, quat, texture, mesh, effects, moves, ObjectList.DIAM, res, scrWidth); |
| 154 | 144 |
} |
| 155 | 145 |
|
| 146 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 147 |
|
|
| 148 |
int[] getSolvedQuats(int cubit, int numLayers) |
|
| 149 |
{
|
|
| 150 |
int status = retCubitSolvedStatus(cubit,numLayers); |
|
| 151 |
return status<0 ? null : buildSolvedQuats(MovementDiamond.FACE_AXIS[mFaceMap[status]],QUATS); |
|
| 152 |
} |
|
| 153 |
|
|
| 156 | 154 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 157 | 155 |
|
| 158 | 156 |
float getScreenRatio() |
| ... | ... | |
| 541 | 539 |
} |
| 542 | 540 |
} |
| 543 | 541 |
|
| 544 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 545 |
// The Diamond is solved if and only if: |
|
| 546 |
// |
|
| 547 |
// - all cubits are rotated by the same quat |
|
| 548 |
// - those which are internal to the side, i.e. those which have only one 'non-black' face, might |
|
| 549 |
// also be optionally rotated by one of the two quats whose axis is perpendicular to the face. |
|
| 550 |
// (including some octahedrons if numLayers>=4) |
|
| 551 |
|
|
| 552 |
public boolean isSolved() |
|
| 553 |
{
|
|
| 554 |
int q = CUBITS[0].mQuatIndex; |
|
| 555 |
int layers = getNumLayers(); |
|
| 556 |
int numO = getNumOctahedrons(layers); |
|
| 557 |
|
|
| 558 |
for(int i=1; i<numO; i++) |
|
| 559 |
{
|
|
| 560 |
if( CUBITS[i].mQuatIndex != q ) return false; |
|
| 561 |
} |
|
| 562 |
|
|
| 563 |
int qI, q1Index, q2Index, face; |
|
| 564 |
|
|
| 565 |
for(int i=numO; i<NUM_CUBITS; i++) |
|
| 566 |
{
|
|
| 567 |
face = retFaceTetraBelongsTo(i-numO,layers); |
|
| 568 |
q1Index = mFaceNeutralQuatIndex[face][0]; |
|
| 569 |
q2Index = mFaceNeutralQuatIndex[face][1]; |
|
| 570 |
qI = CUBITS[i].mQuatIndex; |
|
| 571 |
|
|
| 572 |
if( qI != q && qI != mulQuat(q,q1Index) && qI != mulQuat(q,q2Index) ) return false; |
|
| 573 |
} |
|
| 574 |
|
|
| 575 |
return true; |
|
| 576 |
} |
|
| 577 |
|
|
| 578 | 542 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 579 | 543 |
|
| 580 | 544 |
public int getObjectName(int numLayers) |
| src/main/java/org/distorted/objects/TwistyDino4.java | ||
|---|---|---|
| 88 | 88 |
super(size, quat, texture, mesh, effects, moves, ObjectList.DIN4, res, scrWidth); |
| 89 | 89 |
} |
| 90 | 90 |
|
| 91 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 92 |
|
|
| 93 |
int[] getSolvedQuats(int cubit, int numLayers) |
|
| 94 |
{
|
|
| 95 |
return null; |
|
| 96 |
} |
|
| 97 |
|
|
| 91 | 98 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 92 | 99 |
|
| 93 | 100 |
int getFaceColor(int cubit, int cubitface, int size) |
| src/main/java/org/distorted/objects/TwistyDino6.java | ||
|---|---|---|
| 45 | 45 |
super(size, quat, texture, mesh, effects, moves, ObjectList.DINO, res, scrWidth); |
| 46 | 46 |
} |
| 47 | 47 |
|
| 48 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 49 |
// Dino6 is solved if and only if: |
|
| 50 |
// |
|
| 51 |
// All four 'X' cubits (i.e. those whose longest edge goes along the X axis) are rotated |
|
| 52 |
// by the same quaternion qX, similarly all four 'Y' cubits by the same qY and all four 'Z' |
|
| 53 |
// by the same qZ, and then either: |
|
| 54 |
// |
|
| 55 |
// a) qX = qY = qZ |
|
| 56 |
// b) qY = qX*Q2 and qZ = qX*Q8 (i.e. swap of WHITE and YELLOW faces) |
|
| 57 |
// c) qX = qY*Q2 and qZ = qY*Q10 (i.e. swap of BLUE and GREEN faces) |
|
| 58 |
// d) qX = qZ*Q8 and qY = qZ*Q10 (i.e. swap of RED and BROWN faces) |
|
| 59 |
// |
|
| 60 |
// BUT: cases b), c) and d) are really the same - it's all just a mirror image of the original. |
|
| 61 |
// |
|
| 62 |
// X cubits: 0, 2, 8, 10 |
|
| 63 |
// Y cubits: 1, 3, 9, 11 |
|
| 64 |
// Z cubits: 4, 5, 6, 7 |
|
| 65 |
|
|
| 66 |
int[] getSolvedQuats(int cubit, int numLayers) |
|
| 67 |
{
|
|
| 68 |
switch(cubit) |
|
| 69 |
{
|
|
| 70 |
case 0: case 2: case 8: case 10: return null; |
|
| 71 |
case 1: case 3: case 9: case 11: return new int[] {2};
|
|
| 72 |
case 4: case 5: case 6: case 7: return new int[] {8};
|
|
| 73 |
} |
|
| 74 |
|
|
| 75 |
return null; |
|
| 76 |
} |
|
| 77 |
|
|
| 48 | 78 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 49 | 79 |
|
| 50 | 80 |
int getFaceColor(int cubit, int cubitface, int size) |
| ... | ... | |
| 87 | 117 |
} |
| 88 | 118 |
} |
| 89 | 119 |
|
| 90 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 91 |
// Dino6 is solved if and only if: |
|
| 92 |
// |
|
| 93 |
// All four 'X' cubits (i.e. those whose longest edge goes along the X axis) are rotated |
|
| 94 |
// by the same quaternion qX, similarly all four 'Y' cubits by the same qY and all four 'Z' |
|
| 95 |
// by the same qZ, and then either: |
|
| 96 |
// |
|
| 97 |
// a) qX = qY = qZ |
|
| 98 |
// b) qY = qX*Q2 and qZ = qX*Q8 (i.e. swap of WHITE and YELLOW faces) |
|
| 99 |
// c) qX = qY*Q2 and qZ = qY*Q10 (i.e. swap of BLUE and GREEN faces) |
|
| 100 |
// d) qX = qZ*Q8 and qY = qZ*Q10 (i.e. swap of RED and BROWN faces) |
|
| 101 |
// |
|
| 102 |
// BUT: cases b), c) and d) are really the same - it's all just a mirror image of the original. |
|
| 103 |
// |
|
| 104 |
// X cubits: 0, 2, 8, 10 |
|
| 105 |
// Y cubits: 1, 3, 9, 11 |
|
| 106 |
// Z cubits: 4, 5, 6, 7 |
|
| 107 |
|
|
| 108 |
public boolean isSolved() |
|
| 109 |
{
|
|
| 110 |
int qX = CUBITS[0].mQuatIndex; |
|
| 111 |
int qY = CUBITS[1].mQuatIndex; |
|
| 112 |
int qZ = CUBITS[4].mQuatIndex; |
|
| 113 |
|
|
| 114 |
if( CUBITS[2].mQuatIndex != qX || CUBITS[8].mQuatIndex != qX || CUBITS[10].mQuatIndex != qX || |
|
| 115 |
CUBITS[3].mQuatIndex != qY || CUBITS[9].mQuatIndex != qY || CUBITS[11].mQuatIndex != qY || |
|
| 116 |
CUBITS[5].mQuatIndex != qZ || CUBITS[6].mQuatIndex != qZ || CUBITS[ 7].mQuatIndex != qZ ) |
|
| 117 |
{
|
|
| 118 |
return false; |
|
| 119 |
} |
|
| 120 |
|
|
| 121 |
return ( qX==qY && qX==qZ ) || ( qY==mulQuat(qX,2) && qZ==mulQuat(qX,8) ); |
|
| 122 |
} |
|
| 123 |
|
|
| 124 | 120 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 125 | 121 |
|
| 126 | 122 |
public int getObjectName(int numLayers) |
| src/main/java/org/distorted/objects/TwistyHelicopter.java | ||
|---|---|---|
| 243 | 243 |
super(size, size, quat, texture, mesh, effects, moves, ObjectList.HELI, res, scrWidth); |
| 244 | 244 |
} |
| 245 | 245 |
|
| 246 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 247 |
|
|
| 248 |
int[] getSolvedQuats(int cubit, int numLayers) |
|
| 249 |
{
|
|
| 250 |
int status = retCubitSolvedStatus(cubit,numLayers); |
|
| 251 |
return status<0 ? null : buildSolvedQuats(MovementHelicopter.FACE_AXIS[status],QUATS); |
|
| 252 |
} |
|
| 253 |
|
|
| 246 | 254 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 247 | 255 |
|
| 248 | 256 |
float getScreenRatio() |
| ... | ... | |
| 426 | 434 |
} |
| 427 | 435 |
} |
| 428 | 436 |
|
| 429 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 430 |
// The Helicopter is solved if and only if: |
|
| 431 |
// |
|
| 432 |
// 1) all of its corner cubits are rotated with the same quat |
|
| 433 |
// 2) all its face cubits are rotated with the same quat like the corner ones, |
|
| 434 |
// and optionally they also might be turned by a multiple of 90 degrees along |
|
| 435 |
// a vector perpendicular to the face they lie on. |
|
| 436 |
// |
|
| 437 |
// i.e. |
|
| 438 |
// cubits 8, 9,10,11,12,13,14,15 - might be extra QUAT 1,8,9 |
|
| 439 |
// cubits 16,17,18,19,20,21,22,23 - might be extra QUAT 2,12,13 |
|
| 440 |
// cubits 24,25,26,27,28,29,30,31 - might be extra QUAT 3,14,15 |
|
| 441 |
|
|
| 442 |
public boolean isSolved() |
|
| 443 |
{
|
|
| 444 |
int q = CUBITS[0].mQuatIndex; |
|
| 445 |
|
|
| 446 |
if ( CUBITS[1].mQuatIndex == q && |
|
| 447 |
CUBITS[2].mQuatIndex == q && |
|
| 448 |
CUBITS[3].mQuatIndex == q && |
|
| 449 |
CUBITS[4].mQuatIndex == q && |
|
| 450 |
CUBITS[5].mQuatIndex == q && |
|
| 451 |
CUBITS[6].mQuatIndex == q && |
|
| 452 |
CUBITS[7].mQuatIndex == q ) |
|
| 453 |
{
|
|
| 454 |
int q1 = mulQuat(q,1); |
|
| 455 |
int q2 = mulQuat(q,8); |
|
| 456 |
int q3 = mulQuat(q,9); |
|
| 457 |
|
|
| 458 |
for(int index=8; index<16; index++) |
|
| 459 |
{
|
|
| 460 |
int qIndex = CUBITS[index].mQuatIndex; |
|
| 461 |
if( qIndex!=q && qIndex!=q1 && qIndex!=q2 && qIndex!=q3 ) return false; |
|
| 462 |
} |
|
| 463 |
|
|
| 464 |
q1 = mulQuat(q, 2); |
|
| 465 |
q2 = mulQuat(q,12); |
|
| 466 |
q3 = mulQuat(q,13); |
|
| 467 |
|
|
| 468 |
for(int index=16; index<24; index++) |
|
| 469 |
{
|
|
| 470 |
int qIndex = CUBITS[index].mQuatIndex; |
|
| 471 |
if( qIndex!=q && qIndex!=q1 && qIndex!=q2 && qIndex!=q3 ) return false; |
|
| 472 |
} |
|
| 473 |
|
|
| 474 |
q1 = mulQuat(q, 3); |
|
| 475 |
q2 = mulQuat(q,14); |
|
| 476 |
q3 = mulQuat(q,15); |
|
| 477 |
|
|
| 478 |
for(int index=24; index<32; index++) |
|
| 479 |
{
|
|
| 480 |
int qIndex = CUBITS[index].mQuatIndex; |
|
| 481 |
if( qIndex!=q && qIndex!=q1 && qIndex!=q2 && qIndex!=q3 ) return false; |
|
| 482 |
} |
|
| 483 |
|
|
| 484 |
return true; |
|
| 485 |
} |
|
| 486 |
|
|
| 487 |
return false; |
|
| 488 |
} |
|
| 489 |
|
|
| 490 | 437 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 491 | 438 |
|
| 492 | 439 |
public int getObjectName(int numLayers) |
| src/main/java/org/distorted/objects/TwistyIvy.java | ||
|---|---|---|
| 124 | 124 |
super(size, size, quat, texture, mesh, effects, moves, ObjectList.IVY, res, scrWidth); |
| 125 | 125 |
} |
| 126 | 126 |
|
| 127 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 128 |
|
|
| 129 |
int[] getSolvedQuats(int cubit, int numLayers) |
|
| 130 |
{
|
|
| 131 |
int status = retCubitSolvedStatus(cubit,numLayers); |
|
| 132 |
return status<0 ? null : buildSolvedQuats(MovementIvy.FACE_AXIS[status],QUATS); |
|
| 133 |
} |
|
| 134 |
|
|
| 127 | 135 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 128 | 136 |
|
| 129 | 137 |
float getScreenRatio() |
| ... | ... | |
| 456 | 464 |
} |
| 457 | 465 |
} |
| 458 | 466 |
|
| 459 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 460 |
// The Ivy is solved if and only if: |
|
| 461 |
// |
|
| 462 |
// 1) all 4 of its corner cubits are rotated with the same quat |
|
| 463 |
// 2) all its face cubits are rotated with the same quat like the corner ones, |
|
| 464 |
// and optionally they also might be upside down. |
|
| 465 |
// |
|
| 466 |
// i.e. |
|
| 467 |
// cubits [4] and [5] - might be extra QUAT[1] |
|
| 468 |
// cubits [6] and [7] - might be extra QUAT[2] |
|
| 469 |
// cubits [8] and [9] - might be extra QUAT[3] |
|
| 470 |
|
|
| 471 |
public boolean isSolved() |
|
| 472 |
{
|
|
| 473 |
int q1,q = CUBITS[0].mQuatIndex; |
|
| 474 |
|
|
| 475 |
if( CUBITS[1].mQuatIndex == q && |
|
| 476 |
CUBITS[2].mQuatIndex == q && |
|
| 477 |
CUBITS[3].mQuatIndex == q ) |
|
| 478 |
{
|
|
| 479 |
q1 = mulQuat(q,1); |
|
| 480 |
if( CUBITS[4].mQuatIndex != q && CUBITS[4].mQuatIndex != q1 ) return false; |
|
| 481 |
if( CUBITS[5].mQuatIndex != q && CUBITS[5].mQuatIndex != q1 ) return false; |
|
| 482 |
|
|
| 483 |
q1 = mulQuat(q,2); |
|
| 484 |
if( CUBITS[6].mQuatIndex != q && CUBITS[6].mQuatIndex != q1 ) return false; |
|
| 485 |
if( CUBITS[7].mQuatIndex != q && CUBITS[7].mQuatIndex != q1 ) return false; |
|
| 486 |
|
|
| 487 |
q1 = mulQuat(q,3); |
|
| 488 |
if( CUBITS[8].mQuatIndex != q && CUBITS[8].mQuatIndex != q1 ) return false; |
|
| 489 |
if( CUBITS[9].mQuatIndex != q && CUBITS[9].mQuatIndex != q1 ) return false; |
|
| 490 |
|
|
| 491 |
return true; |
|
| 492 |
} |
|
| 493 |
|
|
| 494 |
return false; |
|
| 495 |
} |
|
| 496 |
|
|
| 497 | 467 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 498 | 468 |
|
| 499 | 469 |
public int getObjectName(int numLayers) |
| src/main/java/org/distorted/objects/TwistyJing.java | ||
|---|---|---|
| 223 | 223 |
super(size, size, quat, texture, mesh, effects, moves, ObjectList.JING, res, scrWidth); |
| 224 | 224 |
} |
| 225 | 225 |
|
| 226 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 227 |
|
|
| 228 |
int[] getSolvedQuats(int cubit, int numLayers) |
|
| 229 |
{
|
|
| 230 |
int status = retCubitSolvedStatus(cubit,numLayers); |
|
| 231 |
return status<0 ? null : buildSolvedQuats(MovementJing.FACE_AXIS[status],QUATS); |
|
| 232 |
} |
|
| 233 |
|
|
| 226 | 234 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 227 | 235 |
|
| 228 | 236 |
float[][] getCubitPositions(int size) |
| ... | ... | |
| 406 | 414 |
} |
| 407 | 415 |
} |
| 408 | 416 |
|
| 409 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 410 |
// JingPyraminx is solved iff |
|
| 411 |
// a) all of its corner and edge cubits are rotated with the same quat |
|
| 412 |
// b) its 4 face cubits might also be rotated along the axis perpendicular to the face. |
|
| 413 |
// |
|
| 414 |
// So: |
|
| 415 |
// [10] might be extra QUAT[4] or QUAT[8] |
|
| 416 |
// [11] might be extra QUAT[5] or QUAT[9] |
|
| 417 |
// [12] might be extra QUAT[2] or QUAT[6] |
|
| 418 |
// [13] might be extra QUAT[3] or QUAT[7] |
|
| 419 |
|
|
| 420 |
public boolean isSolved() |
|
| 421 |
{
|
|
| 422 |
int q1, q = CUBITS[0].mQuatIndex; |
|
| 423 |
|
|
| 424 |
if( CUBITS[1].mQuatIndex != q ) return false; |
|
| 425 |
if( CUBITS[2].mQuatIndex != q ) return false; |
|
| 426 |
if( CUBITS[3].mQuatIndex != q ) return false; |
|
| 427 |
if( CUBITS[4].mQuatIndex != q ) return false; |
|
| 428 |
if( CUBITS[5].mQuatIndex != q ) return false; |
|
| 429 |
if( CUBITS[6].mQuatIndex != q ) return false; |
|
| 430 |
if( CUBITS[7].mQuatIndex != q ) return false; |
|
| 431 |
if( CUBITS[8].mQuatIndex != q ) return false; |
|
| 432 |
if( CUBITS[9].mQuatIndex != q ) return false; |
|
| 433 |
|
|
| 434 |
q1 = CUBITS[10].mQuatIndex; |
|
| 435 |
if( q1!=q && q1!=mulQuat(q,4) && q1!=mulQuat(q,8) ) return false; |
|
| 436 |
q1 = CUBITS[11].mQuatIndex; |
|
| 437 |
if( q1!=q && q1!=mulQuat(q,5) && q1!=mulQuat(q,9) ) return false; |
|
| 438 |
q1 = CUBITS[12].mQuatIndex; |
|
| 439 |
if( q1!=q && q1!=mulQuat(q,2) && q1!=mulQuat(q,6) ) return false; |
|
| 440 |
q1 = CUBITS[13].mQuatIndex; |
|
| 441 |
if( q1!=q && q1!=mulQuat(q,3) && q1!=mulQuat(q,7) ) return false; |
|
| 442 |
|
|
| 443 |
return true; |
|
| 444 |
} |
|
| 445 |
|
|
| 446 | 417 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 447 | 418 |
|
| 448 | 419 |
public int getObjectName(int numLayers) |
| src/main/java/org/distorted/objects/TwistyKilominx.java | ||
|---|---|---|
| 695 | 695 |
return 2; |
| 696 | 696 |
} |
| 697 | 697 |
|
| 698 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 699 |
// PUBLIC API |
|
| 700 |
|
|
| 701 |
public boolean isSolved() |
|
| 702 |
{
|
|
| 703 |
int index = CUBITS[0].mQuatIndex; |
|
| 704 |
|
|
| 705 |
for(int i=1; i<NUM_CUBITS; i++) |
|
| 706 |
{
|
|
| 707 |
if( thereIsVisibleDifference(CUBITS[i], index) ) return false; |
|
| 708 |
} |
|
| 709 |
|
|
| 710 |
return true; |
|
| 711 |
} |
|
| 712 |
|
|
| 713 | 698 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 714 | 699 |
|
| 715 | 700 |
public int getObjectName(int numLayers) |
| src/main/java/org/distorted/objects/TwistyMegaminx.java | ||
|---|---|---|
| 608 | 608 |
return 4; |
| 609 | 609 |
} |
| 610 | 610 |
|
| 611 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 612 |
// PUBLIC API |
|
| 613 |
|
|
| 614 |
public boolean isSolved() |
|
| 615 |
{
|
|
| 616 |
int index = CUBITS[0].mQuatIndex; |
|
| 617 |
|
|
| 618 |
for(int i=1; i<NUM_CUBITS; i++) |
|
| 619 |
{
|
|
| 620 |
if( thereIsVisibleDifference(CUBITS[i], index) ) return false; |
|
| 621 |
} |
|
| 622 |
|
|
| 623 |
return true; |
|
| 624 |
} |
|
| 625 |
|
|
| 626 | 611 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 627 | 612 |
|
| 628 | 613 |
public int getObjectName(int numLayers) |
| src/main/java/org/distorted/objects/TwistyMinx.java | ||
|---|---|---|
| 81 | 81 |
MINX_DBLUE , MINX_DYELLOW, MINX_WHITE , MINX_GREY |
| 82 | 82 |
}; |
| 83 | 83 |
|
| 84 |
private static final int[] mFaceMap = new int[] {8,10,3,7,1,11,9,2,4,0,5,6};
|
|
| 85 |
|
|
| 84 | 86 |
// All 60 legal rotation quats of a Minx |
| 85 | 87 |
static final Static4D[] QUATS = new Static4D[] |
| 86 | 88 |
{
|
| ... | ... | |
| 336 | 338 |
super(numLayers, realSize, quat, texture, mesh, effects, moves, obj, res, scrWidth); |
| 337 | 339 |
} |
| 338 | 340 |
|
| 341 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 342 |
|
|
| 343 |
int[] getSolvedQuats(int cubit, int numLayers) |
|
| 344 |
{
|
|
| 345 |
int status = retCubitSolvedStatus(cubit,numLayers); |
|
| 346 |
return status<0 ? null : buildSolvedQuats(MovementMinx.FACE_AXIS[mFaceMap[status]],QUATS); |
|
| 347 |
} |
|
| 348 |
|
|
| 339 | 349 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 340 | 350 |
|
| 341 | 351 |
Static4D[] getQuats() |
| src/main/java/org/distorted/objects/TwistyObject.java | ||
|---|---|---|
| 95 | 95 |
final int NUM_CUBITS; |
| 96 | 96 |
final int NUM_AXIS; |
| 97 | 97 |
|
| 98 |
private static final float[] mTmp1 = new float[4]; |
|
| 99 |
private static final float[] mTmp2 = new float[4]; |
|
| 100 |
|
|
| 101 | 98 |
private final int mNumCubitFaces; |
| 102 | 99 |
private final Static3D[] mAxis; |
| 103 | 100 |
private final float[][] mCuts; |
| ... | ... | |
| 119 | 116 |
private final DistortedTexture mTexture; |
| 120 | 117 |
private final float mInitScreenRatio; |
| 121 | 118 |
private float mObjectScreenRatio; |
| 119 |
private int[][] mSolvedQuats; |
|
| 120 |
private int[][] mQuatMult; |
|
| 121 |
private int[] mTmpQuats; |
|
| 122 | 122 |
private int mNumTexRows, mNumTexCols; |
| 123 | 123 |
private int mRotRowBitmap; |
| 124 | 124 |
private int mRotAxis; |
| ... | ... | |
| 186 | 186 |
|
| 187 | 187 |
CUBITS = new Cubit[NUM_CUBITS]; |
| 188 | 188 |
createMeshAndCubits(list,res); |
| 189 |
createDataStructuresForSolved(numLayers); |
|
| 189 | 190 |
|
| 190 | 191 |
mTexture = new DistortedTexture(); |
| 191 | 192 |
mEffects = new DistortedEffects(); |
| ... | ... | |
| 316 | 317 |
return mesh; |
| 317 | 318 |
} |
| 318 | 319 |
|
| 320 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 321 |
|
|
| 322 |
private void createDataStructuresForSolved(int numLayers) |
|
| 323 |
{
|
|
| 324 |
mTmpQuats = new int[QUATS.length]; |
|
| 325 |
mSolvedQuats = new int[NUM_CUBITS][]; |
|
| 326 |
|
|
| 327 |
for(int c=0; c<NUM_CUBITS; c++) |
|
| 328 |
{
|
|
| 329 |
mSolvedQuats[c] = getSolvedQuats(c,numLayers); |
|
| 330 |
} |
|
| 331 |
} |
|
| 332 |
|
|
| 333 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 334 |
// This is used to build internal data structures for the generic 'isSolved()' |
|
| 335 |
// |
|
| 336 |
// if this is an internal cubit (all faces black): return -1 |
|
| 337 |
// if this is a face cubit (one non-black face): return the color index of the only non-black face. |
|
| 338 |
// Color index, i.e. the index into the 'FACE_COLORS' table. |
|
| 339 |
// else (edge or corner cubit, more than one non-black face): return -2. |
|
| 340 |
|
|
| 341 |
int retCubitSolvedStatus(int cubit, int numLayers) |
|
| 342 |
{
|
|
| 343 |
int numNonBlack=0, nonBlackIndex=-1, color; |
|
| 344 |
|
|
| 345 |
for(int face=0; face<mNumCubitFaces; face++) |
|
| 346 |
{
|
|
| 347 |
color = getFaceColor(cubit,face,numLayers); |
|
| 348 |
|
|
| 349 |
if( color<NUM_TEXTURES ) |
|
| 350 |
{
|
|
| 351 |
numNonBlack++; |
|
| 352 |
nonBlackIndex = color%NUM_FACES; |
|
| 353 |
} |
|
| 354 |
} |
|
| 355 |
|
|
| 356 |
if( numNonBlack==0 ) return -1; |
|
| 357 |
if( numNonBlack>=2 ) return -2; |
|
| 358 |
|
|
| 359 |
return nonBlackIndex; |
|
| 360 |
} |
|
| 361 |
|
|
| 362 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 363 |
|
|
| 364 |
int[] buildSolvedQuats(Static3D faceAx, Static4D[] quats) |
|
| 365 |
{
|
|
| 366 |
final float MAXD = 0.0001f; |
|
| 367 |
float x = faceAx.get0(); |
|
| 368 |
float y = faceAx.get1(); |
|
| 369 |
float z = faceAx.get2(); |
|
| 370 |
float a,dx,dy,dz,qx,qy,qz; |
|
| 371 |
Static4D quat; |
|
| 372 |
|
|
| 373 |
int len = quats.length; |
|
| 374 |
int place = 0; |
|
| 375 |
|
|
| 376 |
for(int q=1; q<len; q++) |
|
| 377 |
{
|
|
| 378 |
quat = quats[q]; |
|
| 379 |
qx = quat.get0(); |
|
| 380 |
qy = quat.get1(); |
|
| 381 |
qz = quat.get2(); |
|
| 382 |
|
|
| 383 |
if( x!=0.0f ) { a = qx/x; }
|
|
| 384 |
else if( y!=0.0f ) { a = qy/y; }
|
|
| 385 |
else { a = qz/z; }
|
|
| 386 |
|
|
| 387 |
dx = a*x-qx; |
|
| 388 |
dy = a*y-qy; |
|
| 389 |
dz = a*z-qz; |
|
| 390 |
|
|
| 391 |
if( dx>-MAXD && dx<MAXD && dy>-MAXD && dy<MAXD && dz>-MAXD && dz<MAXD ) |
|
| 392 |
{
|
|
| 393 |
mTmpQuats[place++] = q; |
|
| 394 |
} |
|
| 395 |
} |
|
| 396 |
|
|
| 397 |
if( place!=0 ) |
|
| 398 |
{
|
|
| 399 |
int[] ret = new int[place]; |
|
| 400 |
System.arraycopy(mTmpQuats,0,ret,0,place); |
|
| 401 |
return ret; |
|
| 402 |
} |
|
| 403 |
|
|
| 404 |
return null; |
|
| 405 |
} |
|
| 406 |
|
|
| 407 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 408 |
|
|
| 409 |
private int getMultQuat(int index1, int index2) |
|
| 410 |
{
|
|
| 411 |
if( mQuatMult==null ) |
|
| 412 |
{
|
|
| 413 |
int len = QUATS.length; |
|
| 414 |
mQuatMult = new int[len][len]; |
|
| 415 |
|
|
| 416 |
for(int i=0; i<len; i++) |
|
| 417 |
for(int j=0; j<len; j++) mQuatMult[i][j] = -1; |
|
| 418 |
} |
|
| 419 |
|
|
| 420 |
if( mQuatMult[index1][index2]==-1 ) |
|
| 421 |
{
|
|
| 422 |
mQuatMult[index1][index2] = mulQuat(index1,index2); |
|
| 423 |
} |
|
| 424 |
|
|
| 425 |
return mQuatMult[index1][index2]; |
|
| 426 |
} |
|
| 427 |
|
|
| 428 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 429 |
|
|
| 430 |
public boolean isSolved() |
|
| 431 |
{
|
|
| 432 |
int len, q1,q = CUBITS[0].mQuatIndex; |
|
| 433 |
int[] solved; |
|
| 434 |
boolean skip; |
|
| 435 |
|
|
| 436 |
for(int c=1; c<NUM_CUBITS; c++) |
|
| 437 |
{
|
|
| 438 |
q1 = CUBITS[c].mQuatIndex; |
|
| 439 |
|
|
| 440 |
if( q1==q ) continue; |
|
| 441 |
|
|
| 442 |
skip = false; |
|
| 443 |
solved = mSolvedQuats[c]; |
|
| 444 |
len = solved==null ? 0:solved.length; |
|
| 445 |
|
|
| 446 |
for(int i=0; i<len; i++) |
|
| 447 |
{
|
|
| 448 |
if( q1==getMultQuat(q,solved[i]) ) |
|
| 449 |
{
|
|
| 450 |
skip = true; |
|
| 451 |
break; |
|
| 452 |
} |
|
| 453 |
} |
|
| 454 |
|
|
| 455 |
if( !skip ) return false; |
|
| 456 |
} |
|
| 457 |
|
|
| 458 |
return true; |
|
| 459 |
} |
|
| 460 |
|
|
| 319 | 461 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 320 | 462 |
|
| 321 | 463 |
public void setObjectRatio(float sizeChange) |
| ... | ... | |
| 523 | 665 |
return -1; |
| 524 | 666 |
} |
| 525 | 667 |
|
| 526 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 527 |
// return if the Cubit, when rotated with its own mQuatScramble, would have looked any different |
|
| 528 |
// then if it were rotated by quaternion 'quat'. |
|
| 529 |
// No it is not so simple as the quats need to be the same - imagine a 4x4x4 cube where the two |
|
| 530 |
// middle squares get interchanged. No visible difference! |
|
| 531 |
// |
|
| 532 |
// So: this is true iff the cubit |
|
| 533 |
// a) is a corner or edge and the quaternions are the same |
|
| 534 |
// b) is inside one of the faces and after rotations by both quats it ends up on the same face. |
|
| 535 |
|
|
| 536 |
boolean thereIsVisibleDifference(Cubit cubit, int quatIndex) |
|
| 537 |
{
|
|
| 538 |
if ( cubit.mQuatIndex == quatIndex ) return false; |
|
| 539 |
|
|
| 540 |
int belongsToHowManyFaces = 0; |
|
| 541 |
int bitmap = (1<<(getNumLayers()-1)) + 1; |
|
| 542 |
|
|
| 543 |
for(int i = 0; i< NUM_AXIS; i++) |
|
| 544 |
{
|
|
| 545 |
if( (cubit.mRotationRow[i] & bitmap) != 0 ) belongsToHowManyFaces++; |
|
| 546 |
} |
|
| 547 |
|
|
| 548 |
switch(belongsToHowManyFaces) |
|
| 549 |
{
|
|
| 550 |
case 0 : return false; // 'inside' cubit that does not lie on any face |
|
| 551 |
case 1 : // cubit that lies inside one of the faces |
|
| 552 |
float[] orig = cubit.getOrigPosition(); |
|
| 553 |
Static4D quat1 = QUATS[quatIndex]; |
|
| 554 |
Static4D quat2 = QUATS[cubit.mQuatIndex]; |
|
| 555 |
|
|
| 556 |
Static4D cubitCenter = new Static4D( orig[0], orig[1], orig[2], 0); // not used for bandaged objects, |
|
| 557 |
Static4D rotated1 = QuatHelper.rotateVectorByQuat( cubitCenter, quat1 ); // only check the first position |
|
| 558 |
Static4D rotated2 = QuatHelper.rotateVectorByQuat( cubitCenter, quat2 ); |
|
| 559 |
|
|
| 560 |
rotated1.get(mTmp1, 0, 0, 0); |
|
| 561 |
rotated2.get(mTmp2, 0, 0, 0); |
|
| 562 |
|
|
| 563 |
for(int i = 0; i< NUM_AXIS; i++) |
|
| 564 |
{
|
|
| 565 |
if( (computeRow(mTmp1,i) & computeRow(mTmp2,i) & bitmap) != 0 ) return false; |
|
| 566 |
} |
|
| 567 |
return true; |
|
| 568 |
|
|
| 569 |
default: return true; // edge or corner |
|
| 570 |
} |
|
| 571 |
} |
|
| 572 |
|
|
| 573 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 574 |
// create StickerCoord and FaceTransform data structures |
|
| 575 |
|
|
| 576 |
void createFaceDataStructures(double[][][] verts, int[][][] indices) |
|
| 577 |
{
|
|
| 578 |
int numCubitTypes = verts.length; |
|
| 579 |
FactoryCubit factory = FactoryCubit.getInstance(); |
|
| 580 |
factory.clear(); |
|
| 581 |
|
|
| 582 |
for(int cubit=0; cubit<numCubitTypes; cubit++) |
|
| 583 |
{
|
|
| 584 |
double[][] vertices = verts[cubit]; |
|
| 585 |
int[][] vertIndices = indices[cubit]; |
|
| 586 |
factory.createNewFaceTransform(vertices,vertIndices); |
|
| 587 |
} |
|
| 588 |
|
|
| 589 |
factory.printFaceTransform(); |
|
| 590 |
factory.printStickerCoords(); |
|
| 591 |
} |
|
| 592 |
|
|
| 593 | 668 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 594 | 669 |
|
| 595 | 670 |
public int getCubitFaceColorIndex(int cubit, int face) |
| ... | ... | |
| 1013 | 1088 |
abstract int getNumCubitVariants(int numLayers); |
| 1014 | 1089 |
abstract Static4D getQuat(int cubit, int numLayers); |
| 1015 | 1090 |
abstract ObjectShape getObjectShape(int cubit, int numLayers); |
| 1091 |
abstract int[] getSolvedQuats(int cubit, int numLayers); |
|
| 1016 | 1092 |
|
| 1017 | 1093 |
public abstract Static3D[] getRotationAxis(); |
| 1018 |
public abstract boolean isSolved(); |
|
| 1019 | 1094 |
public abstract int[] getBasicAngle(); |
| 1020 | 1095 |
public abstract void randomizeNewScramble(int[][] scramble, Random rnd, int curScramble, int totScrambles); |
| 1021 | 1096 |
public abstract int getObjectName(int numLayers); |
| src/main/java/org/distorted/objects/TwistyPyraminx.java | ||
|---|---|---|
| 135 | 135 |
super(size, size, quat, texture, mesh, effects, moves, ObjectList.PYRA, res, scrWidth); |
| 136 | 136 |
} |
| 137 | 137 |
|
| 138 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 139 |
|
|
| 140 |
int[] getSolvedQuats(int cubit, int numLayers) |
|
| 141 |
{
|
|
| 142 |
int status = retCubitSolvedStatus(cubit,numLayers); |
|
| 143 |
return status<0 ? null : buildSolvedQuats(MovementPyraminx.FACE_AXIS[status],QUATS); |
|
| 144 |
} |
|
| 145 |
|
|
| 138 | 146 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 139 | 147 |
|
| 140 | 148 |
private float[] getRowChances(int numLayers) |
| ... | ... | |
| 441 | 449 |
} |
| 442 | 450 |
} |
| 443 | 451 |
|
| 444 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 445 |
|
|
| 446 |
public boolean isSolved() |
|
| 447 |
{
|
|
| 448 |
int index = CUBITS[0].mQuatIndex; |
|
| 449 |
|
|
| 450 |
for(int i=1; i<NUM_CUBITS; i++) |
|
| 451 |
{
|
|
| 452 |
if( thereIsVisibleDifference(CUBITS[i], index) ) return false; |
|
| 453 |
} |
|
| 454 |
|
|
| 455 |
return true; |
|
| 456 |
} |
|
| 457 |
|
|
| 458 | 452 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 459 | 453 |
|
| 460 | 454 |
public int getObjectName(int numLayers) |
| src/main/java/org/distorted/objects/TwistyRedi.java | ||
|---|---|---|
| 213 | 213 |
super(size, size, quat, texture, mesh, effects, moves, ObjectList.REDI, res, scrWidth); |
| 214 | 214 |
} |
| 215 | 215 |
|
| 216 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 217 |
|
|
| 218 |
int[] getSolvedQuats(int cubit, int numLayers) |
|
| 219 |
{
|
|
| 220 |
int status = retCubitSolvedStatus(cubit,numLayers); |
|
| 221 |
return status<0 ? null : buildSolvedQuats(MovementRedi.FACE_AXIS[status],QUATS); |
|
| 222 |
} |
|
| 223 |
|
|
| 216 | 224 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 217 | 225 |
|
| 218 | 226 |
float getScreenRatio() |
| ... | ... | |
| 478 | 486 |
} |
| 479 | 487 |
} |
| 480 | 488 |
|
| 481 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 482 |
// The Redi is solved if and only if all cubits are rotated with the same quat. |
|
| 483 |
|
|
| 484 |
public boolean isSolved() |
|
| 485 |
{
|
|
| 486 |
int q = CUBITS[0].mQuatIndex; |
|
| 487 |
|
|
| 488 |
return ( CUBITS[ 1].mQuatIndex == q && |
|
| 489 |
CUBITS[ 2].mQuatIndex == q && |
|
| 490 |
CUBITS[ 3].mQuatIndex == q && |
|
| 491 |
CUBITS[ 4].mQuatIndex == q && |
|
| 492 |
CUBITS[ 5].mQuatIndex == q && |
|
| 493 |
CUBITS[ 6].mQuatIndex == q && |
|
| 494 |
CUBITS[ 7].mQuatIndex == q && |
|
| 495 |
CUBITS[ 8].mQuatIndex == q && |
|
| 496 |
CUBITS[ 9].mQuatIndex == q && |
|
| 497 |
CUBITS[10].mQuatIndex == q && |
|
| 498 |
CUBITS[11].mQuatIndex == q && |
|
| 499 |
CUBITS[12].mQuatIndex == q && |
|
| 500 |
CUBITS[13].mQuatIndex == q && |
|
| 501 |
CUBITS[14].mQuatIndex == q && |
|
| 502 |
CUBITS[15].mQuatIndex == q && |
|
| 503 |
CUBITS[16].mQuatIndex == q && |
|
| 504 |
CUBITS[17].mQuatIndex == q && |
|
| 505 |
CUBITS[18].mQuatIndex == q && |
|
| 506 |
CUBITS[19].mQuatIndex == q ); |
|
| 507 |
} |
|
| 508 |
|
|
| 509 | 489 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 510 | 490 |
|
| 511 | 491 |
public int getObjectName(int numLayers) |
| src/main/java/org/distorted/objects/TwistyRex.java | ||
|---|---|---|
| 160 | 160 |
super(size, size, quat, texture, mesh, effects, moves, ObjectList.REX, res, scrWidth); |
| 161 | 161 |
} |
| 162 | 162 |
|
| 163 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 164 |
|
|
| 165 |
int[] getSolvedQuats(int cubit, int numLayers) |
|
| 166 |
{
|
|
| 167 |
int status = retCubitSolvedStatus(cubit,numLayers); |
|
| 168 |
return status<0 ? null : buildSolvedQuats(MovementRex.FACE_AXIS[status],QUATS); |
|
| 169 |
} |
|
| 170 |
|
|
| 163 | 171 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 164 | 172 |
|
| 165 | 173 |
float getScreenRatio() |
| ... | ... | |
| 487 | 495 |
} |
| 488 | 496 |
} |
| 489 | 497 |
|
| 490 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 491 |
// The Rex is solved if and only if: |
|
| 492 |
// |
|
| 493 |
// 1) all 12 of its edge cubits are rotated with the same quat |
|
| 494 |
// 2) all its face & corner cubits are rotated with the same quat like the edge ones, |
|
| 495 |
// and optionally they also might be upside down. |
|
| 496 |
// |
|
| 497 |
// i.e. |
|
| 498 |
// corners ( 0, 1, 2, 3, 4, 5, 6, 7) and faces (24,25) - might be extra QUAT[1] |
|
| 499 |
// corners ( 8, 9,10,11,12,13,14,15) and faces (26,27) - might be extra QUAT[2] |
|
| 500 |
// corners (16,17,18,19,20,21,22,23) and faces (28,29) - might be extra QUAT[3] |
|
| 501 |
|
|
| 502 |
public boolean isSolved() |
|
| 503 |
{
|
|
| 504 |
int q1,q = CUBITS[30].mQuatIndex; |
|
| 505 |
|
|
| 506 |
for(int i=31; i<42; i++) |
|
| 507 |
{
|
|
| 508 |
if( CUBITS[i].mQuatIndex != q) return false; |
|
| 509 |
} |
|
| 510 |
|
|
| 511 |
q1 = mulQuat(q,1); |
|
| 512 |
|
|
| 513 |
for(int i=0; i<8; i++) |
|
| 514 |
{
|
|
| 515 |
if( CUBITS[i].mQuatIndex != q && CUBITS[i].mQuatIndex != q1 ) return false; |
|
| 516 |
} |
|
| 517 |
|
|
| 518 |
if( CUBITS[24].mQuatIndex != q && CUBITS[24].mQuatIndex != q1 ) return false; |
|
| 519 |
if( CUBITS[25].mQuatIndex != q && CUBITS[25].mQuatIndex != q1 ) return false; |
|
| 520 |
|
|
| 521 |
q1 = mulQuat(q,2); |
|
| 522 |
|
|
| 523 |
for(int i=8; i<16; i++) |
|
| 524 |
{
|
|
| 525 |
if( CUBITS[i].mQuatIndex != q && CUBITS[i].mQuatIndex != q1 ) return false; |
|
| 526 |
} |
|
| 527 |
|
|
| 528 |
if( CUBITS[26].mQuatIndex != q && CUBITS[26].mQuatIndex != q1 ) return false; |
|
| 529 |
if( CUBITS[27].mQuatIndex != q && CUBITS[27].mQuatIndex != q1 ) return false; |
|
| 530 |
|
|
| 531 |
q1 = mulQuat(q,3); |
|
| 532 |
|
|
| 533 |
for(int i=16; i<24; i++) |
|
| 534 |
{
|
|
| 535 |
if( CUBITS[i].mQuatIndex != q && CUBITS[i].mQuatIndex != q1 ) return false; |
|
| 536 |
} |
|
| 537 |
|
|
| 538 |
if( CUBITS[28].mQuatIndex != q && CUBITS[28].mQuatIndex != q1 ) return false; |
|
| 539 |
if( CUBITS[29].mQuatIndex != q && CUBITS[29].mQuatIndex != q1 ) return false; |
|
| 540 |
|
|
| 541 |
return true; |
|
| 542 |
} |
|
| 543 |
|
|
| 544 | 498 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 545 | 499 |
|
| 546 | 500 |
public int getObjectName(int numLayers) |
| src/main/java/org/distorted/objects/TwistySkewb.java | ||
|---|---|---|
| 197 | 197 |
super(size, 2*size-2, quat, texture, mesh, effects, moves, ObjectList.SKEW, res, scrWidth); |
| 198 | 198 |
} |
| 199 | 199 |
|
| 200 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 201 |
|
|
| 202 |
int[] getSolvedQuats(int cubit, int numLayers) |
|
| 203 |
{
|
|
| 204 |
int status = retCubitSolvedStatus(cubit,numLayers); |
|
| 205 |
return status<0 ? null : buildSolvedQuats(MovementSkewb.FACE_AXIS[status],QUATS); |
|
| 206 |
} |
|
| 207 |
|
|
| 200 | 208 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 201 | 209 |
|
| 202 | 210 |
private int getNumCorners() |
| ... | ... | |
| 605 | 613 |
} |
| 606 | 614 |
} |
| 607 | 615 |
|
| 608 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 609 |
// The Skewb is solved if and only if: |
|
| 610 |
// |
|
| 611 |
// 1) all of its corner and edge cubits are rotated with the same quat |
|
| 612 |
// 2) all its face cubits are rotated with the same quat like the corner ones, |
|
| 613 |
// and optionally they also might be upside down. |
|
| 614 |
// |
|
| 615 |
// i.e. |
|
| 616 |
// cubits [ 8] and [ 9] - might be extra QUAT[1] |
|
| 617 |
// cubits [10] and [11] - might be extra QUAT[2] |
|
| 618 |
// cubits [12] and [13] - might be extra QUAT[3] |
|
| 619 |
|
|
| 620 |
public boolean isSolved() |
|
| 621 |
{
|
|
| 622 |
int q = CUBITS[0].mQuatIndex; |
|
| 623 |
|
|
| 624 |
int numLayers = getNumLayers(); |
|
| 625 |
int numCorners = getNumCorners(); |
|
| 626 |
int numEdges = getNumEdges(numLayers); |
|
| 627 |
int cornersAndEdges= numCorners + numEdges; |
|
| 628 |
int centersPerFace = getNumCentersPerFace(numLayers); |
|
| 629 |
int cubit, q1=q; |
|
| 630 |
|
|
| 631 |
for(cubit=0; cubit<cornersAndEdges; cubit++) |
|
| 632 |
{
|
|
| 633 |
if( CUBITS[cubit].mQuatIndex != q ) return false; |
|
| 634 |
} |
|
| 635 |
|
|
| 636 |
for(int face=0; face<6; face++) |
|
| 637 |
{
|
|
| 638 |
if( face%2==0 ) q1 = mulQuat(q, (face/2)+1); |
|
| 639 |
|
|
| 640 |
for(int center=0; center<centersPerFace; center++) |
|
| 641 |
{
|
|
| 642 |
if( CUBITS[cubit].mQuatIndex != q && CUBITS[cubit].mQuatIndex != q1 ) return false; |
|
| 643 |
cubit++; |
|
| 644 |
} |
|
| 645 |
} |
|
| 646 |
|
|
| 647 |
return true; |
|
| 648 |
} |
|
| 649 |
|
|
| 650 | 616 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 651 | 617 |
|
| 652 | 618 |
public int getObjectName(int numLayers) |
| src/main/java/org/distorted/objects/TwistySquare1.java | ||
|---|---|---|
| 176 | 176 |
mCornerQuat = new int[8]; |
| 177 | 177 |
} |
| 178 | 178 |
|
| 179 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 180 |
|
|
| 181 |
int[] getSolvedQuats(int cubit, int numLayers) |
|
| 182 |
{
|
|
| 183 |
int status = retCubitSolvedStatus(cubit,numLayers); |
|
| 184 |
return status<0 ? null : buildSolvedQuats(MovementSquare.FACE_AXIS[status],QUATS); |
|
| 185 |
} |
|
| 186 |
|
|
| 179 | 187 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 180 | 188 |
|
| 181 | 189 |
ObjectShape getObjectShape(int cubit, int numLayers) |
| ... | ... | |
| 513 | 521 |
} |
| 514 | 522 |
} |
| 515 | 523 |
|
| 516 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 517 |
|
|
| 518 |
public boolean isSolved() |
|
| 519 |
{
|
|
| 520 |
int index = CUBITS[0].mQuatIndex; |
|
| 521 |
|
|
| 522 |
for(int i=1; i<NUM_CUBITS; i++) |
|
| 523 |
{
|
|
| 524 |
if( CUBITS[i].mQuatIndex != index ) return false; |
|
| 525 |
} |
|
| 526 |
|
|
| 527 |
return true; |
|
| 528 |
} |
|
| 529 |
|
|
| 530 | 524 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 531 | 525 |
|
| 532 | 526 |
public int getObjectName(int numLayers) |
| src/main/java/org/distorted/objects/TwistySquare2.java | ||
|---|---|---|
| 181 | 181 |
super(size, quat, texture, mesh, effects, moves, ObjectList.SQU2, res, scrWidth); |
| 182 | 182 |
} |
| 183 | 183 |
|
| 184 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 185 |
// Square-2 is solved iff |
|
| 186 |
// a) all of its cubits are rotated with the same quat |
|
| 187 |
// b) its two 'middle' cubits are rotated with the same quat, the 6 'front' and 6 'back' |
|
| 188 |
// edges and corners with this quat multiplied by QUATS[18] (i.e. those are upside down) |
|
| 189 |
// and all the 12 left and right edges and corners also with the same quat multiplied by |
|
| 190 |
// QUATS[12] - i.e. also upside down. |
|
| 191 |
|
|
| 192 |
private static final int[] S18 = new int[] {18};
|
|
| 193 |
private static final int[] S12 = new int[] {12};
|
|
| 194 |
|
|
| 195 |
int[] getSolvedQuats(int cubit, int numLayers) |
|
| 196 |
{
|
|
| 197 |
switch(cubit) |
|
| 198 |
{
|
|
| 199 |
case 0: case 1: return null; |
|
| 200 |
case 2: case 4: case 6: case 8: |
|
| 201 |
case 10: case 12: case 14: case 16: |
|
| 202 |
case 19: case 21: case 23: case 25: return S18; |
|
| 203 |
case 3: case 5: case 7: case 9: |
|
| 204 |
case 11: case 13: case 15: case 17: |
|
| 205 |
case 18: case 20: case 22: case 24: return S12; |
|
| 206 |
} |
|
| 207 |
|
|
| 208 |
return null; |
|
| 209 |
} |
|
| 210 |
|
|
| 184 | 211 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 185 | 212 |
|
| 186 | 213 |
ObjectShape getObjectShape(int cubit, int numLayers) |
| ... | ... | |
| 327 | 354 |
} |
| 328 | 355 |
} |
| 329 | 356 |
|
| 330 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 331 |
// Square-2 is solved iff |
|
| 332 |
// a) all of its cubits are rotated with the same quat |
|
| 333 |
// b) its two 'middle' cubits are rotated with the same quat, the 6 'front' and 6 'back' |
|
| 334 |
// edges and corners with this quat multiplied by QUATS[18] (i.e. those are upside down) |
|
| 335 |
// and all the 12 left and right edges and corners also with the same quat multiplied by |
|
| 336 |
// QUATS[12] - i.e. also upside down. |
|
| 337 |
|
|
| 338 |
public boolean isSolved() |
|
| 339 |
{
|
|
| 340 |
int index = CUBITS[0].mQuatIndex; |
|
| 341 |
|
|
| 342 |
if( CUBITS[1].mQuatIndex!=index ) return false; |
|
| 343 |
|
|
| 344 |
int indexX = mulQuat(index,12); // QUATS[12] = 180deg (1,0,0) |
|
| 345 |
int indexZ = mulQuat(index,18); // QUATS[18] = 180deg (0,0,1) |
|
| 346 |
|
|
| 347 |
for(int i=2; i<18; i+=2) |
|
| 348 |
{
|
|
| 349 |
if( CUBITS[i].mQuatIndex != index && CUBITS[i].mQuatIndex != indexZ ) return false; |
|
| 350 |
} |
|
| 351 |
for(int i=3; i<18; i+=2) |
|
| 352 |
{
|
|
| 353 |
if( CUBITS[i].mQuatIndex != index && CUBITS[i].mQuatIndex != indexX ) return false; |
|
| 354 |
} |
|
| 355 |
for(int i=18; i<NUM_CUBITS; i+=2) |
|
| 356 |
{
|
|
| 357 |
if( CUBITS[i].mQuatIndex != index && CUBITS[i].mQuatIndex != indexX ) return false; |
|
| 358 |
} |
|
| 359 |
for(int i=19; i<NUM_CUBITS; i+=2) |
|
| 360 |
{
|
|
| 361 |
if( CUBITS[i].mQuatIndex != index && CUBITS[i].mQuatIndex != indexZ ) return false; |
|
| 362 |
} |
|
| 363 |
|
|
| 364 |
return true; |
|
| 365 |
} |
|
| 366 |
|
|
| 367 | 357 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 368 | 358 |
|
| 369 | 359 |
public int getObjectName(int numLayers) |
| src/main/java/org/distorted/objects/TwistyUltimate.java | ||
|---|---|---|
| 240 | 240 |
super(size, size, quat, texture, mesh, effects, moves, ObjectList.ULTI, res, scrWidth); |
| 241 | 241 |
} |
| 242 | 242 |
|
| 243 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 244 |
|
|
| 245 |
int[] getSolvedQuats(int cubit, int numLayers) |
|
| 246 |
{
|
|
| 247 |
int status = retCubitSolvedStatus(cubit,numLayers); |
|
| 248 |
return status<0 ? null : buildSolvedQuats(MovementUltimate.FACE_AXIS[status],QUATS); |
|
| 249 |
} |
|
| 250 |
|
|
| 243 | 251 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 244 | 252 |
|
| 245 | 253 |
ObjectShape getObjectShape(int cubit, int numLayers) |
| ... | ... | |
| 422 | 430 |
} |
| 423 | 431 |
} |
| 424 | 432 |
|
| 425 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 426 |
|
|
| 427 |
public boolean isSolved() |
|
| 428 |
{
|
|
| 429 |
int index = CUBITS[0].mQuatIndex; |
|
| 430 |
|
|
| 431 |
for(int i=1; i<NUM_CUBITS; i++) |
|
| 432 |
{
|
|
| 433 |
if( CUBITS[i].mQuatIndex != index ) return false; |
|
| 434 |
} |
|
| 435 |
|
|
| 436 |
return true; |
|
| 437 |
} |
|
| 438 |
|
|
| 439 | 433 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 440 | 434 |
|
| 441 | 435 |
public int getObjectName(int numLayers) |
Also available in: Unified diff
Standarize the 'isSolved()' method: now all objects, except one (Dino4) have a standard isSolved().
This incidentally also fixes detection of the solved state in case of Diamond4, i.e. a Master FTO.