Project

General

Profile

« Previous | Next » 

Revision 9aabc9eb

Added by Leszek Koltunski almost 3 years ago

Dynamics: introduce two speed modes - smooth and segment_constant.
Prepare the third mode - globally_constant.

View differences:

src/main/java/org/distorted/library/type/Dynamic.java
55 55

  
56 56
public abstract class Dynamic
57 57
  {
58
  /**
59
   * Keep the speed of interpolation always changing. Time to cover one segment (distance between
60
   * two consecutive points) always the same. Smoothly interpolate the speed between two segments.
61
   */
62
  public static final int SPEED_MODE_SMOOTH            = 0;
63
  /**
64
   * Make each segment have constant speed. Time to cover each segment is still the same, thus the
65
   * speed will jump when passing through a point and then keep constant.
66
   */
67
  public static final int SPEED_MODE_SEGMENT_CONSTANT  = 1;
68
  /**
69
   * Have the speed be always, globally the same across all segments. Time to cover one segment will
70
   * thus generally no longer be the same.
71
   */
72
  public static final int SPEED_MODE_GLOBALLY_CONSTANT = 2;
73

  
58 74
  /**
59 75
   * One revolution takes us from the first point to the last and back to first through the shortest path.
60 76
   */
......
92 108
  protected float mCount;       // number of loops/paths we will do; mCount = 1.5 means we go from the first vector to the last, back to first, and to the last again. 
93 109
  protected double mLastPos;
94 110
  protected int mAccessType;
111
  protected int mSpeedMode;
95 112

  
96 113
  protected class VectorNoise
97 114
    {
......
123 140
  protected float[][] baseV;
124 141

  
125 142
  ///////////////////////////////////////////////////////////////////////////////////////////////////
126
  // the coefficients of the X(t), Y(t) and Z(t) polynomials: X(t) = ax*T^3 + bx*T^2 + cx*t + dx  etc.
127
  // (tangent) is the vector tangent to the path.
143
  // the coefficients of the X(t), Y(t) and Z(t) polynomials: X(t) = a[0]*T^3 + b[0]*T^2 + c[0]*t + d[0]  etc.
144
  // (velocity) is the velocity vector.
128 145
  // (cached) is the original vector from vv (copied here so when interpolating we can see if it is
129 146
  // still valid and if not - rebuild the Cache
130 147

  
......
134 151
    float[] b;
135 152
    float[] c;
136 153
    float[] d;
137
    float[] tangent;
154
    float[] velocity;
138 155
    float[] cached;
156
    float[] path_ratio;
139 157

  
140 158
    VectorCache()
141 159
      {
......
143 161
      b = new float[mDimension];
144 162
      c = new float[mDimension];
145 163
      d = new float[mDimension];
146
      tangent = new float[mDimension];
147
      cached = new float[mDimension];
164

  
165
      velocity   = new float[mDimension];
166
      cached     = new float[mDimension];
167
      path_ratio = new float[NUM_RATIO];
148 168
      }
149 169
    }
150 170

  
151 171
  protected Vector<VectorCache> vc;
152
  protected VectorCache tmp1, tmp2;
172
  protected VectorCache tmpCache1, tmpCache2;
153 173
  protected float mConvexity;
154 174

  
175
  private static final int NUM_RATIO = 10; // we attempt to 'smooth out' the speed in each segment -
176
                                           // remember this many 'points' inside the Cache for each segment.
177

  
178
  protected static final float[] mTmpRatio = new float[NUM_RATIO];
179

  
155 180
  private float[] buf;
156 181
  private float[] old;
157 182
  private static final Random mRnd = new Random();
......
184 209
    mSegment   = -1;
185 210
    mLastPos   = -1;
186 211
    mAccessType= ACCESS_TYPE_RANDOM;
212
    mSpeedMode = SPEED_MODE_SMOOTH;
187 213
    mConvexity = 1.0f;
188 214
    mStartTime = -1;
189 215
    mCorrectedTime = 0;
......
208 234
    mPausedTime = System.currentTimeMillis();
209 235
    }
210 236

  
237
///////////////////////////////////////////////////////////////////////////////////////////////////
238

  
239
  private float valueAtPoint(float t, VectorCache cache)
240
    {
241
    float tmp,sum = 0.0f;
242

  
243
    for(int d=0; d<mDimension; d++)
244
      {
245
      tmp = (3*cache.a[d]*t + 2*cache.b[d])*t + cache.c[d];
246
      sum += tmp*tmp;
247
      }
248

  
249
    return (float)Math.sqrt(sum);
250
    }
251

  
252
///////////////////////////////////////////////////////////////////////////////////////////////////
253

  
254
  protected float smoothSpeed(float time, VectorCache cache)
255
    {
256
    float fndex = time*NUM_RATIO;
257
    int index = (int)fndex;
258
    float prev = index==0 ? 0.0f : cache.path_ratio[index-1];
259
    float next = cache.path_ratio[index];
260

  
261
    return prev + (next-prev)*(fndex-index);
262
    }
