1
2 package hep.wired.heprep.projection;
3
4 import javax.swing.event.*;
5
6 import hep.wired.heprep.services.Projection;
7 import hep.wired.feature.Resetable;
8
9 import hep.wired.variable.DoubleVariable;
10
11 /***
12 * Blows up the center of the plot cylindrically while squeezing the outer parts.
13 *
14 * @author Mark Donszelmann
15 * @version $Id: CylindricalFishEyeProjection.java 2161 2005-08-02 22:47:40Z duns $
16 */
17
18 public class CylindricalFishEyeProjection extends VariableProjection implements Resetable {
19
20 private DoubleVariable varAlpha, varRhoMax, varZMax;
21 private double alpha, resetAlpha;
22 private double rhoMax, resetRhoMax;
23 private double zMax, resetZMax;
24
25 public CylindricalFishEyeProjection() {
26
27 this(0.01, 0.01, 6860, 4000, 6860, 4000);
28 }
29
30 private CylindricalFishEyeProjection(double alpha, double resetAlpha,
31 double rhoMax, double resetRhoMax,
32 double zMax, double resetZMax) {
33 super("CylindricalFishEye");
34 varAlpha = addVariable("alpha", 0.0, 0.03, alpha, null, "Distortion Factor");
35 varRhoMax = addVariable("rhoMax", 0.1, 10000, rhoMax, null, "Maximum rho for distortion");
36 varZMax = addVariable("zMax", 0.1, 10000, zMax, null, "Maximum Z for distortion");
37
38 varRhoMax.addChangeListener(new ChangeListener() {
39 public void stateChanged(ChangeEvent e) {
40 setMaximumAlpha();
41 }
42 });
43
44 varZMax.addChangeListener(new ChangeListener() {
45 public void stateChanged(ChangeEvent e) {
46 setMaximumAlpha();
47 }
48 });
49
50 this.resetAlpha = resetAlpha;
51 this.resetRhoMax = resetRhoMax;
52 this.resetZMax = resetZMax;
53 }
54
55 private void setMaximumAlpha() {
56 varAlpha.setMaximum(10/Math.min(varRhoMax.getDoubleVariable(), varZMax.getDoubleVariable()));
57 }
58
59 public String getFormula() {
60 return "(u,v,w) = "+
61 "f(rho',phi), where rho'=rho/(1+a*rho), "+
62 "f(rho',phi), where rho'=rho/(1+a*rho), "+
63 "z / (1+a*|z|)";
64 }
65
66 public double[] transform(double[] xyz) {
67 double x = xyz[X];
68 double y = xyz[Y];
69 double z = xyz[Z];
70
71 double phi = Math.atan2(y, x);
72 double rho = Math.sqrt((x*x) + (y*y));
73 double rhoPrime = rho / (1 + (alpha*rho));
74 rhoPrime *= (1 + (alpha*Math.abs(rhoMax)));
75
76 double zPrime = z / (1 + (alpha*Math.abs(z)));
77 zPrime *= (1 + (alpha*Math.abs(zMax)));
78
79 xyz[U] = rhoPrime * Math.cos(phi);
80 xyz[V] = rhoPrime * Math.sin(phi);
81 xyz[W] = zPrime;
82
83 return xyz;
84 }
85
86 public double[] deltaTransform(double[] xyz) {
87 return transform(xyz);
88 }
89
90 public double[] inverseTransform(double[] uvw) throws UnsupportedOperationException {
91 throw new UnsupportedOperationException("No inverse transform on "+getClass());
92 }
93
94 public double[] inverseDeltaTransform(double[] uvw) throws UnsupportedOperationException {
95 return inverseTransform(uvw);
96 }
97
98 public Projection copy() {
99 return new CylindricalFishEyeProjection(alpha, resetAlpha,
100 rhoMax, resetRhoMax,
101 zMax, resetZMax);
102 }
103
104
105 public Object reset(Object newState) {
106 Object oldState = new double[] { alpha, rhoMax, zMax };
107 if (newState == null) {
108 alpha = resetAlpha;
109 rhoMax = resetRhoMax;
110 zMax = resetZMax;
111 } else {
112 double[] array = (double[])newState;
113 alpha = array[0];
114 rhoMax = array[1];
115 zMax = array[2];
116 }
117 return oldState;
118 }
119
120 }