Project

General

Profile

« Previous | Next » 

Revision 4946b635

Added by Leszek Koltunski about 3 years ago

Major abstraction - automatically compute the 'computeRowFromOffset()' function from CUTS.
Still one thing left: it appears like the CUTS of Mega/Kilominxes are not correct.

View differences:

src/main/java/org/distorted/main/RubikSurfaceView.java
394 394

  
395 395
      Static4D touchPoint2 = new Static4D(x, y, 0, 0);
396 396
      Static4D rotatedTouchPoint2= QuatHelper.rotateVectorByInvertedQuat(touchPoint2, mQuat);
397
      Static2D res = mMovement.newRotation(numLayers,rotatedTouchPoint2,object.getObjectRatio());
397
      Static2D res = mMovement.newRotation(rotatedTouchPoint2,object.getObjectRatio());
398 398

  
399 399
      mCurrentAxis = (int)res.get0();
400 400
      mCurrentRow  = (int)res.get1();
src/main/java/org/distorted/objects/Movement.java
34 34
  private final float[] mPoint, mCamera, mTouch;
35 35
  private final float[] mPoint2D, mMove2D;
36 36
  private final int[] mEnabledRotAxis;
37
  private final float mDistanceCenterFace3D, mDistanceCenterFace2D;
37
  private final float mDistanceCenterFace3D;
38 38
  private final Static3D[] mFaceAxis;
39 39

  
40 40
  private int mLastTouchedFace;
41 41
  private float[][][] mCastedRotAxis;
42 42
  private Static4D[][] mCastedRotAxis4D;
43
  private float[][] mTouchBorders, mA, mB;
43 44

  
44 45
///////////////////////////////////////////////////////////////////////////////////////////////////
45 46

  
46 47
  abstract boolean isInsideFace(int face, float[] point);
47 48
  abstract void computeEnabledAxis(int face, float[] touchPoint, int[] enabledAxis);
48
  abstract int computeRowFromOffset(int face, int axisIndex, int numLayers, float offset);
49 49
  public abstract float returnRotationFactor(int numLayers, int row);
50 50

  
51 51
///////////////////////////////////////////////////////////////////////////////////////////////////
52 52

  
53
  Movement(Static3D[] rotAxis, Static3D[] faceAxis, float distance3D, float distance2D)
53
  Movement(Static3D[] rotAxis, Static3D[] faceAxis, float[][] cuts, boolean[][] rotatable, float distance3D, int size)
54 54
    {
55 55
    mPoint = new float[3];
56 56
    mCamera= new float[3];
......
65 65
    mEnabledRotAxis = new int[rotAxis.length+1];
66 66

  
67 67
    mDistanceCenterFace3D = distance3D; // distance from the center of the object to each of its faces
68
    mDistanceCenterFace2D = distance2D; // distance from the center of a face to its edge
69 68

  
70 69
    computeCastedAxis(rotAxis);
70
    computeBorders(cuts,rotatable,size);
71
    computeLinear(distance3D,rotAxis,faceAxis);
71 72
    }
72 73

  
73 74
///////////////////////////////////////////////////////////////////////////////////////////////////
......
249 250

  
250 251
///////////////////////////////////////////////////////////////////////////////////////////////////
251 252

  
252
  float[] computeBorder(float scale, float[] cuts, boolean[] rotatable)
253
  private float[] computeBorder(float[] cuts, boolean[] rotatable, int size)
253 254
    {
254 255
    int len = cuts.length;
255 256
    float[] border = new float[len];
......
262 263
        }
263 264
      else
264 265
        {
265
        if( rotatable[i+1] ) border[i] = scale*cuts[i];
266
        if( rotatable[i+1] ) border[i] = cuts[i]/size;
266 267
        else
267 268
          {
268 269
          int found = -1;
......
276 277
              }
277 278
            }
278 279

  
279
          border[i] = found>0 ? scale*(cuts[i]+cuts[found-1])/2 : Float.MAX_VALUE;
280
          border[i] = found>0 ? (cuts[i]+cuts[found-1])/(2*size) : Float.MAX_VALUE;
280 281
          }
281 282
        }
282 283
      }
......
285 286
    }
286 287

  
287 288
///////////////////////////////////////////////////////////////////////////////////////////////////
289
// size, not numLayers (see Master Skewb where size!=numLayers)
288 290

  
289
  float[][] computeBorders(float coeff, float[][] cuts, boolean[][] rotatable)
291
  void computeBorders(float[][] cuts, boolean[][] rotatable, int size)
