/Users/lyon/j4p/src/ip/gui/frames/DotArrayFrame.java
|
1 package ip.gui.frames;
2
3 import math.Mat3;
4
5 import java.awt.*;
6 import java.awt.event.ActionEvent;
7 import java.awt.event.MouseEvent;
8 import java.awt.event.MouseListener;
9 import java.awt.event.MouseMotionListener;
10
11 public class DotArrayFrame extends ShortCutFrame
12 implements MouseListener, MouseMotionListener {
13
14 XformFrame xf = null;
15
16 MenuBar mb = new MenuBar();
17 Menu transformMenu = getMenu("Transform");
18 Menu pointMenu = getMenu("Point...");
19
20 MenuItem revert_mi = addMenuItem(
21 transformMenu, "[l]oad image from file");
22 MenuItem applyBilinear4Points_mi = addMenuItem(
23 transformMenu, "[a]applyBilinear4Points");
24
25 MenuItem movePointd_mi = addMenuItem(
26 pointMenu, "[d]ont move points");
27 MenuItem printPoints_mi = addMenuItem(
28 pointMenu, "[p]rint points");
29 MenuItem selection = movePointd_mi;
30
31 private Polygon p = new Polygon();
32 Image img = null;
33 boolean doRevert = false;
34 short rn[][];
35 short gn[][];
36 short bn[][];
37 Mat3 at;
38 int x1 = 0;
39 int y1 = 0;
40 int xPoints = 5; //grid X
41 int yPoints = 5; //grid Y
42 boolean busy = false;
43 int width;
44 int height;
45 int centroid[] = {width / 2, height / 2};
46 int xtranslate = 10;
47 int ytranslate = 50;
48
49 int pointToMove = -1;
50
51 public Polygon getPolygon() {
52 return at.transform(p);
53 }
54
55 public void actionPerformed(ActionEvent e) {
56 if (match(e, printPoints_mi)) {
57 printPoints();
58 return;
59 }
60 if (match(e, movePointd_mi)) {
61 pointToMove = -1;
62 return;
63 }
64 if (match(e, applyBilinear4Points_mi)) {
65 xf.revert();
66 applyBilinear();
67 return;
68 }
69 if (match(e, revert_mi)) {
70 revert();
71 return;
72 }
73 super.actionPerformed(e);
74 }
75
76 public DotArrayFrame(String title, TopFrame _xf) {
77 super(title);
78 xf = _xf;
79 width = xf.getImageWidth();
80 height = xf.getImageHeight();
81 init();
82 addMouseListener(this);
83 addMouseMotionListener(this);
84 transformMenu.add(pointMenu);
85 mb.add(transformMenu);
86 setMenuBar(mb);
87 setSize(width, height);
88 }
89
90 private void init() {
91 for (int i = 0; i <= yPoints; i++)
92 for (int j = 0; j <= xPoints; j++)
93 p.addPoint((int) (j * width / xPoints), (int) (i * height / yPoints));
94 centroid = Mat3.centroid(p);
95 setPose(0, 1, 1);
96 }
97
98 private void revert() {
99 xf.revert();
100 width = xf.getImageWidth();
101 height = xf.getImageHeight();
102 img = xf.getImage();
103 doRevert = true;
104 p = new Polygon();
105 init();
106 setSize(width + 2 * xtranslate, height + ytranslate + 15);
107 repaint();
108 }
109
110 public void setPose(double theta, double sx, double sy) {
111 Mat3 tr1 = new Mat3();
112 Mat3 tr2 = new Mat3();
113 Mat3 rt = new Mat3();
114 Mat3 sc = new Mat3();
115 centroid = rt.centroid(p);
116
117 tr1.setTranslation(centroid[0], centroid[1]);
118 sc.setScale(sx, sy);
119 rt.setRotation(theta);
120 tr2.setTranslation(-centroid[0], -centroid[1]);
121 at = tr1.multiply(rt);
122 at = at.multiply(sc);
123 at = at.multiply(tr2);
124 }
125
126
127 public void update(Graphics g) {
128 paint(g);
129 }
130
131 public void paint(Graphics g) {
132 if (doRevert) {
133 if ((img != null))
134 g.drawImage(img, xtranslate, ytranslate, width, height, this);
135 }
136 Polygon pt = at.transform(p);
137 g.translate(xtranslate, ytranslate);
138 for (int i = 0; i <= yPoints; i++)
139 for (int j = 0; j <= xPoints; j++) {
140 if (j != (xPoints))
141 g.drawLine(pt.xpoints[j + i * (xPoints + 1)],
142 pt.ypoints[j + i * (xPoints + 1)],
143 pt.xpoints[j + 1 + i * (xPoints + 1)],
144 pt.ypoints[j + 1 + i * (xPoints + 1)]);
145 if (i != (yPoints))
146 g.drawLine(pt.xpoints[j + i * (xPoints + 1)],
147 pt.ypoints[j + i * (xPoints + 1)],
148 pt.xpoints[j + (i + 1) * (xPoints + 1)],
149 pt.ypoints[j + (i + 1) * (xPoints + 1)]);
150 }
151 for (int i = 0; i < pt.npoints; i++)
152 g.drawRect(pt.xpoints[i] - 2, pt.ypoints[i] - 2, 4, 4);
153 }
154
155 public void applyBilinear() {
156 rn = new short[width][height];
157 gn = new short[width][height];
158 bn = new short[width][height];
159
160 for (int i = 0; i < yPoints; i++)
161 for (int j = 0; j < xPoints; j++) {
162 Polygon sourcePoly = new Polygon();
163 sourcePoly.addPoint((int) (j * width / xPoints), (int) (i * height / yPoints));
164 sourcePoly.addPoint((int) ((j + 1) * width / xPoints), (int) (i * height / yPoints));
165 sourcePoly.addPoint((int) ((j + 1) * width / xPoints), (int) ((i + 1) * height / yPoints));
166 sourcePoly.addPoint((int) (j * width / xPoints), (int) ((i + 1) * height / yPoints));
167 Polygon destPoly = new Polygon();
168 destPoly.addPoint(p.xpoints[j + i * (xPoints + 1)], p.ypoints[j + i * (xPoints + 1)]);
169 destPoly.addPoint(p.xpoints[j + 1 + i * (xPoints + 1)], p.ypoints[j + 1 + i * (xPoints + 1)]);
170 destPoly.addPoint(p.xpoints[j + 1 + (i + 1) * (xPoints + 1)], p.ypoints[j + 1 + (i + 1) * (xPoints + 1)]);
171 destPoly.addPoint(p.xpoints[j + (i + 1) * (xPoints + 1)], p.ypoints[j + (i + 1) * (xPoints + 1)]);
172 solve(sourcePoly, destPoly);
173 }
174 short[][] r = rn;
175 xf.shortImageBean.setR(r);
176 xf.setG(gn);
177 xf.setB(bn);
178 xf.short2Image();
179 }
180
181 int Dist(Point a, Point b) {
182 return (int) (Math.sqrt(((b.x - a.x) * (b.x - a.x)) + ((b.y - a.y) * (b.y - a.y))));
183 }
184
185 public void solve(Polygon S, Polygon D) {
186 int w = width;
187 int h = height;
188 double xStart1, xEnd1,yStart1, yEnd1;
189 double xStart2, xEnd2,yStart2, yEnd2;
190 Point s0,s1,s2,s3,d0,d1,d2,d3;
191 int MAX = 0;
192 int MAX1 = 0;
193 int xc, yc, xp, yp;
194 s0 = new Point(S.xpoints[0], S.ypoints[0]);
195 s1 = new Point(S.xpoints[1], S.ypoints[1]);
196 s2 = new Point(S.xpoints[2], S.ypoints[2]);
197 s3 = new Point(S.xpoints[3], S.ypoints[3]);
198 d0 = new Point(D.xpoints[0], D.ypoints[0]);
199 d1 = new Point(D.xpoints[1], D.ypoints[1]);
200 d2 = new Point(D.xpoints[2], D.ypoints[2]);
201 d3 = new Point(D.xpoints[3], D.ypoints[3]);
202
203 MAX = Dist(d0, d1);
204 MAX1 = Dist(d1, d2);
205 if (MAX1 > MAX) MAX = MAX1;
206 MAX1 = Dist(d2, d3);
207 if (MAX1 > MAX) MAX = MAX1;
208 MAX1 = Dist(d3, d0);
209 if (MAX1 > MAX) MAX = MAX1;
210
211 MAX1 = Dist(s0, s1);
212 if (MAX1 > MAX) MAX = MAX1;
213 MAX1 = Dist(s1, s2);
214 if (MAX1 > MAX) MAX = MAX1;
215 MAX1 = Dist(s2, s3);
216 if (MAX1 > MAX) MAX = MAX1;
217 MAX1 = Dist(s3, s0);
218 if (MAX1 > MAX) MAX = MAX1;
219 MAX = MAX + 20;
220
221 for (int i = 0; i < MAX; i++) {
222 xStart1 = d0.x + ((d3.x - d0.x) * i / MAX);
223 xEnd1 = d1.x + ((d2.x - d1.x) * i / MAX);
224
225 yStart1 = d0.y + ((d3.y - d0.y) * i / MAX);
226 yEnd1 = d1.y + ((d2.y - d1.y) * i / MAX);
227
228 xStart2 = s0.x + ((s3.x - s0.x) * i / MAX);
229 xEnd2 = s1.x + ((s2.x - s1.x) * i / MAX);
230
231 yStart2 = s0.y + ((s3.y - s0.y) * i / MAX);
232 yEnd2 = s1.y + ((s2.y - s1.y) * i / MAX);
233
234 for (int j = 0; j < MAX; j++) {
235 xc = (int) (xStart1 + ((xEnd1 - xStart1) * j / MAX));
236 yc = (int) (yStart1 + ((yEnd1 - yStart1) * j / MAX));
237 xp = (int) (xStart2 + ((xEnd2 - xStart2) * j / MAX));
238 yp = (int) (yStart2 + ((yEnd2 - yStart2) * j / MAX));
239
240 if ((xp < w) && (yp < h) &&
241 (xp >= 0) &&
242 (yp >= 0) && (xc < w) && (yc < h) &&
243 (xc >= 0) && (yc >= 0)) {
244 rn[xc][yc] = xf.shortImageBean.getR()[xp][yp];
245 gn[xc][yc] = xf.shortImageBean.getG()[xp][yp];
246 bn[xc][yc] = xf.shortImageBean.getB()[xp][yp];
247 }
248 }
249 }
250 }
251
252 public void movePoints(MouseEvent e) {
253 int i = pointToMove;
254 p.xpoints[i] = getX(e);
255 p.ypoints[i] = getY(e);
256 repaint();
257 }
258
259 public void printPoints() {
260 for (int i = 0; i < p.xpoints.length; i++) {
261 System.out.println("af.setPoint(" + i + "," + p.xpoints[i] + "," + p.ypoints[i] + ");");
262 }
263 }
264
265 public void setPoint(int i, int x, int y) {
266 p.xpoints[i] = x;
267 p.ypoints[i] = y;
268 repaint();
269 }
270
271 private int getX(MouseEvent e) {
272 return (int) (e.getX() - xtranslate);
273 }
274
275 private int getY(MouseEvent e) {
276 return (int) (e.getY() - ytranslate);
277 }
278
279 public void mousePressed(MouseEvent e) {
280 }
281
282 public void mouseExited(MouseEvent e) {
283 }
284
285 public void mouseEntered(MouseEvent e) {
286 }
287
288 public void mouseClicked(MouseEvent e) {
289 }
290
291 public void mouseReleased(MouseEvent e) {
292 busy = false;
293 repaint();
294 }
295
296 public void mouseDragged(MouseEvent e) {
297 e.consume();
298 double dx = getX(e);
299 double dy = getY(e);
300 double sx, sy;
301 double ray = 100000;
302 if (!busy) {
303 busy = true;
304 pointToMove = -1;
305 for (int i = 0; i < p.npoints; i++) {
306 sx = (p.xpoints[i] - dx) * (p.xpoints[i] - dx);
307 sy = (p.ypoints[i] - dy) * (p.ypoints[i] - dy);
308 if ((sx + sy) < ray) {
309 ray = sx + sy;
310 pointToMove = i;
311 }
312 }
313 }
314 if (pointToMove != -1) {
315 movePoints(e);
316 return;
317 }
318 repaint();
319 }
320
321 public void mouseMoved(MouseEvent e) {
322 }
323
324 }
325