commit c6dec65b807126aae4062991080529c04d344548
Author: Leszek Koltunski <leszek@distorted.org>
Date:   Tue Nov 1 17:20:44 2016 +0000

    1. Attempt to deal with unstable Orthonormal Base in Dynamic class (so far unsuccessful)
    2. Improvements to the 'Dynamic' (and by necessity, 'MovingEffects') applications (to be able to debug the previous)

diff --git a/src/main/java/org/distorted/library/type/Dynamic.java b/src/main/java/org/distorted/library/type/Dynamic.java
index 55eb87b..85c06b8 100644
--- a/src/main/java/org/distorted/library/type/Dynamic.java
+++ b/src/main/java/org/distorted/library/type/Dynamic.java
@@ -103,7 +103,8 @@ public abstract class Dynamic
   protected float[] mFactor;
   protected float[] mNoise;
   protected float[][] baseV;
-  private float[] buffer;
+  private float[] buf;
+  private float[] old;
 
   ///////////////////////////////////////////////////////////////////////////////////////////////////
   // the coefficients of the X(t), Y(t) and Z(t) polynomials: X(t) = ax*T^3 + bx*T^2 + cx*t + dx  etc.
@@ -155,7 +156,8 @@ public abstract class Dynamic
     mDimension = dimension;
 
     baseV = new float[mDimension][mDimension];
-    buffer= new float[mDimension];
+    buf= new float[mDimension];
+    old= new float[mDimension];
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -168,11 +170,11 @@ public abstract class Dynamic
       }
     else
       {
-      float x = (float)currentDuration/mDuration;
+      double x = (double)currentDuration/mDuration;
            
       if( x<=mCount || mCount<=0.0f )
         {
-        interpolate(buffer,offset,x-(int)x);
+        interpolate(buffer,offset, (float)(x-(int)x) );
         }
       }
     }
@@ -187,11 +189,11 @@ public abstract class Dynamic
       return false;
       }
      
