Project

General

Profile

« Previous | Next » 

Revision bdfb04b3

Added by Leszek Koltunski 11 months ago

Further abstractions in the 'detect solved state' engine.

It should now be able to work in all cases - but it is still buggy (Dino4 does not work now!)

View differences:

src/main/java/org/distorted/objectlib/main/TwistyObject.java
1752 1752
    return mObjectQuats;
1753 1753
    }
1754 1754

  
1755
///////////////////////////////////////////////////////////////////////////////////////////////////
1756
// Return the 'surface' the given face of the given cubit is on. (px,py,pz) is the pre-computed
1757
// center of the cubit (so we don't have to keep re-computing this per each face)
1758
// If the face is not external, return null.
1759
//
1760
// This is needed by the TwistyObjectSolved's method2 detecting if the object is in a solved state.
1761
//
1762
// What is a 'surface' ? For objects with flat monochromatic external walls, it is simply a 4-tuple
1763
// [(nx,ny,nz),d] (normal vector + distance from origin) describing a 3D plane this face is part of.
1764
// Exceptions are objects with curved external walls (ATM Masterball & Penrose Cubes): it is a union
1765
// of several surfaces which together define the bent, monochromatic wall. I.e. Penrose Cube has 3
1766
// surfaces (blue, yellow and red), each defined by 3 planes (think before the bending effect!)
1767
//
1768
// This is the default which simply returns the single plane. If some puzzle has more complicated
1769
// surfaces, it needs to override this method.
1770
//
1771
// We never need to test if a given point is part of a given surface (see TwistyObjectSurface!) - we
1772
// only need to be able to rotate the surface by quats and test if two surfaces are the same. Thus:
1773
// it is possible to provide some artificial surfaces - for example, in case of the Penrose, the
1774
// three surfaces can be only the single 'middle' plane [the one on the bend].
1775

  
1776
  public float[] getMonochromaticSurface(int variant, int cubitIndex, int faceIndex, float px, float py, float pz)
1777
    {
1778
    if( !faceIsOuter(cubitIndex,faceIndex) ) return null;
1779

  
1780
    Static4D cubitQuat = getCubitQuats(cubitIndex,mNumLayers);
1781

  
1782
    float[] normal   = new float[4];
1783
    float[] intPoint = new float[3];
1784
    float[] rotPoint = new float[4];
1785
    float[] surface  = new float[4];
1786

  
1787
    ObjectShape objShape = mShapes[variant];
1788
    objShape.getFacePoint(faceIndex,intPoint);
1789
    objShape.getFaceNormal(faceIndex,normal);
1790

  
1791
    QuatHelper.rotateVectorByQuat(rotPoint,intPoint[0],intPoint[1],intPoint[2],1,cubitQuat);
1792
    QuatHelper.rotateVectorByQuat(surface,normal[0],normal[1],normal[2],0,cubitQuat);
1793

  
1794
    float x = rotPoint[0] + px;
1795
    float y = rotPoint[1] + py;
1796
    float z = rotPoint[2] + pz;
1797
    surface[3] = x*surface[0] + y*surface[1] + z*surface[2];
1798

  
1799
    return surface;
1800
    }
1801

  
1755 1802
///////////////////////////////////////////////////////////////////////////////////////////////////
1756 1803

  
1757 1804
  public int[][] getVariantFaceIsOuter()
src/main/java/org/distorted/objectlib/main/TwistyObjectSolved.java
388 388
    for(int c=0; c<numCubits; c++)