290 292
    {
291 293
    int numCuts = cuts.length;
292
    float[][] borders = new float[numCuts][];
294
    mTouchBorders = new float[numCuts][];
293 295

  
294 296
    for(int i=0; i<numCuts; i++)
295 297
      {
296
      borders[i] = computeBorder(coeff,cuts[i],rotatable[i]);
298
      mTouchBorders[i] = computeBorder(cuts[i],rotatable[i],size);
299
      }
300
    }
301

  
302
///////////////////////////////////////////////////////////////////////////////////////////////////
303

  
304
  private int computeSign(Static3D a, Static3D b)
305
    {
306
    float a1 = a.get0();
307
    float a2 = a.get1();
308
    float a3 = a.get2();
309
    float b1 = b.get0();
310
    float b2 = b.get1();
311
    float b3 = b.get2();
312

  
313
    return a1*b1+a2*b2+a3*b3 < 0 ? 1:-1;
314
    }
315

  
316
///////////////////////////////////////////////////////////////////////////////////////////////////
317

  
318
  private float crossProductLen(Static3D a, Static3D b)
319
    {
320
    float a1 = a.get0();
321
    float a2 = a.get1();
322
    float a3 = a.get2();
323
    float b1 = b.get0();
324
    float b2 = b.get1();
325
    float b3 = b.get2();
326

  
327
    float x1 = a2*b3-a3*b2;
328
    float x2 = a3*b1-a1*b3;
329
    float x3 = a1*b2-a2*b1;
330

  
331
    return (float)Math.sqrt(x1*x1 + x2*x2 + x3*x3);
332
    }
333

  
334
///////////////////////////////////////////////////////////////////////////////////////////////////
335
// compute the array of 'A' and 'B' coeffs of the Ax+B linear function by which we need to multiply
336
// the 3D 'cuts' to translate it from 3D (i.e. with respect to the rotAxis) to 2D in-face (i.e. with
337
// respect to the 2D rotAxis cast into a particular face)
338

  
339
  void computeLinear(float distance3D, Static3D[] rotAxis, Static3D[] faceAxis)
340
    {
341
    int numFaces = faceAxis.length;
342
    int numRot   = rotAxis.length;
343

  
344
    mA = new float[numFaces][numRot];
345
    mB = new float[numFaces][numRot];
346

  
347
    for(int i=0; i<numFaces; i++)
348
      for(int j=0; j<numRot; j++)
349
        {
350
        mA[i][j] = crossProductLen(faceAxis[i],rotAxis[j]);
351

  
352
        if( mA[i][j]!=0.0f )
353
          {
354
          float coeff = (float)Math.sqrt(1/(mA[i][j]*mA[i][j]) -1);
355
          int sign = computeSign(faceAxis[i],rotAxis[j]);
356
          mB[i][j] = sign*distance3D*coeff;
357
          }
358
        else mB[i][j] = 0.0f;
359

  
360
        android.util.Log.e("D", "face="+i+" rot="+j+" a="+mA[i][j]+" B="+mB[i][j]);
361
        }
362
    }
363

  
364
///////////////////////////////////////////////////////////////////////////////////////////////////
365

  
366
  private int computeRowFromOffset(int face, int axisIndex, float offset)
367
    {
368
    float[] borders = mTouchBorders[axisIndex];
369
    int len = borders.length;
370
    float A = mA[face][axisIndex];
371

  
372
    if( A!=0.0f )
373
      {
374
      float B = mB[face][axisIndex];
375

  
376
      for(int i=0; i<len; i++)
377
        {
378
        float translated = B + borders[i]/A;
379

  
380
        android.util.Log.e("D", "offset="+offset+" borders[i]="+borders[i]+" translated="+translated+" A="+A+" B="+B);
381

  
382
        if( offset<translated ) return i;
383
        }
297 384
      }
298 385

  
299
    return borders;
386
    return len;
300 387
    }
301 388

  
302 389
///////////////////////////////////////////////////////////////////////////////////////////////////
......
328 415

  
329 416
///////////////////////////////////////////////////////////////////////////////////////////////////
330 417

  
331
  public Static2D newRotation(int numLayers, Static4D rotatedTouchPoint, float objectRatio)
418
  public Static2D newRotation(Static4D rotatedTouchPoint, float objectRatio)
