commit 12ad3fcacb9eb1398dc099d9ae5a8811fb48803c
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Thu Mar 12 17:19:24 2020 +0000

    Progress with object Movement - almost finished.

diff --git a/src/main/java/org/distorted/effect/scramble/ScrambleEffect.java b/src/main/java/org/distorted/effect/scramble/ScrambleEffect.java
index 6bda74e3..e2c13340 100644
--- a/src/main/java/org/distorted/effect/scramble/ScrambleEffect.java
+++ b/src/main/java/org/distorted/effect/scramble/ScrambleEffect.java
@@ -308,7 +308,7 @@ public abstract class ScrambleEffect extends BaseEffect implements EffectListene
 
     mObject.solve();
 
-    mNumAxis    = mObject.getNumAxis();
+    mNumAxis    = mObject.getRotationAxis().length;
     mBasicAngle = mObject.getBasicAngle();
 
     int numScrambles = renderer.getNumScrambles();
diff --git a/src/main/java/org/distorted/magic/RubikSurfaceView.java b/src/main/java/org/distorted/magic/RubikSurfaceView.java
index a03f49f5..d37c615f 100644
--- a/src/main/java/org/distorted/magic/RubikSurfaceView.java
+++ b/src/main/java/org/distorted/magic/RubikSurfaceView.java
@@ -27,6 +27,7 @@ import android.util.AttributeSet;
 import android.view.MotionEvent;
 
 import org.distorted.library.type.Static2D;
+import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
 import org.distorted.object.RubikObject;
 import org.distorted.object.RubikObjectMovement;
@@ -59,9 +60,12 @@ public class RubikSurfaceView extends GLSurfaceView
     private RubikRenderer mRenderer;
     private RubikObjectMovement mMovement;
     private boolean mDragging, mBeginningRotation, mContinuingRotation;
-    private float mX, mY;
     private int mScreenWidth, mScreenHeight, mScreenMin;
 
+    private float mX, mY;
+    private float mStartRotX, mStartRotY;
+    private float mAxisX, mAxisY;
+
     private static Static4D mQuatCurrent    = new Static4D(0,0,0,1);
     private static Static4D mQuatAccumulated= new Static4D(-0.25189602f,0.3546389f,0.009657208f,0.90038127f);
     private static Static4D mTempCurrent    = new Static4D(0,0,0,1);
@@ -74,7 +78,7 @@ public class RubikSurfaceView extends GLSurfaceView
       mScreenWidth = width;
       mScreenHeight= height;
 
-      mScreenMin = width<height ? width:height;
+      mScreenMin = Math.min(width, height);
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -146,6 +150,61 @@ public class RubikSurfaceView extends GLSurfaceView
       return new Static4D(0f, 0f, 0f, 1f);
       }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    private void setUpDragOrRotate(float x, float y)
+      {
+      Static4D touchPoint1 = new Static4D(x, y, 0, 0);
+      Static4D rotatedTouchPoint1= rotateVectorByInvertedQuat(touchPoint1, mQuatAccumulated);
+      Static4D rotatedCamera= rotateVectorByInvertedQuat(CAMERA_POINT, mQuatAccumulated);
+
+      if( mMovement!=null && mMovement.faceTouched(rotatedTouchPoint1,rotatedCamera) )
+        {
+        mDragging           = false;
+        mBeginningRotation  = mRenderer.canRotate();
+        mContinuingRotation = false;
+        }
+      else
+        {
+        mDragging           = mRenderer.canDrag();
+        mBeginningRotation  = false;
+        mContinuingRotation = false;
+        }
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// cast the 3D axis we are currently rotating along to the 2D in-screen-surface axis
+
+    private void computeCurrentAxis(Static3D axis)
+      {
+      Static4D axis4D = new Static4D(axis.get0(), axis.get1(), axis.get2(), 0);
+      Static4D result = rotateVectorByQuat(axis4D, mQuatAccumulated);
+
+      mAxisX =result.get0();
+      mAxisY =result.get1();
+
+      float len = (float)Math.sqrt(mAxisX*mAxisX + mAxisY*mAxisY);
+      mAxisX /= len;
+      mAxisY /= len;
+
+      android.util.Log.e("axis", "axis 2D: "+mAxisX+" , "+mAxisY);
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    private float continueRotation(float dx, float dy)
+      {
+      float alpha = dx*mAxisX + dy*mAxisY;
+      float x = dx - alpha*mAxisX;
+      float y = dy - alpha*mAxisY;
+
+      float len = (float)Math.sqrt(x*x + y*y);
+
+
+
+      return len;
+      }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // return quat1*quat2
 
@@ -220,28 +279,6 @@ public class RubikSurfaceView extends GLSurfaceView
         }
       }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    private void setUpDragOrRotate(float x, float y)
