Revision 221a4090
Added by Leszek Koltunski almost 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.