Project

General

Profile

« Previous | Next » 

Revision 6612cbb4

Added by Leszek Koltunski 11 months ago

Progress with scrambling a bandaged pyraminx.

View differences:

src/main/java/org/distorted/objectlib/bandaged/BandagedObjectPyraminx.java
33 33

  
34 34
///////////////////////////////////////////////////////////////////////////////////////////////////
35 35

  
36
  private void addTetrahedralLattice(int size, float[][] pos)
36
  private static void addTetrahedralLattice(int size, float[][] pos)
37 37
    {
38 38
    final float DX = 1.0f;
39 39
    final float DY = SQ2/2;
......
56 56

  
57 57
        for(int z=0; z<size-layer; z++)
58 58
          {
59
          pos[index] = new float[] {currX,currY,currZ};
60
          index++;
59
          if( x==0 || x==layer || z==0 || z==size-layer-1 )
60
            {
61
            pos[index]=new float[]{currX, currY, currZ};
62
            index++;
63
            }
61 64
          currZ -= DZ;
62 65
          }
63 66

  
64 67
        currX += DX;
65 68
        }
66 69

  
67
      startX-=DX/2;
68
      startY+=DY;
69
      startZ-=DZ/2;
70
      startX -= DX/2;
71
      startY += DY;
72
      startZ -= DZ/2;
70 73
      }
71 74
    }
72 75

  
76
///////////////////////////////////////////////////////////////////////////////////////////////////
77

  
78
  public static float[][][] createPositions(int size)
79
    {
80
    int numO= (size-1)*size*(size+1)/6;
81
    int numT= (size+1)*size*(size+2)/6;
82

  
83
    float[][] retO = new float[numO][];
84
    float[][] retT = new float[numT][];
85

  
86
    addTetrahedralLattice(size-1,retO);
87
    addTetrahedralLattice(size  ,retT);
88

  
89
    return new float[][][] { retO,retT };
90
    }
91

  
73 92
///////////////////////////////////////////////////////////////////////////////////////////////////
74 93

  
75 94
  float getDist2D()
......
95 114

  
96 115
  float[][][] getPositions()
97 116
    {
98
    int num = mSize[0];
99
    int numO= (num-1)*num*(num+1)/6;
100
    int numT= (num+1)*num*(num+2)/6;
101

  
102
    float[][] retO = new float[numO][];
103
    float[][] retT = new float[numT][];
104

  
105
    addTetrahedralLattice(num-1,retO);
106
    addTetrahedralLattice(num  ,retT);
107

  
108
    return new float[][][] { retO,retT };
117
    return createPositions(mSize[0]);
109 118
    }
110 119

  
111 120
///////////////////////////////////////////////////////////////////////////////////////////////////
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
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/objectlib/json/JsonReader.java
9 9

  
10 10
package org.distorted.objectlib.json;
11 11

  
12
import static org.distorted.objectlib.objects.TwistyBandagedCuboid.OBJECT_NAME;
12
import static org.distorted.objectlib.objects.TwistyBandagedCuboid.OBJECT_NAME_CUBOID;
13
import static org.distorted.objectlib.objects.TwistyBandagedPyraminx.OBJECT_NAME_PYRAMINX;
13 14
import static org.distorted.objectlib.scrambling.ScrambleStateLocallyBandaged.MAX_SUPPORTED_SIZE;
14 15

  
15 16
import java.io.BufferedReader;
......
97 98
        }
98 99
      }
99 100

  
100
    if( longName.equals(OBJECT_NAME) ) new ObjectSignature(shortName,signature);
101
    if( longName.equals(OBJECT_NAME_CUBOID)   ||
102
        longName.equals(OBJECT_NAME_PYRAMINX)  ) new ObjectSignature(shortName,signature);
101 103

  
102 104
    return new ObjectSignature(signature);
103 105
    }
src/main/java/org/distorted/objectlib/objects/TwistyBandagedCuboid.java
30 30

  
31 31
public class TwistyBandagedCuboid extends TwistyBandagedAbstract
32 32
{
33
  public static final String OBJECT_NAME = "LOCAL_BANDAGED";
33
  public static final String OBJECT_NAME_CUBOID = "LOCAL_BANDAGED";
34 34

  
35 35
  public static final float STRENGTH = 0.04f;
36 36
  public static final float REGION_SIZE = 0.15f;
......
753 753
    if( mPosition==POS_5 ) return "AI Cube";
754 754
    if( mPosition==POS_6 ) return "Burr Cube";
755 755

  
756
    return OBJECT_NAME;
756
    return OBJECT_NAME_CUBOID;
757 757
    }
758 758

  
759 759
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/objectlib/objects/TwistyBandagedPyraminx.java
31 31

  
32 32
public class TwistyBandagedPyraminx extends ShapeTetrahedron
33 33
{
34
  public static final String OBJECT_NAME = "LOCAL_PYRAMINX";
34
  public static final String OBJECT_NAME_PYRAMINX = "LOCAL_PYRAMINX";
35 35

  
36 36
  private static final Static3D[] ROT_AXIS = new Static3D[]
37 37
        {
......
66 66

  
67 67
///////////////////////////////////////////////////////////////////////////////////////////////////
68 68

  
69
  private boolean isTetCubitFaceOnPuzzleFace(float[] pos, int numLayers, int face)
70
    {
71
    Static3D ax= TouchControlTetrahedron.FACE_AXIS[face];
72
    float dist = pos[0]*ax.get0() + pos[1]*ax.get1() + pos[2]*ax.get2();
73
    return (dist > (numLayers-1)*SQ6/12 - 0.001f);
74
    }
75

  
76
///////////////////////////////////////////////////////////////////////////////////////////////////
77

  
78
  private int getType(float[] pos)
69
  private int getType(float[] pos, int numLayers)
79 70
    {
80 71
    if( pos.length>3 ) return OTHER;
81
    int[] numLayers = getNumLayers();
82
    int variant = FactoryBandagedPyraminx.getElementVariant(numLayers[0],pos[1]);
72
    int variant = FactoryBandagedPyraminx.getElementVariant(numLayers,pos[1]);
83 73
    return variant==0 ? OCT_1 : TET_1;
84 74
    }
85 75

  
86

  
87 76
///////////////////////////////////////////////////////////////////////////////////////////////////
88 77

  
89 78
  private int getType(int variant)
......
266 255

  
267 256
      for (int cubit=0; cubit<numCubits; cubit++)
268 257
        {
269
        int type = getType(positions[cubit]);
258
        int type = getType(positions[cubit],numLayers[0]);
270 259

  
271 260
        switch (type)
272 261
          {
......
425 414
    }
426 415

  
427 416
///////////////////////////////////////////////////////////////////////////////////////////////////
428
// TODO
429 417

  
430 418
  public ObjectSignature getSignature()
431 419
    {
432 420
    if( mSignature==null )
433 421
      {
434 422
      int[] numLayers = getNumLayers();
435
      mSignature = new ObjectSignature(numLayers[0],numLayers[1],numLayers[2],mPosition);
423
      mSignature = new ObjectSignature(numLayers[0],mPosition);
436 424
      }
437 425
    return mSignature;
438 426
    }
......
441 429

  
442 430
  public String getObjectName()
443 431
    {
444
    return OBJECT_NAME;
432
    return OBJECT_NAME_PYRAMINX;
445 433
    }
446 434

  
447 435
///////////////////////////////////////////////////////////////////////////////////////////////////

Also available in: Unified diff