-      {
-      Static4D touchPoint1 = new Static4D(x, y, 0, 0);
-      Static4D rotatedTouchPoint1= rotateVectorByInvertedQuat(touchPoint1, mQuatAccumulated);
-      Static4D rotatedCamera= rotateVectorByInvertedQuat(CAMERA_POINT, mQuatAccumulated);
-
-      if( mMovement!=null && mMovement.faceTouched(rotatedTouchPoint1,rotatedCamera) )
-        {
-        mDragging           = false;
-        mBeginningRotation  = mRenderer.canRotate();
-        mContinuingRotation = false;
-        }
-      else
-        {
-        mDragging           = mRenderer.canDrag();
-        mBeginningRotation  = false;
-        mContinuingRotation = false;
-        }
-      }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
     @Override
@@ -261,13 +298,19 @@ public class RubikSurfaceView extends GLSurfaceView
                                          {
                                          if( (mX-x)*(mX-x)+(mY-y)*(mY-y) > 1.0f/(ROTATION_SENSITIVITY*ROTATION_SENSITIVITY) )
                                            {
+                                           mStartRotX = x;
+                                           mStartRotY = y;
+
                                            Static4D touchPoint2 = new Static4D(x, y, 0, 0);
                                            Static4D rotatedTouchPoint2= rotateVectorByInvertedQuat(touchPoint2, mQuatAccumulated);
 
                                            Static2D rot = mMovement.newRotation(rotatedTouchPoint2);
                                            RubikObject object = mRenderer.getObject();
 
-                                           object.beginNewRotation( (int)rot.get0(), object.returnRowFromOffset(rot.get1()) );
+                                           int axis = (int)rot.get0();
+                                           computeCurrentAxis( object.getRotationAxis()[axis] );
+
+                                           object.beginNewRotation( axis, object.returnRowFromOffset(rot.get1()) );
 
                                            if( RubikState.getCurrentState()==RubikState.SOLV )
                                              {
@@ -281,10 +324,11 @@ public class RubikSurfaceView extends GLSurfaceView
                                          }
                                        else if( mContinuingRotation )
                                          {
-                                         Static4D touchPoint3 = new Static4D(x, y, 0, 0);
-                                         Static4D rotatedTouchPoint3= rotateVectorByInvertedQuat(touchPoint3, mQuatAccumulated);
+                                         //Static4D touchPoint3 = new Static4D(x, y, 0, 0);
+                                         //Static4D rotatedTouchPoint3= rotateVectorByInvertedQuat(touchPoint3, mQuatAccumulated);
 
-                                         float angle = mMovement.continueRotation(rotatedTouchPoint3);
+                                         float angle = continueRotation(x-mStartRotX,y-mStartRotY);
+                                         //float angle = mMovement.continueRotation(rotatedTouchPoint3);
                                          mRenderer.getObject().continueRotation(SWIPING_SENSITIVITY*angle);
                                          }
                                        else if( mDragging )
diff --git a/src/main/java/org/distorted/object/RubikCube.java b/src/main/java/org/distorted/object/RubikCube.java
index 56d30e3f..ca2ee74e 100644
--- a/src/main/java/org/distorted/object/RubikCube.java
+++ b/src/main/java/org/distorted/object/RubikCube.java
@@ -145,13 +145,6 @@ class RubikCube extends RubikObject
     return new VertexEffectSink( new Static1D(strength), center, region );
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  Static3D[] getRotationAxis()
-    {
-    return AXIS;
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // paint only the square with lower-left corner at (face*TEX_H,0) and side length TEX_H
 
@@ -207,6 +200,13 @@ class RubikCube extends RubikObject
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // PUBLIC API
 
+  public Static3D[] getRotationAxis()
+    {
+    return AXIS;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
   public int getBasicAngle()
     {
     return 4;
diff --git a/src/main/java/org/distorted/object/RubikCubeMovement.java b/src/main/java/org/distorted/object/RubikCubeMovement.java
index 01d2bed7..e6ed15fb 100644
--- a/src/main/java/org/distorted/object/RubikCubeMovement.java
+++ b/src/main/java/org/distorted/object/RubikCubeMovement.java
@@ -28,31 +28,10 @@ class RubikCubeMovement extends RubikObjectMovement
     super(RubikCube.AXIS, 2, 0.5f, 0.5f);
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void fillPossibleRotations(int axis, int[] output)
-    {
-    switch(axis)
-      {
-      case 0: output[0]=2; output[1]=1; break; // (Z,Y) when looking at LEFT or RIGHT
-      case 1: output[0]=0; output[1]=2; break; // (X,Z) when looking at BOTTOM or TOP
-      case 2: output[0]=0; output[1]=1; break; // (X,Y) when looking at FRONT or BACK
-      }
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   boolean isInsideFace(float[] p)
     {
     return ( p[0]<=0.5f && p[0]>=-0.5f && p[1]<=0.5f && p[1]>=-0.5f );
     }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  float returnAngle(float[] v, int[] possible)
-    {
-    float angle= (mRotationVect==possible[0] ? v[possible[1]] : -v[possible[0]]);
-    if( mLastTouchedAxis==2 ) angle = -angle;
-    return angle;
-    }
 }
diff --git a/src/main/java/org/distorted/object/RubikObject.java b/src/main/java/org/distorted/object/RubikObject.java
index 28fd19b9..082fd1fd 100644
--- a/src/main/java/org/distorted/object/RubikObject.java
+++ b/src/main/java/org/distorted/object/RubikObject.java
@@ -468,13 +468,6 @@ public abstract class RubikObject extends DistortedNode
      mRotationAngleStatic.set0(0);
      }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getNumAxis()
-    {
-    return ROTATION_AXIS.length;
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   abstract float getScreenRatio();
@@ -484,7 +477,7 @@ public abstract class RubikObject extends DistortedNode
   abstract int getNumFaces();
   abstract void createFaceTexture(Canvas canvas, Paint paint, int face);
   abstract MeshBase createCubitMesh(int cubit, int vertices);
-  abstract Static3D[] getRotationAxis();
+  public abstract Static3D[] getRotationAxis();
   public abstract int getBasicAngle();
   public abstract int returnRowFromOffset(float offset);
   }
diff --git a/src/main/java/org/distorted/object/RubikObjectMovement.java b/src/main/java/org/distorted/object/RubikObjectMovement.java
index 7be2cb09..6f1acdc8 100644
--- a/src/main/java/org/distorted/object/RubikObjectMovement.java
+++ b/src/main/java/org/distorted/object/RubikObjectMovement.java
@@ -27,22 +27,18 @@ import org.distorted.library.type.Static4D;
 
 public abstract class RubikObjectMovement
   {
-  int mRotationVect, mLastTouchedAxis;
-
-  private float[] mPoint, mCamera, mDiff, mTouch;
+  private int mLastTouchedAxis;
+  private float[] mPoint, mCamera, mTouch;
   private float[] mPoint2D, mMove2D;
   private float[][][] mCastAxis;
   private int mLastTouchedLR;
   private int mNumAxis, mNumFacesPerAxis;
-  private int[] mPossible;
   private float mDistanceCenterFace3D, mDistanceCenterFace2D;
   private Static3D[] mAxis;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   abstract boolean isInsideFace(float[] point);
-  abstract float returnAngle(float[] vect, int[] possible);
-  abstract void fillPossibleRotations(int axis, int[] output);
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -50,7 +46,6 @@ public abstract class RubikObjectMovement
     {
     mPoint = new float[3];
     mCamera= new float[3];
-    mDiff  = new float[3];
     mTouch = new float[3];
 
     mPoint2D = new float[2];
@@ -61,7 +56,6 @@ public abstract class RubikObjectMovement
     mNumFacesPerAxis = numFacesPerAxis;
     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
-    mPossible = new int[mNumAxis-1];
 
     // mCastAxis[1][2]{0,1} are the 2D coords of the 2nd axis cast onto the face defined by the
     // 1st pair (axis,lr)
@@ -107,7 +101,7 @@ public abstract class RubikObjectMovement
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // find the casted axis with which our move2D vector forms an angle closest to 90 deg.
 
-  private int computeRotationVect(int axis, int lr, float[] move2D)
+  private int computeRotationIndex(int axis, int lr, float[] move2D)
     {
     float cosAngle, minCosAngle = Float.MAX_VALUE;
     int minIndex=-1;
@@ -238,21 +232,6 @@ public abstract class RubikObjectMovement
     output[1] = v0*y0 + v1*y1 + v2*y2;
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private String getFaceColor(int axis)
-    {
-    switch(axis)
-      {
-      case 0: return "yellow (bottom) ";
-      case 1: return "green (back) ";
-      case 2: return "blue (right) ";
-      case 3: return "red (left) ";
-      }
-
-    return null;
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // PUBLIC API
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -276,11 +255,7 @@ public abstract class RubikObjectMovement
           castTouchPointOntoFace(mAxis[mLastTouchedAxis], mLastTouchedLR, mTouch);
           convertTo2Dcoords(mTouch, mAxis[mLastTouchedAxis], mLastTouchedLR, mPoint2D);
 
-          if( isInsideFace(mPoint2D) )
-            {
-            fillPossibleRotations(mLastTouchedAxis, mPossible);
-            return true;
-            }
+          if( isInsideFace(mPoint2D) ) return true;
           }
         }
       }
@@ -302,21 +277,10 @@ public abstract class RubikObjectMovement
     mMove2D[0] -= mPoint2D[0];
     mMove2D[1] -= mPoint2D[1];
 
-    mRotationVect= computeRotationVect(mLastTouchedAxis, mLastTouchedLR, mMove2D);
-    int index = mLastTouchedAxis*mNumFacesPerAxis+mLastTouchedLR;
-    float offset = computeOffset(mPoint2D, mCastAxis[index][mRotationVect]);
-
-    return new Static2D(mRotationVect,offset);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public float continueRotation(Static4D rotatedTouchPoint)
-    {
-    mDiff[0] = rotatedTouchPoint.get0()/RubikObject.OBJECT_SCREEN_RATIO - mPoint[0];
-    mDiff[1] = rotatedTouchPoint.get1()/RubikObject.OBJECT_SCREEN_RATIO - mPoint[1];
-    mDiff[2] = rotatedTouchPoint.get2()/RubikObject.OBJECT_SCREEN_RATIO - mPoint[2];
+    int rotIndex = computeRotationIndex(mLastTouchedAxis, mLastTouchedLR, mMove2D);
+    int index    = mLastTouchedAxis*mNumFacesPerAxis+mLastTouchedLR;
+    float offset = computeOffset(mPoint2D, mCastAxis[index][rotIndex]);
 
-    return (mLastTouchedLR-0.5f)*returnAngle(mDiff, mPossible);
+    return new Static2D(rotIndex,offset);
     }
   }
diff --git a/src/main/java/org/distorted/object/RubikPyraminx.java b/src/main/java/org/distorted/object/RubikPyraminx.java
index c5574602..607b9e6a 100644
--- a/src/main/java/org/distorted/object/RubikPyraminx.java
+++ b/src/main/java/org/distorted/object/RubikPyraminx.java
@@ -208,13 +208,6 @@ public class RubikPyraminx extends RubikObject
     return new VertexEffectSink( new Static1D(1.3f), center, region );
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  Static3D[] getRotationAxis()
-    {
-    return AXIS;
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   void createFaceTexture(Canvas canvas, Paint paint, int face)
@@ -299,6 +292,13 @@ public class RubikPyraminx extends RubikObject
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // PUBLIC API
 
+  public Static3D[] getRotationAxis()
+    {
+    return AXIS;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
   public int getBasicAngle()
     {
     return 3;
diff --git a/src/main/java/org/distorted/object/RubikPyraminxMovement.java b/src/main/java/org/distorted/object/RubikPyraminxMovement.java
index df8287be..1b1de91a 100644
--- a/src/main/java/org/distorted/object/RubikPyraminxMovement.java
+++ b/src/main/java/org/distorted/object/RubikPyraminxMovement.java
@@ -33,23 +33,6 @@ class RubikPyraminxMovement extends RubikObjectMovement
     super(RubikPyraminx.AXIS, 1, SQ2*SQ3/12, SQ3/6);
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// (         0,        1,       0 )  BOTTOM
-// (         0,  -1.0f/3, 2*SQ2/3 )  BACK
-// (-SQ2*SQ3/3,  -1.0f/3,  -SQ2/3 )  LEFT
-// ( SQ2*SQ3/3,  -1.0f/3,  -SQ2/3 )  RIGHT
-
-  void fillPossibleRotations(int axis, int[] output)
-    {
-    switch(axis)
-      {
-      case 0: output[0]=3; output[1]=1; output[2]=2; break; // (RIGHT,BACK,LEFT) when looking at BOTTOM
-      case 1: output[0]=2; output[1]=0; output[2]=3; break; // (LEFT,BOTTOM,RIGHT) when looking at BACK
-      case 2: output[0]=3; output[1]=0; output[2]=1; break; // (RIGHT,BOTTOM,BACK) when looking at LEFT
-      case 3: output[0]=1; output[1]=0; output[2]=2; break; // (BACK,BOTTOM,LEFT) when looking at RIGHT
-      }
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   boolean isInsideFace(float[] p)
@@ -60,18 +43,4 @@ class RubikPyraminxMovement extends RubikObjectMovement
 
     return a1 && a2 && a3;
     }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// TODO
-
-  float returnAngle(float[] v, int[] possible)
-    {
-    /*
-    float angle= (mRotationVect==possible[0] ? v[possible[1]] : -v[possible[0]]);
-    if( mLastTouchedAxis==2 ) angle = -angle;
-    return angle;
-     */
-
-    return 0;
-    }
 }
