/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