Project

General

Profile

Download (34.6 KB) Statistics
| Branch: | Revision:

examples / src / main / java / org / distorted / examples / dynamic / DynamicSurfaceView.java @ bcbd5b45

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2016 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// Distorted is free software: you can redistribute it and/or modify                             //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Distorted is distributed in the hope that it will be useful,                                  //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

    
20
package org.distorted.examples.dynamic;
21

    
22
import android.app.ActivityManager;
23
import android.content.Context;
24
import android.content.pm.ConfigurationInfo;
25
import android.graphics.Rect;
26
import android.opengl.GLSurfaceView;
27
import android.view.MotionEvent;
28
import android.util.AttributeSet;
29
import android.graphics.Canvas;
30
import android.graphics.Paint.Style;
31
import android.graphics.Paint;
32

    
33
import org.distorted.library.type.Dynamic;
34
import org.distorted.library.type.Dynamic1D;
35
import org.distorted.library.type.Dynamic2D;
36
import org.distorted.library.type.Dynamic3D;
37
import org.distorted.library.type.Dynamic4D;
38
import org.distorted.library.type.DynamicQuat;
39
import org.distorted.library.type.Static1D;
40
import org.distorted.library.type.Static2D;
41
import org.distorted.library.type.Static3D;
42
import org.distorted.library.type.Static4D;
43

    
44
import java.lang.ref.WeakReference;
45

    
46
///////////////////////////////////////////////////////////////////////////////////////////////////
47

    
48
public class DynamicSurfaceView extends GLSurfaceView
49
    {
50
    public static final int DIM_1D   = 0; 
51
    public static final int DIM_2D   = 1; 
52
    public static final int DIM_3DXY = 2; 
53
    public static final int DIM_3DXZ = 3; 
54
    public static final int DIM_4DXY = 4;
55
    public static final int DIM_4DZW = 5;
56
    public static final int DIM_Q_XY = 6;
57
    public static final int DIM_Q_ZW = 7;
58

    
59
    private static final int MAX_DIM = 4;
60
    private static final float QUAT_QUOT = 0.9f;
61

    
62
    static final int NUM_POINTS = 250;
63
    private static final Object lock = new Object();
64

    
65
    private WeakReference<DynamicActivity> mAct;
66

    
67
    private static int halfScreenHeight=0;
68
    private static int halfScreenWidth =0;
69

    
70
    private Dynamic1D   di1D;
71
    private Dynamic2D   di2D;
72
    private Dynamic3D   di3D;
73
    private Dynamic4D   di4D;
74
    private DynamicQuat diQu;
75
    
76
    private Paint mPaint;
77
    private int mMoving;
78
    private int mDuration;
79
    private int mPosition;
80
    private long mDiffTime, mLastTime, mStartTime;
81
    private float[] mNoise = new float[MAX_DIM];
82
    private float mCount;
83

    
84
    private int mSize1, mSize2, mSizeT, mAvg;
85
    private float mFontHeight;
86

    
87
    private int currentDim= DIM_2D;
88
    
89
    private Static1D p1D;
90
    private Static2D p2D;
91
    private Static3D p3D;
92
    private Static4D p4D;
93
    private Static4D pQD;
94

    
95
    private Static1D p1N;
96
    private Static2D p2N;
97
    private Static3D p3N;
98
    private Static4D p4N;
99
    private Static4D pQN;
100

    
101
    private float[] mPoints = new float[MAX_DIM*NUM_POINTS];
102
    private boolean mRunning;
103

    
104
///////////////////////////////////////////////////////////////////////////////////////////////////
105
    
106
    public DynamicSurfaceView(Context context, AttributeSet attrs)
107
      {
108
      super(context, attrs);
109

    
110
      DynamicActivity act = (DynamicActivity)context;
111
      mAct = new WeakReference<>(act);
112

    
113
      mPaint = new Paint();
114
      mPaint.setStyle(Style.FILL);
115
      mPaint.setAntiAlias(true);
116

    
117
      mDuration = 10000;
118
      mCount    = 0.0f;
119
      mPosition = 0;
120
      mDiffTime = -1;
121
      mLastTime = -1;
122
      mStartTime= -1;
123
      mMoving   = -1;
124
      mRunning  = false;
125

    
126
      for(int i=0; i<MAX_DIM; i++) mNoise[i] = 0.0f;
127

    
128
      clearPoints();
129

    
130
      di1D = new Dynamic1D(mDuration,mCount);
131
      p1N  = new Static1D(mNoise[0]);
132
      di2D = new Dynamic2D(mDuration,mCount);
133
      p2N  = new Static2D(mNoise[0],mNoise[1]);
134
      di3D = new Dynamic3D(mDuration,mCount);
135
      p3N  = new Static3D(mNoise[0],mNoise[1],mNoise[2]);
136
      di4D = new Dynamic4D(mDuration,mCount);
137
      p4N  = new Static4D(mNoise[0],mNoise[1],mNoise[2],mNoise[3]);
138
      diQu = new DynamicQuat(mDuration,mCount);
139
      pQN  = new Static4D(mNoise[0],mNoise[1],mNoise[2],mNoise[3]);
140

    
141
      di1D.setAccessType(Dynamic.ACCESS_TYPE_SEQUENTIAL);
142
      di2D.setAccessType(Dynamic.ACCESS_TYPE_SEQUENTIAL);
143
      di3D.setAccessType(Dynamic.ACCESS_TYPE_SEQUENTIAL);
144
      di4D.setAccessType(Dynamic.ACCESS_TYPE_SEQUENTIAL);
145
      diQu.setAccessType(Dynamic.ACCESS_TYPE_SEQUENTIAL);
146

    
147
      if(!isInEditMode())
148
        {
149
        setFocusable(true);
150
        setFocusableInTouchMode(true);
151
        DynamicRenderer mRenderer = new DynamicRenderer(this);
152
        final ActivityManager activityManager     = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
153
        final ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo();
154
        setEGLContextClientVersion( (configurationInfo.reqGlEsVersion>>16) >= 3 ? 3:2 );
155
        setRenderer(mRenderer);
156
        }
157
      }
158

    
159
///////////////////////////////////////////////////////////////////////////////////////////////////
160

    
161
    public void onSurfaceChanged(int width,int height)
162
      {
163
      mAvg = (width+height)/2;
164

    
165
      mSize1 = mAvg/150;
166
      mSize2 = mAvg/50;
167
      mSizeT = mAvg/30;
168

    
169
      mPaint.setTextSize(mSizeT);
170
      mPaint.setTextAlign(Paint.Align.CENTER);
171

    
172
      final Rect textBounds = new Rect();
173
      String text = "1";
174
      mPaint.getTextBounds(text, 0, text.length(), textBounds);
175
      mFontHeight = textBounds.exactCenterY();
176

    
177
      clearPoints();
178
      }
179

    
180
///////////////////////////////////////////////////////////////////////////////////////////////////
181

    
182
    public static void setHalfWidth(int hw)
183
      {
184
      halfScreenWidth = hw;
185
      }
186

    
187
///////////////////////////////////////////////////////////////////////////////////////////////////
188

    
189
    public static void setHalfHeight(int hh)
190
      {
191
      halfScreenHeight = hh;
192
      }
193

    
194
///////////////////////////////////////////////////////////////////////////////////////////////////
195

    
196
    public void setMode(int mode)
197
      {
198
      di1D.setMode(mode);  
199
      di2D.setMode(mode);
200
      di3D.setMode(mode);
201
      di4D.setMode(mode);
202
      diQu.setMode(mode);
203
      }
204

    
205
///////////////////////////////////////////////////////////////////////////////////////////////////
206

    
207
    public void setDuration(int duration)
208
      {
209
      mDuration = duration;
210
      
211
      di1D.setDuration(duration);
212
      di2D.setDuration(duration);
213
      di3D.setDuration(duration);
214
      di4D.setDuration(duration);
215
      diQu.setDuration(duration);
216
      }
217

    
218
///////////////////////////////////////////////////////////////////////////////////////////////////
219

    
220
    public void setCount(float count)
221
      {
222
      mCount = count;
223

    
224
      di1D.setCount(count);
225
      di2D.setCount(count);
226
      di3D.setCount(count);
227
      di4D.setCount(count);
228
      diQu.setCount(count);
229
      }
230

    
231
///////////////////////////////////////////////////////////////////////////////////////////////////
232

    
233
    public void setConvexity(float convexity)
234
      {
235
      di1D.setConvexity(convexity);
236
      di2D.setConvexity(convexity);
237
      di3D.setConvexity(convexity);
238
      di4D.setConvexity(convexity);
239
      diQu.setConvexity(convexity);
240
      }
241

    
242
///////////////////////////////////////////////////////////////////////////////////////////////////
243
// DynamicQuat does not support noise
244

    
245
    public void setNoise(float noise0, float noise1, float noise2, float noise3)
246
      {
247
      mNoise[0] = noise0;
248
      mNoise[1] = noise1;
249
      mNoise[2] = noise2;
250
      mNoise[3] = noise3;
251

    
252
      p1N.set(mNoise[0]);
253
      p2N.set(mNoise[0],mNoise[1]);
254
      p3N.set(mNoise[0],mNoise[1],mNoise[2]);
255
      p4N.set(mNoise[0],mNoise[1],mNoise[2], mNoise[3]);
256

    
257
      di1D.setNoise(p1N);
258
      di2D.setNoise(p2N);
259
      di3D.setNoise(p3N);
260
      di4D.setNoise(p4N);
261
      }
262
    
263
///////////////////////////////////////////////////////////////////////////////////////////////////
264

    
265
    public void setDimension(int dim)
266
      {
267
      if( currentDim != dim )
268
        {
269
        if( !(currentDim==DIM_3DXY && dim==DIM_3DXZ) && !(currentDim==DIM_3DXZ && dim==DIM_3DXY) &&
270
            !(currentDim==DIM_4DXY && dim==DIM_4DZW) && !(currentDim==DIM_4DZW && dim==DIM_4DXY) &&
271
            !(currentDim==DIM_Q_XY && dim==DIM_Q_ZW) && !(currentDim==DIM_Q_ZW && dim==DIM_Q_XY)  )
272
          {
273
          resetPoints();
274
          }
275

    
276
        currentDim = dim;
277
        }
278
      }
279
    
280
///////////////////////////////////////////////////////////////////////////////////////////////////
281
    
282
    public void drawCurve(Canvas c, long time)
283
      {
284
      if( mLastTime<0 )
285
        {
286
        mLastTime = time;
287
        }
288
      else
289
        {
290
        mDiffTime = time - mLastTime;
291
        }
292

    
293
      synchronized(lock)
294
        {
295
        switch(currentDim)
296
          {
297
          case DIM_1D  : drawHorizontalAxis(c,"x");
298
                         drawPath(c,di1D,0,1,time);
299
                         drawRedPoints1D(c);
300
                         break;
301
          case DIM_2D  : drawHorizontalAxis(c,"x");
302
                         drawVerticalAxis  (c,"y");
303
                         drawPath(c,di2D,0,1,time);
304
                         drawRedPoints2D(c);
305
                         break;
306
          case DIM_3DXY: drawHorizontalAxis(c,"x");
307
                         drawVerticalAxis  (c,"y");
308
                         drawPath(c,di3D,0,1,time);
309
                         drawRedPoints3D(c);
310
                         break;
311
          case DIM_3DXZ: drawHorizontalAxis(c,"x");
312
                         drawVerticalAxis  (c,"z");
313
                         drawPath(c,di3D,0,2,time);
314
                         drawRedPoints3D(c);
315
                         break;
316
          case DIM_4DXY: drawHorizontalAxis(c,"x");
317
                         drawVerticalAxis  (c,"y");
318
                         drawPath(c,di4D,0,1,time);
319
                         drawRedPoints4D(c);
320
                         break;
321
          case DIM_4DZW: drawHorizontalAxis(c,"z");
322
                         drawVerticalAxis  (c,"w");
323
                         drawPath(c,di4D,2,3,time);
324
                         drawRedPoints4D(c);
325
                         break;
326
          case DIM_Q_XY: drawHorizontalAxis(c,"x");
327
                         drawVerticalAxis  (c,"y");
328
                         drawPath(c,diQu,0,1,time);
329
                         drawRedPointsQu(c);
330
                         break;
331
          case DIM_Q_ZW: drawHorizontalAxis(c,"z");
332
                         drawVerticalAxis  (c,"w");
333
                         drawPath(c,diQu,2,3,time);
334
                         drawRedPointsQu(c);
335
                         break;
336
          }
337
        }
338

    
339
      mLastTime = time;
340
      }
341

    
342
///////////////////////////////////////////////////////////////////////////////////////////////////
343

    
344
    private void clearPoints()
345
      {
346
      for(int i=0; i<MAX_DIM*NUM_POINTS; i++)
347
         {
348
         mPoints[i] = -100000.0f;
349
         }
350
      }
351

    
352
///////////////////////////////////////////////////////////////////////////////////////////////////
353

    
354
    public void resetPoints()
355
      {
356
      synchronized(lock)
357
        {
358
        clearPoints();
359

    
360
        switch(currentDim)
361
          {
362
          case DIM_1D  : di1D.removeAll(); break;
363
          case DIM_2D  : di2D.removeAll(); break;
364
          case DIM_3DXY:
365
          case DIM_3DXZ: di3D.removeAll(); break;
366
          case DIM_4DXY:
367
          case DIM_4DZW: di4D.removeAll(); break;
368
          case DIM_Q_XY:
369
          case DIM_Q_ZW: diQu.removeAll(); break;
370
          }
371

    
372
        DynamicActivity act = mAct.get();
373
        act.setNumRedPoints(0);
374
        act.clearPoints();
375
        }
376
      }
377

    
378
///////////////////////////////////////////////////////////////////////////////////////////////////
379

    
380
    public void startDynamic()
381
      {
382
      mRunning = true;
383
      mLastTime= -1;
384
      mStartTime = System.currentTimeMillis();
385

    
386
      clearPoints();
387
      di1D.resetToBeginning();
388
      di2D.resetToBeginning();
389
      di3D.resetToBeginning();
390
      di4D.resetToBeginning();
391
      diQu.resetToBeginning();
392
      }
393

    
394
///////////////////////////////////////////////////////////////////////////////////////////////////
395

    
396
    public void stopDynamic()
397
      {
398
      mRunning = false;
399
      }
400

    
401
///////////////////////////////////////////////////////////////////////////////////////////////////
402

    
403
    private void drawHorizontalAxis(Canvas c, String label)
404
      {
405
      mPaint.setColor(0xff000000);
406

    
407
      c.drawLine(0, halfScreenHeight, halfScreenWidth*2, halfScreenHeight, mPaint);
408
      c.drawText( label, 0.95f*halfScreenWidth*2, halfScreenHeight + mSizeT , mPaint);
409
      }
410

    
411

    
412
///////////////////////////////////////////////////////////////////////////////////////////////////
413

    
414
    private void drawVerticalAxis(Canvas c, String label)
415
      {
416
      mPaint.setColor(0xff000000);
417

    
418
      c.drawLine(halfScreenWidth, 0, halfScreenWidth, halfScreenHeight*2, mPaint);
419
      c.drawText(label, halfScreenWidth + mSizeT,                mSizeT , mPaint);
420
      }
421

    
422
///////////////////////////////////////////////////////////////////////////////////////////////////
423

    
424
    private void drawPath(Canvas c, Dynamic dyn, int indexH, int indexW, long time)
425
      {
426
      int len = dyn.getNumPoints();
427

    
428
      if( len>=2 )
429
        {
430
        if( mRunning )
431
          {
432
          if ( ++mPosition >= NUM_POINTS ) mPosition=0;
433

    
434
          if( dyn.getDimension()==1 )
435
            {
436
            mPoints[MAX_DIM*mPosition+indexW] = halfScreenHeight;
437
            }
438

    
439
          if( dyn.get(mPoints,MAX_DIM*mPosition, time-mStartTime, mDiffTime) )
440
            {
441
            stopDynamic();
442
            }
443

    
444
          addNewSpeedPoint(time);
445
          }
446

    
447
        if( currentDim!=DIM_Q_XY && currentDim!=DIM_Q_ZW )
448
          {
449
          for(int i=0; i<NUM_POINTS; i++)
450
            {
451
            int color = i<=mPosition ? 0xff - (mPosition           -i)*0xff/(NUM_POINTS-1)
452
                                     : 0xff - (mPosition+NUM_POINTS-i)*0xff/(NUM_POINTS-1);
453

    
454
            mPaint.setColor( 0xffffff + ((color&0xff)<<24) );
455
            c.drawCircle(mPoints[MAX_DIM*i+indexH], mPoints[MAX_DIM*i+indexW] , mSize1, mPaint );
456
            }
457
          }
458
        else
459
          {
460
          float x,y,min = QUAT_QUOT* (halfScreenWidth<halfScreenHeight ? halfScreenWidth:halfScreenHeight );
461

    
462
          for(int i=0; i<NUM_POINTS; i++)
463
            {
464
            int color = i<=mPosition ? 0xff - (mPosition           -i)*0xff/(NUM_POINTS-1)
465
                                     : 0xff - (mPosition+NUM_POINTS-i)*0xff/(NUM_POINTS-1);
466

    
467
            mPaint.setColor( 0xffffff + ((color&0xff)<<24) );
468
            x = mPoints[MAX_DIM*i+indexH]*min + halfScreenWidth;
469
            y = mPoints[MAX_DIM*i+indexW]*min + halfScreenHeight;
470
            c.drawCircle( x, y, mSize1, mPaint );
471
            }
472
          }
473
        }
474
      }
475

    
476
///////////////////////////////////////////////////////////////////////////////////////////////////
477

    
478
    private void drawRedPoints1D(Canvas c)
479
      {
480
      int len = di1D.getNumPoints();
481

    
482
      for(int curr=0; curr<len; curr++)
483
        {
484
        p1D = di1D.getPoint(curr);
485
        drawRedPoint(c,curr+"", p1D.get0(), halfScreenHeight);
486
        }
487
      }
488

    
489
///////////////////////////////////////////////////////////////////////////////////////////////////
490

    
491
    private void drawRedPoints2D(Canvas c)
492
      {
493
      int len = di2D.getNumPoints();
494

    
495
      for(int curr=0; curr<len; curr++)
496
        {
497
        p2D = di2D.getPoint(curr);
498
        drawRedPoint(c,curr+"", p2D.get0(), p2D.get1());
499
        }
500
      }
501

    
502
///////////////////////////////////////////////////////////////////////////////////////////////////
503

    
504
    private void drawRedPoints3D(Canvas c)
505
      {
506
      int len = di3D.getNumPoints();
507

    
508
      for(int curr=0; curr<len; curr++)
509
        {
510
        p3D = di3D.getPoint(curr);
511
        drawRedPoint(c,curr+"", p3D.get0(), currentDim==DIM_3DXY ? p3D.get1():p3D.get2());
512
        }
513
      }
514

    
515
///////////////////////////////////////////////////////////////////////////////////////////////////
516

    
517
    private void drawRedPoints4D(Canvas c)
518
      {
519
      int len = di4D.getNumPoints();
520

    
521
      for(int curr=0; curr<len; curr++)
522
        {
523
        p4D = di4D.getPoint(curr);
524

    
525
        if( currentDim==DIM_4DXY ) drawRedPoint(c,curr+"", p4D.get0(), p4D.get1());
526
        else                       drawRedPoint(c,curr+"", p4D.get2(), p4D.get3());
527
        }
528
      }
529

    
530
///////////////////////////////////////////////////////////////////////////////////////////////////
531

    
532
    private void drawRedPointsQu(Canvas c)
533
      {
534
      int len = diQu.getNumPoints();
535
      float x,y, min = QUAT_QUOT* (halfScreenWidth<halfScreenHeight ? halfScreenWidth:halfScreenHeight );
536

    
537
      for(int curr=0; curr<len; curr++)
538
        {
539
        pQD = diQu.getPoint(curr);
540

    
541
        if( currentDim==DIM_Q_XY )
542
          {
543
          x = pQD.get0()*min + halfScreenWidth;
544
          y = pQD.get1()*min + halfScreenHeight;
545
          }
546
        else
547
          {
548
          x = pQD.get2()*min + halfScreenWidth;
549
          y = pQD.get3()*min + halfScreenHeight;
550
          }
551

    
552
        drawRedPoint(c,curr+"", x,y);
553
        }
554
      }
555

    
556
///////////////////////////////////////////////////////////////////////////////////////////////////
557

    
558
    private void drawRedPoint(Canvas c, String label, float width, float height)
559
      {
560
      mPaint.setColor(0xffff0000);
561
      c.drawCircle( width, height, mSize2, mPaint);
562
      mPaint.setColor(0xffffffff);
563
      c.drawText(label, width,height-mFontHeight, mPaint);
564
      }
565

    
566
///////////////////////////////////////////////////////////////////////////////////////////////////
567

    
568
    private void addNewPoint(float x, float y)
569
      {
570
      float gx,gy,gz,gw;
571
      int len;
572
      int minDist = (mAvg*mAvg)/100;
573

    
574
      switch(currentDim)
575
        {
576
        case DIM_1D : len = di1D.getNumPoints();
577

    
578
                      for(int g=0; g<len; g++)
579
                        {
580
                        p1D = di1D.getPoint(g);
581
                        gx = p1D.get0();
582
                                    
583
                        if( (x-gx)*(x-gx) < minDist )
584
                          {
585
                          mMoving = g;
586
                          break;
587
                          }
588
                        }
589
                      if( mMoving <0 )
590
                        {
591
                        synchronized(lock)
592
                          {
593
                          di1D.add(new Static1D(x));
594
                          mAct.get().setNumRedPoints(len+1);
595
                          }
596
                        }
597
                      break;
598
        case DIM_2D : len = di2D.getNumPoints();
599
                                 
600
                      for(int g=0; g<len; g++)
601
                        {
602
                        p2D = di2D.getPoint(g);
603
                        gx = p2D.get0();
604
                        gy = p2D.get1();
605
                                    
606
                        if( (x-gx)*(x-gx) + (y-gy)*(y-gy) < minDist )
607
                          {
608
                          mMoving = g;
609
                          break;
610
                          }
611
                        }
612
                      if( mMoving <0 )
613
                        {
614
                        synchronized(lock)
615
                          {
616
                          di2D.add(new Static2D(x,y));
617
                          mAct.get().setNumRedPoints(len+1);
618
                          }
619
                        }
620
                      break;
621
        case DIM_3DXY:
622
        case DIM_3DXZ:len = di3D.getNumPoints();
623
                                 
624
                      for(int g=0; g<len; g++)
625
                        {
626
                        p3D = di3D.getPoint(g);
627
                        gx = p3D.get0();
628
                        gy = p3D.get1();
629
                        gz = p3D.get2();
630
                               
631
                        if( currentDim==DIM_3DXY )
632
                          {
633
                          if( (x-gx)*(x-gx) + (y-gy)*(y-gy) < minDist )
634
                            {
635
                            mMoving = g;
636
                            break;
637
                            }
638
                          }
639
                        if( currentDim==DIM_3DXZ )
640
                          {
641
                          if( (x-gx)*(x-gx) + (y-gz)*(y-gz) < minDist )
642
                            {
643
                            mMoving = g;
644
                            break;
645
                            }
646
                          }
647
                        }
648

    
649
                      if( mMoving <0 )
650
                        {
651
                        synchronized(lock)
652
                          {
653
                          if( currentDim==DIM_3DXY ) di3D.add(new Static3D(x,y, halfScreenHeight));
654
                          if( currentDim==DIM_3DXZ ) di3D.add(new Static3D(x, halfScreenHeight,y));
655
                          mAct.get().setNumRedPoints(len+1);
656
                          }
657
                        }
658
                      break;
659
        case DIM_4DXY:
660
        case DIM_4DZW:len = di4D.getNumPoints();
661

    
662
                      for(int g=0; g<len; g++)
663
                        {
664
                        p4D = di4D.getPoint(g);
665
                        gx = p4D.get0();
666
                        gy = p4D.get1();
667
                        gz = p4D.get2();
668
                        gw = p4D.get3();
669

    
670
                        if( currentDim==DIM_4DXY )
671
                          {
672
                          if( (x-gx)*(x-gx) + (y-gy)*(y-gy) < minDist )
673
                            {
674
                            mMoving = g;
675
                            break;
676
                            }
677
                          }
678
                        if( currentDim==DIM_4DZW )
679
                          {
680
                          if( (x-gz)*(x-gz) + (y-gw)*(y-gw) < minDist )
681
                            {
682
                            mMoving = g;
683
                            break;
684
                            }
685
                          }
686
                        }
687

    
688
                      if( mMoving <0 )
689
                        {
690
                        synchronized(lock)
691
                          {
692
                          if( currentDim==DIM_4DXY ) di4D.add(new Static4D(x,y, halfScreenWidth, halfScreenHeight));
693
                          if( currentDim==DIM_4DZW ) di4D.add(new Static4D( halfScreenWidth, halfScreenHeight,x,y));
694
                          mAct.get().setNumRedPoints(len+1);
695
                          }
696
                        }
697
                      break;
698
        case DIM_Q_XY:
699
        case DIM_Q_ZW:len = diQu.getNumPoints();
700
                      float min = QUAT_QUOT* (halfScreenWidth<halfScreenHeight ? halfScreenWidth:halfScreenHeight );
701

    
702
                      for(int g=0; g<len; g++)
703
                        {
704
                        pQD = diQu.getPoint(g);
705

    
706
                        if( currentDim==DIM_Q_XY )
707
                          {
708
                          gx = pQD.get0()*min + halfScreenWidth;
709
                          gy = pQD.get1()*min + halfScreenHeight;
710

    
711
                          if( (x-gx)*(x-gx) + (y-gy)*(y-gy) < minDist )
712
                            {
713
                            mMoving = g;
714
                            break;
715
                            }
716
                          }
717
                        if( currentDim==DIM_Q_ZW )
718
                          {
719
                          gz = pQD.get2()*min + halfScreenWidth;
720
                          gw = pQD.get3()*min + halfScreenHeight;
721

    
722
                          if( (x-gz)*(x-gz) + (y-gw)*(y-gw) < minDist )
723
                            {
724
                            mMoving = g;
725
                            break;
726
                            }
727
                          }
728
                        }
729

    
730
                      if( mMoving <0 )
731
                        {
732
                        float z,w;
733
                        x = (x - halfScreenWidth ) / min;
734
                        y = (y - halfScreenHeight) / min;
735
                        float len1 = x*x + y*y;
736

    
737
                        if( len1>= 1.0f )
738
                          {
739
                          float A = (float)Math.sqrt(len1);
740
                          x = x/A;
741
                          y = y/A;
742
                          z = 0.0f;
743
                          w = 0.0f;
744
                          }
745
                        else
746
                          {
747
                          z = (float)Math.sqrt(1-len1);
748
                          w = 0.0f;
749
                          }
750

    
751
                        synchronized(lock)
752
                          {
753
                          if( currentDim==DIM_Q_XY ) diQu.add(new Static4D(x,y,z,w));
754
                          if( currentDim==DIM_Q_ZW ) diQu.add(new Static4D(z,w,x,y));
755
                          mAct.get().setNumRedPoints(len+1);
756
                          }
757
                        }
758
                      break;
759
        }
760
      }
761

    
762
///////////////////////////////////////////////////////////////////////////////////////////////////
763

    
764
    private void addNewSpeedPoint(long time)
765
      {
766
      int prev = mPosition-1;
767
      if( prev<0 ) prev = NUM_POINTS-1;
768

    
769
      float xdiff = mPoints[MAX_DIM*prev  ]-mPoints[MAX_DIM*mPosition  ];
770
      float ydiff = mPoints[MAX_DIM*prev+1]-mPoints[MAX_DIM*mPosition+1];
771
      float zdiff = mPoints[MAX_DIM*prev+2]-mPoints[MAX_DIM*mPosition+2];
772
      float wdiff = mPoints[MAX_DIM*prev+3]-mPoints[MAX_DIM*mPosition+3];
773

    
774
      float dist = (float)Math.sqrt( xdiff*xdiff + ydiff*ydiff + zdiff*zdiff + wdiff*wdiff);
775
      float speed= mDiffTime<=0 ? 0: dist / mDiffTime;
776
      float timepoint = ((float)(time-mStartTime))/mDuration;
777

    
778
      if( dist<1000.0f )   // otherwise this is a very first call; do not send it!
779
        {
780
        mAct.get().addPoint( timepoint - (int)timepoint, speed );
781
        }
782
      }
783

    
784
///////////////////////////////////////////////////////////////////////////////////////////////////
785

    
786
    @Override
787
    public boolean onTouchEvent(MotionEvent event)
788
      {
789
      int action = event.getAction();
790
      float xDown, yDown;
791

    
792
      switch(action)
793
        {
794
        case MotionEvent.ACTION_DOWN: xDown = event.getX();
795
                                      yDown = event.getY();
796

    
797
                                      addNewPoint(xDown,yDown);
798

    
799
                                      break;
800
        case MotionEvent.ACTION_MOVE: if( mMoving >=0 )
801
                                        {
802
                                        xDown = event.getX();
803
                                        yDown = event.getY();
804
                                        
805
                                        switch(currentDim)
806
                                          {
807
                                          case DIM_1D  : di1D.setPoint(mMoving, xDown);
808
                                                         break;
809
                                          case DIM_2D  : di2D.setPoint(mMoving, xDown, yDown);
810
                                                         break;
811
                                          case DIM_3DXY: di3D.setPoint(mMoving, xDown, yDown, (int)di3D.getPoint(mMoving).get2());
812
                                                         break;
813
                                          case DIM_3DXZ: di3D.setPoint(mMoving, xDown, (int)di3D.getPoint(mMoving).get1(), yDown);
814
                                                         break;
815
                                          case DIM_4DXY: di4D.setPoint(mMoving, xDown, yDown, (int)di4D.getPoint(mMoving).get2(), (int)di4D.getPoint(mMoving).get3());
816
                                                         break;
817
                                          case DIM_4DZW: di4D.setPoint(mMoving, (int)di4D.getPoint(mMoving).get0(), (int)di4D.getPoint(mMoving).get1(), xDown, yDown);
818
                                                         break;
819
                                          case DIM_Q_XY: float min1 = QUAT_QUOT* (halfScreenWidth<halfScreenHeight ? halfScreenWidth:halfScreenHeight );
820
                                                         float x1 = (xDown - halfScreenWidth ) / min1;
821
                                                         float y1 = (yDown - halfScreenHeight) / min1;
822
                                                         float z1 = diQu.getPoint(mMoving).get2();
823
                                                         float w1 = diQu.getPoint(mMoving).get3();
824
                                                         float len1 = x1*x1 + y1*y1;
825

    
826
                                                         if( len1 <= 1.0f )
827
                                                           {
828
                                                           float len2 = z1*z1 + w1*w1;
829

    
830
                                                           if( len2 == 0 )
831
                                                             {
832
                                                             if( len1 == 0 )
833
                                                               {
834
                                                               w1 = 1.0f;
835
                                                               }
836
                                                             else
837
                                                               {
838
                                                               float B = (float)Math.sqrt(len1);
839
                                                               x1 = x1/B;
840
                                                               y1 = y1/B;
841
                                                               }
842
                                                             }
843
                                                           else
844
                                                             {
845
                                                             float A = (float)Math.sqrt((1.0f - len1)/len2);
846
                                                             z1 = A*z1;
847
                                                             w1 = A*w1;
848
                                                             }
849
                                                           }
850
                                                         else
851
                                                           {
852
                                                           float B = (float)Math.sqrt(len1);
853
                                                           x1 = x1/B;
854
                                                           y1 = y1/B;
855
                                                           z1 = 0.0f;
856
                                                           w1 = 0.0f;
857
                                                           }
858
                                                         diQu.setPoint(mMoving, x1,y1,z1,w1);
859
                                                         break;
860
                                          case DIM_Q_ZW: float min2 = QUAT_QUOT* (halfScreenWidth<halfScreenHeight ? halfScreenWidth:halfScreenHeight );
861
                                                         float x2 = diQu.getPoint(mMoving).get0();
862
                                                         float y2 = diQu.getPoint(mMoving).get1();
863
                                                         float z2 = (xDown - halfScreenWidth ) / min2;
864
                                                         float w2 = (yDown - halfScreenHeight) / min2;
865
                                                         float len3 = z2*z2 + w2*w2;
866

    
867
                                                         if( len3 <= 1.0f )
868
                                                           {
869
                                                           float len4 = x2*x2 + y2*y2;
870

    
871
                                                           if( len4 == 0 )
872
                                                             {
873
                                                             if( len3 == 0 )
874
                                                               {
875
                                                               w2 = 1.0f;
876
                                                               }
877
                                                             else
878
                                                               {
879
                                                               float B = (float)Math.sqrt(len3);
880
                                                               z2 = z2/B;
881
                                                               w2 = w2/B;
882
                                                               }
883
                                                             }
884
                                                           else
885
                                                             {
886
                                                             float A = (float)Math.sqrt((1.0f - len3)/len4);
887
                                                             x2 = A*x2;
888
                                                             y2 = A*y2;
889
                                                             }
890
                                                           }
891
                                                         else
892
                                                           {
893
                                                           float B = (float)Math.sqrt(len3);
894
                                                           x2 = 0.0f;
895
                                                           y2 = 0.0f;
896
                                                           z2 = z2/B;
897
                                                           w2 = w2/B;
898
                                                           }
899
                                                         diQu.setPoint(mMoving, x2,y2,z2,w2);
900
                                                         break;
901
                                          }
902
                                        }                           
903
                                      break;
904
        case MotionEvent.ACTION_UP  : mMoving = -1;
905
                                      break;
906
        }
907
            
908
      return true;
909
      }
910
  }
(4-4/4)