1 package edu.uci.ics.jung.visualization.control;
2
3 import java.awt.Color;
4 import java.awt.Graphics;
5 import java.awt.Graphics2D;
6 import java.awt.Shape;
7 import java.awt.geom.AffineTransform;
8 import java.awt.geom.CubicCurve2D;
9 import java.awt.geom.Point2D;
10
11 import edu.uci.ics.jung.visualization.BasicVisualizationServer;
12 import edu.uci.ics.jung.visualization.VisualizationServer;
13 import edu.uci.ics.jung.visualization.util.ArrowFactory;
14
15 public class CubicCurveEdgeEffects<V,E> implements EdgeEffects<V,E> {
16
17 protected CubicCurve2D rawEdge = new CubicCurve2D.Float();
18 protected Shape edgeShape;
19 protected Shape rawArrowShape;
20 protected Shape arrowShape;
21 protected VisualizationServer.Paintable edgePaintable;
22 protected VisualizationServer.Paintable arrowPaintable;
23
24
25 public CubicCurveEdgeEffects() {
26 this.rawEdge.setCurve(0.0f, 0.0f, 0.33f, 100, 0.66f, -50, 1.0f, 0.0f);
27 rawArrowShape = ArrowFactory.getNotchedArrow(20, 16, 8);
28 this.edgePaintable = new EdgePaintable();
29 this.arrowPaintable = new ArrowPaintable();
30 }
31
32
33 public void startEdgeEffects(BasicVisualizationServer<V, E> vv,
34 Point2D down, Point2D out) {
35 transformEdgeShape(down, out);
36 vv.addPostRenderPaintable(edgePaintable);
37 }
38
39
40 public void midEdgeEffects(BasicVisualizationServer<V, E> vv,
41 Point2D down, Point2D out) {
42 transformEdgeShape(down, out);
43 }
44
45
46 public void endEdgeEffects(BasicVisualizationServer<V, E> vv) {
47 vv.removePostRenderPaintable(edgePaintable);
48 }
49
50
51 public void startArrowEffects(BasicVisualizationServer<V, E> vv,
52 Point2D down, Point2D out) {
53 transformArrowShape(down, out);
54 vv.addPostRenderPaintable(arrowPaintable);
55 }
56
57
58 public void midArrowEffects(BasicVisualizationServer<V, E> vv,
59 Point2D down, Point2D out) {
60 transformArrowShape(down, out);
61 }
62
63
64 public void endArrowEffects(BasicVisualizationServer<V, E> vv) {
65 vv.removePostRenderPaintable(arrowPaintable);
66 }
67
68
69
70
71
72 private void transformEdgeShape(Point2D down, Point2D out) {
73 float x1 = (float) down.getX();
74 float y1 = (float) down.getY();
75 float x2 = (float) out.getX();
76 float y2 = (float) out.getY();
77
78 AffineTransform xform = AffineTransform.getTranslateInstance(x1, y1);
79
80 float dx = x2-x1;
81 float dy = y2-y1;
82 float thetaRadians = (float) Math.atan2(dy, dx);
83 xform.rotate(thetaRadians);
84 float dist = (float) Math.sqrt(dx*dx + dy*dy);
85 xform.scale(dist / rawEdge.getBounds().getWidth(), 1.0);
86 edgeShape = xform.createTransformedShape(rawEdge);
87 }
88
89 private void transformArrowShape(Point2D down, Point2D out) {
90 float x1 = (float) down.getX();
91 float y1 = (float) down.getY();
92 float x2 = (float) out.getX();
93 float y2 = (float) out.getY();
94
95 AffineTransform xform = AffineTransform.getTranslateInstance(x2, y2);
96
97 float dx = x2-x1;
98 float dy = y2-y1;
99 float thetaRadians = (float) Math.atan2(dy, dx);
100 xform.rotate(thetaRadians);
101 arrowShape = xform.createTransformedShape(rawArrowShape);
102 }
103
104
105
106 class EdgePaintable implements VisualizationServer.Paintable {
107
108 public void paint(Graphics g) {
109 if(edgeShape != null) {
110 Color oldColor = g.getColor();
111 g.setColor(Color.black);
112 ((Graphics2D)g).draw(edgeShape);
113 g.setColor(oldColor);
114 }
115 }
116
117 public boolean useTransform() {
118 return false;
119 }
120 }
121
122
123
124
125 class ArrowPaintable implements VisualizationServer.Paintable {
126
127 public void paint(Graphics g) {
128 if(arrowShape != null) {
129 Color oldColor = g.getColor();
130 g.setColor(Color.black);
131 ((Graphics2D)g).fill(arrowShape);
132 g.setColor(oldColor);
133 }
134 }
135
136 public boolean useTransform() {
137 return false;
138 }
139 }
140 }