/Users/lyon/j4p/src/ip/gui/frames/XformFrame.java
|
1 package ip.gui.frames;
2
3 import ip.gui.dialog.RotoLog;
4 import ip.transforms.TransformTable;
5 import j2d.ShortImageBean;
6 import math.Mat3;
7 import math.Mat4;
8
9 import java.awt.*;
10 import java.awt.event.ActionEvent;
11
12 public class XformFrame extends ColorFrame {
13
14 private AffineFrame af = null;
15
16
17 private Menu xformMenu = getMenu("Xform");
18 private MenuItem showAffineFrame_mi =
19 addMenuItem(xformMenu, "[T-A]Show affine frame..");
20 private MenuItem showDotArrayFrame_mi =
21 addMenuItem(xformMenu, "[T-D]ot array..");
22
23 private Menu turnMenu = getMenu("Turn");
24 private MenuItem turn90_mi =
25 addMenuItem(turnMenu, "[E-9]0 turn and back");
26 private MenuItem turn180_mi =
27 addMenuItem(turnMenu, "[T-1] turn 90 increments");
28 private MenuItem mirror_mi =
29 addMenuItem(turnMenu, "[T-m] mirror");
30 private MenuItem rotate_mi =
31 addMenuItem(turnMenu, "rotate...");
32
33
34
35 public void copyToChildFrame() {
36 ShortImageBean sib = super.getShortImageBean();
37 ShortImageBean nsib =
38 ShortImageBean.getShortImageBean(sib);
39 setChild(new TopFrame(
40 "Child",
41 nsib));
42 }
43
44 public void actionPerformed(ActionEvent e) {
45
46
47 if (match(e, showDotArrayFrame_mi)) {
48 showDotArrayFrame();
49 return;
50 }
51 if (match(e, mirror_mi)) {
52 mirror();
53 return;
54 }
55 if (match(e, showAffineFrame_mi)) {
56 showAffineFrame();
57 return;
58 }
59 if (match(e, turn180_mi)) {
60 turn180();
61 return;
62 }
63 if (match(e, turn90_mi)) {
64 turn90();
65 return;
66 }
67 if (match(e, rotate_mi)) {
68 rotate();
69 return;
70 }
71 super.actionPerformed(e);
72
73 }
74
75 public void showDotArrayFrame() {
76 DotArrayFrame af = new DotArrayFrame(
77 "DotArray", new TopFrame("TopFrame"));
78 af.setVisible(true);
79
80 }
81
82 public void setPose(double theta, double sx, double sy) {
83 Mat3 tr1 = new Mat3();
84 Mat3 tr2 = new Mat3();
85 Mat3 rt = new Mat3();
86 Mat3 sc = new Mat3();
87 Mat3 at;
88 int xc = getImageWidth() / 2;
89 int yc = getImageHeight() / 2;
90 tr1.setTranslation(xc, yc);
91 sc.setScale(sx, sy);
92 rt.setRotation(theta);
93 tr2.setTranslation(-xc, -yc);
94 at = tr1.multiply(rt);
95 at = at.multiply(sc);
96 at = at.multiply(tr2);
97 xform(at);
98 }
99
100 public void setPoseFeedback(double theta, double sx, double sy) {
101 Mat3 tr1 = new Mat3();
102 Mat3 tr2 = new Mat3();
103 Mat3 rt = new Mat3();
104 Mat3 sc = new Mat3();
105 Mat3 at;
106 int xc = getImageWidth() / 2;
107 int yc = getImageHeight() / 2;
108 tr1.setTranslation(xc, yc);
109 sc.setScale(sx, sy);
110 rt.setRotation(theta);
111 tr2.setTranslation(-xc, -yc);
112 at = tr1.multiply(rt);
113 at = at.multiply(sc);
114 at = at.multiply(tr2);
115 xformFeedback(at);
116 }
117
118 public void turn(double angle) {
119 setPose(angle, 1, 1);
120 }
121
122 public void turnFeedback(double angle) {
123 setPoseFeedback(angle, 1, 1);
124 }
125
126 public void mirror() {
127 turn90();
128 turn180();
129 }
130
131 public void turn90() {
132 short ro[][] = new short[shortImageBean.getR()[0].length][shortImageBean.getR().length];
133 short go[][] = new short[shortImageBean.getR()[0].length][shortImageBean.getR().length];
134 short bo[][] = new short[shortImageBean.getR()[0].length][shortImageBean.getR().length];
135 for (int x = 0; x < shortImageBean.getR().length; x++)
136 for (int y = 0; y < shortImageBean.getR()[0].length; y++) {
137 ro[y][x] = shortImageBean.getR()[x][y];
138 go[y][x] = shortImageBean.getG()[x][y];
139 bo[y][x] = shortImageBean.getB()[x][y];
140 }
141 shortImageBean.setR(ro);
142 setG(go);
143 setB(bo);
144 setImageHeight(shortImageBean.getR().length);
145 setImageWidth(shortImageBean.getR()[0].length);
146 short2Image();
147 }
148
149 public void turn180() {
150 short ro[][] = new short[shortImageBean.getR()[0].length][shortImageBean.getR().length];
151 short go[][] = new short[shortImageBean.getR()[0].length][shortImageBean.getR().length];
152 short bo[][] = new short[shortImageBean.getR()[0].length][shortImageBean.getR().length];
153 for (
154 int y = 0,k = shortImageBean.getR()[0].length - 1;
155 y < shortImageBean.getR()[0].length; y++, k--)
156 for (int x = 0; x < shortImageBean.getR().length; x++) {
157 ro[k][x] = shortImageBean.getR()[x][y];
158 go[k][x] = shortImageBean.getG()[x][y];
159 bo[k][x] = shortImageBean.getB()[x][y];
160 }
161 shortImageBean.setR(ro);
162 setG(go);
163 setB(bo);
164 setImageHeight(shortImageBean.getR().length);
165 setImageWidth(shortImageBean.getR()[0].length);
166 short2Image();
167 }
168
169 public void showAffineFrame() {
170 Rectangle r = getBounds();
171 Dimension d = r.getSize();
172 af = new AffineFrame("Affine Frame", this, getImageWidth(), getImageHeight());
173 af.setLocation(d.width, d.height);
174 af.setSize(150, 150);
175 af.setVisible(true);
176 }
177
178 /* fast invert map with maple....
179 // [x y] = [uv u v 1] * A;
180 // using destination scanning.
181 with(linalg):
182 readlib(C):
183 b:=vector([u*v, u, v,1]):
184 a:=array(0..3,0..1,[]):
185 c:=multiply(b,matrix(a)):
186 C(c,optimized);
187 */
188 public Point invertMap(double a[][], double u, double v) {
189 double t1 = u * v;
190 double c[] = new double[2];
191 c[0] = t1 * a[0][0] + u * a[1][0] + v * a[2][0] + a[3][0];
192 c[1] = t1 * a[0][1] + u * a[1][1] + v * a[2][1] + a[3][1];
193 return interpolateCoordinates(c);
194 }
195
196 // the dumb interpolation...
197 // This should be improved. DL...8/18/98
198 public Point interpolateCoordinates(double c[]) {
199 return new Point((int) c[0], (int) c[1]);
200 }
201
202 public void applyAffineFrame2() {
203 }
204
205 public Mat3 infer3PointA(Polygon sp, Polygon dp) {
206 // D3 is destination
207 // S3 is source
208 double s3 [][] = {
209 {(double)sp.xpoints[0], (double) sp.xpoints[1], (double) sp.xpoints[2]},
210 {(double) sp.ypoints[0], sp.ypoints[1], (double) sp.ypoints[2]},
211 {(double) 1, 1, 1}};
212 double d3 [][] = {
213 {(double) dp.xpoints[0], dp.xpoints[1], dp.xpoints[2]},
214 {(double) dp.ypoints[0], dp.ypoints[1], dp.ypoints[2]},
215 {1., 1., 1.}};
216 Mat3 d3Mat = new Mat3(d3);
217 Mat3 s3Mat = new Mat3(s3);
218 Mat3 s3MatInverse = s3Mat.invert();
219 Mat3 a = d3Mat.multiply(s3MatInverse);
220 return a;
221 }
222
223 public double[][] infer4PointA(Polygon sp, Polygon dp) {
224 // D is destination
225 // S is source
226 int xd[] = dp.xpoints;
227 int yd[] = dp.ypoints;
228 int xs[] = sp.xpoints;
229 int ys[] = sp.ypoints;
230
231 // d4 is a 2x4
232 double d4 [][] = {
233 {(double) xd[0], xd[1], xd[2], xd[3]},
234 {(double) yd[0], yd[1], yd[2], yd[3]},
235 };
236 // s4 is a 4x4
237 double s4[][] = {
238 {(double) xs[0], xs[1], xs[2], xs[3]},
239 {(double) ys[0], ys[1], ys[2], ys[3]},
240 {(double) xs[0] * ys[0], xs[1] * ys[1], xs[2] * ys[2], xs[3] * ys[3]},
241 {(double) 1, 1, 1, 1},
242 };
243 Mat4 s4Mat = new Mat4(s4);
244 Mat4 s4MatInverse = s4Mat.invert();
245 // 2x4*4x4 = 2x4
246 double[][] a = s4MatInverse.multiply2x4(d4);
247 return a;
248 }
249
250 // select one of two roots
251 // for a x**2 + bx + c
252 public double quadraticRoot(double a, double b, double c) {
253 if (a == 0) a = 0.00001;
254 double sqrtArg = b * b - 4 * a * c;
255 double aa = 2 * a;
256 if (sqrtArg < 0) return -b / aa; // ignore imaginary part.
257 double root1 = (-b + Math.sqrt(sqrtArg)) / aa;
258 double root2 = (-b - Math.sqrt(sqrtArg)) / aa;
259 if ((root1 >= 0) && (root1 < getImageHeight())) return root1;
260 if ((root2 >= 0) && (root2 < getImageHeight())) return root2;
261 if (root1 > getImageHeight()) return getImageHeight();
262 return 0;
263 }
264
265 /*
266 eq1:=xp=(a[0,0]*x+a[0,1]*y+a[0,2]*x*y+a[0,3]);
267 eq2:=yp=(a[1,0]*x+a[1,1]*y+a[1,2]*x*y+a[1,3]);
268 solve({eq1,eq2},{x,y});
269 */
270 public double[] inverseMap4(double a[][], double xp, double yp) {
271 double as =
272 -a[1][1] * a[0][2]
273 + a[1][2] * a[0][1];
274 double b =
275 a[0][2] * yp + a[1][0] * a[0][1] - a[0][0] * a[1][1]
276 - a[1][2] * xp + a[1][2] * a[0][3] - a[0][2] * a[1][3];
277 double c = yp * a[0][0]
278 - a[1][0] * xp
279 + a[1][0] * a[0][3]
280 - a[1][3] * a[0][0];
281 double y = quadraticRoot(as, b, c);
282 double x =
283 (xp - a[0][1] * y - a[0][3]) / (a[0][0] + a[0][2] * y);
284 double p[] = {x, y};
285 return p;
286 }
287
288 public void applyBilinear4Points(
289 Polygon sourcePoly, Polygon destPoly) {
290 double a[][];
291 try {
292 a = infer4PointA(
293 sourcePoly,
294 destPoly);
295 inverseBilinearXform(a);
296 } catch (ArithmeticException e) {
297 System.out.println("error in user input, trying 3 point transform");
298 xform(
299 infer3PointA(sourcePoly, destPoly));
300 }
301
302 }
303
304 public void applyBilinear4PointsFeedback(
305 Polygon sourcePoly, Polygon destPoly) {
306 double a[][];
307 a = infer4PointA(
308 sourcePoly,
309 destPoly);
310 inverseBilinearXformfeedback(a);
311 }
312
313 public void applyBilinear4Points() {
314 Polygon sourcePoly = new Polygon();
315 // p0 p1
316 // p3 p2
317 sourcePoly.addPoint(0, 0);
318 sourcePoly.addPoint(getImageWidth(), 0);
319 sourcePoly.addPoint(getImageWidth(), getImageHeight());
320 sourcePoly.addPoint(0, getImageHeight());
321 Polygon destPoly = af.getPolygon();
322 applyBilinear4Points(sourcePoly, destPoly);
323 }
324
325 public void applyBilinear4PointsFeedback() {
326 Polygon sourcePoly = new Polygon();
327 // p0 p1
328 // p3 p2
329 sourcePoly.addPoint(0, 0);
330 sourcePoly.addPoint(getImageWidth(), 0);
331 sourcePoly.addPoint(getImageWidth(), getImageHeight());
332 sourcePoly.addPoint(0, getImageHeight());
333 Polygon destPoly = af.getPolygon();
334 applyBilinear4PointsFeedback(sourcePoly, destPoly);
335 }
336
337 public void inverseBilinearXform(double a[][]) {
338 int w = getImageWidth();
339 int h = getImageHeight();
340 short rn[][] = new short[w][h];
341 short gn[][] = new short[w][h];
342 short bn[][] = new short[w][h];
343 double p[] = new double[2];
344 int xp, yp;
345 for (int x = 0; x < w; x++)
346 for (int y = 0; y < h; y++) {
347 p = inverseMap4(a, x, y);
348 xp = (int) (p[0]);
349 yp = (int) (p[1]);
350 if ((xp < w - 1) && (yp < h - 1) && (xp > 0) && (yp > 0)) {
351 rn[x][y] = shortImageBean.getR()[xp][yp];
352 gn[x][y] = shortImageBean.getG()[xp][yp];
353 bn[x][y] = shortImageBean.getB()[xp][yp];
354 }
355 }
356 shortImageBean.setR(rn);
357 setG(gn);
358 setB(bn);
359 short2Image();
360 }
361
362 public void colorize() {
363 TransformTable tt = new TransformTable(256);
364 tt.randomize();
365 short lut[] = tt.getLut();
366 for (int y = 0; y < getImageHeight(); y++)
367 for (int x = 0; x < getImageWidth(); x++) {
368 shortImageBean.getR()[x][y] = lut[shortImageBean.getR()[x][y]];
369 shortImageBean.getG()[x][y] = shortImageBean.getR()[x][y];
370 shortImageBean.getB()[x][y] = shortImageBean.getR()[x][y];
371 }
372 short2Image();
373 }
374
375 public void zedSquare() {
376 int w = getImageWidth();
377 int h = getImageHeight();
378 int xc = w / 2;
379 int yc = h / 2;
380 short rn[][] = new short[getImageWidth()][getImageHeight()];
381 short gn[][] = new short[getImageWidth()][getImageHeight()];
382 short bn[][] = new short[getImageWidth()][getImageHeight()];
383 double p[] = new double[2];
384 int xp, yp;
385 double R = Math.sqrt(w * w / 4 + h * h / 4);
386 for (int x = 0; x < w; x++)
387 for (int y = 0; y < h; y++) {
388 double dx = x - xc;
389 double dy = y - yc;
390 double radius = Math.sqrt(dx * dx + dy * dy);
391 double a = (180 / Math.PI) * Math.atan2(dy, dx);
392
393
394 a = a * 2;
395 radius = radius * radius / R;
396
397
398 a = a * Math.PI / 180;
399
400 p[0] = radius * Math.cos(a);
401 p[1] = radius * Math.sin(a);
402 xp = (int) p[0] + xc;
403 yp = (int) p[1] + yc;
404 if ((xp < w) && (yp < h) && (xp >= 0) && (yp >= 0)) {
405 rn[x][y] = shortImageBean.getR()[xp][yp];
406 gn[x][y] = shortImageBean.getG()[xp][yp];
407 bn[x][y] = shortImageBean.getB()[xp][yp];
408 }
409 }
410 shortImageBean.setR(rn);
411 setG(gn);
412 setB(bn);
413 short2Image();
414 }
415
416 public void zedSquare(float dilate) {
417 int w = getImageWidth();
418 int h = getImageHeight();
419 int xc = w / 2;
420 int yc = h / 2;
421 short rn[][] = new short[getImageWidth()][getImageHeight()];
422 short gn[][] = new short[getImageWidth()][getImageHeight()];
423 short bn[][] = new short[getImageWidth()][getImageHeight()];
424 double p[] = new double[2];
425 int xp, yp;
426 double R = Math.sqrt(w * w / 4 + h * h / 4);
427 for (int x = 0; x < w; x++)
428 for (int y = 0; y < h; y++) {
429 double dx = x - xc;
430 double dy = y - yc;
431 double radius = Math.sqrt(dx * dx + dy * dy);
432 double a = (180 / Math.PI) * Math.atan2(dy, dx);
433
434
435 a = a * 2;
436 radius = radius * radius / R;
437
438
439 a = a * Math.PI / 180;
440 radius = dilate * radius;
441
442 p[0] = radius * Math.cos(a);
443 p[1] = radius * Math.sin(a);
444 xp = (int) p[0] + xc;
445 yp = (int) p[1] + yc;
446 if ((xp < w) && (yp < h) && (xp >= 0) && (yp >= 0)) {
447 rn[x][y] = shortImageBean.getR()[xp][yp];
448 gn[x][y] = shortImageBean.getG()[xp][yp];
449 bn[x][y] = shortImageBean.getB()[xp][yp];
450 }
451 }
452 shortImageBean.setR(rn);
453 setG(gn);
454 setB(bn);
455 short2Image();
456 }
457
458
459 public void inverseBilinearXformfeedback(double a[][]) {
460 int w = getImageWidth();
461 int h = getImageHeight();
462 double p[] = new double[2];
463 int xp, yp;
464 double startPoint[] = inverseMap4(a, 0, 0);
465 double endPoint[] = inverseMap4(a, w - 1, h - 1);
466 int x1 = (int) startPoint[0];
467 int y1 = (int) startPoint[1];
468 int x2 = (int) endPoint[0];
469 int y2 = (int) endPoint[1];
470 for (int x = x1; x < x2; x++)
471 for (int y = y1; y < y2; y++) {
472 p = inverseMap4(a, x, y);
473 xp = (int) (p[0]);
474 yp = (int) (p[1]);
475 if ((xp < w - 1) && (yp < h - 1) && (xp > 0) && (yp > 0)) {
476 shortImageBean.getR()[x][y] = shortImageBean.getR()[xp][yp];
477 shortImageBean.getG()[x][y] = shortImageBean.getG()[xp][yp];
478 shortImageBean.getB()[x][y] = shortImageBean.getB()[xp][yp];
479 }
480 }
481 short2Image();
482 }
483
484 public void applyAffineFrameThreePoints() {
485 Polygon sourcePoly = new Polygon();
486 sourcePoly.addPoint(0, 0);
487 sourcePoly.addPoint(getImageWidth(), 0);
488 sourcePoly.addPoint(getImageWidth(), getImageHeight());
489 xform(
490 infer3PointA(sourcePoly,
491 af.getPolygon()));
492 }
493
494 public void rotate() {
495 String prompts[] = {
496 "angle (degs):"
497 };
498
499 String defaults[] = {"0.0"};
500 String title = "Rotation Dialog";
501
502 new RotoLog(
503 this,
504 title,
505 prompts,
506 defaults, 9);
507 }
508
509
510 public XformFrame(String title) {
511 super(title);
512 MenuBar menuBar = getMenuBar();
513 xformMenu.add(turnMenu);
514 menuBar.add(xformMenu);
515 setMenuBar(menuBar);
516 }
517
518 public static void main(String args[]) {
519 String title = "Kahindu by D. Lyon";
520 if (args.length == 1)
521 title = args[0];
522 XformFrame xf =
523 new XformFrame(title);
524 xf.setVisible(true);
525 }
526
527 public void fishEye() {
528 fishEye(getImageWidth() / 2, getImageHeight() / 2, 2.1);
529 }
530
531 public void fishEye(double gamma) {
532 fishEye(getImageWidth() / 2, getImageHeight() / 2, gamma);
533 }
534
535 public void fishEye(int xc, int yc, double gamma) {
536 int w = getImageWidth();
537 int h = getImageHeight();
538 short rn[][] = new short[getImageWidth()][getImageHeight()];
539 short gn[][] = new short[getImageWidth()][getImageHeight()];
540 short bn[][] = new short[getImageWidth()][getImageHeight()];
541 double p[] = new double[2];
542 int xp, yp;
543 double R = Math.sqrt(w * w / 4 + h * h / 4);
544 for (int x = 0; x < w; x++)
545 for (int y = 0; y < h; y++) {
546 double dx = x - xc;
547 double dy = y - yc;
548 double radius = Math.sqrt(dx * dx + dy * dy);
549 // From [Holzmann] pp. 60
550 double u = Math.pow(radius, gamma) / R;
551 double a = Math.atan2(dy, dx);
552
553 p[0] = u * Math.cos(a);
554 p[1] = u * Math.sin(a);
555 xp = (int) p[0] + xc;
556 yp = (int) p[1] + yc;
557 if ((xp < w) && (yp < h) && (xp >= 0) && (yp >= 0)) {
558 rn[x][y] = shortImageBean.getR()[xp][yp];
559 gn[x][y] = shortImageBean.getG()[xp][yp];
560 bn[x][y] = shortImageBean.getB()[xp][yp];
561 }
562 }
563 shortImageBean.setR(rn);
564 setG(gn);
565 setB(bn);
566 short2Image();
567 }
568
569 public void polarTransform() {
570 int w = getImageWidth();
571 int h = getImageHeight();
572 int xc = w / 2;
573 int yc = h / 2;
574 short rn[][] = new short[getImageWidth()][getImageHeight()];
575 short gn[][] = new short[getImageWidth()][getImageHeight()];
576 short bn[][] = new short[getImageWidth()][getImageHeight()];
577 double p[] = new double[2];
578 int xp, yp;
579 for (int x = 0; x < w; x++)
580 for (int y = 0; y < h; y++) {
581 double dx = x - xc;
582 double dy = y - yc;
583 double radius = Math.sqrt(dx * dx + dy * dy);
584 double a = (180 / Math.PI) * Math.atan2(dy, dx);
585
586 a = a + radius;
587
588 a = a * Math.PI / 180;
589 p[0] = radius * Math.cos(a);
590 p[1] = radius * Math.sin(a);
591 xp = (int) p[0] + xc;
592 yp = (int) p[1] + yc;
593 if ((xp < w) && (yp < h) && (xp >= 0) && (yp >= 0)) {
594 rn[x][y] = shortImageBean.getR()[xp][yp];
595 gn[x][y] = shortImageBean.getG()[xp][yp];
596 bn[x][y] = shortImageBean.getB()[xp][yp];
597 }
598 }
599 shortImageBean.setR(rn);
600 setG(gn);
601 setB(bn);
602 short2Image();
603 }
604
605 public void polarTransform(double t, double ta) {
606 int w = getImageWidth();
607 int h = getImageHeight();
608 int xc = w / 2;
609 int yc = h / 2;
610 short rn[][] = new short[getImageWidth()][getImageHeight()];
611 short gn[][] = new short[getImageWidth()][getImageHeight()];
612 short bn[][] = new short[getImageWidth()][getImageHeight()];
613 double p[] = new double[2];
614 int xp, yp;
615 for (int x = 0; x < w; x++)
616 for (int y = 0; y < h; y++) {
617 double dx = x - xc;
618 double dy = y - yc;
619 double radius = (t * 2) * Math.sqrt(dx * dx + dy * dy);
620 double a = (180 / Math.PI) * Math.atan2(dy, dx);
621
622 a = a + radius;
623
624 a = ta * a * Math.PI / 180;
625 p[0] = radius * Math.cos(a);
626 p[1] = radius * Math.sin(a);
627 xp = (int) p[0] + xc;
628 yp = (int) p[1] + yc;
629 if ((xp < w) && (yp < h) && (xp >= 0) && (yp >= 0)) {
630 rn[x][y] = shortImageBean.getR()[xp][yp];
631 gn[x][y] = shortImageBean.getG()[xp][yp];
632 bn[x][y] = shortImageBean.getB()[xp][yp];
633 }
634 }
635 shortImageBean.setR(rn);
636 setG(gn);
637 setB(bn);
638 short2Image();
639 }
640
641 public void sqrt() {
642 sqrt(1.0);
643 }
644
645 public void sqrt(double t) {
646 int w = getImageWidth();
647 int h = getImageHeight();
648 int xc = w / 2;
649 int yc = h / 2;
650 short rn[][] = new short[getImageWidth()][getImageHeight()];
651 short gn[][] = new short[getImageWidth()][getImageHeight()];
652 short bn[][] = new short[getImageWidth()][getImageHeight()];
653 double p[] = new double[2];
654 int xp, yp;
655 double R = Math.sqrt(w * w / 4 + h * h / 4);
656 for (int x = 0; x < w; x++)
657 for (int y = 0; y < h; y++) {
658 double dx = x - xc;
659 double dy = y - yc;
660 double radius = t * Math.sqrt(dx * dx + dy * dy);
661 double a = (180 / Math.PI) * Math.atan2(dy, dx);
662 radius = Math.sqrt(radius * R);
663
664 a = t * a * Math.PI / 180;
665 p[0] = radius * Math.cos(a);
666 p[1] = radius * Math.sin(a);
667 xp = (int) p[0] + xc;
668 yp = (int) p[1] + yc;
669 if ((xp < w) && (yp < h) && (xp >= 0) && (yp >= 0)) {
670 rn[x][y] = shortImageBean.getR()[xp][yp];
671 gn[x][y] = shortImageBean.getG()[xp][yp];
672 bn[x][y] = shortImageBean.getB()[xp][yp];
673 }
674 }
675 shortImageBean.setR(rn);
676 setG(gn);
677 setB(bn);
678 short2Image();
679 }
680 //This is an example of an inverse mapping
681 public void xform(Mat3 transform) {
682
683 int w = getImageWidth();
684 int h = getImageHeight();
685 short rn[][] = new short[getImageWidth()][getImageHeight()];
686 short gn[][] = new short[getImageWidth()][getImageHeight()];
687 short bn[][] = new short[getImageWidth()][getImageHeight()];
688 int p[] = new int[3];
689 int xp, yp;
690 transform = transform.invert();
691 for (int x = 0; x < w; x++)
692 for (int y = 0; y < h; y++) {
693 p = transform.multiply(x, y, 1);
694 xp = (p[0] / p[2]);
695 yp = (p[1] / p[2]);
696 if ((xp < w) && (yp < h) && (xp >= 0) && (yp >= 0)) {
697 rn[x][y] = shortImageBean.getR()[xp][yp];
698 gn[x][y] = shortImageBean.getG()[xp][yp];
699 bn[x][y] = shortImageBean.getB()[xp][yp];
700 }
701 }
702 shortImageBean.setR(rn);
703 setG(gn);
704 setB(bn);
705 short2Image();
706 }
707
708 //This is an example of an inverse mapping
709 public void xformFeedback(Mat3 transform) {
710 int w = getImageWidth();
711 int h = getImageHeight();
712 int p[] = new int[3];
713 int xp, yp;
714 transform = transform.invert();
715 int startPoint[] = transform.multiply(0, 0, 1);
716 int endPoint[] = transform.multiply(w - 1, h - 1, 1);
717 for (int x = startPoint[0]; x < endPoint[0]; x++)
718 for (int y = startPoint[1]; y < endPoint[1]; y++) {
719 p = transform.multiply(x, y, 1);
720 xp = p[0];
721 yp = p[1];
722 if (x < 0 || x >= shortImageBean.getR().length) continue;
723 if (y < 0 || y >= shortImageBean.getR()[0].length) continue;
724 try {
725 if ((xp < w) && (yp < h) && (xp >= 0) && (yp >= 0)) {
726 shortImageBean.getR()[x][y] = shortImageBean.getR()[xp][yp];
727 shortImageBean.getG()[x][y] = shortImageBean.getG()[xp][yp];
728 shortImageBean.getB()[x][y] = shortImageBean.getB()[xp][yp];
729 }
730 } catch (Exception e) {
731 System.out.println(e +
732 "x,y=" + x + "," + y + " xp,yp=" + xp + "," + "yp");
733 break;
734 }
735 }
736 short2Image();
737 }
738
739 public AffineFrame getAf() {
740 return af;
741 }
742
743 public void setAf(AffineFrame af) {
744 this.af = af;
745 }
746
747 public Menu getXformMenu() {
748 return xformMenu;
749 }
750
751 public void setXformMenu(Menu xformMenu) {
752 this.xformMenu = xformMenu;
753 }
754 }
755
756
757