332 419
    {
333 420
    mPoint[0] = rotatedTouchPoint.get0()/objectRatio;
334 421
    mPoint[1] = rotatedTouchPoint.get1()/objectRatio;
......
343 430
    computeEnabledAxis(mLastTouchedFace, mPoint2D, mEnabledRotAxis);
344 431
    int rotIndex = computeRotationIndex(mLastTouchedFace, mMove2D, mEnabledRotAxis);
345 432
    float offset = computeOffset(mPoint2D, mCastedRotAxis[mLastTouchedFace][rotIndex]);
346
    int row      = computeRowFromOffset(mLastTouchedFace,rotIndex,numLayers,offset);
433
    int row      = computeRowFromOffset(mLastTouchedFace,rotIndex,offset);
347 434

  
348 435
    return new Static2D(rotIndex,row);
349 436
    }
src/main/java/org/distorted/objects/Movement12.java
51 51
           new Static3D(-SIN54/LEN,    0     ,   -C2/LEN )
52 52
         };
53 53

  
54
  private final float[][] mTouchBorders;
55

  
56
///////////////////////////////////////////////////////////////////////////////////////////////////
57

  
58
  Movement12(Static3D[] rotAxis,float[][] cuts, boolean[][] rotatable, int numLayers)
59
    {
60
    super(rotAxis, FACE_AXIS, DIST3D, DIST2D);
61
    float scale = (DIST2D*(1.5f)/(2*DIST3D))/numLayers; // SQ5/2 is 1/cos(dihedral-90)
62
    mTouchBorders = computeBorders(scale,cuts,rotatable);
63
    }
64

  
65 54
///////////////////////////////////////////////////////////////////////////////////////////////////
66 55

  
67
  int computeRowFromOffset(int face, int axisIndex, int numLayers, float offset)
56
  Movement12(Static3D[] rotAxis,float[][] cuts, boolean[][] rotatable, int size)
68 57
    {
69
    float[] borders = mTouchBorders[axisIndex];
70
    int len = borders.length;
71

  
72
    for(int i=0; i<len; i++)
73
      {
74
      if( offset<borders[i] ) return i;
75
      }
76

  
77
    return len;
58
    super(rotAxis, FACE_AXIS, cuts,rotatable,DIST3D, size);
78 59
    }
79 60

  
80 61
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/objects/Movement4.java
39 39
           new Static3D(+SQ6/3,-SQ3/3,     0),
40 40
         };
41 41

  
42
  private final float[][] mTouchBorders;
43

  
44
///////////////////////////////////////////////////////////////////////////////////////////////////
45

  
46
  Movement4(Static3D[] rotAxis,float[][] cuts, boolean[][] rotatable,int numLayers)
47
    {
48
    super(rotAxis, FACE_AXIS, DIST3D, DIST2D);
49
    float scale = (3*SQ2/4)/numLayers; // 3*SQ2/4 is height(face)/height(tetra)
50
    mTouchBorders = computeBorders(scale,cuts,rotatable);
51
    }
52

  
53 42
///////////////////////////////////////////////////////////////////////////////////////////////////
54 43

  
55
  int computeRowFromOffset(int face, int axisIndex, int numLayers, float offset)
44
  Movement4(Static3D[] rotAxis,float[][] cuts, boolean[][] rotatable, int size)
56 45
    {
57
    float[] borders = mTouchBorders[axisIndex];
58
    int len = borders.length;
59

  
60
    for(int i=0; i<len; i++)
61
      {
62
      if( offset<borders[i] ) return i;
63
      }
64

  
65
    return len;
46
    super(rotAxis, FACE_AXIS, cuts, rotatable, DIST3D, size);
66 47
    }
67 48

  
68 49
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/objects/Movement6.java
38 38
           new Static3D(0,0,1), new Static3D(0,0,-1)
39 39
         };
40 40

  
41
  private final float[][] mTouchBorders;
42

  
43
///////////////////////////////////////////////////////////////////////////////////////////////////
44

  
45
  Movement6(Static3D[] rotAxis,float[][] cuts, boolean[][] rotatable, int numLayers)
46
    {
47
    super(rotAxis, FACE_AXIS, DIST3D, DIST2D);
48
    float scale = 1.0f/numLayers; // 1.0 is (2*DIST3D)/(2*DIST2D)
49
    mTouchBorders = computeBorders(scale,cuts,rotatable);
50
    }
51

  
52 41
///////////////////////////////////////////////////////////////////////////////////////////////////
53 42

  
54
  int computeRowFromOffset(int face, int axisIndex, int numLayers, float offset)
43
  Movement6(Static3D[] rotAxis,float[][] cuts, boolean[][] rotatable, int size)
55 44
    {
56
    float[] borders = mTouchBorders[axisIndex];
57
    int len = borders.length;
58

  
59
    for(int i=0; i<len; i++)
60
      {
61
      if( offset<borders[i] ) return i;
62
      }
63

  
64
    return len;
45
    super(rotAxis, FACE_AXIS, cuts, rotatable, DIST3D, size);
65 46
    }
