commit 4946b635838e121da6cc37dc8ae8ab2ae97ce176
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Fri Sep 24 11:30:59 2021 +0200

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

diff --git a/src/main/java/org/distorted/main/RubikSurfaceView.java b/src/main/java/org/distorted/main/RubikSurfaceView.java
index b68fe2e5..ca471e5f 100644
--- a/src/main/java/org/distorted/main/RubikSurfaceView.java
+++ b/src/main/java/org/distorted/main/RubikSurfaceView.java
@@ -394,7 +394,7 @@ public class RubikSurfaceView extends GLSurfaceView
 
       Static4D touchPoint2 = new Static4D(x, y, 0, 0);
       Static4D rotatedTouchPoint2= QuatHelper.rotateVectorByInvertedQuat(touchPoint2, mQuat);
-      Static2D res = mMovement.newRotation(numLayers,rotatedTouchPoint2,object.getObjectRatio());
+      Static2D res = mMovement.newRotation(rotatedTouchPoint2,object.getObjectRatio());
 
       mCurrentAxis = (int)res.get0();
       mCurrentRow  = (int)res.get1();
diff --git a/src/main/java/org/distorted/objects/Movement.java b/src/main/java/org/distorted/objects/Movement.java
index da2561e3..02e82e0e 100644
--- a/src/main/java/org/distorted/objects/Movement.java
+++ b/src/main/java/org/distorted/objects/Movement.java
@@ -34,23 +34,23 @@ public abstract class Movement
   private final float[] mPoint, mCamera, mTouch;
   private final float[] mPoint2D, mMove2D;
   private final int[] mEnabledRotAxis;
-  private final float mDistanceCenterFace3D, mDistanceCenterFace2D;
+  private final float mDistanceCenterFace3D;
   private final Static3D[] mFaceAxis;
 
   private int mLastTouchedFace;
   private float[][][] mCastedRotAxis;
   private Static4D[][] mCastedRotAxis4D;
+  private float[][] mTouchBorders, mA, mB;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   abstract boolean isInsideFace(int face, float[] point);
   abstract void computeEnabledAxis(int face, float[] touchPoint, int[] enabledAxis);
-  abstract int computeRowFromOffset(int face, int axisIndex, int numLayers, float offset);
   public abstract float returnRotationFactor(int numLayers, int row);
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  Movement(Static3D[] rotAxis, Static3D[] faceAxis, float distance3D, float distance2D)
+  Movement(Static3D[] rotAxis, Static3D[] faceAxis, float[][] cuts, boolean[][] rotatable, float distance3D, int size)
     {
     mPoint = new float[3];
     mCamera= new float[3];
@@ -65,9 +65,10 @@ public abstract class Movement
     mEnabledRotAxis = new int[rotAxis.length+1];
 
     mDistanceCenterFace3D = distance3D; // distance from the center of the object to each of its faces
-    mDistanceCenterFace2D = distance2D; // distance from the center of a face to its edge
 
     computeCastedAxis(rotAxis);
+    computeBorders(cuts,rotatable,size);
+    computeLinear(distance3D,rotAxis,faceAxis);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -249,7 +250,7 @@ public abstract class Movement
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  float[] computeBorder(float scale, float[] cuts, boolean[] rotatable)
+  private float[] computeBorder(float[] cuts, boolean[] rotatable, int size)
     {
     int len = cuts.length;
     float[] border = new float[len];
@@ -262,7 +263,7 @@ public abstract class Movement
         }
       else
         {
-        if( rotatable[i+1] ) border[i] = scale*cuts[i];
+        if( rotatable[i+1] ) border[i] = cuts[i]/size;
         else
           {
           int found = -1;
@@ -276,7 +277,7 @@ public abstract class Movement
               }
             }
 
-          border[i] = found>0 ? scale*(cuts[i]+cuts[found-1])/2 : Float.MAX_VALUE;
+          border[i] = found>0 ? (cuts[i]+cuts[found-1])/(2*size) : Float.MAX_VALUE;
           }
         }
       }
@@ -285,18 +286,104 @@ public abstract class Movement
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
+// size, not numLayers (see Master Skewb where size!=numLayers)
 
