1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package org.ximtec.igesture.algorithm.feature;
28
29 import java.util.ArrayList;
30 import java.util.List;
31 import java.util.StringTokenizer;
32 import java.util.logging.Level;
33 import java.util.logging.Logger;
34
35 import org.sigtec.ink.Note;
36 import org.sigtec.ink.Point;
37 import org.sigtec.ink.Trace;
38 import org.sigtec.util.Constant;
39 import org.ximtec.igesture.util.DoubleVector;
40
41
42
43
44
45
46
47
48
49 public class FeatureTool {
50
51 private static final Logger LOGGER = Logger.getLogger(FeatureTool.class
52 .getName());
53
54
55
56
57
58
59
60
61 public static Trace createTrace(Note note) {
62 final Trace result = new Trace();
63
64 for (final Trace trace : note.getTraces()) {
65 result.addAll(trace.getPoints());
66 }
67
68 return result;
69 }
70
71
72
73
74
75
76
77
78
79 public static double getDeltaX(int i, Point[] points) {
80 return points[i + 1].getX() - points[i].getX();
81 }
82
83
84
85
86
87
88
89
90
91 public static double getDeltaY(int i, Point[] points) {
92 return points[i + 1].getY() - points[i].getY();
93 }
94
95
96
97
98
99
100
101
102
103 public static double getDeltaT(int i, Point[] points) {
104 return points[i + 1].getTimestamp() - points[i].getTimestamp();
105 }
106
107
108
109
110
111
112
113
114
115 public static double getDeltaT(Point p1, Point p2) {
116 return p2.getTimestamp() - p1.getTimestamp();
117 }
118
119
120
121
122
123
124
125
126
127 public static double roh(int i, Point[] points) {
128 final double divisor = getDeltaX(i, points) * getDeltaY(i - 1, points)
129 - getDeltaX(i - 1, points) * getDeltaY(i, points);
130 final double dividend = getDeltaX(i, points) * getDeltaX(i - 1, points)
131 + getDeltaY(i, points) * getDeltaY(i - 1, points);
132 final double result = Math.atan(divisor / dividend);
133
134 if (Double.isNaN(result)) {
135 return 1;
136 }
137 else {
138 return result;
139 }
140
141 }
142
143
144
145
146
147
148
149
150
151 public static double getAngle(Point p1, Point p2) {
152 final double r = p1.distance(p2);
153 final double x = p2.getX() - p1.getX();
154
155 double alpha = Math.toDegrees(Math.acos(x / r));
156
157 if (p2.getY() - p1.getY() < 0) {
158 alpha = 360 - alpha;
159 }
160
161 return alpha;
162 }
163
164
165
166
167
168
169
170
171
172 public static List<Trace> removeShortTraces(List<Trace> traces,
173 int minNumOfPoints) {
174 final List<Trace> result = new ArrayList<Trace>();
175
176 for (final Trace trace : traces) {
177
178 if (trace.size() >= minNumOfPoints) {
179 result.add(trace);
180 }
181
182 }
183 return result;
184 }
185
186
187
188
189
190
191
192
193
194 public static List<Feature> createFeatureList(String featureList) {
195 final ArrayList<Feature> result = new ArrayList<Feature>();
196 final StringTokenizer tokenizer = new StringTokenizer(featureList,
197 Constant.COMMA);
198
199 while (tokenizer.hasMoreElements()) {
200 result.add(createFeature(tokenizer.nextToken()));
201 }
202
203 return result;
204 }
205
206
207
208
209
210
211
212
213 public static Feature createFeature(String classname) {
214 try {
215 return (Feature)Class.forName(classname.trim()).newInstance();
216 }
217 catch (final InstantiationException e) {
218 LOGGER.log(Level.SEVERE, Constant.EMPTY_STRING, e);
219 }
220 catch (final IllegalAccessException e) {
221 LOGGER.log(Level.SEVERE, Constant.EMPTY_STRING, e);
222 }
223 catch (final ClassNotFoundException e) {
224 LOGGER.log(Level.SEVERE, Constant.EMPTY_STRING, e);
225 }
226
227 return null;
228 }
229
230
231
232
233
234
235
236
237
238
239
240 public static DoubleVector computeFeatureVector(Note note, int minDistance,
241 Feature[] featureList) throws FeatureException {
242
243
244 final Note clone = (Note)note.clone();
245
246
247 clone.filter(minDistance);
248
249
250 final DoubleVector featureVector = new DoubleVector(featureList.length);
251
252 for (int i = 0; i < featureList.length; i++) {
253 featureVector.set(i, featureList[i].compute(clone));
254 }
255
256 return featureVector;
257 }
258
259
260
261
262
263
264
265 public static int computeMinimalNumberOfRequiredPoints(Feature[] list) {
266 int result = 0;
267 for (Feature feature : list) {
268 result = Math.max(result, feature.getMinimalNumberOfPoints());
269 }
270 return result;
271 }
272
273
274 public static double computeD1(Note note) {
275 Trace trace = createTrace(note);
276 double a = Math.pow(trace.get(trace.size() / 2).getX()
277 - trace.getStartPoint().getX(), 2);
278 double b = Math.pow(trace.get(trace.size() / 2).getY()
279 - trace.getStartPoint().getY(), 2);
280 return Math.sqrt(a + b);
281 }
282
283
284 public static double computeD2(Note note) {
285 Trace trace = createTrace(note);
286 double a = Math.pow(trace.getEndPoint().getX()
287 - trace.get(trace.size() / 2).getX(), 2);
288 double b = Math.pow(trace.getEndPoint().getY()
289 - trace.get(trace.size() / 2).getY(), 2);
290 return Math.sqrt(a + b);
291 }
292
293
294 public static double computeD3(Note note) {
295 Trace trace = createTrace(note);
296 double a = Math.pow(trace.getEndPoint().getX()
297 - trace.getStartPoint().getX(), 2);
298 double b = Math.pow(trace.getEndPoint().getY()
299 - trace.getStartPoint().getY(), 2);
300 return Math.sqrt(a + b);
301 }
302
303 }