66 47

  
67 48
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/objects/Movement8.java
39 39
           new Static3D(     0,+SQ3/3,-SQ6/3), new Static3D(     0,-SQ3/3,+SQ6/3)
40 40
         };
41 41

  
42
  private final float[][] mTouchBorders;
43

  
44
///////////////////////////////////////////////////////////////////////////////////////////////////
45

  
46
  Movement8(Static3D[] rotAxis,float[][] cuts, boolean[][] rotatable, int numLayers)
47
    {
48
    super(rotAxis, FACE_AXIS, DIST3D, DIST2D);
49
    float scale = (3*SQ2/4)/numLayers; // 3*SQ2/4 is 1/cos(dihedral-90)
50
    mTouchBorders = computeBorders(scale,cuts,rotatable);
51
    }
52

  
53 42
///////////////////////////////////////////////////////////////////////////////////////////////////
54
// We have either one of the four faces (1,3,4,6) which, when the retAxis are cast onto it, they
55
// point the right way (and so the triangle then spans from offset=-SQ3/6 to offset=+SQ3/3 with
56
// midpoint at SQ3/12) or one of the other face when the cast rotAxis are the wrong way round (and
57
// the triangle spans then from 0 to SQ3/2 with midpoint at SQ3/4).
58
//
59
// This is only true if the rotAxis connect the centers of opposing faces!
60 43

  
61
  int computeRowFromOffset(int face, int axisIndex, int numLayers, float offset)
44
  Movement8(Static3D[] rotAxis,float[][] cuts, boolean[][] rotatable, int size)
62 45
    {
63
    float off = ( face==1 || face==3 || face==4 || face==6 ) ? DIST2D/2 : -DIST2D/2;
64
    float[] borders = mTouchBorders[axisIndex];
65
    int len = borders.length;
66

  
67
    for(int i=0; i<len; i++)
68
      {
69
      if( offset+off<borders[i] ) return i;
70
      }
71

  
72
    return len;
46
    super(rotAxis, FACE_AXIS, cuts, rotatable, DIST3D, size);
73 47
    }
74 48

  
75 49
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/objects/MovementCornerTwisting.java
35 35

  
36 36
///////////////////////////////////////////////////////////////////////////////////////////////////
37 37

  
38
  MovementCornerTwisting(float[][] cuts, boolean[][] rotatable, int numLayers)
38
  MovementCornerTwisting(float[][] cuts, boolean[][] rotatable,int size)
39 39
    {
40
    super(TwistySkewb.ROT_AXIS,cuts,rotatable,numLayers);
40
    super(TwistySkewb.ROT_AXIS,cuts,rotatable,size);
41 41
    }
42 42

  
43 43
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/objects/MovementCube.java
30 30

  
31 31
///////////////////////////////////////////////////////////////////////////////////////////////////
32 32

  
33
  MovementCube(float[][] cuts, boolean[][] rotatable, int numLayers)
33
  MovementCube(float[][] cuts, boolean[][] rotatable, int size)
34 34
    {
35
    super(TwistyCube.ROT_AXIS,cuts,rotatable,numLayers);
35
    super(TwistyCube.ROT_AXIS,cuts,rotatable,size);
36 36
    }