-    float x = (float)currentDuration/mDuration;
+    double x = (double)currentDuration/mDuration;
            
     if( x<=mCount || mCount<=0.0f )
       {
-      interpolate(buffer,offset,x-(int)x);
+      interpolate(buffer,offset, (float)(x-(int)x) );
         
       if( currentDuration+step > mDuration*mCount && mCount>0.0f )
         {
@@ -296,6 +298,44 @@ public abstract class Dynamic
       }
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private void checkAngle(int index)
+    {
+    float cosA = 0.0f;
+
+    for(int k=0;k<mDimension; k++)
+      cosA += baseV[index][k]*old[k];
+
+    if( cosA<0.0f )
+      {
+/*
+      /// DEBUGGING ////
+      String s = index+" (";
+      float t;
+
+      for(int j=0; j<mDimension; j++)
+        {
+        t = ((int)(100*baseV[index][j]))/(100.0f);
+        s+=(" "+t);
+        }
+      s += ") (";
+
+      for(int j=0; j<mDimension; j++)
+        {
+        t = ((int)(100*old[j]))/(100.0f);
+        s+=(" "+t);
+        }
+      s+= ")";
+
+      android.util.Log.e("dynamic", "kat: " + s);
+      /// END DEBUGGING ///
+*/
+      for(int j=0; j<mDimension; j++)
+        baseV[index][j] = -baseV[index][j];
+      }
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // helper function in case we are interpolating through exactly 2 points
 
@@ -414,75 +454,70 @@ public abstract class Dynamic
       }
     else
       {
-      for(int i=0; i<mDimension-1; i++)
-        for(int j=0; j<mDimension; j++)
-          {
-          if( (i<last_non_zero && j==i) || (i>=last_non_zero && j==i+1) )
-            baseV[i+1][j]= baseV[0][last_non_zero];
-          else
-            baseV[i+1][j]= 0.0f;
-          }
-
-      // That's it if velocity vector is already one of the standard orthonormal
-      // vectors. Otherwise (i.e. non_zeros>1) velocity is linearly independent
-      // to what's in baseV right now and we can use (modified!) Gram-Schmidt.
+      // We can use (modified!) Gram-Schmidt.
       //
       // b[0] = b[0]
       // b[1] = b[1] - (<b[1],b[0]>/<b[0],b[0]>)*b[0]
       // b[2] = b[2] - (<b[2],b[0]>/<b[0],b[0]>)*b[0] - (<b[2],b[1]>/<b[1],b[1]>)*b[1]
       // b[3] = b[3] - (<b[3],b[0]>/<b[0],b[0]>)*b[0] - (<b[3],b[1]>/<b[1],b[1]>)*b[1] - (<b[3],b[2]>/<b[2],b[2]>)*b[2]
-      //
+      // (...)
       // then b[i] = b[i] / |b[i]|
 
-      if( non_zeros>1 )
+      float tmp;
+
+      for(int i=1; i<mDimension; i++)          /// one iteration computes baseV[i][*], the i-th orthonormal vector.
         {
-        float tmp;
+        buf[i-1]=0.0f;
 
-        for(int i=1; i<mDimension; i++)
+        for(int k=0; k<mDimension; k++)
           {
-          buffer[i-1]=0.0f;
-
-          for(int k=0; k<mDimension; k++)
-            {
-            value = baseV[i-1][k];
-            buffer[i-1] += value*value;
-            }
-
-          for(int j=0; j<i; j++)
-            {
-            tmp = 0.0f;
+          old[k] = baseV[i][k];
 
-            for(int k=0;k<mDimension; k++)
-              {
-              tmp += baseV[i][k]*baseV[j][k];
-              }
-
-            tmp /= buffer[j];
+          if( (i<=last_non_zero && k==i-1) || (i>=(last_non_zero+1) && k==i) )
+            baseV[i][k]= baseV[0][last_non_zero];
+          else
+            baseV[i][k]= 0.0f;
 
-            for(int k=0;k<mDimension; k++)
-              {
-              baseV[i][k] -= tmp*baseV[j][k];
-              }
-            }
+          value = baseV[i-1][k];
+          buf[i-1] += value*value;
           }
 
-        buffer[mDimension-1]=0.0f;
-        for(int k=0; k<mDimension; k++)
+        for(int j=0; j<i; j++)
           {
-          value = baseV[mDimension-1][k];
-          buffer[mDimension-1] += value*value;
-          }
+          tmp = 0.0f;
 
-        for(int i=1; i<mDimension; i++)
-          {
-          tmp = (float)Math.sqrt(buffer[0]/buffer[i]);
+          for(int k=0;k<mDimension; k++)
+            {
+            tmp += baseV[i][k]*baseV[j][k];
+            }
+
+          tmp /= buf[j];
 
           for(int k=0;k<mDimension; k++)
             {
-            baseV[i][k] *= tmp;
+            baseV[i][k] -= tmp*baseV[j][k];
             }
           }
-        }
+
+        if( i>=2 ) checkAngle(i);
+        }                                       /// end compute baseV[i][*]
+
+      buf[mDimension-1]=0.0f;                   /// Normalize
+      for(int k=0; k<mDimension; k++)           //
+        {                                       //
+        value = baseV[mDimension-1][k];         //
+        buf[mDimension-1] += value*value;       //
+        }                                       //
+                                                //
+      for(int i=1; i<mDimension; i++)           //
+        {                                       //
+        tmp = (float)Math.sqrt(buf[0]/buf[i]);  //
+                                                //
+        for(int k=0;k<mDimension; k++)          //
+          {                                     //
+          baseV[i][k] *= tmp;                   //
+          }                                     //
+        }                                       /// End Normalize
       }
 
     //printBase("end");