263

  
264
///////////////////////////////////////////////////////////////////////////////////////////////////
265
// First, compute the approx length of the segment from time=0 to time=(i+1)/NUM_TIME and store this
266
// in cache.path_ratio[i]. Then the last path_ratio is the length from 0 to 1, i.e. the total length
267
// of the segment.
268
// We do this by computing the integral from 0 to 1 of sqrt( (dx/dt)^2 + (dy/dt)^2 ) (i.e. the length
269
// of the segment) using the approx 'trapezoids' integration method.
270
//
271
// Then, for every i, divide path_ratio[i] by the total length to get the percentage of total path
272
// length covered at time i. At this time, path_ratio[3] = 0.45 means 'at time 3/NUM_RATIO, we cover
273
// 0.45 = 45% of the total length of the segment.
274
//
275
// Finally, invert this function (for quicker lookups in smoothSpeed) so that after this step,
276
// path_ratio[3] = 0.45 means 'at 45% of the time, we cover 3/NUM_RATIO distance'.
277

  
278
  protected void smoothOutSegment(VectorCache cache)
279
    {
280
    float vPrev, sum = 0.0f;
281
    float vNext = valueAtPoint(0.0f,cache);
282

  
283
    for(int i=0; i<NUM_RATIO; i++)
284
      {
285
      vPrev = vNext;
286
      vNext = valueAtPoint( (float)(i+1)/NUM_RATIO,cache);
287
      sum += (vPrev+vNext);
288
      cache.path_ratio[i] = sum;
289
      }
290

  
291
    float total = cache.path_ratio[NUM_RATIO-1];
292

  
293
    for(int i=0; i<NUM_RATIO; i++) cache.path_ratio[i] /= total;
294

  
295
    int writeIndex = 0;
296
    float prev=0.0f, next, ratio= 1.0f/NUM_RATIO;
297

  
298
    for(int readIndex=0; readIndex<NUM_RATIO; readIndex++)
299
      {
300
      next = cache.path_ratio[readIndex];
301

  
302
      while( prev<ratio && ratio<=next )
303
        {
304
        float a = (next-ratio)/(next-prev);
305
        mTmpRatio[writeIndex] = (readIndex+1-a)/NUM_RATIO;
306
        writeIndex++;
307
        ratio = (writeIndex+1.0f)/NUM_RATIO;
308
        }
309

  
310
      prev = next;
311
      }
312

  
313
    System.arraycopy(mTmpRatio, 0, cache.path_ratio, 0, NUM_RATIO);
314
    }
315

  
211 316
///////////////////////////////////////////////////////////////////////////////////////////////////
212 317

  
213 318
  protected float noise(float time,int vecNum)
......
340 445

  
341 446
    if( cosA<0.0f )
342 447
      {
343
/*
344
      /// DEBUGGING ////
345
      String s = index+" (";
346
      float t;
347

  
348
      for(int j=0; j<mDimension; j++)
349
        {
350
        t = ((int)(100*baseV[index][j]))/(100.0f);
351
        s+=(" "+t);
352
        }
353
      s += ") (";
354

  
355
      for(int j=0; j<mDimension; j++)
356
        {
357
        t = ((int)(100*old[j]))/(100.0f);
358
        s+=(" "+t);
359
        }
360
      s+= ")";
361

  
362
      android.util.Log.e("dynamic", "kat: " + s);
363
      /// END DEBUGGING ///
364
*/
365 448
      for(int j=0; j<mDimension; j++)
366 449
        baseV[index][j] = -baseV[index][j];
367 450
      }
......
658 741
    mLastPos = -1;
659 742
    }
660 743

  
744
///////////////////////////////////////////////////////////////////////////////////////////////////
745
/**
746
 * @return See {@link Dynamic#setSpeedMode(int)}
747
 */
748
  public float getSpeedMode()
749
    {
750
    return mSpeedMode;
751
    }
752

  
753
///////////////////////////////////////////////////////////////////////////////////////////////////
754
/**
755
 * Sets the way we compute the interpolation speed.
756
 *
757
 * @param mode {@link Dynamic#SPEED_MODE_SMOOTH} or {@link Dynamic#SPEED_MODE_SEGMENT_CONSTANT} or
758
 *             {@link Dynamic#SPEED_MODE_GLOBALLY_CONSTANT}
759
 */
760
  public void setSpeedMode(int mode)
761
    {
762
    if( mSpeedMode!=mode )
763
      {
764
      if( mSpeedMode==SPEED_MODE_SMOOTH )
765
        {
766
        for(int i=0; i<numPoints; i++)
767
          {
768
          tmpCache1 = vc.elementAt(i);
769
          smoothOutSegment(tmpCache1);
770
          }
771
        }
772

  
773
      mSpeedMode = mode;
774
      }
775
    }
776

  
661 777
///////////////////////////////////////////////////////////////////////////////////////////////////
662 778
/**
663 779
 * Return the Dimension, ie number of floats in a single Point this Dynamic interpolates through.

Also available in: Unified diff