/Users/lyon/j4p/src/bookExamples/ch26Graphics/draw2d/SketchFrame.java
|
1 package bookExamples.ch26Graphics.draw2d;
2
3 import j2d.ImageUtils;
4 import graphics.dclap.SavePICT;
5 import ip.gui.frames.ColorGridFrame;
6 import ip.gui.frames.ShortCutFrame;
7 import ip.gui.frames.XformFrame;
8 import math.Mat3;
9
10 import java.awt.*;
11 import java.awt.event.ActionEvent;
12 import java.awt.event.MouseEvent;
13 import java.awt.event.MouseListener;
14 import java.awt.event.MouseMotionListener;
15 import java.io.FileOutputStream;
16 import java.io.IOException;
17 import java.io.OutputStream;
18
19 public class SketchFrame extends ShortCutFrame
20 implements MouseListener, MouseMotionListener {
21
22 MenuBar mb = new MenuBar();
23
24 Menu transformMenu = new Menu("Transform");
25 Menu fileMenu = new Menu("File");
26
27 Menu pointMenu = new Menu("Point...");
28
29
30 MenuItem rotate_mi =
31 addMenuItem(transformMenu, "[r]otate");
32 MenuItem scale_mi =
33 addMenuItem(transformMenu, "scale - xy");
34 MenuItem scalex_mi =
35 addMenuItem(transformMenu, "[X]scale - x");
36 MenuItem scaley_mi =
37 addMenuItem(transformMenu, "[Y]scale - y");
38 MenuItem scaleRotate_mi =
39 addMenuItem(transformMenu, "[*]scalexy+rotate");
40 MenuItem shearx_mi =
41 addMenuItem(transformMenu, "shear x");
42 MenuItem sheary_mi =
43 addMenuItem(transformMenu, "[y]shear y");
44 MenuItem shearRotate_mi =
45 addMenuItem(transformMenu, "[R]otate+shear");
46 MenuItem revert_mi =
47 addMenuItem(transformMenu, "[E-R]evert to saved");
48 MenuItem apply_mi =
49 addMenuItem(transformMenu, "[a]pply transform");
50 MenuItem applyBilinear4Points_mi =
51 addMenuItem(transformMenu, "[4]applyBilinear4Points");
52 MenuItem colorize_mi =
53 addMenuItem(transformMenu, "[c]olorize");
54 MenuItem saveAsPict_mi =
55 addMenuItem(fileMenu, "[s]ave as pict...");
56 MenuItem print_mi =
57 addMenuItem(fileMenu, "print...");
58
59 MenuItem movePoint0_mi =
60 addMenuItem(pointMenu, "[E-0]move point 0");
61 MenuItem movePoint1_mi =
62 addMenuItem(pointMenu, "[E-1]move point 1");
63 MenuItem movePoint2_mi =
64 addMenuItem(pointMenu, "[E-2]move point 2");
65 MenuItem movePoint3_mi =
66 addMenuItem(pointMenu, "[E-3]move point 3");
67 MenuItem movePointd_mi =
68 addMenuItem(pointMenu, "[E-d]dont move points");
69 MenuItem printPoints_mi =
70 addMenuItem(pointMenu, "print points");
71
72 MenuItem selection = rotate_mi;
73
74 private Polygon p = new Polygon();
75 Mat3 at;
76 int x1 = 0;
77 int y1 = 0;
78 int width;
79 int height;
80 int centroid[] = {width / 2, height / 2};
81 int xtranslate = width;
82 int ytranslate = height;
83
84 int pointToMove = -1;
85
86 private void print() {
87 ImageUtils.print(this);
88 }
89
90 public Polygon getPolygon() {
91 return at.transform(p);
92 }
93
94 public void actionPerformed(ActionEvent e) {
95
96 if (match(e, saveAsPict_mi)) {
97 saves();
98 return;
99 }
100 if (match(e, print_mi)) {
101 print();
102 return;
103 }
104 if (match(e, printPoints_mi)) {
105 printPoints();
106 return;
107 }
108 if (match(e, colorize_mi)) {
109 ColorGridFrame cgf = new ColorGridFrame(this);
110 return;
111 }
112 if (match(e, movePointd_mi)) {
113 pointToMove = -1;
114 return;
115 }
116 if (match(e, movePoint0_mi)) {
117 pointToMove = 0;
118 return;
119 }
120 if (match(e, movePoint1_mi)) {
121 pointToMove = 1;
122 return;
123 }
124 if (match(e, movePoint2_mi)) {
125 pointToMove = 2;
126 return;
127 }
128 if (match(e, movePoint3_mi)) {
129 pointToMove = 3;
130 return;
131 }
132 if (match(e, revert_mi)) {
133 revert();
134 return;
135 }
136 if (match(e, rotate_mi)) {
137 selection = rotate_mi;
138 return;
139 }
140
141 if (match(e, apply_mi)) {
142 apply();
143 return;
144 }
145 if (match(e, shearRotate_mi)) {
146 selection = shearRotate_mi;
147 return;
148 }
149 if (match(e, scaleRotate_mi)) {
150 selection = scaleRotate_mi;
151 return;
152 }
153 if (match(e, scale_mi)) {
154 selection = scale_mi;
155 return;
156 }
157 if (match(e, scalex_mi)) {
158 selection = scalex_mi;
159 return;
160 }
161 if (match(e, scaley_mi)) {
162 selection = scaley_mi;
163 return;
164 }
165 if (match(e, shearx_mi)) {
166 selection = shearx_mi;
167 return;
168 }
169 if (match(e, sheary_mi)) {
170 selection = sheary_mi;
171 return;
172 }
173 super.actionPerformed(e);
174 }
175
176 SketchFrame(String title, XformFrame _xf, int w, int h) {
177 super(title);
178 width = w;
179 height = w;
180 init();
181 addMouseListener(this);
182 addMouseMotionListener(this);
183 transformMenu.add(pointMenu);
184 mb.add(fileMenu);
185 mb.add(transformMenu);
186 setMenuBar(mb);
187 }
188
189 // p0 p1
190 // p3 p2
191 private void init() {
192 int x2 = x1 + width / 2;
193 int y2 = y1 + height / 2;
194 p.addPoint(x1, y1);
195 p.addPoint(x2, y1);
196 p.addPoint(x2, y2);
197 p.addPoint(x1, y2);
198 centroid = Mat3.centroid(p);
199 setPose(0, 1, 1);
200
201 }
202
203 private void revert() {
204 p = new Polygon();
205 init();
206 repaint();
207 }
208
209 public void setPose(double theta, double sx, double sy) {
210 Mat3 tr1 = new Mat3();
211 Mat3 tr2 = new Mat3();
212 Mat3 rt = new Mat3();
213 Mat3 sc = new Mat3();
214 centroid = rt.centroid(p);
215
216 tr1.setTranslation(centroid[0], centroid[1]);
217 sc.setScale(sx, sy);
218 rt.setRotation(theta);
219 tr2.setTranslation(-centroid[0], -centroid[1]);
220 at = tr1.multiply(rt);
221 at = at.multiply(sc);
222 at = at.multiply(tr2);
223
224 }
225
226 public void setShear(double theta, double shx, double shy) {
227 Mat3 tr1 = new Mat3();
228 Mat3 tr2 = new Mat3();
229 Mat3 rt = new Mat3();
230 Mat3 sc = new Mat3();
231 centroid = rt.centroid(p);
232
233 tr1.setTranslation(centroid[0], centroid[1]);
234 sc.setShear(shx, shy);
235 rt.setRotation(theta);
236 tr2.setTranslation(-centroid[0], -centroid[1]);
237 at = tr1.multiply(rt);
238 at = at.multiply(sc);
239 at = at.multiply(tr2);
240
241 }
242
243 public static void main(String args[]) {
244 SketchFrame af = new SketchFrame(
245 "SketchFrame", new XformFrame("SketchFrame"), 100, 100);
246 af.setSize(150, 150);
247 af.setVisible(true);
248 }
249
250 public void drawPolygon(Graphics g, Polygon p) {
251 int n = p.xpoints.length;
252 for (int i = 0; i < n - 1; i++)
253 g.drawLine(p.xpoints[i], p.ypoints[i],
254 p.xpoints[i + 1], p.ypoints[i + 1]);
255 g.drawLine(p.xpoints[0], p.ypoints[0],
256 p.xpoints[n - 1], p.ypoints[n - 1]);
257 }
258
259 public void paint2(Graphics g) {
260 Font f = new Font("Serif", Font.PLAIN, 12);
261 g.setFont(f);
262 Polygon pt = at.transform(p);
263 g.translate(50, 50);
264 drawPolygon(g, pt);
265 for (int i = 0; i < pt.npoints; i++)
266 g.drawString("p" + i, pt.xpoints[i], pt.ypoints[i]);
267 Rectangle r = pt.getBounds();
268 g.drawString("h=" + r.height + " w=" + r.width, r.height / 2, r.width / 2);
269 }
270
271 public void paint(Graphics g) {
272 Font f = new Font("Serif", Font.PLAIN, 12);
273 g.setFont(f);
274 g.translate(50, 50);
275 for (float theta = 0; theta < 360; theta += 10f) {
276 setPose(theta, sin(theta), sin(theta));
277 Polygon pt = at.transform(p);
278 drawPolygon(g, pt);
279 }
280 }
281
282 public static final double PI_ON_180
283 = Math.PI / 180f;
284
285 public float sin(float theta) {
286 return
287 (float) Math.sin(theta * PI_ON_180);
288 }
289
290 public float cos(float theta) {
291 return
292 (float) Math.cos(theta * PI_ON_180);
293 }
294
295 public void apply() {
296 p = at.transform(p);
297 }
298
299 public void movePoints(MouseEvent e) {
300 int i = pointToMove;
301 p.xpoints[i] = getX(e);
302 p.ypoints[i] = getY(e);
303 repaint();
304 }
305
306 public void printPoints() {
307 for (int i = 0; i < p.xpoints.length; i++) {
308 System.out.println("af.setPoint(" + i + "," + p.xpoints[i] + "," + p.ypoints[i] + ");");
309 }
310 }
311
312 public void setPoint(int i, int x, int y) {
313 p.xpoints[i] = x;
314 p.ypoints[i] = y;
315 repaint();
316 }
317
318 public void translatePoints(int x, int y) {
319 for (int i = 0; i < p.xpoints.length; i++) {
320 p.xpoints[i] += x;
321 p.ypoints[i] += y;
322 }
323 }
324
325 private int getX(MouseEvent e) {
326 return (int) (e.getX() - xtranslate);
327 }
328
329 private int getY(MouseEvent e) {
330 return (int) (e.getY() - ytranslate);
331 }
332
333 public void mousePressed(MouseEvent e) {
334 }
335
336 public void mouseExited(MouseEvent e) {
337 }
338
339 public void mouseEntered(MouseEvent e) {
340 }
341
342 public void mouseClicked(MouseEvent e) {
343 }
344
345 public void mouseReleased(MouseEvent e) {
346
347 }
348
349 public void mouseDragged(MouseEvent e) {
350 e.consume();
351 double dx = getX(e) - centroid[0];
352 double dy = getY(e) - centroid[1];
353 double sx = 2 * Math.sqrt(dx * dx + dy * dy) / getSize().width;
354 double sy = sx;
355 double theta = Math.atan2(dy, dx) * 180 / Math.PI;
356 double shx = Math.abs(dx) / getSize().width;
357 double shy = Math.abs(dy) / getSize().height;
358 if (pointToMove != -1) {
359 movePoints(e);
360 return;
361 }
362 if (selection == rotate_mi) {
363 setPose(theta, 1, 1);
364 }
365 if (selection == scale_mi) {
366 setPose(0, sx, sy);
367 }
368 if (selection == scalex_mi) {
369 setPose(0, sx, 1);
370 }
371 if (selection == scaley_mi) {
372 setPose(0, 1, sy);
373 }
374 if (selection == scaleRotate_mi) {
375 setPose(theta, sx, sy);
376 }
377 if (selection == shearx_mi) {
378 setShear(0, shx, 0);
379 }
380 if (selection == sheary_mi) {
381 setShear(0, 0, shy);
382 }
383 if (selection == shearRotate_mi) {
384 setShear(theta, shx, shy);
385 }
386 repaint();
387 }
388
389 public void mouseMoved(MouseEvent e) {
390 }
391
392 private void saves2() {
393 ImageUtils.print(this);
394 }
395
396 private void saves() {
397 FileDialog fd = new FileDialog(this,
398 "Enter a pict file name", FileDialog.SAVE);
399 fd.show();
400 fd.setVisible(false);
401 String fn = fd.getDirectory() + fd.getFile();
402 //if usr canceled, return
403 if (fd.getFile() == null) return;
404 try {
405 FileOutputStream fos =
406 new FileOutputStream(fn);
407 Component c = this;
408 SavePICT p = new SavePICT();
409 p.saveAsPict(c, (OutputStream) fos);
410 fos.close();
411
412 } catch (IOException e) {
413 System.out.println(e);
414 }
415 }
416
417
418 }