commit 451c6c368e31a859facd9b534c33d0a576c02bd2
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Sun Jan 3 22:02:05 2021 +0100

    Progress with the Kilominx movement (appears to be working now)

diff --git a/src/main/java/org/distorted/objects/MovementMinx.java b/src/main/java/org/distorted/objects/MovementMinx.java
index f5e68949..50226153 100644
--- a/src/main/java/org/distorted/objects/MovementMinx.java
+++ b/src/main/java/org/distorted/objects/MovementMinx.java
@@ -72,33 +72,232 @@ class MovementMinx extends Movement
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// TODO; approximation
+// return angle (in radians) that the line connecting the center C of the pentagonal face and the
+// first vertex of the pentagon makes with a vertical line coming upwards from the center C.
+
+  private float returnAngle(int face)
+    {
+    switch(face)
+      {
+      case  0:
+      case  2:
+      case  6:
+      case  7: return 0.0f;
+      case  1:
+      case  3:
+      case  4:
+      case  5: return (float)(36*Math.PI/180);
+      case  9:
+      case 10: return (float)(54*Math.PI/180);
+      case  8:
+      case 11: return (float)(18*Math.PI/180);
+      }
+
+    return 0.0f;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// The pair (distance,angle) defines a point P in R^2 in polar coordinate system. Let V be the vector
+// from the center of the coordinate system to P.
+// Let P' be the point defined by polar (distance,angle+PI/2). Let Lh be the half-line starting at
+// P' and going in the direction of V.
+// Return true iff point 'point' lies on the left of Lh, i.e. when we rotate (using the center of
+// the coordinate system as the center of rotation) 'point' and Lh in such a way that Lh points
+// directly upwards, is 'point' on the left or the right of it?
+
+  private boolean isOnTheLeft(float[] point, float distance, float angle)
+    {
+    float sin = (float)Math.sin(angle);
+    float cos = (float)Math.cos(angle);
+
+    float vx = point[0] + sin*distance;
+    float vy = point[1] - cos*distance;
+
+    return vx*sin < vy*cos;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Return 1,2,3,4,5 - the vertex of the pentagon to which point 'point' is the closest, if the
+// 'point' is inside the pentagon - or 0 otherwise.
+// The 'first' vertex is the one we meet the first when we rotate clockwise starting from 12:00.
+// This vertex makes angle 'returnAngle()' with the line coming out upwards from the center of the
+// pentagon.
+// Distance from the center to a vertex of the pentagon = 1/(6*COS54)
+
+  private int returnPartOfThePentagon(float[] point, int face)
+    {
+    float angle = returnAngle(face);
+    float A = (float)(Math.PI/5);
+
+    for(int i=0; i<5; i++)
+      {
+      if( isOnTheLeft(point, DIST2D, (9-2*i)*A-angle) ) return 0;
+      }
+
+    if( isOnTheLeft(point, 0, 2.5f*A-angle) )
+      {
+      if( isOnTheLeft(point, 0, 3.5f*A-angle) )
+        {
+        return isOnTheLeft(point, 0, 5.5f*A-angle) ? 4 : 5;
+        }
+      else return 1;
+      }
+    else
+      {
+      if( isOnTheLeft(point, 0, 4.5f*A-angle) )
+        {
+        return 3;
+        }
+      else
+        {
+        return isOnTheLeft(point, 0, 6.5f*A-angle) ? 2 : 1;
+        }
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
   boolean isInsideFace(int face, float[] p)
     {
-    return ( p[0]*p[0] + p[1]*p[1] <= 1/(4*COS54*COS54) );
+    return returnPartOfThePentagon(p,face) > 0;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   void computeEnabledAxis(int face, float[] touchPoint, int[] enabled)
     {
-    enabled[0] = 5;
+    int part = returnPartOfThePentagon(touchPoint,face);
 
-    switch(face)
+    if( part>0 )
       {
-      case  0:
-      case  3:  enabled[1]=1; enabled[2]=2; enabled[3]=3; enabled[4]=4; enabled[5]=5; break;
-      case  1:
-      case  2:  enabled[1]=0; enabled[2]=2; enabled[3]=3; enabled[4]=4; enabled[5]=5; break;
-      case  4:
-      case  7:  enabled[1]=0; enabled[2]=1; enabled[3]=3; enabled[4]=4; enabled[5]=5; break;
-      case  5:
-      case  6:  enabled[1]=0; enabled[2]=1; enabled[3]=2; enabled[4]=4; enabled[5]=5; break;
-      case  8:
-      case 11:  enabled[1]=0; enabled[2]=1; enabled[3]=2; enabled[4]=3; enabled[5]=5; break;
-      case  9:
-      case 10:  enabled[1]=0; enabled[2]=1; enabled[3]=2; enabled[4]=3; enabled[5]=4; break;
+      enabled[0] = 2;
+
+      switch(face)
+        {
+        case  0:  switch(part)
+                    {
+                    case 1: enabled[1]=2; enabled[2]=3; break;
+                    case 2: enabled[1]=3; enabled[2]=5; break;
+                    case 3: enabled[1]=5; enabled[2]=1; break;
+                    case 4: enabled[1]=1; enabled[2]=4; break;
+                    case 5: enabled[1]=4; enabled[2]=2; break;
+                    }
+                  break;
+
+        case  1:  switch(part)
+                    {
+                    case 1: enabled[1]=0; enabled[2]=5; break;
+                    case 2: enabled[1]=5; enabled[2]=2; break;
+                    case 3: enabled[1]=2; enabled[2]=3; break;
+                    case 4: enabled[1]=3; enabled[2]=4; break;
+                    case 5: enabled[1]=4; enabled[2]=0; break;
+                    }
+                  break;
+
+        case  2:  switch(part)
+                    {
+                    case 1: enabled[1]=3; enabled[2]=2; break;
+                    case 2: enabled[1]=2; enabled[2]=5; break;
+                    case 3: enabled[1]=5; enabled[2]=0; break;
+                    case 4: enabled[1]=0; enabled[2]=4; break;
+                    case 5: enabled[1]=4; enabled[2]=3; break;
+                    }
+                  break;
+
+        case  3:  switch(part)
+                    {
+                    case 1: enabled[1]=1; enabled[2]=5; break;
+                    case 2: enabled[1]=5; enabled[2]=3; break;
+                    case 3: enabled[1]=3; enabled[2]=2; break;
+                    case 4: enabled[1]=2; enabled[2]=4; break;
+                    case 5: enabled[1]=4; enabled[2]=1; break;
+                    }
+                  break;
+
+        case  4:  switch(part)
+                    {
+                    case 1: enabled[1]=3; enabled[2]=0; break;
+                    case 2: enabled[1]=0; enabled[2]=4; break;
+                    case 3: enabled[1]=4; enabled[2]=5; break;
+                    case 4: enabled[1]=5; enabled[2]=1; break;
+                    case 5: enabled[1]=1; enabled[2]=3; break;
+                    }
+                  break;
+
+        case  5:  switch(part)
+                    {
+                    case 1: enabled[1]=2; enabled[2]=1; break;
+                    case 2: enabled[1]=1; enabled[2]=4; break;
+                    case 3: enabled[1]=4; enabled[2]=5; break;
+                    case 4: enabled[1]=5; enabled[2]=0; break;
+                    case 5: enabled[1]=0; enabled[2]=2; break;
+                    }
+                  break;
+
+        case  6:  switch(part)
+                    {
+                    case 1: enabled[1]=5; enabled[2]=4; break;
+                    case 2: enabled[1]=4; enabled[2]=1; break;
+                    case 3: enabled[1]=1; enabled[2]=2; break;
+                    case 4: enabled[1]=2; enabled[2]=0; break;
+                    case 5: enabled[1]=0; enabled[2]=5; break;
+                    }
+                  break;
+
+        case  7:  switch(part)
+                    {
+                    case 1: enabled[1]=5; enabled[2]=4; break;
+                    case 2: enabled[1]=4; enabled[2]=0; break;
+                    case 3: enabled[1]=0; enabled[2]=3; break;
+                    case 4: enabled[1]=3; enabled[2]=1; break;
+                    case 5: enabled[1]=1; enabled[2]=5; break;
+                    }
+                  break;
+
+        case  8: switch(part)
+                    {
+                    case 1: enabled[1]=2; enabled[2]=0; break;
+                    case 2: enabled[1]=0; enabled[2]=1; break;
+                    case 3: enabled[1]=1; enabled[2]=3; break;
+                    case 4: enabled[1]=3; enabled[2]=5; break;
+                    case 5: enabled[1]=5; enabled[2]=2; break;
+                    }
+                  break;
+
+        case  9:  switch(part)
+                    {
+                    case 1: enabled[1]=3; enabled[2]=4; break;
+                    case 2: enabled[1]=4; enabled[2]=2; break;
+                    case 3: enabled[1]=2; enabled[2]=1; break;
+                    case 4: enabled[1]=1; enabled[2]=0; break;
+                    case 5: enabled[1]=0; enabled[2]=3; break;
+                    }
+                  break;
+
+        case 10:  switch(part)
+                    {
+                    case 1: enabled[1]=2; enabled[2]=4; break;
+                    case 2: enabled[1]=4; enabled[2]=3; break;
+                    case 3: enabled[1]=3; enabled[2]=0; break;
+                    case 4: enabled[1]=0; enabled[2]=1; break;
+                    case 5: enabled[1]=1; enabled[2]=2; break;
+                    }
+                  break;
+
+        case 11:  switch(part)
+                    {
+                    case 1: enabled[1]=3; enabled[2]=1; break;
+                    case 2: enabled[1]=1; enabled[2]=0; break;
+                    case 3: enabled[1]=0; enabled[2]=2; break;
+                    case 4: enabled[1]=2; enabled[2]=5; break;
+                    case 5: enabled[1]=5; enabled[2]=3; break;
+                    }
+                  break;
+        }
+      }
+    else
+      {
+      enabled[0] = 0;
       }
     }
 }