diff --git a/src/main/java/org/distorted/library/type/Dynamic1D.java b/src/main/java/org/distorted/library/type/Dynamic1D.java
index 9759759..d95e7c1 100644
--- a/src/main/java/org/distorted/library/type/Dynamic1D.java
+++ b/src/main/java/org/distorted/library/type/Dynamic1D.java
@@ -386,7 +386,7 @@ public class Dynamic1D extends Dynamic implements Data1D
  * @param time Time of interpolation. Time=0.0 would return the first Point, Time=0.5 - the last,
  *             time=1.0 - the first again, and time 0.1 would be 1/5 of the way between the first and the last Points.
  */
-  public synchronized void interpolate(float[] buffer, int offset, float time)
+  synchronized void interpolate(float[] buffer, int offset, float time)
     {
     switch(numPoints)
       {
diff --git a/src/main/java/org/distorted/library/type/Dynamic2D.java b/src/main/java/org/distorted/library/type/Dynamic2D.java
index 7cf99d8..89c2986 100644
--- a/src/main/java/org/distorted/library/type/Dynamic2D.java
+++ b/src/main/java/org/distorted/library/type/Dynamic2D.java
@@ -407,7 +407,7 @@ public class Dynamic2D extends Dynamic implements Data2D
  * @param time Time of interpolation. Time=0.0 would return the first Point, Time=0.5 - the last,
  *             time=1.0 - the first again, and time 0.1 would be 1/5 of the way between the first and the last Points.
  */  
-  public synchronized void interpolate(float[] buffer, int offset, float time)
+  synchronized void interpolate(float[] buffer, int offset, float time)
     {
     switch(numPoints)
       {
diff --git a/src/main/java/org/distorted/library/type/Dynamic3D.java b/src/main/java/org/distorted/library/type/Dynamic3D.java
index bcec7a6..9429684 100644
--- a/src/main/java/org/distorted/library/type/Dynamic3D.java
+++ b/src/main/java/org/distorted/library/type/Dynamic3D.java
@@ -430,7 +430,7 @@ public class Dynamic3D extends Dynamic implements Data3D
  * @param time Time of interpolation. Time=0.0 would return the first Point, Time=0.5 - the last,
  *             time=1.0 - the first again, and time 0.1 would be 1/5 of the way between the first and the last Points.
  */    
-  public synchronized void interpolate(float[] buffer, int offset, float time)
+  synchronized void interpolate(float[] buffer, int offset, float time)
     {  
     switch(numPoints)
       {
diff --git a/src/main/java/org/distorted/library/type/Dynamic4D.java b/src/main/java/org/distorted/library/type/Dynamic4D.java
index e7ed51e..ba762ab 100644
--- a/src/main/java/org/distorted/library/type/Dynamic4D.java
+++ b/src/main/java/org/distorted/library/type/Dynamic4D.java
@@ -449,7 +449,7 @@ public class Dynamic4D extends Dynamic implements Data4D
  * @param time Time of interpolation. Time=0.0 would return the first Point, Time=0.5 - the last,
  *             time=1.0 - the first again, and time 0.1 would be 1/5 of the way between the first and the last Points.
  */    
-  public synchronized void interpolate(float[] buffer, int offset, float time)
+  synchronized void interpolate(float[] buffer, int offset, float time)
     {  
     switch(numPoints)
       {
diff --git a/src/main/java/org/distorted/library/type/Dynamic5D.java b/src/main/java/org/distorted/library/type/Dynamic5D.java
index 01846be..b1ef795 100644
--- a/src/main/java/org/distorted/library/type/Dynamic5D.java
+++ b/src/main/java/org/distorted/library/type/Dynamic5D.java
@@ -468,7 +468,7 @@ public class Dynamic5D extends Dynamic implements Data5D
  * @param time Time of interpolation. Time=0.0 would return the first Point, Time=0.5 - the last,
  *             time=1.0 - the first again, and time 0.1 would be 1/5 of the way between the first and the last Points.
  */    
-  public synchronized void interpolate(float[] buffer, int offset, float time)
+  synchronized void interpolate(float[] buffer, int offset, float time)
     {  
     switch(numPoints)
       {
