commit 37a257880b18de47de24e62424aeb00c174fc31b
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Wed Mar 11 15:43:04 2020 +0000

    Progress with object Movement.

diff --git a/src/main/java/org/distorted/object/RubikCube.java b/src/main/java/org/distorted/object/RubikCube.java
index 2d01e4c8..1fd3f536 100644
--- a/src/main/java/org/distorted/object/RubikCube.java
+++ b/src/main/java/org/distorted/object/RubikCube.java
@@ -47,7 +47,7 @@ class RubikCube extends RubikObject
            new Static3D(0,0,1)
          };
 
-  static final int[] FACE_COLORS = new int[]
+  private static final int[] FACE_COLORS = new int[]
          {
            0xffffff00, 0xffffffff,   // AXIS[0]right (right-YELLOW) AXIS[0]left (left  -WHITE)
            0xff0000ff, 0xff00ff00,   // AXIS[1]right (top  -BLUE  ) AXIS[1]left (bottom-GREEN)
diff --git a/src/main/java/org/distorted/object/RubikCubeMovement.java b/src/main/java/org/distorted/object/RubikCubeMovement.java
index 6a6d77ee..73ee1166 100644
--- a/src/main/java/org/distorted/object/RubikCubeMovement.java
+++ b/src/main/java/org/distorted/object/RubikCubeMovement.java
@@ -25,7 +25,7 @@ class RubikCubeMovement extends RubikObjectMovement
 {
   RubikCubeMovement()
     {
-    super(3,2);
+    super(RubikCube.AXIS,2,0.5f);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -35,28 +35,6 @@ class RubikCubeMovement extends RubikObjectMovement
     return (y>x) ? (y>=-x) : (y< -x);
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  boolean faceIsVisible(int axis, int lr)
-    {
-    return (2*lr-1)*mCamera[axis] > 0.5f;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// given precomputed mCamera and mPoint, respectively camera and touch point positions in ScreenSpace,
-// cast this touch point onto the surface defined by the 'face' and write the cast coords to 'output'.
-// Center of the 'face' = (0,0), third coord always +- cubeHalfSize.
-
-  void castTouchPointOntoFace(int axis, int lr, float[] output)
-    {
-    float diff = mPoint[axis]-mCamera[axis];
-    float ratio= diff!=0.0f ? ((lr-0.5f)-mCamera[axis])/diff : 0.0f;
-
-    output[0] = (mPoint[0]-mCamera[0])*ratio + mCamera[0];
-    output[1] = (mPoint[1]-mCamera[1])*ratio + mCamera[1];
-    output[2] = (mPoint[2]-mCamera[2])*ratio + mCamera[2];
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   void fillPossibleRotations(int axis, int[] output)
diff --git a/src/main/java/org/distorted/object/RubikObjectMovement.java b/src/main/java/org/distorted/object/RubikObjectMovement.java
index 2e558a69..07fd0a7d 100644
--- a/src/main/java/org/distorted/object/RubikObjectMovement.java
+++ b/src/main/java/org/distorted/object/RubikObjectMovement.java
@@ -20,43 +20,87 @@
 package org.distorted.object;
 
 import org.distorted.library.type.Static2D;
+import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 public abstract class RubikObjectMovement
   {
-  float[] mPoint, mCamera, mTouch;
+  float[] mTouch;
   int mRotationVect, mLastTouchedAxis;
 
-  private float[] mDiff;
+  private float[] mPoint, mCamera, mDiff;
   private int mLastTouchedLR;
   private int mNumAxis, mNumFacesPerAxis;
   private int[] mPossible;
+  private float mDistanceCenterFace;
+  private Static3D[] mAxis;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  abstract boolean faceIsVisible(int axis, int lr);
-  abstract void castTouchPointOntoFace(int axis, int lr, float[] output);
   abstract boolean isInsideFace(float[] point);
-  abstract void fillPossibleRotations(int axis, int[] output);
   abstract float fillUpRotationVectAndOffset(float[] vect, int[] possible);
   abstract float returnAngle(float[] vect, int[] possible);
+  abstract void fillPossibleRotations(int axis, int[] output);
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  RubikObjectMovement(int numAxis, int numFacesPerAxis)
+  RubikObjectMovement(Static3D[] axis, int numFacesPerAxis, float distance)
     {
     mPoint = new float[3];
     mCamera= new float[3];
     mDiff  = new float[3];
     mTouch = new float[3];
 
-    mNumAxis = numAxis;
+    mAxis = axis;
+    mNumAxis = mAxis.length;
     mNumFacesPerAxis = numFacesPerAxis;
+    mDistanceCenterFace = distance;
     mPossible = new int[mNumAxis-1];
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private boolean faceIsVisible(Static3D axis, int lr)
+    {
+    float castCameraOnAxis = mCamera[0]*axis.get0() + mCamera[1]*axis.get1() + mCamera[2]*axis.get2();
+    return (2*lr-1)*castCameraOnAxis > mDistanceCenterFace;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// given precomputed mCamera and mPoint, respectively camera and touch point positions in ScreenSpace,
+// compute point 'output[]' which:
+// 1) lies on a face of the Object, i.e. surface defined by (axis, distance from (0,0,0)) [and this
+//    distance is +-mDistanceCenterFace, depending if it is the face on the left or the right end of
+//    the axis] (lr=0 or 1, so (2lr-1)*mDistanceCenterFace)
+// 2) is co-linear with mCamera and mPoint
+//
+// output = camera + alpha*(point-camera), where alpha = [dist-axis*camera] / [axis*(point-camera)]
+
+  private void castTouchPointOntoFace(Static3D axis, int lr, float[] output)
+    {
+    float d0 = mPoint[0]-mCamera[0];
+    float d1 = mPoint[1]-mCamera[1];
+    float d2 = mPoint[2]-mCamera[2];
+    float a0 = axis.get0();
+    float a1 = axis.get1();
+    float a2 = axis.get2();
+
+    float denom = a0*d0 + a1*d1 + a2*d2;
+
+    if( denom != 0.0f )
+      {
+      float axisCam = a0*mCamera[0] + a1*mCamera[1] + a2*mCamera[2];
+      float distance = (2*lr-1)*mDistanceCenterFace;
+      float alpha = (distance-axisCam)/denom;
+
+      output[0] = mCamera[0] + d0*alpha;
+      output[1] = mCamera[1] + d1*alpha;
+      output[2] = mCamera[2] + d2*alpha;
+      }
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // PUBLIC API
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -75,9 +119,9 @@ public abstract class RubikObjectMovement
       {
       for( mLastTouchedLR=0; mLastTouchedLR<mNumFacesPerAxis; mLastTouchedLR++)
         {
-        if( faceIsVisible(mLastTouchedAxis, mLastTouchedLR) )
+        if( faceIsVisible(mAxis[mLastTouchedAxis], mLastTouchedLR) )
           {
-          castTouchPointOntoFace(mLastTouchedAxis, mLastTouchedLR, mTouch);
+          castTouchPointOntoFace(mAxis[mLastTouchedAxis], mLastTouchedLR, mTouch);
 
           if( isInsideFace(mTouch) )
             {
@@ -99,7 +143,7 @@ public abstract class RubikObjectMovement
     mPoint[1] = rotatedTouchPoint.get1()/RubikObject.OBJECT_SCREEN_RATIO;
     mPoint[2] = rotatedTouchPoint.get2()/RubikObject.OBJECT_SCREEN_RATIO;
 
-    castTouchPointOntoFace(mLastTouchedAxis, mLastTouchedLR, mDiff);
+    castTouchPointOntoFace(mAxis[mLastTouchedAxis], mLastTouchedLR, mDiff);
 
     mDiff[0] -= mTouch[0];
     mDiff[1] -= mTouch[1];
diff --git a/src/main/java/org/distorted/object/RubikPyraminx.java b/src/main/java/org/distorted/object/RubikPyraminx.java
index ed2087b5..ba05af41 100644
--- a/src/main/java/org/distorted/object/RubikPyraminx.java
+++ b/src/main/java/org/distorted/object/RubikPyraminx.java
@@ -44,7 +44,7 @@ public class RubikPyraminx extends RubikObject
   private static final float SQ2 = (float)Math.sqrt(2);
   private static final float SQ3 = (float)Math.sqrt(3);
 
-  private static final Static3D[] AXIS = new Static3D[]
+  static final Static3D[] AXIS = new Static3D[]
          {
            new Static3D(         0,        1,       0 ),
            new Static3D(         0,  -1.0f/3, 2*SQ2/3 ),
diff --git a/src/main/java/org/distorted/object/RubikPyraminxMovement.java b/src/main/java/org/distorted/object/RubikPyraminxMovement.java
index 8e182e5a..b16eaa52 100644
--- a/src/main/java/org/distorted/object/RubikPyraminxMovement.java
+++ b/src/main/java/org/distorted/object/RubikPyraminxMovement.java
@@ -30,29 +30,7 @@ class RubikPyraminxMovement extends RubikObjectMovement
 
   RubikPyraminxMovement()
     {
-    super(4,1);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  boolean faceIsVisible(int axis, int lr)
-    {
-    return mCamera[axis] < -SQ2*SQ3/12;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// TODO
-
-  void castTouchPointOntoFace(int axis, int lr, float[] output)
-    {
-    /*
-    float diff = mPoint[axis]-mCamera[axis];
-    float ratio= diff!=0.0f ? ((lr-0.5f)-mCamera[axis])/diff : 0.0f;
-
-    output[0] = (mPoint[0]-mCamera[0])*ratio + mCamera[0];
-    output[1] = (mPoint[1]-mCamera[1])*ratio + mCamera[1];
-    output[2] = (mPoint[2]-mCamera[2])*ratio + mCamera[2];
-    */
+    super(RubikPyraminx.AXIS,1,SQ2*SQ3/12);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