-  float[][] computeBorders(float coeff, float[][] cuts, boolean[][] rotatable)
+  void computeBorders(float[][] cuts, boolean[][] rotatable, int size)
     {
     int numCuts = cuts.length;
-    float[][] borders = new float[numCuts][];
+    mTouchBorders = new float[numCuts][];
 
     for(int i=0; i<numCuts; i++)
       {
-      borders[i] = computeBorder(coeff,cuts[i],rotatable[i]);
+      mTouchBorders[i] = computeBorder(cuts[i],rotatable[i],size);
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private int computeSign(Static3D a, Static3D b)
+    {
+    float a1 = a.get0();
+    float a2 = a.get1();
+    float a3 = a.get2();
+    float b1 = b.get0();
+    float b2 = b.get1();
+    float b3 = b.get2();
+
+    return a1*b1+a2*b2+a3*b3 < 0 ? 1:-1;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private float crossProductLen(Static3D a, Static3D b)
+    {
+    float a1 = a.get0();
+    float a2 = a.get1();
+    float a3 = a.get2();
+    float b1 = b.get0();
+    float b2 = b.get1();
+    float b3 = b.get2();
+
+    float x1 = a2*b3-a3*b2;
+    float x2 = a3*b1-a1*b3;
+    float x3 = a1*b2-a2*b1;
+
+    return (float)Math.sqrt(x1*x1 + x2*x2 + x3*x3);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// compute the array of 'A' and 'B' coeffs of the Ax+B linear function by which we need to multiply
+// the 3D 'cuts' to translate it from 3D (i.e. with respect to the rotAxis) to 2D in-face (i.e. with
+// respect to the 2D rotAxis cast into a particular face)
+
+  void computeLinear(float distance3D, Static3D[] rotAxis, Static3D[] faceAxis)
+    {
+    int numFaces = faceAxis.length;
+    int numRot   = rotAxis.length;
+
+    mA = new float[numFaces][numRot];
+    mB = new float[numFaces][numRot];
+
+    for(int i=0; i<numFaces; i++)
+      for(int j=0; j<numRot; j++)
+        {
+        mA[i][j] = crossProductLen(faceAxis[i],rotAxis[j]);
+
+        if( mA[i][j]!=0.0f )
+          {
+          float coeff = (float)Math.sqrt(1/(mA[i][j]*mA[i][j]) -1);
+          int sign = computeSign(faceAxis[i],rotAxis[j]);
+          mB[i][j] = sign*distance3D*coeff;
+          }
+        else mB[i][j] = 0.0f;
+
+        android.util.Log.e("D", "face="+i+" rot="+j+" a="+mA[i][j]+" B="+mB[i][j]);
+        }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private int computeRowFromOffset(int face, int axisIndex, float offset)
+    {
+    float[] borders = mTouchBorders[axisIndex];
+    int len = borders.length;
+    float A = mA[face][axisIndex];
+
+    if( A!=0.0f )
+      {
+      float B = mB[face][axisIndex];
+
+      for(int i=0; i<len; i++)
+        {
+        float translated = B + borders[i]/A;
+
+        android.util.Log.e("D", "offset="+offset+" borders[i]="+borders[i]+" translated="+translated+" A="+A+" B="+B);
+
+        if( offset<translated ) return i;
+        }
       }
 
-    return borders;
+    return len;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -328,7 +415,7 @@ public abstract class Movement
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public Static2D newRotation(int numLayers, Static4D rotatedTouchPoint, float objectRatio)
+  public Static2D newRotation(Static4D rotatedTouchPoint, float objectRatio)
     {
     mPoint[0] = rotatedTouchPoint.get0()/objectRatio;
     mPoint[1] = rotatedTouchPoint.get1()/objectRatio;
@@ -343,7 +430,7 @@ public abstract class Movement
     computeEnabledAxis(mLastTouchedFace, mPoint2D, mEnabledRotAxis);
     int rotIndex = computeRotationIndex(mLastTouchedFace, mMove2D, mEnabledRotAxis);
     float offset = computeOffset(mPoint2D, mCastedRotAxis[mLastTouchedFace][rotIndex]);
-    int row      = computeRowFromOffset(mLastTouchedFace,rotIndex,numLayers,offset);
+    int row      = computeRowFromOffset(mLastTouchedFace,rotIndex,offset);
 
     return new Static2D(rotIndex,row);
     }
diff --git a/src/main/java/org/distorted/objects/Movement12.java b/src/main/java/org/distorted/objects/Movement12.java
index ce7b45c8..5384b699 100644
--- a/src/main/java/org/distorted/objects/Movement12.java
+++ b/src/main/java/org/distorted/objects/Movement12.java
@@ -51,30 +51,11 @@ abstract class Movement12 extends Movement
            new Static3D(-SIN54/LEN,    0     ,   -C2/LEN )
          };
 
-  private final float[][] mTouchBorders;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  Movement12(Static3D[] rotAxis,float[][] cuts, boolean[][] rotatable, int numLayers)
-    {
-    super(rotAxis, FACE_AXIS, DIST3D, DIST2D);
-    float scale = (DIST2D*(1.5f)/(2*DIST3D))/numLayers; // SQ5/2 is 1/cos(dihedral-90)
-    mTouchBorders = computeBorders(scale,cuts,rotatable);
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  int computeRowFromOffset(int face, int axisIndex, int numLayers, float offset)
+  Movement12(Static3D[] rotAxis,float[][] cuts, boolean[][] rotatable, int size)
     {
-    float[] borders = mTouchBorders[axisIndex];
-    int len = borders.length;
-
-    for(int i=0; i<len; i++)
-      {
-      if( offset<borders[i] ) return i;
-      }
-
-    return len;
+    super(rotAxis, FACE_AXIS, cuts,rotatable,DIST3D, size);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/Movement4.java b/src/main/java/org/distorted/objects/Movement4.java
index 135904f9..388a970c 100644
--- a/src/main/java/org/distorted/objects/Movement4.java
+++ b/src/main/java/org/distorted/objects/Movement4.java
@@ -39,30 +39,11 @@ abstract class Movement4 extends Movement
            new Static3D(+SQ6/3,-SQ3/3,     0),
          };
 
-  private final float[][] mTouchBorders;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  Movement4(Static3D[] rotAxis,float[][] cuts, boolean[][] rotatable,int numLayers)
-    {
-    super(rotAxis, FACE_AXIS, DIST3D, DIST2D);
-    float scale = (3*SQ2/4)/numLayers; // 3*SQ2/4 is height(face)/height(tetra)
-    mTouchBorders = computeBorders(scale,cuts,rotatable);
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  int computeRowFromOffset(int face, int axisIndex, int numLayers, float offset)
+  Movement4(Static3D[] rotAxis,float[][] cuts, boolean[][] rotatable, int size)
     {
-    float[] borders = mTouchBorders[axisIndex];
-    int len = borders.length;
-
-    for(int i=0; i<len; i++)
-      {
-      if( offset<borders[i] ) return i;
-      }
-
-    return len;
+    super(rotAxis, FACE_AXIS, cuts, rotatable, DIST3D, size);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/Movement6.java b/src/main/java/org/distorted/objects/Movement6.java
index 355f8fe5..c82bd75c 100644
--- a/src/main/java/org/distorted/objects/Movement6.java
+++ b/src/main/java/org/distorted/objects/Movement6.java
@@ -38,30 +38,11 @@ abstract class Movement6 extends Movement
            new Static3D(0,0,1), new Static3D(0,0,-1)
          };
 
-  private final float[][] mTouchBorders;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  Movement6(Static3D[] rotAxis,float[][] cuts, boolean[][] rotatable, int numLayers)
-    {
-    super(rotAxis, FACE_AXIS, DIST3D, DIST2D);
-    float scale = 1.0f/numLayers; // 1.0 is (2*DIST3D)/(2*DIST2D)
-    mTouchBorders = computeBorders(scale,cuts,rotatable);
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  int computeRowFromOffset(int face, int axisIndex, int numLayers, float offset)
+  Movement6(Static3D[] rotAxis,float[][] cuts, boolean[][] rotatable, int size)
     {
-    float[] borders = mTouchBorders[axisIndex];
-    int len = borders.length;
-
-    for(int i=0; i<len; i++)
-      {
-      if( offset<borders[i] ) return i;
-      }
-
-    return len;
+    super(rotAxis, FACE_AXIS, cuts, rotatable, DIST3D, size);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/Movement8.java b/src/main/java/org/distorted/objects/Movement8.java
index 7e6c17f7..6d020929 100644
--- a/src/main/java/org/distorted/objects/Movement8.java
+++ b/src/main/java/org/distorted/objects/Movement8.java
@@ -39,37 +39,11 @@ abstract class Movement8 extends Movement
            new Static3D(     0,+SQ3/3,-SQ6/3), new Static3D(     0,-SQ3/3,+SQ6/3)
          };
 
-  private final float[][] mTouchBorders;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  Movement8(Static3D[] rotAxis,float[][] cuts, boolean[][] rotatable, int numLayers)
-    {
-    super(rotAxis, FACE_AXIS, DIST3D, DIST2D);
-    float scale = (3*SQ2/4)/numLayers; // 3*SQ2/4 is 1/cos(dihedral-90)
-    mTouchBorders = computeBorders(scale,cuts,rotatable);
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// We have either one of the four faces (1,3,4,6) which, when the retAxis are cast onto it, they
-// point the right way (and so the triangle then spans from offset=-SQ3/6 to offset=+SQ3/3 with
-// midpoint at SQ3/12) or one of the other face when the cast rotAxis are the wrong way round (and
-// the triangle spans then from 0 to SQ3/2 with midpoint at SQ3/4).
-//
-// This is only true if the rotAxis connect the centers of opposing faces!
 
-  int computeRowFromOffset(int face, int axisIndex, int numLayers, float offset)
+  Movement8(Static3D[] rotAxis,float[][] cuts, boolean[][] rotatable, int size)
     {
-    float off = ( face==1 || face==3 || face==4 || face==6 ) ? DIST2D/2 : -DIST2D/2;
-    float[] borders = mTouchBorders[axisIndex];
-    int len = borders.length;
-
-    for(int i=0; i<len; i++)
-      {
-      if( offset+off<borders[i] ) return i;
-      }
-
-    return len;
+    super(rotAxis, FACE_AXIS, cuts, rotatable, DIST3D, size);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/MovementCornerTwisting.java b/src/main/java/org/distorted/objects/MovementCornerTwisting.java
index 0ac70635..5e45e76f 100644
--- a/src/main/java/org/distorted/objects/MovementCornerTwisting.java
+++ b/src/main/java/org/distorted/objects/MovementCornerTwisting.java
@@ -35,9 +35,9 @@ class MovementCornerTwisting extends Movement6
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  MovementCornerTwisting(float[][] cuts, boolean[][] rotatable, int numLayers)
+  MovementCornerTwisting(float[][] cuts, boolean[][] rotatable,int size)
     {
-    super(TwistySkewb.ROT_AXIS,cuts,rotatable,numLayers);
+    super(TwistySkewb.ROT_AXIS,cuts,rotatable,size);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/MovementCube.java b/src/main/java/org/distorted/objects/MovementCube.java
index 44e2f615..12ea035f 100644
--- a/src/main/java/org/distorted/objects/MovementCube.java
+++ b/src/main/java/org/distorted/objects/MovementCube.java
@@ -30,9 +30,9 @@ class MovementCube extends Movement6
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  MovementCube(float[][] cuts, boolean[][] rotatable, int numLayers)
+  MovementCube(float[][] cuts, boolean[][] rotatable, int size)
     {
-    super(TwistyCube.ROT_AXIS,cuts,rotatable,numLayers);
+    super(TwistyCube.ROT_AXIS,cuts,rotatable,size);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/MovementDiamond.java b/src/main/java/org/distorted/objects/MovementDiamond.java
index 329a2143..3502ff11 100644
--- a/src/main/java/org/distorted/objects/MovementDiamond.java
+++ b/src/main/java/org/distorted/objects/MovementDiamond.java
@@ -23,9 +23,9 @@ package org.distorted.objects;
 
 class MovementDiamond extends Movement8
 {
-  MovementDiamond(float[][] cuts, boolean[][] rotatable, int numLayers)
+  MovementDiamond(float[][] cuts, boolean[][] rotatable, int size)
     {
-    super(TwistyDiamond.ROT_AXIS,cuts,rotatable, numLayers);
+    super(TwistyDiamond.ROT_AXIS,cuts,rotatable,size);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/MovementHelicopter.java b/src/main/java/org/distorted/objects/MovementHelicopter.java
index 9bf78ee0..d6f369a5 100644
--- a/src/main/java/org/distorted/objects/MovementHelicopter.java
+++ b/src/main/java/org/distorted/objects/MovementHelicopter.java
@@ -23,9 +23,9 @@ package org.distorted.objects;
 
 class MovementHelicopter extends Movement6
 {
-  MovementHelicopter(float[][] cuts, boolean[][] rotatable, int numLayers)
+  MovementHelicopter(float[][] cuts, boolean[][] rotatable, int size)
     {
-    super(TwistyHelicopter.ROT_AXIS,cuts,rotatable, numLayers);
+    super(TwistyHelicopter.ROT_AXIS,cuts,rotatable,size);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/MovementIvy.java b/src/main/java/org/distorted/objects/MovementIvy.java
index 0c770c07..629e7d7d 100644
--- a/src/main/java/org/distorted/objects/MovementIvy.java
+++ b/src/main/java/org/distorted/objects/MovementIvy.java
@@ -23,9 +23,9 @@ package org.distorted.objects;
 
 class MovementIvy extends Movement6
 {
-  MovementIvy(float[][] cuts, boolean[][] rotatable, int numLayers)
+  MovementIvy(float[][] cuts, boolean[][] rotatable, int size)
     {
-    super(TwistyIvy.ROT_AXIS,cuts,rotatable,numLayers);
+    super(TwistyIvy.ROT_AXIS,cuts,rotatable,size);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/MovementJing.java b/src/main/java/org/distorted/objects/MovementJing.java
index 67139a83..a02d6530 100644
--- a/src/main/java/org/distorted/objects/MovementJing.java
+++ b/src/main/java/org/distorted/objects/MovementJing.java
@@ -23,9 +23,9 @@ package org.distorted.objects;
 
 class MovementJing extends Movement4
 {
-  MovementJing(float[][] cuts, boolean[][] rotatable, int numLayers)
+  MovementJing(float[][] cuts, boolean[][] rotatable, int size)
     {
-    super(TwistyJing.ROT_AXIS,cuts,rotatable,numLayers);
+    super(TwistyJing.ROT_AXIS,cuts,rotatable,size);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/MovementMinx.java b/src/main/java/org/distorted/objects/MovementMinx.java
index c532f063..ef728a30 100644
--- a/src/main/java/org/distorted/objects/MovementMinx.java
+++ b/src/main/java/org/distorted/objects/MovementMinx.java
@@ -23,9 +23,9 @@ package org.distorted.objects;
 
 class MovementMinx extends Movement12
 {
-  MovementMinx(float[][] cuts, boolean[][] rotatable, int numLayers)
+  MovementMinx(float[][] cuts, boolean[][] rotatable, int size)
     {
-    super(TwistyMinx.ROT_AXIS,cuts,rotatable,numLayers);
+    super(TwistyMinx.ROT_AXIS,cuts,rotatable,size);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/MovementPyraminx.java b/src/main/java/org/distorted/objects/MovementPyraminx.java
index b68e6125..6c32f05f 100644
--- a/src/main/java/org/distorted/objects/MovementPyraminx.java
+++ b/src/main/java/org/distorted/objects/MovementPyraminx.java
@@ -23,9 +23,9 @@ package org.distorted.objects;
 
 class MovementPyraminx extends Movement4
 {
-  MovementPyraminx(float[][] cuts, boolean[][] rotatable,int numLayers)
+  MovementPyraminx(float[][] cuts, boolean[][] rotatable, int size)
     {
-    super(TwistyPyraminx.ROT_AXIS,cuts,rotatable,numLayers);
+    super(TwistyPyraminx.ROT_AXIS,cuts,rotatable,size);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/MovementSquare.java b/src/main/java/org/distorted/objects/MovementSquare.java
index 4b5fa82f..f035c151 100644
--- a/src/main/java/org/distorted/objects/MovementSquare.java
+++ b/src/main/java/org/distorted/objects/MovementSquare.java
@@ -23,9 +23,9 @@ package org.distorted.objects;
 
 class MovementSquare extends Movement6
 {
-  MovementSquare(float[][] cuts, boolean[][] rotatable, int numLayers)
+  MovementSquare(float[][] cuts, boolean[][] rotatable, int size)
     {
-    super(TwistySquare.ROT_AXIS,cuts,rotatable,numLayers);
+    super(TwistySquare.ROT_AXIS,cuts,rotatable,size);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/MovementUltimate.java b/src/main/java/org/distorted/objects/MovementUltimate.java
index e9c6d225..3cbefb25 100644
--- a/src/main/java/org/distorted/objects/MovementUltimate.java
+++ b/src/main/java/org/distorted/objects/MovementUltimate.java
@@ -23,9 +23,9 @@ package org.distorted.objects;
 
 class MovementUltimate extends Movement12
 {
-  MovementUltimate(float[][] cuts, boolean[][] rotatable, int numLayers)
+  MovementUltimate(float[][] cuts, boolean[][] rotatable, int size)
     {
-    super(TwistyUltimate.ROT_AXIS,cuts,rotatable,numLayers);
+    super(TwistyUltimate.ROT_AXIS,cuts,rotatable,size);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/TwistyPyraminx.java b/src/main/java/org/distorted/objects/TwistyPyraminx.java
index 82970ec6..f22904fd 100644
--- a/src/main/java/org/distorted/objects/TwistyPyraminx.java
+++ b/src/main/java/org/distorted/objects/TwistyPyraminx.java
@@ -222,7 +222,7 @@ public class TwistyPyraminx extends Twisty4
 
       for(int i=0; i<numLayers-1; i++)
         {
-        float cut = (1.0f+i-numLayers/3.0f)*(SQ6/3);
+        float cut = (1.0f+i-numLayers/4.0f)*(SQ6/3);
         mCuts[0][i] = cut;
         mCuts[1][i] = cut;
         mCuts[2][i] = cut;
diff --git a/src/main/java/org/distorted/objects/TwistySkewb.java b/src/main/java/org/distorted/objects/TwistySkewb.java
index 4767388c..24a1aa31 100644
--- a/src/main/java/org/distorted/objects/TwistySkewb.java
+++ b/src/main/java/org/distorted/objects/TwistySkewb.java
@@ -553,7 +553,7 @@ public class TwistySkewb extends Twisty6
       if( mCuts==null ) getCuts(numLayers);
       getLayerRotatable(numLayers);
 
-      mMovement = new MovementCornerTwisting(mCuts,mLayerRotatable,numLayers);
+      mMovement = new MovementCornerTwisting(mCuts,mLayerRotatable,2*numLayers-2);
       }
     return mMovement;
     }
diff --git a/src/main/java/org/distorted/tutorials/TutorialSurfaceView.java b/src/main/java/org/distorted/tutorials/TutorialSurfaceView.java
index 578a99c3..0d052bc8 100644
--- a/src/main/java/org/distorted/tutorials/TutorialSurfaceView.java
+++ b/src/main/java/org/distorted/tutorials/TutorialSurfaceView.java
@@ -339,7 +339,7 @@ public class TutorialSurfaceView extends GLSurfaceView
 
       Static4D touchPoint2 = new Static4D(x, y, 0, 0);
       Static4D rotatedTouchPoint2= QuatHelper.rotateVectorByInvertedQuat(touchPoint2, mQuat);
-      Static2D res = mMovement.newRotation(numLayers,rotatedTouchPoint2,object.getObjectRatio());
+      Static2D res = mMovement.newRotation(rotatedTouchPoint2,object.getObjectRatio());
 
       mCurrentAxis = (int)res.get0();
       mCurrentRow  = (int)res.get1();
