Revision 6612cbb4
Added by Leszek Koltunski 11 months ago
src/main/java/org/distorted/objectlib/helpers/ObjectSignature.java | ||
---|---|---|
11 | 11 |
|
12 | 12 |
import java.util.ArrayList; |
13 | 13 |
|
14 |
import static org.distorted.objectlib.main.TwistyObject.SQ6; |
|
14 | 15 |
import static org.distorted.objectlib.scrambling.ScrambleStateLocallyBandaged.MAX_SUPPORTED_SIZE; |
15 | 16 |
|
17 |
import org.distorted.objectlib.bandaged.BandagedObjectPyraminx; |
|
18 |
|
|
16 | 19 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
17 | 20 |
|
18 | 21 |
public class ObjectSignature implements Comparable<ObjectSignature> |
... | ... | |
51 | 54 |
else |
52 | 55 |
{ |
53 | 56 |
mSignature = new long[SIZE]; |
54 |
|
|
55 |
for(int i=0; i<size; i++) |
|
56 |
{ |
|
57 |
mSignature[diff+i] = signature[i]; |
|
58 |
} |
|
57 |
for(int i=0; i<size; i++) mSignature[diff+i] = signature[i]; |
|
59 | 58 |
} |
60 | 59 |
} |
61 | 60 |
|
... | ... | |
89 | 88 |
|
90 | 89 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
91 | 90 |
// locally created bandaged cuboids created from JSON (version2) |
91 |
// or locally created bandaged pyraminxes. |
|
92 |
// How to tell apart: pyraminx's shortName starts with a 'P'. |
|
92 | 93 |
|
93 | 94 |
public ObjectSignature(String shortName, long[] signature) |
94 | 95 |
{ |
95 | 96 |
setUpSignature(signature); |
96 | 97 |
|
97 |
int x = shortName.charAt(0) - '0'; |
|
98 |
int y = shortName.charAt(1) - '0'; |
|
99 |
int z = shortName.charAt(2) - '0'; |
|
100 |
|
|
101 |
mLayer = new int[] {x,y,z}; |
|
102 |
|
|
103 |
prepareCubitTouch(); |
|
104 |
prepareAllCycles(); |
|
98 |
if( shortName.charAt(0) != 'P' ) |
|
99 |
{ |
|
100 |
int x=shortName.charAt(0)-'0'; |
|
101 |
int y=shortName.charAt(1)-'0'; |
|
102 |
int z=shortName.charAt(2)-'0'; |
|
103 |
mLayer=new int[]{x, y, z}; |
|
104 |
prepareCubitTouch(); |
|
105 |
prepareAllCycles(); |
|
106 |
} |
|
107 |
else |
|
108 |
{ |
|
109 |
int x=shortName.charAt(1)-'0'; |
|
110 |
mLayer=new int[]{x, x, x, x}; |
|
111 |
prepareCubitTouchPyraminx(); |
|
112 |
prepareAllCyclesPyraminx(); |
|
113 |
} |
|
105 | 114 |
} |
106 | 115 |
|
107 | 116 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
168 | 177 |
} |
169 | 178 |
} |
170 | 179 |
|
180 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
181 |
// Locally created bandaged pyraminxes 1<=N<=7 |
|
182 |
|
|
183 |
public ObjectSignature(int len , float[][] position) |
|
184 |
{ |
|
185 |
mLayer = new int[] {len,len,len,len}; |
|
186 |
mSignature = new long[SIZE]; |
|
187 |
|
|
188 |
prepareCubitTouchPyraminx(); |
|
189 |
prepareAllCyclesPyraminx(); |
|
190 |
|
|
191 |
for(float[] pos : position) |
|
192 |
{ |
|
193 |
int numCenters = pos.length/3; |
|
194 |
|
|
195 |
for(int i=0; i<numCenters; i++) |
|
196 |
{ |
|
197 |
float xi = pos[3*i ]; |
|
198 |
float yi = pos[3*i+1]; |
|
199 |
float zi = pos[3*i+2]; |
|
200 |
|
|
201 |
for(int j=i+1; j<numCenters; j++) |
|
202 |
{ |
|
203 |
float xj = pos[3*j ]; |
|
204 |
float yj = pos[3*j+1]; |
|
205 |
float zj = pos[3*j+2]; |
|
206 |
|
|
207 |
if( areNeighboursPyraminx(xi-xj,yi-yj,zi-zj) ) |
|
208 |
{ |
|
209 |
float xc = (xi+xj)/2; |
|
210 |
float yc = (yi+yj)/2; |
|
211 |
float zc = (zi+zj)/2; |
|
212 |
|
|
213 |
int bitIndex = getIndexOfCubitTouch(xc,yc,zc); |
|
214 |
setBit(bitIndex,1); |
|
215 |
} |
|
216 |
} |
|
217 |
} |
|
218 |
} |
|
219 |
} |
|
220 |
|
|
171 | 221 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
172 | 222 |
|
173 | 223 |
public void setSignature(int signature) |
... | ... | |
232 | 282 |
} |
233 | 283 |
|
234 | 284 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
285 |
// TODO |
|
235 | 286 |
|
236 | 287 |
public boolean isUnblockedFromLeft(int axis, int layer) |
237 | 288 |
{ |
... | ... | |
261 | 312 |
if( cycles!=null && cycles.length>0 && cycles[0]!=null ) |
262 | 313 |
{ |
263 | 314 |
if( cycles[0].length==4 ) for(int[] cyc : cycles) ret.cycle4(turn,cyc); |
315 |
if( cycles[0].length==3 ) for(int[] cyc : cycles) ret.cycle3(turn,cyc); |
|
264 | 316 |
else for(int[] cyc : cycles) ret.cycle2(cyc); |
265 | 317 |
} |
266 | 318 |
} |
... | ... | |
289 | 341 |
setBit(index0,b1); |
290 | 342 |
} |
291 | 343 |
|
344 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
345 |
|
|
346 |
private void cycle3(int turn, int[] cyc) |
|
347 |
{ |
|
348 |
int index0 = cyc[0]; |
|
349 |
int index1 = cyc[1]; |
|
350 |
int index2 = cyc[2]; |
|
351 |
|
|
352 |
long b0 = getBit(index0); |
|
353 |
long b1 = getBit(index1); |
|
354 |
long b2 = getBit(index2); |
|
355 |
|
|
356 |
switch(turn) |
|
357 |
{ |
|
358 |
case 1: setBit(index0,b2); |
|
359 |
setBit(index1,b0); |
|
360 |
setBit(index2,b1); |
|
361 |
break; |
|
362 |
case 2: setBit(index0,b1); |
|
363 |
setBit(index1,b2); |
|
364 |
setBit(index2,b0); |
|
365 |
break; |
|
366 |
} |
|
367 |
} |
|
368 |
|
|
292 | 369 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
293 | 370 |
|
294 | 371 |
private void cycle4(int turn, int[] cyc) |
... | ... | |
429 | 506 |
{ |
430 | 507 |
for(int i=0; i<mNumCubitTouches; i++) |
431 | 508 |
{ |
432 |
int i0 = rotateIndex(axis,i); |
|
509 |
int i0 = rotateIndex4(axis,i);
|
|
433 | 510 |
if( i0<=i ) continue; |
434 |
int i1 = rotateIndex(axis,i0); |
|
511 |
int i1 = rotateIndex4(axis,i0);
|
|
435 | 512 |
if( i1<=i ) continue; |
436 |
int i2 = rotateIndex(axis,i1); |
|
513 |
int i2 = rotateIndex4(axis,i1);
|
|
437 | 514 |
if( i2<=i ) continue; |
438 | 515 |
|
439 | 516 |
float[] f0 = getCubitTouchOfIndex(i); |
... | ... | |
520 | 597 |
|
521 | 598 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
522 | 599 |
|
523 |
private int rotateIndex(int axis, int index) |
|
600 |
private int rotateIndex4(int axis, int index)
|
|
524 | 601 |
{ |
525 | 602 |
float[] touch = getCubitTouchOfIndex(index); |
526 | 603 |
|
... | ... | |
550 | 627 |
return -1; |
551 | 628 |
} |
552 | 629 |
|
630 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
631 |
|
|
632 |
private void prepareCubitTouchPyraminx() |
|
633 |
{ |
|
634 |
float[][][] centers = BandagedObjectPyraminx.createPositions(mLayer[0]); |
|
635 |
float[][] octs = centers[0]; |
|
636 |
float[][] tets = centers[1]; |
|
637 |
|
|
638 |
int numO = octs.length; |
|
639 |
int numT = tets.length; |
|
640 |
|
|
641 |
ArrayList<float[]> mTouch = new ArrayList<>(); |
|
642 |
|
|
643 |
for(int i=0; i<numO; i++) |
|
644 |
for(int j=i+1; j<numT; j++) |
|
645 |
{ |
|
646 |
float[] c0 = octs[i]; |
|
647 |
float[] c1 = tets[j]; |
|
648 |
|
|
649 |
float x1 = c0[0]; |
|
650 |
float y1 = c0[1]; |
|
651 |
float z1 = c0[2]; |
|
652 |
float x2 = c1[0]; |
|
653 |
float y2 = c1[1]; |
|
654 |
float z2 = c1[2]; |
|
655 |
|
|
656 |
if( areNeighboursPyraminx(x1-x2,y1-y2,z1-z2) ) |
|
657 |
{ |
|
658 |
float xc = (x1+x2)/2; |
|
659 |
float yc = (y1+y2)/2; |
|
660 |
float zc = (z1+z2)/2; |
|
661 |
|
|
662 |
float[] touch = new float[] {xc,yc,zc}; |
|
663 |
mTouch.add(touch); |
|
664 |
} |
|
665 |
} |
|
666 |
|
|
667 |
mNumCubitTouches = mTouch.size(); |
|
668 |
mCubitTouch = new float[mNumCubitTouches][]; |
|
669 |
for(int i=0; i<mNumCubitTouches; i++) mCubitTouch[i] = mTouch.remove(0); |
|
670 |
} |
|
671 |
|
|
672 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
673 |
|
|
674 |
private void prepareAllCyclesPyraminx() |
|
675 |
{ |
|
676 |
ArrayList<float[][]> cycles0 = new ArrayList<>(); |
|
677 |
ArrayList<float[][]> cycles1 = new ArrayList<>(); |
|
678 |
ArrayList<float[][]> cycles2 = new ArrayList<>(); |
|
679 |
ArrayList<float[][]> cycles3 = new ArrayList<>(); |
|
680 |
|
|
681 |
generate3CyclesPyraminx(cycles0,0); |
|
682 |
generate3CyclesPyraminx(cycles0,1); |
|
683 |
generate3CyclesPyraminx(cycles0,2); |
|
684 |
generate3CyclesPyraminx(cycles0,3); |
|
685 |
|
|
686 |
mCycles = new int[4][][][]; |
|
687 |
|
|
688 |
int numLayers = mLayer[0]; |
|
689 |
mCycles[0] = fillUpCyclesPyraminx(cycles0,0,numLayers); |
|
690 |
mCycles[1] = fillUpCyclesPyraminx(cycles1,1,numLayers); |
|
691 |
mCycles[2] = fillUpCyclesPyraminx(cycles2,2,numLayers); |
|
692 |
mCycles[3] = fillUpCyclesPyraminx(cycles3,3,numLayers); |
|
693 |
} |
|
694 |
|
|
695 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
696 |
|
|
697 |
private void generate3CyclesPyraminx(ArrayList<float[][]> cycles, int axis) |
|
698 |
{ |
|
699 |
for(int i=0; i<mNumCubitTouches; i++) |
|
700 |
{ |
|
701 |
int i0 = rotateIndex3(axis,i); |
|
702 |
if( i0<=i ) continue; |
|
703 |
int i1 = rotateIndex3(axis,i0); |
|
704 |
if( i1<=i ) continue; |
|
705 |
|
|
706 |
float[] f0 = getCubitTouchOfIndex(i); |
|
707 |
float[] f1 = getCubitTouchOfIndex(i0); |
|
708 |
float[] f2 = getCubitTouchOfIndex(i1); |
|
709 |
|
|
710 |
float[][] cycle = new float[][] { f0,f1,f2 }; |
|
711 |
cycles.add(cycle); |
|
712 |
} |
|
713 |
} |
|
714 |
|
|
715 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
716 |
// TODO |
|
717 |
|
|
718 |
private int[][][] fillUpCyclesPyraminx(ArrayList<float[][]> cyc, int axis, int numLayers) |
|
719 |
{ |
|
720 |
int numCycles = cyc.size(); |
|
721 |
int[] index = new int[numLayers]; |
|
722 |
|
|
723 |
int numFirst = mNumCentCyclesPerLayer[axis]; |
|
724 |
int numNext = mNumLeftCyclesPerLayer[axis] + mNumInneCyclesPerLayer[axis]; |
|
725 |
int numLast = mNumLeftCyclesPerLayer[axis] + numFirst; |
|
726 |
|
|
727 |
int[][][] ret = new int[numLayers][][]; |
|
728 |
ret[ 0] = new int[numFirst][]; |
|
729 |
ret[numLayers-1] = new int[numLast][]; |
|
730 |
|
|
731 |
for(int i=1; i<numLayers-1; i++) ret[i] = new int[numNext][]; |
|
732 |
|
|
733 |
for(int i=0; i<numCycles; i++) |
|
734 |
{ |
|
735 |
float[][] cycle = cyc.remove(0); |
|
736 |
int layer = (int)(cycle[0][axis]+numLayers*0.5f); |
|
737 |
|
|
738 |
if( cycle.length==4 ) |
|
739 |
{ |
|
740 |
int i0 = getIndexOfCubitTouch(cycle[0][0],cycle[0][1],cycle[0][2]); |
|
741 |
int i1 = getIndexOfCubitTouch(cycle[1][0],cycle[1][1],cycle[1][2]); |
|
742 |
int i2 = getIndexOfCubitTouch(cycle[2][0],cycle[2][1],cycle[2][2]); |
|
743 |
int i3 = getIndexOfCubitTouch(cycle[3][0],cycle[3][1],cycle[3][2]); |
|
744 |
ret[layer][index[layer]] = new int[] {i0,i1,i2,i3}; |
|
745 |
index[layer]++; |
|
746 |
} |
|
747 |
else |
|
748 |
{ |
|
749 |
int i0 = getIndexOfCubitTouch(cycle[0][0],cycle[0][1],cycle[0][2]); |
|
750 |
int i1 = getIndexOfCubitTouch(cycle[1][0],cycle[1][1],cycle[1][2]); |
|
751 |
ret[layer][index[layer]] = new int[] {i0,i1}; |
|
752 |
index[layer]++; |
|
753 |
} |
|
754 |
} |
|
755 |
|
|
756 |
return ret; |
|
757 |
} |
|
758 |
|
|
759 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
760 |
|
|
761 |
private int rotateIndex3(int axis, int index) |
|
762 |
{ |
|
763 |
float[] touch = getCubitTouchOfIndex(index); |
|
764 |
|
|
765 |
switch(axis) |
|
766 |
{ |
|
767 |
case 0: return getIndexOfCubitTouch(+touch[0],-touch[1],-touch[2]); |
|
768 |
case 1: return getIndexOfCubitTouch(-touch[0],+touch[1],-touch[2]); |
|
769 |
case 2: return getIndexOfCubitTouch(-touch[0],-touch[1],+touch[2]); |
|
770 |
} |
|
771 |
|
|
772 |
return -1; |
|
773 |
} |
|
774 |
|
|
553 | 775 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
554 | 776 |
|
555 | 777 |
private int getIndexOfCubitTouch(float x, float y, float z) |
... | ... | |
574 | 796 |
|
575 | 797 |
private boolean areNeighbours(float dx, float dy, float dz) |
576 | 798 |
{ |
577 |
return dx*dx+dy*dy+dz*dz<1.1f; |
|
799 |
return dx*dx+dy*dy+dz*dz < 1.01f; |
|
800 |
} |
|
801 |
|
|
802 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
803 |
|
|
804 |
private boolean areNeighboursPyraminx(float dx, float dy, float dz) |
|
805 |
{ |
|
806 |
return dx*dx+dy*dy+dz*dz < SQ6/4 + 0.01f; |
|
578 | 807 |
} |
579 | 808 |
|
580 | 809 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
Also available in: Unified diff
Progress with scrambling a bandaged pyraminx.