389 389
      {
390 390
      int variant = mParent.getCubitVariant(c,numLayers);
391
      ObjectShape s = shapes[variant];
392
      int numFaces = s.getNumFaces();
391
      ObjectShape objShape = shapes[variant];
392
      int numFaces = objShape.getNumFaces();
393 393
      mCubitFaceToPuzzleFaceMap[c] = new int[numFaces];
394 394
      mCubitFaceToSurfaceMap[c] = new int[numFaces];
395 395
      for(int f=0; f<numFaces; f++) mCubitFaceToSurfaceMap[c][f] = -1;
396 396

  
397
      Static4D cubitQuat = mParent.getCubitQuats(c,numLayers);
398

  
399 397
      float[] po = pos[c];
400 398
      int poslen = po.length/3;
401 399
      float px=0, py=0, pz=0;
......
417 415

  
418 416
        //android.util.Log.e("D", "cubit "+c+" face "+f+" puzzle face: "+ mCubitFaceToPuzzleFaceMap[c][f]);
419 417

  
420
        if( !mParent.faceIsOuter(c,f) ) continue;
421

  
422
        float[] surface  = new float[4];
423
        float[] rotPoint = new float[4];
424
        float[] normal   = new float[4];
425
        float[] intPoint = new float[3];
426

  
427
        s.getFacePoint(f,intPoint);
428
        s.getFaceNormal(f,normal);
429

  
430
        QuatHelper.rotateVectorByQuat(rotPoint,intPoint[0],intPoint[1],intPoint[2],1,cubitQuat);
431
        QuatHelper.rotateVectorByQuat(surface,normal[0],normal[1],normal[2],0,cubitQuat);
432

  
433
        float x = rotPoint[0] + px;
434
        float y = rotPoint[1] + py;
435
        float z = rotPoint[2] + pz;
436
        surface[3] = x*surface[0] + y*surface[1] + z*surface[2];
418
        float[] surface = mParent.getMonochromaticSurface(variant,c,f,px,py,pz);
437 419

  
420
        if( surface==null ) continue;
438 421
        TwistyObjectSurface si = new TwistyObjectSurface(surface);
439 422
        int index = surfaceExists(tmpSurfaces,si);
440 423

  
src/main/java/org/distorted/objectlib/main/TwistyObjectSurface.java
21 21
// monochromatic surfaces (Masterball, Penroses) cannot use this method..
22 22
//
23 23
// 'indices' is a map which shows which surface our surface changes to when rotated by all the
24
// 'numQuats' quats.
24
// 'numQuats' quats. Only kept here for a moment, then offloaded to TwistyObjectSolved.mSurfaceTable
25 25
//
26 26
// Used only in TwistyObjectSolved's method2.
27 27
///////////////////////////////////////////////////////////////////////////////////////////////////
......
56 56

  
57 57
  String print()
58 58
    {
59
    return surface[0]+" "+surface[1]+" "+surface[2]+" "+surface[3];
59
    int numPlanes = surface.length / 4;
60
    StringBuilder sb = new StringBuilder();
61

  
62
    for(int p=0; p<numPlanes; p++)
63
      {
64
      sb.append('[');
65
      sb.append(surface[4*p]);
66
      sb.append(' ');
67
      sb.append(surface[4*p+1]);
68
      sb.append(' ');
69
      sb.append(surface[4*p+2]);
70
      sb.append(' ');
71
      sb.append(surface[4*p+3]);
72
      sb.append(']');
73
      sb.append(' ');
74
      }
75

  
76
    return sb.toString();
60 77
    }
61 78

  
62 79
///////////////////////////////////////////////////////////////////////////////////////////////////
63 80

  
64
  boolean isSame(TwistyObjectSurface s)
81
  private boolean surfaceSame(float[] s1, int i1, float[] s2, int i2)
65 82
    {
66 83
    final float MAX_ERROR = 0.01f;
67 84
    float dnx,dny,dnz,dnw;
68
    float[] sur = s.surface;
69

  
70
    dnx = sur[0] + surface[0];
71
    dny = sur[1] + surface[1];
72
    dnz = sur[2] + surface[2];
73
    dnw = sur[3] + surface[3];
85
    float x1 = s1[4*i1  ];
86
    float y1 = s1[4*i1+1];
87
    float z1 = s1[4*i1+2];
88
    float w1 = s1[4*i1+3];
89
    float x2 = s2[4*i2  ];
90
    float y2 = s2[4*i2+1];
91
    float z2 = s2[4*i2+2];
92
    float w2 = s2[4*i2+3];
93

  
94
    dnx = x1 + x2;
95
    dny = y1 + y2;
96
    dnz = z1 + z2;
97
    dnw = w1 + w2;
74 98

  
75 99
    if( dnx*dnx + dny*dny + dnz*dnz + dnw*dnw < MAX_ERROR ) return true;
76 100

  
77
    dnx = sur[0] - surface[0];
78
    dny = sur[1] - surface[1];
79
    dnz = sur[2] - surface[2];
80
    dnw = sur[3] - surface[3];
101
    dnx = x1 - x2;
102
    dny = y1 - y2;
103
    dnz = z1 - z2;
104
    dnw = w1 - w2;
81 105

  
82 106
    if( dnx*dnx + dny*dny + dnz*dnz + dnw*dnw < MAX_ERROR ) return true;
83 107

  
84 108
    return false;
85 109
    }
86 110

  
111
///////////////////////////////////////////////////////////////////////////////////////////////////
112

  
113
  boolean isSame(TwistyObjectSurface s)
114
    {
115
    int n1 = surface.length/4;
116
    int n2 = s.surface.length/4;
117

  
118
    for(int n=0; n<n1; n++)
119
      {
120
      boolean exists = false;
121

  
122
      for(int p=0; p<n2; p++)
123
        if( surfaceSame(surface,n,s.surface,p) )
124
          {
125
          exists = true;
126
          break;
127
          }
128

  
129
      if( !exists ) return false;
130
      }
131

  
132
    return true;
133
    }
134

  
87 135
///////////////////////////////////////////////////////////////////////////////////////////////////
88 136

  
89 137
  TwistyObjectSurface rotateSurface(Static4D quat)
90 138
    {
91
    float[] ret = new float[4];
92
    QuatHelper.rotateVectorByQuat(ret,surface[0],surface[1],surface[2],0,quat);
93
    ret[3] = surface[3];
139
    int numPlanes = surface.length / 4;
140
    float[] ret = new float[numPlanes*4];
141
    float[] tmp = new float[4];
142

  
143
    for(int p=0; p<numPlanes; p++)
144
      {
145
      QuatHelper.rotateVectorByQuat(tmp,surface[4*p],surface[4*p+1],surface[4*p+2],0,quat);
146
      ret[4*p  ] = tmp[0];
147
      ret[4*p+1] = tmp[1];
148
      ret[4*p+2] = tmp[2];
149
      ret[4*p+3] = surface[4*p+3];
150
      }
151

  
94 152
    return new TwistyObjectSurface(ret);
95 153
    }
96 154
}
src/main/java/org/distorted/objectlib/objects/TwistyDino4.java
29 29
    super(iconMode, quat, move, scale, meta, asset);
