1
2 package hep.wired.edit;
3
4 import java.awt.*;
5 import java.awt.geom.*;
6 import java.util.logging.*;
7 import javax.swing.*;
8 import javax.swing.undo.*;
9
10 import hep.wired.services.RecordPlot;
11 import hep.wired.services.GraphicsPanel;
12 import hep.wired.util.Matrix3D;
13 import hep.wired.feature.Rotateable2D;
14 import hep.wired.feature.Rotateable3D;
15
16 /***
17 * Rotates a plot in 2D or 3D.
18 *
19 * @author Mark Donszelmann
20 * @version $Id: Rotate.java 689 2005-03-16 09:06:57Z duns $
21 */
22 public class Rotate extends AnimatedWiredEdit implements GraphicsPanelEdit {
23
24 private static Logger logger = Logger.getLogger(Rotate.class.getPackage().getName());
25
26
27
28
29
30
31
32 private double nx, ny, nz;
33 private double theta;
34 private Matrix3D matrix;
35
36 /***
37 * Creates a rotate edit with no rotation.
38 */
39 public Rotate() {
40 this(0, 0, 0, 1);
41 }
42
43 /***
44 * Creates a rotate edit with given rotation.
45 */
46 public Rotate(double theta, double nx, double ny, double nz) {
47 this(theta, nx, ny, nz, null, 0);
48 }
49
50 /***
51 * Creates a rotate edit with given rotation, animation shape and number of frames.
52 */
53 public Rotate(double theta, double nx, double ny, double nz,
54 Shape shape, int frames) {
55 super(shape, frames);
56 matrix = Matrix3D.getRotateInstance(theta, nx, ny, nz);
57 this.theta = theta;
58 this.nx = nx;
59 this.ny = ny;
60 this.nz = nz;
61 }
62
63 public WiredEdit copy(RecordPlot plot) {
64 WiredEdit copy = new Rotate(theta, nx, ny, nz, getShape(), getFrames());
65 copy.setRecordPlot(plot);
66 return copy;
67 }
68
69 protected Shape[] getShapes(Shape shape, int steps) {
70 if ((shape == null) || (steps <= 1)) return null;
71
72
73 if ((nx != 0) || (ny != 0) || (nz != 1)) return null;
74
75 Shape[] shapes = new Shape[steps];
76
77
78 double dtheta = theta/(steps-1);
79
80
81 double w = getRecordPlot().getWidth()/2.0;
82 double h = getRecordPlot().getHeight()/2.0;
83
84
85 for (int i=0; i<steps; i++) {
86 AffineTransform transform = new AffineTransform();
87
88 transform.rotate(-i*dtheta, w, h);
89
90 shapes[i] = transform.createTransformedShape(shape);
91 }
92 return shapes;
93 }
94
95 public Shape createTransformedShape(Component component, Shape shape) {
96
97 if ((nx != 0) || (ny != 0) || (nz != 1)) return null;
98
99 double w = component.getWidth()/2.0;
100 double h = component.getHeight()/2.0;
101
102 AffineTransform transform = new AffineTransform();
103 transform.rotate(-theta, w, h);
104 return transform.createTransformedShape(shape);
105 }
106
107 public String getPresentationName() {
108 double[] n = new double[3];
109 double theta = matrix.getRotation(n);
110 return toString()+" "+format.format(Math.toDegrees(theta))+" degrees over ("+format.format(n[0])+", "+format.format(n[1])+", "+format.format(n[2])+")";
111 }
112
113 public String toString() {
114 return "Rotate";
115 }
116
117 public boolean addEdit(UndoableEdit edit) {
118 if (edit instanceof Rotate) {
119 Rotate rotate = (Rotate)edit;
120 matrix.preConcatenate(rotate.matrix);
121
122 matrix = matrix.createOrthonormalized();
123
124 rotate.matrix = matrix;
125
126
127 return false;
128 }
129 return false;
130 }
131
132 public boolean isSupportedBy(GraphicsPanel p) {
133 return p.supports(Rotateable2D.class) || p.supports(Rotateable3D.class);
134 }
135
136 protected void redoEdit() {
137 GraphicsPanel panel = getRecordPlot().getGraphicsPanel();
138 Rotateable3D rotateable3D = (Rotateable3D)panel.getFeature(Rotateable3D.class);
139 if (rotateable3D != null) {
140 rotateable3D.rotate(theta, nx, ny, nz);
141 } else {
142 Rotateable2D rotateable2D = (Rotateable2D)panel.getFeature(Rotateable2D.class);
143 if (rotateable2D == null) {
144 System.err.println("Could not redo: "+this);
145 return;
146 }
147
148 rotateable2D.rotate(theta);
149 }
150 getRecordPlot().repaint();
151 logger.finer(toString());
152 }
153
154 protected void undoEdit() {
155 GraphicsPanel panel = getRecordPlot().getGraphicsPanel();
156 Rotateable3D rotateable3D = (Rotateable3D)panel.getFeature(Rotateable3D.class);
157 if (rotateable3D != null) {
158 rotateable3D.rotate(-theta, nx, ny, nz);
159 } else {
160 Rotateable2D rotateable2D = (Rotateable2D)panel.getFeature(Rotateable2D.class);
161 if (rotateable2D == null) {
162 System.err.println("Could not undo: "+this);
163 return;
164 }
165
166 rotateable2D.rotate(-theta);
167 }
168 getRecordPlot().repaint();
169 logger.finer(toString());
170 }
171 }