37 37

  
38 38
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/objects/MovementDiamond.java
23 23

  
24 24
class MovementDiamond extends Movement8
25 25
{
26
  MovementDiamond(float[][] cuts, boolean[][] rotatable, int numLayers)
26
  MovementDiamond(float[][] cuts, boolean[][] rotatable, int size)
27 27
    {
28
    super(TwistyDiamond.ROT_AXIS,cuts,rotatable, numLayers);
28
    super(TwistyDiamond.ROT_AXIS,cuts,rotatable,size);
29 29
    }
30 30

  
31 31
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/objects/MovementHelicopter.java
23 23

  
24 24
class MovementHelicopter extends Movement6
25 25
{
26
  MovementHelicopter(float[][] cuts, boolean[][] rotatable, int numLayers)
26
  MovementHelicopter(float[][] cuts, boolean[][] rotatable, int size)
27 27
    {
28
    super(TwistyHelicopter.ROT_AXIS,cuts,rotatable, numLayers);
28
    super(TwistyHelicopter.ROT_AXIS,cuts,rotatable,size);
29 29
    }
30 30

  
31 31
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/objects/MovementIvy.java
23 23

  
24 24
class MovementIvy extends Movement6
25 25
{
26
  MovementIvy(float[][] cuts, boolean[][] rotatable, int numLayers)
26
  MovementIvy(float[][] cuts, boolean[][] rotatable, int size)
27 27
    {
28
    super(TwistyIvy.ROT_AXIS,cuts,rotatable,numLayers);
28
    super(TwistyIvy.ROT_AXIS,cuts,rotatable,size);
29 29
    }
30 30

  
31 31
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/objects/MovementJing.java
23 23

  
24 24
class MovementJing extends Movement4
25 25
{
26
  MovementJing(float[][] cuts, boolean[][] rotatable, int numLayers)
26
  MovementJing(float[][] cuts, boolean[][] rotatable, int size)
27 27
    {
28
    super(TwistyJing.ROT_AXIS,cuts,rotatable,numLayers);
28
    super(TwistyJing.ROT_AXIS,cuts,rotatable,size);
29 29
    }
30 30

  
31 31
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/objects/MovementMinx.java
23 23

  
24 24
class MovementMinx extends Movement12
25 25
{
26
  MovementMinx(float[][] cuts, boolean[][] rotatable, int numLayers)
26
  MovementMinx(float[][] cuts, boolean[][] rotatable, int size)
27 27
    {
28
    super(TwistyMinx.ROT_AXIS,cuts,rotatable,numLayers);
28
    super(TwistyMinx.ROT_AXIS,cuts,rotatable,size);
29 29
    }
30 30

  
31 31
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/objects/MovementPyraminx.java
23 23

  
24 24
class MovementPyraminx extends Movement4
25 25
{
26
  MovementPyraminx(float[][] cuts, boolean[][] rotatable,int numLayers)
26
  MovementPyraminx(float[][] cuts, boolean[][] rotatable, int size)
27 27
    {
28
    super(TwistyPyraminx.ROT_AXIS,cuts,rotatable,numLayers);
28
    super(TwistyPyraminx.ROT_AXIS,cuts,rotatable,size);
29 29
    }
30 30

  
31 31
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/objects/MovementSquare.java
23 23

  
24 24
class MovementSquare extends Movement6
25 25
{
26
  MovementSquare(float[][] cuts, boolean[][] rotatable, int numLayers)
26
  MovementSquare(float[][] cuts, boolean[][] rotatable, int size)
27 27
    {
28
    super(TwistySquare.ROT_AXIS,cuts,rotatable,numLayers);
28
    super(TwistySquare.ROT_AXIS,cuts,rotatable,size);
29 29
    }
30 30

  
31 31
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/objects/MovementUltimate.java
23 23

  
24 24
class MovementUltimate extends Movement12
25 25
{
26
  MovementUltimate(float[][] cuts, boolean[][] rotatable, int numLayers)
26
  MovementUltimate(float[][] cuts, boolean[][] rotatable, int size)
27 27
    {
28
    super(TwistyUltimate.ROT_AXIS,cuts,rotatable,numLayers);
28
    super(TwistyUltimate.ROT_AXIS,cuts,rotatable,size);
29 29
    }
30 30

  
31 31
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/objects/TwistyPyraminx.java
222 222

  
223 223
      for(int i=0; i<numLayers-1; i++)
224 224
        {
225
        float cut = (1.0f+i-numLayers/3.0f)*(SQ6/3);
225
        float cut = (1.0f+i-numLayers/4.0f)*(SQ6/3);
226 226
        mCuts[0][i] = cut;
227 227
        mCuts[1][i] = cut;
228 228
        mCuts[2][i] = cut;
src/main/java/org/distorted/objects/TwistySkewb.java
553 553
      if( mCuts==null ) getCuts(numLayers);
554 554
      getLayerRotatable(numLayers);
555 555

  
556
      mMovement = new MovementCornerTwisting(mCuts,mLayerRotatable,numLayers);
556
      mMovement = new MovementCornerTwisting(mCuts,mLayerRotatable,2*numLayers-2);
557 557
      }
558 558
    return mMovement;
559 559
    }
src/main/java/org/distorted/tutorials/TutorialSurfaceView.java
339 339

  
340 340
      Static4D touchPoint2 = new Static4D(x, y, 0, 0);
341 341
      Static4D rotatedTouchPoint2= QuatHelper.rotateVectorByInvertedQuat(touchPoint2, mQuat);
342
      Static2D res = mMovement.newRotation(numLayers,rotatedTouchPoint2,object.getObjectRatio());
342
      Static2D res = mMovement.newRotation(rotatedTouchPoint2,object.getObjectRatio());
343 343

  
344 344
      mCurrentAxis = (int)res.get0();
345 345
      mCurrentRow  = (int)res.get1();

Also available in: Unified diff