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