Revision 221a4090
Added by Leszek Koltunski over 4 years ago
| build.gradle | ||
|---|---|---|
| 36 | 36 |
dependencies {
|
| 37 | 37 |
implementation fileTree(dir: 'libs', include: ['*.jar']) |
| 38 | 38 |
implementation 'com.google.firebase:firebase-analytics:18.0.2' |
| 39 |
implementation 'com.google.firebase:firebase-crashlytics:17.3.1'
|
|
| 39 |
implementation 'com.google.firebase:firebase-crashlytics:17.4.0'
|
|
| 40 | 40 |
implementation 'com.google.android.play:core:1.10.0' |
| 41 | 41 |
|
| 42 | 42 |
api project(':distorted-library')
|
| src/main/java/org/distorted/objects/TwistyBandagedAbstract.java | ||
|---|---|---|
| 30 | 30 |
import org.distorted.library.mesh.MeshSquare; |
| 31 | 31 |
import org.distorted.library.type.Static3D; |
| 32 | 32 |
import org.distorted.library.type.Static4D; |
| 33 |
import org.distorted.main.RubikSurfaceView; |
|
| 34 | 33 |
|
| 35 | 34 |
import java.util.Random; |
| 36 | 35 |
|
| ... | ... | |
| 389 | 388 |
} |
| 390 | 389 |
|
| 391 | 390 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 391 |
// TODO |
|
| 392 | 392 |
|
| 393 | 393 |
public boolean isSolved() |
| 394 | 394 |
{
|
| ... | ... | |
| 402 | 402 |
return true; |
| 403 | 403 |
} |
| 404 | 404 |
|
| 405 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 406 |
// return if the Cubit, when rotated with its own mQuatScramble, would have looked any different |
|
| 407 |
// then if it were rotated by quaternion 'quat'. |
|
| 408 |
// No it is not so simple as the quats need to be the same - imagine a 4x4x4 cube where the two |
|
| 409 |
// middle squares get interchanged. No visible difference! |
|
| 410 |
// |
|
| 411 |
// So: this is true iff the cubit |
|
| 412 |
// a) is a corner or edge and the quaternions are the same |
|
| 413 |
// b) is inside one of the faces and after rotations by both quats it ends up on the same face. |
|
| 414 |
|
|
| 415 |
private boolean thereIsNoVisibleDifference(Cubit cubit, int quatIndex) |
|
| 416 |
{
|
|
| 417 |
if ( cubit.mQuatIndex == quatIndex ) return true; |
|
| 418 |
|
|
| 419 |
int belongsToHowManyFaces = 0; |
|
| 420 |
int lastLayer = getNumLayers()-1; |
|
| 421 |
float row; |
|
| 422 |
final float MAX_ERROR = 0.01f; |
|
| 423 |
|
|
| 424 |
for(int i=0; i<NUM_AXIS; i++) |
|
| 425 |
{
|
|
| 426 |
row = cubit.mRotationRow[i]; |
|
| 427 |
if( (row <MAX_ERROR && row >-MAX_ERROR) || |
|
| 428 |
(row-lastLayer<MAX_ERROR && row-lastLayer>-MAX_ERROR) ) belongsToHowManyFaces++; |
|
| 429 |
} |
|
| 430 |
|
|
| 431 |
switch(belongsToHowManyFaces) |
|
| 432 |
{
|
|
| 433 |
case 0 : return true ; // 'inside' cubit that does not lie on any face |
|
| 434 |
case 1 : // cubit that lies inside one of the faces |
|
| 435 |
Static3D orig = cubit.getOrigPosition(); |
|
| 436 |
Static4D quat1 = QUATS[quatIndex]; |
|
| 437 |
Static4D quat2 = QUATS[cubit.mQuatIndex]; |
|
| 438 |
|
|
| 439 |
Static4D cubitCenter = new Static4D( orig.get0(), orig.get1(), orig.get2(), 0); |
|
| 440 |
Static4D rotated1 = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat1 ); |
|
| 441 |
Static4D rotated2 = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat2 ); |
|
| 442 |
|
|
| 443 |
float row1, row2; |
|
| 444 |
float x1 = rotated1.get0(); |
|
| 445 |
float y1 = rotated1.get1(); |
|
| 446 |
float z1 = rotated1.get2(); |
|
| 447 |
float x2 = rotated2.get0(); |
|
| 448 |
float y2 = rotated2.get1(); |
|
| 449 |
float z2 = rotated2.get2(); |
|
| 450 |
|
|
| 451 |
for(int i=0; i<NUM_AXIS; i++) |
|
| 452 |
{
|
|
| 453 |
row1 = computeRow(x1,y1,z1,i); |
|
| 454 |
row2 = computeRow(x2,y2,z2,i); |
|
| 455 |
|
|
| 456 |
if( (row1==0 && row2==0) || (row1==lastLayer && row2==lastLayer) ) return true; |
|
| 457 |
} |
|
| 458 |
return false; |
|
| 459 |
|
|
| 460 |
default: return false; // edge or corner |
|
| 461 |
} |
|
| 462 |
} |
|
| 463 |
|
|
| 464 | 405 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 465 | 406 |
// only needed for solvers - there are no Bandaged solvers ATM) |
| 466 | 407 |
|
| src/main/java/org/distorted/objects/TwistyCube.java | ||
|---|---|---|
| 216 | 216 |
|
| 217 | 217 |
int getFaceColor(int cubit, int cubitface, int size) |
| 218 | 218 |
{
|
| 219 |
float diff = CUBITS[cubit].mRotationRow[cubitface/2] - (cubitface%2==0 ? size-1:0); |
|
| 220 |
return diff*diff < 0.0001f ? cubitface : NUM_FACES; |
|
| 219 |
return CUBITS[cubit].mRotationRow[cubitface/2] == (cubitface%2==0 ? size-1:0) ? cubitface : NUM_FACES; |
|
| 221 | 220 |
} |
| 222 | 221 |
|
| 223 | 222 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| ... | ... | |
| 301 | 300 |
return true; |
| 302 | 301 |
} |
| 303 | 302 |
|
| 304 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 305 |
// return if the Cubit, when rotated with its own mQuatScramble, would have looked any different |
|
| 306 |
// then if it were rotated by quaternion 'quat'. |
|
| 307 |
// No it is not so simple as the quats need to be the same - imagine a 4x4x4 cube where the two |
|
| 308 |
// middle squares get interchanged. No visible difference! |
|
| 309 |
// |
|
| 310 |
// So: this is true iff the cubit |
|
| 311 |
// a) is a corner or edge and the quaternions are the same |
|
| 312 |
// b) is inside one of the faces and after rotations by both quats it ends up on the same face. |
|
| 313 |
|
|
| 314 |
private boolean thereIsNoVisibleDifference(Cubit cubit, int quatIndex) |
|
| 315 |
{
|
|
| 316 |
if ( cubit.mQuatIndex == quatIndex ) return true; |
|
| 317 |
|
|
| 318 |
int belongsToHowManyFaces = 0; |
|
| 319 |
int lastLayer = getNumLayers()-1; |
|
| 320 |
float row; |
|
| 321 |
final float MAX_ERROR = 0.01f; |
|
| 322 |
|
|
| 323 |
for(int i=0; i<NUM_AXIS; i++) |
|
| 324 |
{
|
|
| 325 |
row = cubit.mRotationRow[i]; |
|
| 326 |
if( (row <MAX_ERROR && row >-MAX_ERROR) || |
|
| 327 |
(row-lastLayer<MAX_ERROR && row-lastLayer>-MAX_ERROR) ) belongsToHowManyFaces++; |
|
| 328 |
} |
|
| 329 |
|
|
| 330 |
switch(belongsToHowManyFaces) |
|
| 331 |
{
|
|
| 332 |
case 0 : return true ; // 'inside' cubit that does not lie on any face |
|
| 333 |
case 1 : // cubit that lies inside one of the faces |
|
| 334 |
Static3D orig = cubit.getOrigPosition(); |
|
| 335 |
Static4D quat1 = QUATS[quatIndex]; |
|
| 336 |
Static4D quat2 = QUATS[cubit.mQuatIndex]; |
|
| 337 |
|
|
| 338 |
Static4D cubitCenter = new Static4D( orig.get0(), orig.get1(), orig.get2(), 0); |
|
| 339 |
Static4D rotated1 = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat1 ); |
|
| 340 |
Static4D rotated2 = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat2 ); |
|
| 341 |
|
|
| 342 |
float row1, row2; |
|
| 343 |
float x1 = rotated1.get0(); |
|
| 344 |
float y1 = rotated1.get1(); |
|
| 345 |
float z1 = rotated1.get2(); |
|
| 346 |
float x2 = rotated2.get0(); |
|
| 347 |
float y2 = rotated2.get1(); |
|
| 348 |
float z2 = rotated2.get2(); |
|
| 349 |
|
|
| 350 |
for(int i=0; i<NUM_AXIS; i++) |
|
| 351 |
{
|
|
| 352 |
row1 = computeRow(x1,y1,z1,i); |
|
| 353 |
row2 = computeRow(x2,y2,z2,i); |
|
| 354 |
|
|
| 355 |
if( (row1==0 && row2==0) || (row1==lastLayer && row2==lastLayer) ) return true; |
|
| 356 |
} |
|
| 357 |
return false; |
|
| 358 |
|
|
| 359 |
default: return false; // edge or corner |
|
| 360 |
} |
|
| 361 |
} |
|
| 362 |
|
|
| 363 | 303 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 364 | 304 |
// order: Up --> Right --> Front --> Down --> Left --> Back |
| 365 | 305 |
// (because the first implemented Solver - the two-phase Cube3 one - expects such order) |
| src/main/java/org/distorted/objects/TwistyMegaminx.java | ||
|---|---|---|
| 582 | 582 |
return true; |
| 583 | 583 |
} |
| 584 | 584 |
|
| 585 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 586 |
// return if the Cubit, when rotated with its own mQuatScramble, would have looked any different |
|
| 587 |
// then if it were rotated by quaternion 'quat'. |
|
| 588 |
// No it is not so simple as the quats need to be the same - imagine a 4x4x4 cube where the two |
|
| 589 |
// middle squares get interchanged. No visible difference! |
|
| 590 |
// |
|
| 591 |
// So: this is true iff the cubit |
|
| 592 |
// a) is a corner or edge and the quaternions are the same |
|
| 593 |
// b) is inside one of the faces and after rotations by both quats it ends up on the same face. |
|
| 594 |
|
|
| 595 |
private boolean thereIsNoVisibleDifference(Cubit cubit, int quatIndex) |
|
| 596 |
{
|
|
| 597 |
if ( cubit.mQuatIndex == quatIndex ) return true; |
|
| 598 |
|
|
| 599 |
int belongsToHowManyFaces = 0; |
|
| 600 |
int lastLayer = getNumLayers()-1; |
|
| 601 |
float row; |
|
| 602 |
final float MAX_ERROR = 0.01f; |
|
| 603 |
|
|
| 604 |
for(int i=0; i<NUM_AXIS; i++) |
|
| 605 |
{
|
|
| 606 |
row = cubit.mRotationRow[i]; |
|
| 607 |
if( (row <MAX_ERROR && row >-MAX_ERROR) || |
|
| 608 |
(row-lastLayer<MAX_ERROR && row-lastLayer>-MAX_ERROR) ) belongsToHowManyFaces++; |
|
| 609 |
} |
|
| 610 |
|
|
| 611 |
switch(belongsToHowManyFaces) |
|
| 612 |
{
|
|
| 613 |
case 0 : return true ; // 'inside' cubit that does not lie on any face |
|
| 614 |
case 1 : // cubit that lies inside one of the faces |
|
| 615 |
Static3D orig = cubit.getOrigPosition(); |
|
| 616 |
Static4D quat1 = QUATS[quatIndex]; |
|
| 617 |
Static4D quat2 = QUATS[cubit.mQuatIndex]; |
|
| 618 |
|
|
| 619 |
Static4D cubitCenter = new Static4D( orig.get0(), orig.get1(), orig.get2(), 0); |
|
| 620 |
Static4D rotated1 = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat1 ); |
|
| 621 |
Static4D rotated2 = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat2 ); |
|
| 622 |
|
|
| 623 |
float row1, row2; |
|
| 624 |
float x1 = rotated1.get0(); |
|
| 625 |
float y1 = rotated1.get1(); |
|
| 626 |
float z1 = rotated1.get2(); |
|
| 627 |
float x2 = rotated2.get0(); |
|
| 628 |
float y2 = rotated2.get1(); |
|
| 629 |
float z2 = rotated2.get2(); |
|
| 630 |
|
|
| 631 |
for(int i=0; i<NUM_AXIS; i++) |
|
| 632 |
{
|
|
| 633 |
row1 = computeRow(x1,y1,z1,i); |
|
| 634 |
row2 = computeRow(x2,y2,z2,i); |
|
| 635 |
|
|
| 636 |
if( (row1==0 && row2==0) || (row1==lastLayer && row2==lastLayer) ) return true; |
|
| 637 |
} |
|
| 638 |
return false; |
|
| 639 |
|
|
| 640 |
default: return false; // edge or corner |
|
| 641 |
} |
|
| 642 |
} |
|
| 643 |
|
|
| 644 | 585 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 645 | 586 |
|
| 646 | 587 |
public int getObjectName(int numLayers) |
| src/main/java/org/distorted/objects/TwistyObject.java | ||
|---|---|---|
| 47 | 47 |
import org.distorted.library.type.Static3D; |
| 48 | 48 |
import org.distorted.library.type.Static4D; |
| 49 | 49 |
import org.distorted.main.BuildConfig; |
| 50 |
import org.distorted.main.RubikSurfaceView; |
|
| 50 | 51 |
|
| 51 | 52 |
import java.io.DataInputStream; |
| 52 | 53 |
import java.io.IOException; |
| ... | ... | |
| 306 | 307 |
|
| 307 | 308 |
private boolean belongsToRotation( int cubit, int axis, int rowBitmap) |
| 308 | 309 |
{
|
| 309 |
int cubitRow = (int)(CUBITS[cubit].mRotationRow[axis]+0.5f); |
|
| 310 |
return ((1<<cubitRow)&rowBitmap)!=0; |
|
| 310 |
return ((1<<CUBITS[cubit].mRotationRow[axis]) & rowBitmap) != 0; |
|
| 311 | 311 |
} |
| 312 | 312 |
|
| 313 | 313 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| ... | ... | |
| 396 | 396 |
pos.set( mOrigPos[minErrorIndex] ); |
| 397 | 397 |
} |
| 398 | 398 |
|
| 399 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 400 |
// return if the Cubit, when rotated with its own mQuatScramble, would have looked any different |
|
| 401 |
// then if it were rotated by quaternion 'quat'. |
|
| 402 |
// No it is not so simple as the quats need to be the same - imagine a 4x4x4 cube where the two |
|
| 403 |
// middle squares get interchanged. No visible difference! |
|
| 404 |
// |
|
| 405 |
// So: this is true iff the cubit |
|
| 406 |
// a) is a corner or edge and the quaternions are the same |
|
| 407 |
// b) is inside one of the faces and after rotations by both quats it ends up on the same face. |
|
| 408 |
|
|
| 409 |
boolean thereIsNoVisibleDifference(Cubit cubit, int quatIndex) |
|
| 410 |
{
|
|
| 411 |
if ( cubit.mQuatIndex == quatIndex ) return true; |
|
| 412 |
|
|
| 413 |
int belongsToHowManyFaces = 0; |
|
| 414 |
int lastLayer = getNumLayers()-1; |
|
| 415 |
int row; |
|
| 416 |
|
|
| 417 |
for(int i=0; i<NUM_AXIS; i++) |
|
| 418 |
{
|
|
| 419 |
row = cubit.mRotationRow[i]; |
|
| 420 |
if( row==0 || row==lastLayer ) 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; |
|
| 436 |
float x1 = rotated1.get0(); |
|
| 437 |
float y1 = rotated1.get1(); |
|
| 438 |
float z1 = rotated1.get2(); |
|
| 439 |
float x2 = rotated2.get0(); |
|
| 440 |
float y2 = rotated2.get1(); |
|
| 441 |
float z2 = rotated2.get2(); |
|
| 442 |
|
|
| 443 |
for(int i=0; i<NUM_AXIS; i++) |
|
| 444 |
{
|
|
| 445 |
row1 = computeRow(x1,y1,z1,i); |
|
| 446 |
row2 = computeRow(x2,y2,z2,i); |
|
| 447 |
|
|
| 448 |
if( (row1==0 && row2==0) || (row1==lastLayer && row2==lastLayer) ) return true; |
|
| 449 |
} |
|
| 450 |
return false; |
|
| 451 |
|
|
| 452 |
default: return false; // edge or corner |
|
| 453 |
} |
|
| 454 |
} |
|
| 455 |
|
|
| 399 | 456 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 400 | 457 |
// the getFaceColors + final black in a grid (so that we do not exceed the maximum texture size) |
| 401 | 458 |
|
| src/main/java/org/distorted/objects/TwistyPyraminx.java | ||
|---|---|---|
| 193 | 193 |
|
| 194 | 194 |
private int faceColor(int cubit, int axis) |
| 195 | 195 |
{
|
| 196 |
float row = CUBITS[cubit].mRotationRow[axis]; |
|
| 197 |
return row*row < 0.1f ? axis : NUM_FACES; |
|
| 196 |
return CUBITS[cubit].mRotationRow[axis] == 0 ? axis : NUM_FACES; |
|
| 198 | 197 |
} |
| 199 | 198 |
|
| 200 | 199 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| ... | ... | |
| 333 | 332 |
return true; |
| 334 | 333 |
} |
| 335 | 334 |
|
| 336 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 337 |
// return if the Cubit, when rotated with its own mQuatScramble, would have looked any different |
|
| 338 |
// then if it were rotated by quaternion 'quat'. |
|
| 339 |
// No it is not so simple as the quats need to be the same - imagine a 4x4x4 cube where the two |
|
| 340 |
// middle squares get interchanged. No visible difference! |
|
| 341 |
// |
|
| 342 |
// So: this is true iff the cubit |
|
| 343 |
// a) is a corner or edge and the quaternions are the same |
|
| 344 |
// b) is inside one of the faces and after rotations by both quats it ends up on the same face. |
|
| 345 |
|
|
| 346 |
private boolean thereIsNoVisibleDifference(Cubit cubit, int quatIndex) |
|
| 347 |
{
|
|
| 348 |
if ( cubit.mQuatIndex == quatIndex ) return true; |
|
| 349 |
|
|
| 350 |
int belongsToHowManyFaces = 0; |
|
| 351 |
int numLayers = getNumLayers()-1; |
|
| 352 |
float row; |
|
| 353 |
final float MAX_ERROR = 0.01f; |
|
| 354 |
|
|
| 355 |
for(int i=0; i<NUM_AXIS; i++) |
|
| 356 |
{
|
|
| 357 |
row = cubit.mRotationRow[i]; |
|
| 358 |
if( (row <MAX_ERROR && row >-MAX_ERROR) || |
|
| 359 |
(row-numLayers<MAX_ERROR && row-numLayers>-MAX_ERROR) ) belongsToHowManyFaces++; |
|
| 360 |
} |
|
| 361 |
|
|
| 362 |
switch(belongsToHowManyFaces) |
|
| 363 |
{
|
|
| 364 |
case 0 : return true ; // 'inside' cubit that does not lie on any face |
|
| 365 |
case 1 : // cubit that lies inside one of the faces |
|
| 366 |
Static3D orig = cubit.getOrigPosition(); |
|
| 367 |
Static4D quat1 = QUATS[quatIndex]; |
|
| 368 |
Static4D quat2 = QUATS[cubit.mQuatIndex]; |
|
| 369 |
|
|
| 370 |
Static4D cubitCenter = new Static4D( orig.get0(), orig.get1(), orig.get2(), 0); |
|
| 371 |
Static4D rotated1 = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat1 ); |
|
| 372 |
Static4D rotated2 = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat2 ); |
|
| 373 |
|
|
| 374 |
float row1, row2; |
|
| 375 |
float x1 = rotated1.get0(); |
|
| 376 |
float y1 = rotated1.get1(); |
|
| 377 |
float z1 = rotated1.get2(); |
|
| 378 |
float x2 = rotated2.get0(); |
|
| 379 |
float y2 = rotated2.get1(); |
|
| 380 |
float z2 = rotated2.get2(); |
|
| 381 |
|
|
| 382 |
for(int i=0; i<NUM_AXIS; i++) |
|
| 383 |
{
|
|
| 384 |
row1 = computeRow(x1,y1,z1,i); |
|
| 385 |
row2 = computeRow(x2,y2,z2,i); |
|
| 386 |
|
|
| 387 |
if( (row1==0 && row2==0) || (row1==numLayers && row2==numLayers) ) return true; |
|
| 388 |
} |
|
| 389 |
return false; |
|
| 390 |
|
|
| 391 |
default: return false; // edge or corner |
|
| 392 |
} |
|
| 393 |
} |
|
| 394 |
|
|
| 395 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 335 |
//////////////////////////////////////////////////////////////////////// |
|
| 396 | 336 |
// only needed for solvers - there are no Pyraminx solvers ATM) |
| 397 | 337 |
|
| 398 | 338 |
public String retObjectString() |
Also available in: Unified diff
Simplification with objects.