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
28
29
30 package org.openimaj.workinprogress;
31
32 import java.io.File;
33 import java.io.IOException;
34
35 import org.openimaj.image.DisplayUtilities;
36 import org.openimaj.image.FImage;
37 import org.openimaj.image.pixel.Pixel;
38 import org.openimaj.image.processing.transform.FProjectionProcessor;
39 import org.openimaj.math.geometry.point.Point2dImpl;
40 import org.openimaj.math.geometry.shape.Circle;
41 import org.openimaj.math.geometry.shape.Rectangle;
42 import org.openimaj.math.geometry.shape.RotatedRectangle;
43 import org.openimaj.math.geometry.shape.Triangle;
44 import org.openimaj.math.geometry.transforms.TransformUtilities;
45
46 import Jama.Matrix;
47
48 public class Pendulum {
49 public static void main(String[] args) throws IOException {
50
51
52 final FImage background = FImage.randomImage(800, 600);
53
54 final Triangle triangle = new Triangle(new Point2dImpl(400, 100),
55 new Point2dImpl(395, 500),
56 new Point2dImpl(405, 500));
57
58 final FImage pendulumImage = new FImage(800, 600);
59 final FImage pendulumMask = new FImage(800, 600);
60 for (int y = 0; y < pendulumImage.height; y++) {
61 for (int x = 0; x < pendulumImage.width; x++) {
62 if (triangle.isInside(new Pixel(x, y))) {
63 pendulumImage.pixels[y][x] = (float) Math.random();
64 pendulumMask.pixels[y][x] = 1;
65 }
66 }
67 }
68
69 final Triangle triangle2 = new Triangle(new Point2dImpl(650, 150),
70 new Point2dImpl(645, 250),
71 new Point2dImpl(655, 250));
72
73 final FImage clockImage = new FImage(800, 600);
74 final FImage clockMask = new FImage(800, 600);
75 for (int y = 0; y < clockImage.height; y++) {
76 for (int x = 0; x < clockImage.width; x++) {
77 if (triangle2.isInside(new Pixel(x, y))) {
78 clockImage.pixels[y][x] = (float) Math.random();
79 clockMask.pixels[y][x] = 1;
80 }
81 }
82 }
83
84 final Circle circle = new Circle(50, 50, 25);
85 final FImage linBallImage = new FImage(800, 600);
86 final FImage linBallMask = new FImage(800, 600);
87 for (int y = 0; y < linBallImage.height; y++) {
88 for (int x = 0; x < linBallImage.width; x++) {
89 if (circle.isInside(new Pixel(x, y))) {
90 linBallImage.pixels[y][x] = (float) Math.random();
91 linBallMask.pixels[y][x] = 1;
92 }
93 }
94 }
95
96 final Circle circle2 = new Circle(50, 550, 25);
97 final FImage accBallImage = new FImage(800, 600);
98 final FImage accBallMask = new FImage(800, 600);
99 for (int y = 0; y < accBallImage.height; y++) {
100 for (int x = 0; x < accBallImage.width; x++) {
101 if (circle2.isInside(new Pixel(x, y))) {
102 accBallImage.pixels[y][x] = (float) Math.random();
103 accBallMask.pixels[y][x] = 1;
104 }
105 }
106 }
107
108 final File dir = new File("/Users/jon/pendulum+circle");
109 dir.mkdirs();
110 int i = 0;
111 final double theta0 = 0.75;
112 final double T = 0.1;
113 double theta;
114
115 final double triMaxSpeed = theta0 * 400;
116 final double clockMaxSpeed = 50 * 100;
117 final double linBallMaxSpeed = 3000;
118 final double accBallMaxSpeed = 30000;
119
120 final double triMaxAcc = theta0 * 400;
121 final double accBallMaxAcc = 500000;
122
123 for (double t = 0; t < 1; t += 0.001, i++) {
124 theta = theta0 * Math.cos(2 * Math.PI * t / T);
125
126 final FImage rotPendulumMask = rotate(pendulumMask, theta, 400, 100);
127 final FImage rotPendulumImage = rotate(pendulumImage, theta, 400, 100);
128
129
130 final FImage rotClockMask = rotate(clockMask, t * 50, 650, 150);
131 final FImage rotClockImage = rotate(clockImage, t * 50, 650, 150);
132 DisplayUtilities.displayName(rotClockMask, "foo");
133
134
135 final FImage transLinBallMask = translate(linBallMask, (float) t * 3000, 0f);
136 final FImage transLinBallImage = translate(linBallImage, (float) t * 3000, 0f);
137
138
139 final FImage transAccBallMask = translate(accBallMask, (float) (t * t * 500 * 500), 0f);
140 final FImage transAccBallImage = translate(accBallImage, (float) (t * t * 500 * 500), 0f);
141
142 final FImage frame = new FImage(800, 600);
143 final FImage frameVelX = new FImage(800, 600);
144 final FImage frameVelY = new FImage(800, 600);
145 final FImage frameVelMag = new FImage(800, 600);
146 final FImage frameAccX = new FImage(800, 600);
147 final FImage frameAccY = new FImage(800, 600);
148 final FImage frameAccMag = new FImage(800, 600);
149 frameVelX.fill(0.5f);
150 frameVelY.fill(0.5f);
151 frameAccX.fill(0.5f);
152 frameAccY.fill(0.5f);
153
154 frame.drawShapeFilled(new Rectangle(50, 275, 50, 50), 1f);
155 frame.drawShapeFilled(new RotatedRectangle(50, 275, 50, 50, Math.PI / 4), 1f);
156
157 for (int y = 0; y < frame.height; y++) {
158 for (int x = 0; x < frame.width; x++) {
159
160 if (rotPendulumMask.pixels[y][x] > 0.5) {
161 frame.pixels[y][x] = rotPendulumImage.pixels[y][x];
162
163
164 final double dx = x - 400, dy = y - 100, r = Math.sqrt(dx * dx + dy * dy);
165 final double vt = -r * theta0 * Math.sin(2 * Math.PI * t / T);
166 final double vx = Math.cos(theta) * vt;
167 final double vy = Math.sin(theta) * vt;
168 frameVelX.pixels[y][x] = (float) ((vx + triMaxSpeed) / (2 * triMaxSpeed));
169 frameVelY.pixels[y][x] = (float) ((vy + triMaxSpeed) / (2 * triMaxSpeed));
170 frameVelMag.pixels[y][x] = (float) (Math.abs(vt) / (triMaxSpeed));
171
172
173 final double at = -r * theta0 * Math.cos(2 * Math.PI * t / T);
174 final double ax = Math.cos(theta) * at;
175 final double ay = Math.sin(theta) * at;
176 frameAccX.pixels[y][x] = (float) ((ax + triMaxAcc) / (2 * triMaxAcc));
177 frameAccY.pixels[y][x] = (float) ((ay + triMaxAcc) / (2 * triMaxAcc));
178 frameAccMag.pixels[y][x] = (float) (Math.abs(at) / (triMaxAcc));
179 } else if (rotClockMask.pixels[y][x] > 0.5) {
180 frame.pixels[y][x] = rotClockImage.pixels[y][x];
181
182
183 final double dx = x - 650, dy = y - 150, r = Math.sqrt(dx * dx + dy * dy);
184 final double vt = r * 50;
185 final double vx = Math.cos(50 * t) * vt;
186 final double vy = Math.sin(50 * t) * vt;
187
188 frameVelX.pixels[y][x] = (float) ((vx + clockMaxSpeed) / (2 * clockMaxSpeed));
189 frameVelY.pixels[y][x] = (float) ((vy + clockMaxSpeed) / (2 * clockMaxSpeed));
190 frameVelMag.pixels[y][x] = (float) (Math.abs(vt) / (clockMaxSpeed));
191
192
193
194 } else if (transLinBallMask.pixels[y][x] > 0.5) {
195 frame.pixels[y][x] = transLinBallImage.pixels[y][x];
196
197
198 frameVelX.pixels[y][x] = (float) (3000f / (2 * linBallMaxSpeed));
199 frameVelMag.pixels[y][x] = (float) (3000f / linBallMaxSpeed);
200
201
202
203 } else if (transAccBallMask.pixels[y][x] > 0.5) {
204 frame.pixels[y][x] = transAccBallImage.pixels[y][x];
205
206
207 frameVelX.pixels[y][x] = (float) (500000 * t / (2 * accBallMaxSpeed));
208 frameVelMag.pixels[y][x] = (float) (500000 * t / accBallMaxSpeed);
209
210
211 frameAccX.pixels[y][x] = (float) (500000 / (2 * accBallMaxAcc));
212 frameAccMag.pixels[y][x] = (float) (500000 / accBallMaxAcc);
213 } else {
214 frame.pixels[y][x] = background.pixels[y][x];
215 }
216 }
217 }
218
219 DisplayUtilities.displayName(frame, "");
220 DisplayUtilities.displayName(frameVelX, "Vx");
221 DisplayUtilities.displayName(frameVelY, "Vy");
222 DisplayUtilities.displayName(frameVelMag, "Velocity Magnitude");
223 DisplayUtilities.displayName(frameAccX, "Ax");
224 DisplayUtilities.displayName(frameAccY, "Ay");
225 DisplayUtilities.displayName(frameAccMag, "Acceleration Magnitude");
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241 }
242 }
243
244 private static FImage rotate(final FImage image, double angle, float px, float py) {
245 final Matrix transform = TransformUtilities.rotationMatrixAboutPoint(angle, px, py);
246 final FProjectionProcessor pp = new FProjectionProcessor();
247 pp.setMatrix(transform);
248 pp.accumulate(image);
249 return pp.performProjection(true, 0f);
250 }
251
252 private static FImage translate(final FImage image, float x, float y) {
253 final Matrix transform = TransformUtilities.translateMatrix(x, y);
254 final FProjectionProcessor pp = new FProjectionProcessor();
255 pp.setMatrix(transform);
256 pp.accumulate(image);
257 return pp.performProjection(true, 0f);
258 }
259 }