~pvigo/+junk/processing-3.1.2

« back to all changes in this revision

Viewing changes to debian/processing/usr/share/processing-3.1.2/modes/java/examples/Demos/Graphics/Yellowtail/Gesture.pde

  • Committer: Pablo Vigo
  • Date: 2016-08-16 10:54:55 UTC
  • Revision ID: pvigo@xtec.cat-20160816105455-4y3x00r4w5anrpr4
2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
class Gesture {
 
2
 
 
3
  float  damp = 5.0;
 
4
  float  dampInv = 1.0 / damp;
 
5
  float  damp1 = damp - 1;
 
6
 
 
7
  int w;
 
8
  int h;
 
9
  int capacity;
 
10
 
 
11
  Vec3f path[];
 
12
  int crosses[];
 
13
  Polygon polygons[];
 
14
  int nPoints;
 
15
  int nPolys;
 
16
 
 
17
  float jumpDx, jumpDy;
 
18
  boolean exists;
 
19
  float INIT_TH = 14;
 
20
  float thickness = INIT_TH;
 
21
 
 
22
  Gesture(int mw, int mh) {
 
23
    w = mw;
 
24
    h = mh;
 
25
    capacity = 600;
 
26
    path = new Vec3f[capacity];
 
27
    polygons = new Polygon[capacity];
 
28
    crosses  = new int[capacity];
 
29
    for (int i=0;i<capacity;i++) {
 
30
      polygons[i] = new Polygon();
 
31
      polygons[i].npoints = 4;
 
32
      path[i] = new Vec3f();
 
33
      crosses[i] = 0;
 
34
    }
 
35
    nPoints = 0;
 
36
    nPolys = 0;
 
37
 
 
38
    exists = false;
 
39
    jumpDx = 0;
 
40
    jumpDy = 0;
 
41
  }
 
42
 
 
43
  void clear() {
 
44
    nPoints = 0;
 
45
    exists = false;
 
46
    thickness = INIT_TH;
 
47
  }
 
48
 
 
49
  void clearPolys() {
 
50
    nPolys = 0;
 
51
  }
 
52
 
 
53
  void addPoint(float x, float y) {
 
54
 
 
55
    if (nPoints >= capacity) {
 
56
      // there are all sorts of possible solutions here,
 
57
      // but for abject simplicity, I don't do anything.
 
58
    } 
 
59
    else {
 
60
      float v = distToLast(x, y);
 
61
      float p = getPressureFromVelocity(v);
 
62
      path[nPoints++].set(x,y,p);
 
63
 
 
64
      if (nPoints > 1) {
 
65
        exists = true;
 
66
        jumpDx = path[nPoints-1].x - path[0].x;
 
67
        jumpDy = path[nPoints-1].y - path[0].y;
 
68
      }
 
69
    }
 
70
 
 
71
  }
 
72
 
 
73
  float getPressureFromVelocity(float v) {
 
74
    final float scale = 18;
 
75
    final float minP = 0.02;
 
76
    final float oldP = (nPoints > 0) ? path[nPoints-1].p : 0;
 
77
    return ((minP + max(0, 1.0 - v/scale)) + (damp1*oldP))*dampInv;
 
78
  }
 
79
 
 
80
  void setPressures() {
 
81
    // pressures vary from 0...1
 
82
    float pressure;
 
83
    Vec3f tmp;
 
84
    float t = 0;
 
85
    float u = 1.0 / (nPoints - 1)*TWO_PI;
 
86
    for (int i = 0; i < nPoints; i++) {
 
87
      pressure = sqrt((1.0 - cos(t))*0.5);
 
88
      path[i].p = pressure;
 
89
      t += u;
 
90
    }
 
91
  }
 
92
 
 
93
  float distToLast(float ix, float iy) {
 
94
    if (nPoints > 0) {
 
95
      Vec3f v = path[nPoints-1];
 
96
      float dx = v.x - ix;
 
97
      float dy = v.y - iy;
 
98
      return mag(dx, dy);
 
99
    } 
 
100
    else {
 
101
      return 30;
 
102
    }
 
103
  }
 
104
 
 
105
  void compile() {
 
106
    // compute the polygons from the path of Vec3f's
 
107
    if (exists) {
 
108
      clearPolys();
 
109
 
 
110
      Vec3f p0, p1, p2;
 
111
      float radius0, radius1;
 
112
      float ax, bx, cx, dx;
 
113
      float ay, by, cy, dy;
 
114
      int   axi, bxi, cxi, dxi, axip, axid;
 
115
      int   ayi, byi, cyi, dyi, ayip, ayid;
 
116
      float p1x, p1y;
 
117
      float dx01, dy01, hp01, si01, co01;
 
118
      float dx02, dy02, hp02, si02, co02;
 
119
      float dx13, dy13, hp13, si13, co13;
 
120
      float taper = 1.0;
 
121
 
 
122
      int  nPathPoints = nPoints - 1;
 
123
      int  lastPolyIndex = nPathPoints - 1;
 
124
      float npm1finv =  1.0 / max(1, nPathPoints - 1);
 
125
 
 
126
      // handle the first point
 
127
      p0 = path[0];
 
128
      p1 = path[1];
 
129
      radius0 = p0.p * thickness;
 
130
      dx01 = p1.x - p0.x;
 
131
      dy01 = p1.y - p0.y;
 
132
      hp01 = sqrt(dx01*dx01 + dy01*dy01);
 
133
      if (hp01 == 0) {
 
134
        hp02 = 0.0001;
 
135
      }
 
136
      co01 = radius0 * dx01 / hp01;
 
137
      si01 = radius0 * dy01 / hp01;
 
138
      ax = p0.x - si01; 
 
139
      ay = p0.y + co01;
 
140
      bx = p0.x + si01; 
 
141
      by = p0.y - co01;
 
142
 
 
143
      int xpts[];
 
144
      int ypts[];
 
145
 
 
146
      int LC = 20;
 
147
      int RC = w-LC;
 
148
      int TC = 20;
 
149
      int BC = h-TC;
 
150
      float mint = 0.618;
 
151
      float tapow = 0.4;
 
152
 
 
153
      // handle the middle points
 
154
      int i = 1;
 
155
      Polygon apoly;
 
156
      for (i = 1; i < nPathPoints; i++) {
 
157
        taper = pow((lastPolyIndex-i)*npm1finv,tapow);
 
158
 
 
159
        p0 = path[i-1];
 
160
        p1 = path[i  ];
 
161
        p2 = path[i+1];
 
162
        p1x = p1.x;
 
163
        p1y = p1.y;
 
164
        radius1 = Math.max(mint,taper*p1.p*thickness);
 
165
 
 
166
        // assumes all segments are roughly the same length...
 
167
        dx02 = p2.x - p0.x;
 
168
        dy02 = p2.y - p0.y;
 
169
        hp02 = (float) Math.sqrt(dx02*dx02 + dy02*dy02);
 
170
        if (hp02 != 0) {
 
171
          hp02 = radius1/hp02;
 
172
        }
 
173
        co02 = dx02 * hp02;
 
174
        si02 = dy02 * hp02;
 
175
 
 
176
        // translate the integer coordinates to the viewing rectangle
 
177
        axi = axip = (int)ax;
 
178
        ayi = ayip = (int)ay;
 
179
        axi=(axi<0)?(w-((-axi)%w)):axi%w;
 
180
        axid = axi-axip;
 
181
        ayi=(ayi<0)?(h-((-ayi)%h)):ayi%h;
 
182
        ayid = ayi-ayip;
 
183
 
 
184
        // set the vertices of the polygon
 
185
        apoly = polygons[nPolys++];
 
186
        xpts = apoly.xpoints;
 
187
        ypts = apoly.ypoints;
 
188
        xpts[0] = axi = axid + axip;
 
189
        xpts[1] = bxi = axid + (int) bx;
 
190
        xpts[2] = cxi = axid + (int)(cx = p1x + si02);
 
191
        xpts[3] = dxi = axid + (int)(dx = p1x - si02);
 
192
        ypts[0] = ayi = ayid + ayip;
 
193
        ypts[1] = byi = ayid + (int) by;
 
194
        ypts[2] = cyi = ayid + (int)(cy = p1y - co02);
 
195
        ypts[3] = dyi = ayid + (int)(dy = p1y + co02);
 
196
 
 
197
        // keep a record of where we cross the edge of the screen
 
198
        crosses[i] = 0;
 
199
        if ((axi<=LC)||(bxi<=LC)||(cxi<=LC)||(dxi<=LC)) { 
 
200
          crosses[i]|=1; 
 
201
        }
 
202
        if ((axi>=RC)||(bxi>=RC)||(cxi>=RC)||(dxi>=RC)) { 
 
203
          crosses[i]|=2; 
 
204
        }
 
205
        if ((ayi<=TC)||(byi<=TC)||(cyi<=TC)||(dyi<=TC)) { 
 
206
          crosses[i]|=4; 
 
207
        }
 
208
        if ((ayi>=BC)||(byi>=BC)||(cyi>=BC)||(dyi>=BC)) { 
 
209
          crosses[i]|=8; 
 
210
        }
 
211
 
 
212
        //swap data for next time
 
213
        ax = dx; 
 
214
        ay = dy;
 
215
        bx = cx; 
 
216
        by = cy;
 
217
      }
 
218
 
 
219
      // handle the last point
 
220
      p2 = path[nPathPoints];
 
221
      apoly = polygons[nPolys++];
 
222
      xpts = apoly.xpoints;
 
223
      ypts = apoly.ypoints;
 
224
 
 
225
      xpts[0] = (int)ax;
 
226
      xpts[1] = (int)bx;
 
227
      xpts[2] = (int)(p2.x);
 
228
      xpts[3] = (int)(p2.x);
 
229
 
 
230
      ypts[0] = (int)ay;
 
231
      ypts[1] = (int)by;
 
232
      ypts[2] = (int)(p2.y);
 
233
      ypts[3] = (int)(p2.y);
 
234
 
 
235
    }
 
236
  }
 
237
 
 
238
  void smooth() {
 
239
    // average neighboring points
 
240
 
 
241
    final float weight = 18;
 
242
    final float scale  = 1.0 / (weight + 2);
 
243
    int nPointsMinusTwo = nPoints - 2;
 
244
    Vec3f lower, upper, center;
 
245
 
 
246
    for (int i = 1; i < nPointsMinusTwo; i++) {
 
247
      lower = path[i-1];
 
248
      center = path[i];
 
249
      upper = path[i+1];
 
250
 
 
251
      center.x = (lower.x + weight*center.x + upper.x)*scale;
 
252
      center.y = (lower.y + weight*center.y + upper.y)*scale;
 
253
    }
 
254
  }
 
255
}
 
256