30 30
    }
31 31

  
32
///////////////////////////////////////////////////////////////////////////////////////////////////
33
// here we define 8 artificial monochromatic 'surfaces' - 8 vectors coming out from the center of the
34
// cube to each vertex and some distance (doesn't matter)
35

  
36
  private static final float[][] mMonoSurfaces =
37
          {
38
                  { 1, 1, 1, 1 },
39
                  { 1, 1,-1, 1 },
40
                  { 1,-1, 1, 1 },
41
                  { 1,-1,-1, 1 },
42
                  {-1, 1, 1, 1 },
43
                  {-1, 1,-1, 1 },
44
                  {-1,-1, 1, 1 },
45
                  {-1,-1,-1, 1 },
46
          };
47
  private static final int[] mSurfaceIndices = { 4,2,2,4,1,2,7,4,1,1,7,7 };
48

  
49
  @Override
50
  public float[] getMonochromaticSurface(int variant, int cubitIndex, int faceIndex, float px, float py, float pz)
51
    {
52
    int index = mSurfaceIndices[cubitIndex];
53
    return faceIndex<2 ? mMonoSurfaces[index] : null;
54
    }
55
/*
32 56
///////////////////////////////////////////////////////////////////////////////////////////////////
33 57

  
34 58
  @Override
......
36 60
    {
37 61
    return 1;
38 62
    }
39

  
63
*/
40 64
///////////////////////////////////////////////////////////////////////////////////////////////////
41 65

  
42 66
  @Override

Also available in: Unified diff