1 package org.catacomb.graph.gui;
2
3
4 import org.catacomb.be.Position;
5 import org.catacomb.datalish.Box;
6 import org.catacomb.datalish.SColor;
7 import org.catacomb.interlish.content.IntPosition;
8 import org.catacomb.interlish.content.Polypoint;
9 import org.catacomb.report.E;
10
11 import java.awt.BasicStroke;
12 import java.awt.Color;
13 import java.awt.Graphics2D;
14 import java.awt.geom.AffineTransform;
15 import java.awt.geom.Ellipse2D;
16
17
18 public final class Painter {
19
20
21 private WorldTransform worldTransform;
22 private Graphics2D g;
23
24
25 private BasicStroke normalStroke;
26 private BasicStroke dashedStroke;
27
28 private PointPainter pointPainter;
29
30
31
32
33
34
35
36
37 AffineTransform upTransform;
38 AffineTransform normalTransform;
39
40
41 private Color[] colorTable;
42 private double ctMin;
43 private double ctMax;
44
45
46 private Box wkBox;
47
48
49 public Painter(WorldTransform transform) {
50 super();
51 setWorldTransform(transform);
52 pointPainter = new PointPainter();
53
54 normalStroke = new BasicStroke((float)1.);
55
56 upTransform = new AffineTransform();
57 upTransform.setToRotation(Math.PI / 2.);
58 normalTransform = new AffineTransform();
59
60 }
61
62
63 PointPainter getPointPainter() {
64 return pointPainter;
65 }
66
67
68 public boolean isShowing(double x, double y) {
69 return worldTransform.isShowing(x, y);
70 }
71
72
73 public void reframe(Box box) {
74 worldTransform.reframe(box);
75 }
76
77
78 public int getCanvasWidth() {
79 return worldTransform.getCanvasWidth();
80 }
81
82 public double getWorldCanvasWidth() {
83 return worldTransform.getWorldCanvasWidth();
84 }
85
86 public int getCanvasHeight() {
87 return worldTransform.getCanvasHeight();
88 }
89
90
91 public Size getPixelSize() {
92 return worldTransform.getPixelSize();
93 }
94
95 public double getPixelArea() {
96 return worldTransform.getPixelArea();
97 }
98
99
100
101 public boolean isOnCanvas(Position p) {
102 return worldTransform.isOnCanvas(p.getX(), p.getY());
103 }
104
105
106 public boolean isOnCanvas(double x, double y) {
107 return worldTransform.isOnCanvas(x, y);
108 }
109
110
111 public boolean intIsOnCanvas(int x, int y) {
112 return worldTransform.intIsOnCanvas(x, y);
113 }
114
115
116 public void setPixelScalingFromTop(double d) {
117 worldTransform.setPixelScalingFromTop(d);
118 }
119
120
121 public final double[] getXYXYLimits() {
122 return worldTransform.getXYXYLimits();
123 }
124
125
126 void setWorldTransform(WorldTransform transform) {
127 worldTransform = transform;
128 }
129
130
131 public void setGraphics(Graphics2D g2d) {
132 g = g2d;
133 pointPainter.setGraphics(g2d);
134 }
135
136
137 public Graphics2D getGraphics() {
138 return g;
139 }
140
141
142
143 public IntPosition pow(Position p) {
144 return new IntPosition(powx(p.getX()), powy(p.getY()));
145 }
146
147
148 public double dxydp() {
149 return worldTransform.pubDxDpix();
150 }
151
152
153 public int powx(double wx) {
154 return worldTransform.powx(wx);
155 }
156
157
158 public int powy(double wy) {
159 return worldTransform.powy(wy);
160 }
161
162
163 public Position wop(IntPosition ip) {
164 return new Position(wopx(ip.getX()), wopy(ip.getY()));
165 }
166
167
168 public double wopx(int x) {
169 return worldTransform.wopx(x);
170 }
171
172
173 public double wopy(int y) {
174 return worldTransform.wopy(y);
175 }
176
177
178
179 void setBasicStroke(double w) {
180 if (w != 1.0) {
181 g.setStroke(new BasicStroke((float)w));
182 }
183 }
184 void setDashedStroke(double w) {
185 if (dashedStroke == null) {
186 float[] dashes= {8, 4, 8, 4};
187 dashedStroke = new BasicStroke(1.f, BasicStroke.CAP_BUTT,
188 BasicStroke.JOIN_BEVEL, 10.f,
189 dashes, 0.f);
190 }
191 g.setStroke(dashedStroke);
192 }
193
194
195 void setNormalStroke() {
196 g.setStroke(normalStroke);
197 }
198
199 private void resetStroke() {
200 g.setStroke(normalStroke);
201 }
202
203
204 public void setStroke(BasicStroke bs) {
205 g.setStroke(bs);
206 }
207
208
209
210 public final void drawPixelLine(int x0, int y0, int x1, int y1) {
211 g.drawLine(x0, y0, x1, y1);
212 }
213
214 void drawPolyline(double[] xp, double[] yp) {
215 drawPolyline(xp, yp, xp.length);
216 }
217
218 public void drawPolyline(double[] xp, double[] yp, int np) {
219 g.drawPolyline(worldTransform.intDeviceX(xp), worldTransform.intDeviceY(yp), np);
220 }
221
222 public void drawPolyline(double[] xp, double[] yp, int np, Color col, double width,
223 boolean widthIsPixels) {
224 setBasicStroke(width);
225 setColor(col);
226 g.drawPolyline(worldTransform.intDeviceX(xp), worldTransform.intDeviceY(yp), np);
227 resetStroke();
228 }
229
230 public void drawMarks(double[] xp, double[] yp) {
231 for (int i = 0; i < xp.length; i++) {
232 int x = powx(xp[i]);
233 int y = powy(yp[i]);
234 g.fillRect(x, y, 1, 1);
235 }
236 }
237
238 public void drawMarks(double[] xp, double[] yp, int n) {
239 for (int i = 0; i < n; i++) {
240 int x = powx(xp[i]);
241 int y = powy(yp[i]);
242 g.fillRect(x, y, 1, 1);
243 }
244 }
245
246 public void drawIntMarks(double[] xp, double[] yp, int n, int w, int h) {
247 for (int i = 0; i < n; i++) {
248 int x = powx(xp[i]);
249 int y = powy(yp[i]);
250 g.fillRect(x, y, w, h);
251 }
252 }
253
254 public void drawAreaMarks(double[] xp, double[] yp, double diam) {
255 int n = xp.length;
256 for (int i = 0; i < n; i++) {
257 int x = powx(xp[i]);
258 int y = powy(yp[i]);
259 g.fill(new Ellipse2D.Double(x, y, diam, diam));
260
261 }
262 }
263
264
265 public void drawPolygon(double[] xp, double[] yp) {
266 drawPolygon(xp, yp, xp.length);
267 }
268
269
270
271 public void drawPolygon(double[] xp, double[] yp, int np) {
272 g.drawPolygon(worldTransform.intDeviceX(xp), worldTransform.intDeviceY(yp), np);
273 }
274
275 public void drawPolygon(double[] xp, double[] yp, int np, Color col, double width,
276 boolean widthIsPixels) {
277 setBasicStroke(width);
278 setColor(col);
279 g.drawPolygon(worldTransform.intDeviceX(xp), worldTransform.intDeviceY(yp), np);
280 resetStroke();
281 }
282
283 public void fillPolygon(double[] xp, double[] yp, int np) {
284 g.fillPolygon(worldTransform.intDeviceX(xp), worldTransform.intDeviceY(yp), np);
285 }
286
287 public void fillPolygon(double[] xp, double[] yp, int np, Color col) {
288 setColor(col);
289 g.fillPolygon(worldTransform.intDeviceX(xp), worldTransform.intDeviceY(yp), np);
290 }
291
292
293 public void fillPolygon(double[] xp, double[] yp) {
294 g.fillPolygon(worldTransform.intDeviceX(xp), worldTransform.intDeviceY(yp), xp.length);
295 }
296
297
298 public void fillPolygon(Polypoint pp, int cfill, int cline) {
299 int[] ix = worldTransform.intDeviceX(pp.getXPts());
300 int[] iy = worldTransform.intDeviceY(pp.getYPts());
301 g.setColor(new Color(cfill));
302 g.fillPolygon(ix, iy, ix.length);
303
304 g.setColor(new Color(cline));
305 g.drawPolygon(ix, iy, ix.length);
306 }
307
308
309 public void setColor(SColor sc) {
310 g.setColor(sc.getColor());
311 }
312
313
314 public void setColor(Color c) {
315 g.setColor(c);
316 }
317
318 public void setColorWhite() {
319 g.setColor(Color.white);
320 }
321
322 public void setColorRed() {
323 g.setColor(Color.red);
324 }
325
326 public void setColorGreen() {
327 g.setColor(Color.green);
328 }
329
330 public void setColorBlue() {
331 g.setColor(Color.blue);
332 }
333
334 public void setColorBlack() {
335 g.setColor(Color.black);
336 }
337
338 public void setColorGray() {
339 g.setColor(Color.gray);
340 }
341
342 public void setColorCyan() {
343 g.setColor(Color.cyan);
344 }
345 public void setColorMagenta() {
346 g.setColor(Color.magenta);
347 }
348
349 public void setColorYellow() {
350 g.setColor(Color.yellow);
351 }
352 public void setColorOrange() {
353 g.setColor(Color.orange);
354 }
355
356
357 public void setColorDarkGray() {
358 g.setColor(Color.darkGray);
359 }
360
361 public void drawWhiteLine(double width, double[] xp, double[] yp) {
362 setColor(Color.white);
363 setBasicStroke(3.);
364 drawPolyline(xp, yp, xp.length);
365 resetStroke();
366 }
367
368
369 public void fillRectangle(double x, double y, Color c, int size) {
370 int ix = powx(x);
371 int iy = powy(y);
372 fillPixelRectangle(ix, iy, c, size);
373 }
374
375 public void fillRectangle(double x1, double y1, double x2, double y2, Color c) {
376 int ix = powx(x1);
377 int iy = powy(y2);
378 int dx = powx(x2) - ix + 1;
379 int dy = powy(y1) - iy + 1;
380 g.setColor(c);
381 g.fillRect(ix, iy, dx, dy);
382 }
383
384 public void fillPixelRectangle(int ix, int iy, Color c, int size) {
385 g.setColor(c);
386 int hs = size / 2;
387 g.fillRect(ix - hs, iy - hs, size, size);
388 }
389
390
391
392 public void drawLine(double x0, double y0, double x1, double y1, Color col, double width,
393 boolean widthIsPixels) {
394 setBasicStroke(width);
395 setColor(col);
396 drawLine(x0, y0, x1, y1);
397 resetStroke();
398 }
399
400
401 public void drawLine(Position p1, Position p2) {
402 drawLine(p1.getX(), p1.getY(), p2.getX(), p2.getY());
403 }
404
405
406 public void drawLine(double x0, double y0, double x1, double y1) {
407 int ix0 = powx(x0);
408 int iy0 = powy(y0);
409 int ix1 = powx(x1);
410 int iy1 = powy(y1);
411
412 g.drawLine(ix0, iy0, ix1, iy1);
413 }
414
415
416 public void drawCenteredBox(Position pos, int hx, int hy) {
417 int ixc = powx(pos.getX());
418 int iyc = powy(pos.getY());
419
420 g.drawRect(ixc - hx, iyc - hy, 2 * hx, 2 * hy);
421 }
422
423 public void fillCenteredBox(Position pos, int hx, int hy) {
424 int ixc = powx(pos.getX());
425 int iyc = powy(pos.getY());
426
427 g.fillRect(ixc - hx, iyc - hy, 2 * hx, 2 * hy);
428 }
429
430
431 public void drawFixedSizeLine(double x, double y, Color c, int idx, int idy, int wfac) {
432 g.setColor(c);
433 resetStroke();
434 int ix = powx(x);
435 int iy = powy(y);
436
437 setBasicStroke(wfac);
438
439 g.drawLine(ix, iy, ix + idx, iy + idy);
440 resetStroke();
441
442 }
443
444 public void drawText(String s, double x, double y) {
445 int ix = powx(x);
446 int iy = powy(y);
447 g.drawString(s, ix, iy);
448 }
449
450
451 public void drawLineOffsetText(String s, double x, double y, int dx, int dy) {
452 int ix = powx(x);
453 int iy = powy(y);
454 g.drawLine(ix, iy, ix + dx, iy + dy);
455 g.drawString(s, ix + dx, iy + dy);
456 }
457
458
459 public void drawString(String s, int x, int y) {
460 g.drawString(s, x, y);
461 }
462
463 public void drawCenteredString(String s, int x, int y) {
464 int w = stringWidth(s);
465
466 g.drawString(s, x-w/2, y);
467 }
468
469 public void drawLabel(String s, double x, double y, Color c) {
470 g.setColor(c);
471 drawLabel(s, x, y);
472 }
473
474
475 public void drawUpLabel(String s, double x, double y, Color c) {
476 g.setColor(c);
477 drawUpLabel(s, x, y);
478 }
479
480
481 public void drawUpLabel(String s, double x, double y) {
482 g.setTransform(upTransform);
483 int ix = powx(x);
484 int iy = powy(y);
485 g.drawString(s, ix + 6, iy);
486 g.setTransform(normalTransform);
487 }
488
489
490
491 public void drawLabel(String s, double x, double y) {
492 int ix = powx(x);
493 int iy = powy(y);
494 drawLabelAt(s, ix, iy - 6);
495 }
496
497 public void drawCenteredLabel(String s, double x, double y) {
498 int ix = powx(x);
499 int iy = powy(y);
500 int hw = stringWidth(s) / 2;
501 drawLabelAt(s, ix - hw, iy - 6);
502 }
503
504 public void drawXCenteredYTopAlignedLabel(String s, double x, double y) {
505 int ix = powx(x);
506 int iy = powy(y);
507 int hw = stringWidth(s) / 2;
508 g.drawString(s, ix-hw, iy + 9);
509 }
510
511 public void drawLeftAlignedLabel(String s, double x, double y) {
512 int ix = powx(x);
513 int iy = powy(y);
514 drawLabelAt(s, ix + 6, iy + 6);
515 }
516
517
518 public void drawRightAlignedLabel(String s, double x, double y) {
519 int ix = powx(x);
520 int iy = powy(y);
521 int w = stringWidth(s);
522 drawLabelAt(s, ix - w - 4, iy + 6);
523 }
524
525 public void drawXCenteredYBottomAlignedLabel(String s, double x, double y) {
526 int ix = powx(x);
527 int iy = powy(y);
528 int hw = stringWidth(s) / 2;
529 drawLabelAt(s, ix - hw, iy - 2);
530 }
531
532
533
534
535
536
537 public void fillCenteredRectangle(double x, double y, double rx, double ry) {
538 E.missing();
539 }
540
541
542 public void drawCircle(double x, double y, double r) {
543 int ix1 = powx(x - r);
544 int iy1 = powy(y + r);
545
546 int ix2 = powx(x + r);
547 int iy2 = powy(y - r);
548
549 g.drawOval(ix1, iy1, ix2 - ix1, iy2 - iy1);
550 }
551
552
553
554 public void fillCircle(double x, double y, double r) {
555 int ix1 = powx(x - r);
556 int iy1 = powy(y + r);
557
558 int ix2 = powx(x + r);
559 int iy2 = powy(y - r);
560
561 g.fillOval(ix1, iy1, ix2 - ix1, iy2 - iy1);
562 }
563
564
565 public void fillIntCircle(double x, double y, int r) {
566 int ix = powx(x);
567 int iy = powy(y);
568 g.fillOval(ix-r, iy-r, 2*r, 2*r);
569 }
570
571 public void drawIntCircle(double x, double y, int r) {
572 int ix = powx(x);
573 int iy = powy(y);
574 g.drawOval(ix-r, iy-r, 2*r, 2*r);
575 }
576
577
578
579 public void fillCenteredOval(double cx, double cy, double rx, double ry, Color cfill) {
580
581 int ix1 = powx(cx - rx);
582 int iy1 = powy(cy + ry);
583
584 int ix2 = powx(cx + rx);
585 int iy2 = powy(cy - ry);
586
587 setColor(cfill);
588 g.fillOval(ix1, iy1, ix2 - ix1, iy2 - iy1);
589 }
590
591 public void fillCenteredOval(Position pos, int ir) {
592
593 int ixc = powx(pos.getX());
594 int iyc = powy(pos.getY());
595
596
597 g.fillOval(ixc-ir, iyc-ir, 2*ir, 2*ir);
598 }
599
600
601
602
603
604 public void drawCenteredOval(double cx, double cy, double rx, double ry,
605 Color clin, double width, boolean widthIsPixels) {
606
607 int ix1 = powx(cx - rx);
608 int iy1 = powy(cy + ry);
609
610 int ix2 = powx(cx + rx);
611 int iy2 = powy(cy - ry);
612 setBasicStroke(width);
613 setColor(clin);
614 g.drawOval(ix1, iy1, ix2 - ix1, iy2 - iy1);
615 resetStroke();
616 }
617
618
619 public void drawCenteredOval(double cx, double cy, int hx, int hy) {
620 int ixc = powx(cx);
621 int iyc = powy(cy);
622 g.drawOval(ixc - hx, iyc - hy, 2 * hx, 2 * hy);
623 }
624
625 public void drawCenteredOval(Position pos, int hx, int hy) {
626 int ixc = powx(pos.getX());
627 int iyc = powy(pos.getY());
628
629 g.drawOval(ixc - hx, iyc - hy, 2 * hx, 2 * hy);
630 }
631
632
633 public void drawFilledOval(double cx, double cy, double rx, double ry, Color cfill,
634 Color cborder, double width, boolean widthIsPixels) {
635
636 int ix1 = powx(cx - rx);
637 int iy1 = powy(cy + ry);
638
639 int ix2 = powx(cx + rx);
640 int iy2 = powy(cy - ry);
641
642 setColor(cfill);
643 g.fillOval(ix1, iy1, ix2 - ix1, iy2 - iy1);
644
645 if (width > 0.5) {
646 setBasicStroke(width);
647 setColor(cborder);
648 g.drawOval(ix1, iy1, ix2 - ix1, iy2 - iy1);
649 resetStroke();
650 }
651 }
652
653
654 public void drawFilledRectangle(double cx, double cy, int w, int h, Color cfill) {
655
656 int ix = powx(cx);
657 int iy = powy(cy);
658
659
660 setColor(cfill);
661 g.fillRect(ix - w/2, iy - h/2, w, h);
662 }
663
664 public void drawFilledRectangle(double cx, double cy, double rx, double ry, Color cfill,
665 Color cborder, double width, boolean widthIsPixels) {
666
667 int ix1 = powx(cx - rx);
668 int iy1 = powy(cy + ry);
669
670 int ix2 = powx(cx + rx);
671 int iy2 = powy(cy - ry);
672
673 setColor(cfill);
674 g.fillRect(ix1, iy1, ix2 - ix1, iy2 - iy1);
675
676 if (width > 0.5) {
677 setBasicStroke(width);
678 setColor(cborder);
679 g.drawRect(ix1, iy1, ix2 - ix1, iy2 - iy1);
680 resetStroke();
681 }
682 }
683
684 public void drawRectangle(double cx, double cy, double rx, double ry,
685 Color cborder, double width, boolean widthIsPixels) {
686
687 int ix1 = powx(cx - rx);
688 int iy1 = powy(cy + ry);
689
690 int ix2 = powx(cx + rx);
691 int iy2 = powy(cy - ry);
692
693 setColor(cborder);
694 g.drawRect(ix1, iy1, ix2 - ix1, iy2 - iy1);
695 }
696
697
698
699
700 public void drawRectangle(int[] xyxy) {
701 g.drawRect(xyxy[0], xyxy[1], xyxy[2] - xyxy[0], xyxy[3] - xyxy[1]);
702 }
703
704
705
706
707
708 public void drawDashedRectangle(double cx, double cy,
709 double rx, double ry) {
710 int ix1 = powx(cx - rx);
711 int iy1 = powy(cy + ry);
712
713 int ix2 = powx(cx + rx);
714 int iy2 = powy(cy - ry);
715
716
717 setDashedStroke(1.);
718
719 g.drawRect(ix1, iy1, ix2 - ix1, iy2 - iy1);
720
721 setNormalStroke();
722 }
723
724 public void drawOval(double cx, double cy, double rx, double ry, Color cborder, double width,
725 boolean widthIsPixels) {
726
727 int ix1 = powx(cx - rx);
728 int iy1 = powy(cy + ry);
729
730 int ix2 = powx(cx + rx);
731 int iy2 = powy(cy - ry);
732
733 setColor(cborder);
734 g.drawOval(ix1, iy1, ix2 - ix1, iy2 - iy1);
735 }
736
737
738
739 public void drawCarrotSides(double xa, double ya, double ra, double xb, double yb, double rb) {
740
741 double vy = xb - xa;
742 double vx = -(yb - ya);
743 double vl = Math.sqrt(vx * vx + vy * vy);
744 if (vl <= 0.0) {
745 vl = 1.e-6;
746 }
747 vx /= vl;
748 vy /= vl;
749 drawLine(xa - ra * vx, ya - ra * vy, xb - rb * vx, yb - rb * vy);
750 drawLine(xa + ra * vx, ya + ra * vy, xb + rb * vx, yb + rb * vy);
751
752
753 }
754
755
756
757 public int getLabelPoint(double[] xpts, double[] ypts) {
758 int n = xpts.length;
759 int iret = 0;
760 for (int i = 0; i < n; i++) {
761 if (isShowing(xpts[i], ypts[i])) {
762 iret = i;
763 break;
764 }
765 }
766 return iret;
767 }
768
769
770 public void drawOffsetCenteredLabel(String s, double x, double y) {
771 int ix = powx(x);
772 int iy = powy(y);
773 iy += 8;
774 ix += 16;
775 int sw = stringWidth(s);
776 if (ix + sw > worldTransform.getCanvasWidth()) {
777 ix = worldTransform.getCanvasWidth() - sw - 20;
778 }
779
780 g.setColor(Color.orange);
781 g.fillRect(ix, iy-16, sw+10, 16);
782 g.setColor(Color.black);
783 g.drawRect(ix, iy-16, sw+10, 16);
784 g.drawString(s, ix+5, iy-3);
785
786 }
787
788 public void drawLabelAt(String s, int ix, int iy) {
789
790 int sw = stringWidth(s);
791
792 g.setColor(Color.white);
793 g.fillRect(ix, iy-16, sw+10, 16);
794 g.setColor(Color.gray);
795 g.drawRect(ix, iy-16, sw+10, 16);
796 g.setColor(Color.black);
797 g.drawString(s, ix+5, iy-3);
798
799 }
800
801
802
803
804
805 public int stringWidth(String s) {
806 return g.getFontMetrics().stringWidth(s);
807 }
808
809
810 public void drawFilledTriangle(double x0, double y0, double x1,
811 double y1, double x2, double y2,
812 Color fillColor, Color color, double width, boolean b) {
813 double[] xpts = {x0, x1, x2};
814 double[] ypts = {y0, y1, y2};
815 int[] ipx = worldTransform.intDeviceX(xpts);
816 int[] ipy = worldTransform.intDeviceY(ypts);
817
818 setColor(fillColor);
819 g.fillPolygon(ipx, ipy, 3);
820 setColor(color);
821 if (b) {
822
823 } else {
824 E.warning("cant do world width lines");
825 }
826
827 if (width > 0.5) {
828 setBasicStroke(width);
829 g.drawPolygon(ipx, ipy, 3);
830 resetStroke();
831 }
832 }
833
834
835 public void drawCircle(Position position, double radius) {
836 drawCircle(position.getX(), position.getY(), radius);
837 }
838
839
840 public void fillCircle(Position position, double radius) {
841 fillCircle(position.getX(), position.getY(), radius);
842 }
843
844
845 public void paintTrash() {
846 paintTrash(false);
847 }
848
849
850 public void paintTrash(boolean live) {
851 int w = worldTransform.getCanvasWidth();
852 int h = worldTransform.getCanvasHeight();
853 int[][] xy = {{w-22, w-4, w-7, w-19},
854 {h-22, h-22, h-6, h-6}
855 };
856 g.setColor(new Color(60, 190, 40));
857 g.fillPolygon(xy[0], xy[1], xy[0].length);
858 g.fillOval(w-19, h-8, 12, 5);
859
860
861 if (live) {
862 g.setColor(Color.red);
863 } else {
864 g.setColor(Color.darkGray);
865 }
866
867 g.fillOval(w-22, h-25, 18, 6);
868
869 g.setColor(new Color(100, 240, 100));
870 g.drawOval(w-22, h-25, 18, 6);
871
872 }
873
874
875
876
877 public void paintLiveTrash() {
878 paintTrash(true);
879 }
880
881
882 public void fillBackground(Color c) {
883 g.setColor(c);
884 g.fillRect(0, 0, getCanvasWidth(), getCanvasHeight());
885 }
886
887
888 public void fillIntRectangle(int x, int y, int cw, int ch, Color color) {
889 g.setColor(color);
890 g.fillRect(x, y, cw, ch);
891 }
892
893
894 public void drawCenteredPixelLine(double x, double y, int[] xpts, int[] ypts) {
895 int cx = powx(x);
896 int cy = powy(y);
897
898 int[] xp = new int[xpts.length];
899 int[] yp = new int[xpts.length];
900 for (int i = 0; i < xpts.length; i++) {
901 xp[i] = cx + xpts[i];
902 yp[i] = cy + ypts[i];
903 }
904 g.drawPolyline(xp, yp, xp.length);
905 }
906
907
908 public void setIntColor(int icol) {
909 setColor(new Color(icol));
910 }
911
912
913 public final void drawCable(Position pa, Position pcenter, Position pb) {
914 double ax = pa.getX();
915 double ay = pa.getY();
916 double bx = pb.getX();
917 double by = pb.getY();
918 double cx = pcenter.getX();
919 double cy = pcenter.getY();
920
921 drawHalfCable(cx, cy, bx-ax, by-ay, bx, by, 14);
922 drawHalfCable(cx, cy, ax-bx, ay-by, ax, ay, 14);
923 }
924
925
926
927 public final void drawHalfCable(double x0, double y0, double dx0, double dy0, double x1,
928 double y1, int n) {
929
930 double vx, vy, vl, dx, dy, dl, f, alp0, alp;
931
932 double r = 0.03;
933 double alpa = 0.1;
934 double alpb = 0.4;
935
936 double[] xp = new double[n];
937 double[] yp = new double[n];
938
939 xp[0] = x0;
940 yp[0] = y0;
941 dx = dx0;
942 dy = dy0;
943 for (int i = 1; i < n; i++) {
944 alp0 = alpa + (alpb * i) / (n - 1);
945 vx = x1 - xp[i - 1];
946 vy = y1 - yp[i - 1];
947 vl = Math.sqrt(vx * vx + vy * vy);
948 alp = (i == 1 ? alp0 / 2 : (i == n - 1 ? 1. : alp0));
949
950 dl = Math.sqrt(dx * dx + dy * dy);
951 dx = (1. - alp) * dx / dl + alp * vx / vl;
952 dy = (1. - alp) * dy / dl + alp * vy / vl;
953 f = (vl - r) / (n - i);
954 xp[i] = xp[i - 1] + f * dx;
955 yp[i] = yp[i - 1] + f * dy;
956 }
957 drawPolyline(xp, yp, n);
958 }
959
960
961
962 public void setColorRange(double ca, double cb) {
963 ctMin = ca;
964 ctMax = cb;
965 }
966
967 public void setColorTable(Color[] ct) {
968 colorTable = ct;
969 }
970
971
972 public void setDefaultColorTable() {
973 colorTable = new Color[256];
974 for (int i = 0; i < colorTable.length; i++) {
975 colorTable[i] = new Color(i, i, i);
976 }
977
978 }
979
980
981
982 public void drawColoredCells(double[][][] mesh, double[] dat) {
983 int nel = dat.length;
984
985 if (colorTable == null) {
986 setDefaultColorTable();
987 }
988
989 double dc = ctMax - ctMin;
990 if (dc <= 0.) {
991 dc = 1.;
992 }
993 for (int i = 0; i < nel; i++) {
994 double[] xb = mesh[i][0];
995 double[] yb = mesh[i][1];
996
997
998 double fc = (dat[i] - ctMin) / dc;
999 if (fc < 0.) {
1000 fc = 0.;
1001 }
1002 int ic = (int)(255 * fc);
1003 if (ic > 255) {
1004 ic = 255;
1005 }
1006 if (ic < 0) {
1007 ic = 0;
1008 }
1009 fillPolygon(xb, yb, xb.length, colorTable[ic]);
1010 }
1011 }
1012
1013
1014
1015 public void drawColoredCells(double[][][] mesh, double[] dat, boolean[] mask) {
1016 int nel = dat.length;
1017
1018 if (colorTable == null) {
1019 setDefaultColorTable();
1020 }
1021
1022 double dc = ctMax - ctMin;
1023 if (dc <= 0.) {
1024 dc = 1.;
1025 }
1026 for (int i = 0; i < nel; i++) {
1027 if (mask[i]) {
1028 double[] xb = mesh[i][0];
1029 double[] yb = mesh[i][1];
1030
1031
1032 double fc = (dat[i] - ctMin) / dc;
1033 if (fc < 0.) {
1034 fc = 0.;
1035 }
1036 int ic = (int)(255 * fc);
1037 if (ic > 255) {
1038 ic = 255;
1039 }
1040 if (ic < 0) {
1041 ic = 0;
1042 }
1043 fillPolygon(xb, yb, xb.length, colorTable[ic]);
1044 }
1045 }
1046 }
1047
1048
1049
1050
1051
1052
1053
1054 public void paintLegend(int ileg, String s) {
1055 int w = worldTransform.getCanvasWidth();
1056 g.drawString(s, w-80, 30 + 20 * ileg);
1057 }
1058
1059
1060
1061
1062
1063 public double getXProj(double[] c) {
1064 return xProj(c[0], c[1], c[2]);
1065 }
1066
1067 public double getYProj(double[] c) {
1068 return yProj(c[0], c[1], c[2]);
1069 }
1070
1071 public double getZProj(double[] c) {
1072 return zProj(c[0], c[1], c[2]);
1073 }
1074
1075 public double getXProj(float[] c) {
1076 return xProj(c[0], c[1], c[2]);
1077 }
1078
1079 public double getYProj(float[] c) {
1080 return yProj(c[0], c[1], c[2]);
1081 }
1082
1083 public double getZProj(float[] c) {
1084 return zProj(c[0], c[1], c[2]);
1085 }
1086
1087
1088
1089 public double getZProj(double x, double y, double z) {
1090 return zProj(x, y, z);
1091 }
1092
1093
1094 public int getXProjPixel(double x, double y, double z) {
1095 double wx = xProj(x, y, z);
1096 int ix = powx(wx);
1097 return ix;
1098 }
1099
1100 public int getYProjPixel(double x, double y, double z) {
1101 double wy = yProj(x, y, z);
1102 int iy = powy(wy);
1103 return iy;
1104 }
1105
1106
1107
1108 double xProj(double x, double y, double z) {
1109 return worldTransform.xProj(x, y, z);
1110 }
1111
1112 double yProj(double x, double y, double z) {
1113 return worldTransform.yProj(x, y, z);
1114 }
1115
1116 private double zProj(double x, double y, double z) {
1117 return worldTransform.zProj(x, y, z);
1118 }
1119
1120
1121
1122 public final void draw3DPoint(double x, double y, double z) {
1123 g.drawOval(powx(xProj(x,y,z)) - 2, powy(yProj(x,y,z)) - 2, 4, 4);
1124 }
1125
1126
1127 public final void fill3DOval(double x, double y, double z,
1128 int hw, int hh) {
1129 g.fillOval(powx(xProj(x,y,z)) - hw, powy(yProj(x,y,z)) - hh, 2*hw, 2 * hh);
1130 /
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162 public final void draw3DZOffsetLine(double xa, double ya, double za,
1163 double xb, double yb, double zb,
1164 double z0, double dpdz) {
1165 double zpa = zProj(xa, ya, za);
1166 double zpb = zProj(xb, yb, zb);
1167 drawLine(xProj(xa,ya,za) + dpdz * (zpa-z0), yProj(xa,ya,za),
1168 xProj(xb,yb,zb) + dpdz * (zpb - z0), yProj(xb,yb,zb));
1169 }
1170
1171
1172
1173 final void drawOutline(double xa, double ya, double ra,
1174 double xb, double yb, double rb) {
1175
1176 double vy = xb - xa;
1177 double vx = -(yb - ya);
1178 double vl = Math.sqrt(vx * vx + vy * vy);
1179 if (vl <= 0.0) vl = 1.e-6;
1180 vx /= vl;
1181 vy /= vl;
1182
1183 drawLine(xa - ra * vx, ya - ra * vy, xb - rb * vx, yb - rb * vy);
1184 drawLine(xa + ra * vx, ya + ra * vy, xb + rb * vx, yb + rb * vy);
1185
1186 drawLine(xa - ra * vx, ya - ra * vy, xa + ra * vx, ya + ra * vy);
1187 drawLine(xb - rb * vx, yb - rb * vy, xb + rb * vx, yb + rb * vy);
1188 }
1189
1190
1191
1192 final void drawSides(double xa, double ya, double ra, double xb, double yb, double rb) {
1193
1194 double vy = xb - xa;
1195 double vx = -(yb - ya);
1196 double vl = Math.sqrt(vx * vx + vy * vy);
1197 if (vl <= 0.0)
1198 vl = 1.e-6;
1199 vx /= vl;
1200 vy /= vl;
1201
1202 drawLine(xa - ra * vx, ya - ra * vy, xb - rb * vx, yb - rb * vy);
1203 drawLine(xa + ra * vx, ya + ra * vy, xb + rb * vx, yb + rb * vy);
1204 }
1205
1206
1207
1208
1209 final void fillOutline(double xa, double ya, double ra,
1210 double xb, double yb, double rb) {
1211
1212 double vy = xb - xa;
1213 double vx = -(yb - ya);
1214 double vl = Math.sqrt(vx * vx + vy * vy);
1215 if (vl <= 0.0) vl = 1.e-6;
1216 vx /= vl;
1217 vy /= vl;
1218 drawLine(xa - ra * vx, ya - ra * vy, xb - rb * vx, yb - rb * vy);
1219 drawLine(xa + ra * vx, ya + ra * vy, xb + rb * vx, yb + rb * vy);
1220
1221 double[] xx = {xa-ra*vx, xb-rb*vx, xb+rb*vx, xa+ra*vx, xa-ra*vx};
1222 double[] yy = {ya-ra*vy, yb-rb*vy, yb+rb*vy, ya+ra*vy, ya-ra*vy};
1223
1224 fillPolygon(xx, yy, 5);
1225 }
1226
1227
1228 public final void draw3DLine(double xa, double ya, double za,
1229 double xb, double yb, double zb) {
1230 drawLine(xProj(xa,ya,za), yProj(xa,ya,za), xProj(xb,yb,zb), yProj(xb,yb,zb));
1231 }
1232
1233
1234 public final void draw3DOutline(double xa, double ya, double za, double ra,
1235 double xb, double yb, double zb, double rb) {
1236 drawOutline(xProj(xa,ya,za), yProj(xa,ya,za), ra,
1237 xProj(xb,yb,zb), yProj(xb,yb,zb), rb);
1238 }
1239
1240
1241 public final void fill3DSegment(double xa, double ya, double za, double ra,
1242 double xb, double yb, double zb, double rb) {
1243 fillOutline(xProj(xa,ya,za), yProj(xa,ya,za), ra,
1244 xProj(xb,yb,zb), yProj(xb,yb,zb), rb);
1245 }
1246
1247 public final void draw3DCarrot(double xa, double ya, double za, double ra,
1248 double xb, double yb, double zb, double rb) {
1249 double x2a = xProj(xa,ya,za);
1250 double y2a = yProj(xa,ya,za);
1251 double x2b = xProj(xb,yb,zb);
1252 double y2b = yProj(xb,yb,zb);
1253 drawSides(x2a, y2a, ra, x2b, y2b, rb);
1254 drawCircle(x2a, y2a, ra);
1255 drawCircle(x2b, y2b, rb);
1256 }
1257
1258
1259 public final void draw3DSegment(double xa, double ya, double za, double ra,
1260 double xb, double yb, double zb, double rb) {
1261 double x2a = xProj(xa,ya,za);
1262 double y2a = yProj(xa,ya,za);
1263 double x2b = xProj(xb,yb,zb);
1264 double y2b = yProj(xb,yb,zb);
1265 drawOutline(x2a, y2a, ra, x2b, y2b, rb);
1266 }
1267
1268
1269 public void drawString3D(double x, double y, double z, String lbl) {
1270 double x2a = xProj(x, y, z);
1271 double y2a = yProj(x, y, z);
1272 drawString(lbl, powx(x2a), powy(y2a));
1273 }
1274
1275 public void drawString3DOffset(double x, double y, double z, String lbl, int idx, int idy) {
1276 double x2a = xProj(x, y, z);
1277 double y2a = yProj(x, y, z);
1278 drawString(lbl, powx(x2a)+idx, powy(y2a)+idy);
1279 }
1280
1281 public final boolean visible3D(double x, double y, double z) {
1282 return worldTransform.visible3D(x, y, z);
1283
1284 }
1285
1286 public void draw3DMarks(float[][] ca, int n) {
1287 for (int i = 0; i < n; i++) {
1288 int x = powx(xProj(ca[i][0], ca[i][1], ca[i][2]));
1289 int y = powy(yProj(ca[i][0], ca[i][1], ca[i][2]));
1290 g.fillRect(x, y, 1, 1);
1291 }
1292 }
1293
1294
1295 public void drawSome3DMarks(float[][] ca, int n, double pas) {
1296 for (double d = 0; d < n; d+= pas) {
1297 int i = (int)d;
1298 int x = powx(xProj(ca[i][0], ca[i][1], ca[i][2]));
1299 int y = powy(yProj(ca[i][0], ca[i][1], ca[i][2]));
1300 g.fillRect(x, y, 1, 1);
1301 }
1302 }
1303
1304
1305 public void draw3DIntMarks(float[][] ca, int n, int w, int h) {
1306 for (int i = 0; i < n; i++) {
1307 int x = powx(xProj(ca[i][0], ca[i][1], ca[i][2]));
1308 int y = powy(yProj(ca[i][0], ca[i][1], ca[i][2]));
1309 g.fillRect(x, y, w, h);
1310 }
1311 }
1312
1313
1314 public void draw3DAreaMarks(float[][] ca, int n, double diam) {
1315 for (int i = 0; i < n; i++) {
1316 int x = powx(xProj(ca[i][0], ca[i][1], ca[i][2]));
1317 int y = powy(yProj(ca[i][0], ca[i][1], ca[i][2]));
1318 g.fill(new Ellipse2D.Double(x, y, diam, diam));
1319
1320 }
1321 }
1322
1323
1324
1325
1326 public void drawUpperSome3DMarks(float[][] ca, int n, double pas, double zp, double zd) {
1327 for (double d = 0; d < n; d+= pas) {
1328 int i = (int)d;
1329 double z = zProj(ca[i][0], ca[i][1], ca[i][2]);
1330 double f = ca[i][4];
1331 if (z < (f * zd + (1.-f) * zp)) {
1332 int x = powx(xProj(ca[i][0], ca[i][1], ca[i][2]));
1333 int y = powy(yProj(ca[i][0], ca[i][1], ca[i][2]));
1334 g.fillRect(x, y, 1, 1);
1335 }
1336 }
1337 }
1338
1339
1340 public void drawUpper3DIntMarks(float[][] ca, int n, int w, int h, double zp, double zd) {
1341 for (int i = 0; i < n; i++) {
1342 double z = zProj(ca[i][0], ca[i][1], ca[i][2]);
1343 double f = ca[i][4];
1344 if (z < (f * zd + (1.-f) * zp)) {
1345
1346 int x = powx(xProj(ca[i][0], ca[i][1], ca[i][2]));
1347 int y = powy(yProj(ca[i][0], ca[i][1], ca[i][2]));
1348 g.fillRect(x, y, w, h);
1349 }
1350 }
1351 }
1352
1353
1354 public void drawUpper3DAreaMarks(float[][] ca, int n, double diam, double zp, double zd) {
1355 for (int i = 0; i < n; i++) {
1356 double z = zProj(ca[i][0], ca[i][1], ca[i][2]);
1357 double f = ca[i][4];
1358 if (z < (f * zd + (1.-f) * zp)) {
1359 int x = powx(xProj(ca[i][0], ca[i][1], ca[i][2]));
1360 int y = powy(yProj(ca[i][0], ca[i][1], ca[i][2]));
1361 g.fill(new Ellipse2D.Double(x, y, diam, diam));
1362 }
1363
1364 }
1365 }
1366
1367
1368
1369 public void draw3DPolygon(double[][] da) {
1370 int n = da.length;
1371 int[] xp = new int[n];
1372 int[] yp = new int[n];
1373 for (int i = 0; i < n; i++) {
1374 xp[i] = powx(xProj(da[i][0], da[i][1], da[i][2]));
1375 yp[i] = powy(yProj(da[i][0], da[i][1], da[i][2]));
1376 }
1377 g.drawPolygon(xp, yp, n);
1378 }
1379
1380
1381
1382
1383
1384 public void startBox() {
1385 wkBox = new Box();
1386 }
1387
1388 public Box getBox() {
1389 return wkBox;
1390 }
1391
1392 public void push3D(double x, double y, double z) {
1393 wkBox.push(xProj(x, y, z), yProj(x, y, z));
1394 }
1395 public void push(double x, double y) {
1396 wkBox.push(x, y);
1397 }
1398
1399
1400 public void drawAxes() {
1401
1402
1403 }
1404
1405
1406 public int screenDistance2(double x, double y, double z, int x2, int y2) {
1407 int xs = powx(xProj(x, y, z));
1408 int ys = powy(yProj(x, y, z));
1409 int dx = xs - x2;
1410 int dy = ys - y2;
1411 int d2 = dx * dx + dy * dy;
1412 return d2;
1413 }
1414
1415
1416 }