View Javadoc

1   // Copyright 2004-2005, FreeHEP.
2   package hep.wired.heprep.projection;
3   
4   import java.awt.geom.*;
5   import java.util.*;
6   
7   import org.jdom.Element;
8   
9   import org.freehep.xml.io.XMLIO;
10  import org.freehep.xml.io.XMLIOManager;
11  
12  import hep.wired.feature.Rotateable2D;
13  import hep.wired.feature.Transformable2D;
14  import hep.wired.feature.Resetable;
15  import hep.wired.services.ViewPort;
16  import hep.wired.heprep.services.Projection;
17  import hep.wired.util.Matrix2D;
18  
19  /***
20   * 2D projection of (X,Y) into (U,V).
21   *
22   * @author Mark Donszelmann
23   * @version $Id: FlatProjection.java 2074 2005-07-20 06:22:09Z duns $
24   */
25  
26  public class FlatProjection extends AbstractProjection 
27          implements Rotateable2D, Transformable2D, 
28                     Resetable {
29  
30      // FIXME WIRED-242, take from preferences
31      public final static double defaultScaleFactor = 0.001;
32  
33      private Matrix2D matrix;
34      private Matrix2D resetMatrix;
35      
36      /***
37       * Creates a 2D projection with given scale factor.
38       */
39      public FlatProjection(double s) {
40          this(new Matrix2D(s, 0, 
41                            0, s, 
42                            0, 0));
43      }
44      
45      /***
46       * Creates a 2D projection.
47       */ 
48      public FlatProjection() {
49          this(defaultScaleFactor);
50      }
51      
52      private FlatProjection(Matrix2D matrix) {
53          this(matrix, matrix);
54      }
55      
56      private FlatProjection(Matrix2D matrix, Matrix2D resetMatrix) {
57          super();
58          this.matrix = (Matrix2D)matrix.clone();
59          this.resetMatrix = (Matrix2D)resetMatrix.clone();
60      }
61  
62      public String getFormula() {
63          return "(u,v,w) = "+
64                 "m00*x + m01*y + m02, "+
65                 "m10*x + m11*y + m12, "+
66          	   "z";
67      }
68      
69      public double[] transform(double[] xyz) {
70          return matrix.transform(xyz, false);
71      }
72      
73      public double[][] transform(double[][] xyz, int n) {
74          return matrix.transform(xyz, n, false);
75      }
76  
77      public double[] deltaTransform(double[] xyz) {
78          return matrix.transform(xyz, true);
79      }
80  
81      public double[] inverseTransform(double[] uvw) throws UnsupportedOperationException {
82          try {
83              Matrix2D inverse = matrix.createInverse();
84              return inverse.transform(uvw, false);
85          } catch (NoninvertibleTransformException e) {
86              throw new UnsupportedOperationException(e.getMessage());
87          }
88      }
89      
90      public double[] inverseDeltaTransform(double[] uvw) throws UnsupportedOperationException {
91          try {
92              Matrix2D inverse = matrix.createInverse();
93              return inverse.transform(uvw, true);
94          } catch (NoninvertibleTransformException e) {
95              throw new UnsupportedOperationException(e.getMessage());
96          }
97      }
98      
99      public Projection copy() {
100         return new FlatProjection(matrix, resetMatrix);
101     }
102 
103     public String toString() {
104         return super.toString()+" : \n"+matrix.toString();
105     }
106 
107 // Rotateable2D
108     public void rotate(double theta) {
109         matrix.rotate(theta);
110     }
111 
112 // Translateable
113     public double[] getModelTranslation(double[] uvw, ViewPort viewPort) {
114         uvw = viewPort.inverseDeltaTransform(uvw);
115         return inverseDeltaTransform(uvw);         
116     }
117 
118     public double[] getScreenTranslation(double[] xyz, ViewPort viewPort) {
119         xyz = deltaTransform(xyz);
120         return viewPort.deltaTransform(xyz);
121     }
122 
123 // Transformable2D
124     public void scale(double s) {
125         scale(s, s);
126     }
127     
128     public void setScale(double s) {
129         setScale(s, s);
130     }
131     
132     public void scale(double sx, double sy) {
133         matrix.scale(sx, sy);
134     }
135 
136     public void setScale(double sx, double sy) {
137         double[] s = getScale();
138         matrix.scale(sx/s[X], sy/s[Y]);
139     }
140 
141     public double[] getScale() {
142         return new double[] {matrix.getScaleX(), matrix.getScaleY()};
143     }
144 
145     public void shear(double shx, double shy) {
146         matrix.shear(shx, shy);
147     }
148         
149     public void translate(double tx, double ty) {
150         matrix.modelTranslate(tx, ty);
151     }
152 
153     public void setTranslate(double tx, double ty) {
154         double[] t = getTranslate();
155         matrix.modelTranslate(tx - t[X], ty - t[Y]);
156     }
157 
158     public double[] getTranslate() {
159         return inverseDeltaTransform(new double[] {matrix.getTranslateX(), matrix.getTranslateY()});
160     }
161 
162 // Resetable
163     public Object reset(Object newState) {
164         Object oldState = matrix.clone();
165         matrix = (newState == null) ? (Matrix2D)resetMatrix.clone() : (Matrix2D)newState;
166         return oldState;
167     }
168 
169 //
170 // XMLIO
171 //
172     public void save(XMLIOManager xmlioManager,
173                      org.jdom.Element nodeEl) {
174         super.save(xmlioManager, nodeEl);
175         nodeEl.addContent(xmlioManager.save(matrix));
176         nodeEl.addContent(xmlioManager.save(resetMatrix));
177     }
178 
179     public void restore(XMLIOManager xmlioManager,
180                         org.jdom.Element nodeEl) {
181         super.restore(xmlioManager, nodeEl);
182         Iterator i=nodeEl.getChildren().iterator();
183         matrix = (Matrix2D)xmlioManager.restore((Element)i.next());
184         resetMatrix = (Matrix2D)xmlioManager.restore((Element)i.next());
185     }     
186 }
187