001    package ui.recognizer;
002    
003    import java.awt.Rectangle;
004    
005    /** A class containing calibration information necessary for the correct mapping
006     *  from image coordinates to data coordinates.
007     */
008    
009    // should we extend it from Rectangle2D?
010    
011    public class Calibration extends Rectangle {
012    
013        // can be more precise than integer pixels by locating the exact center of the border (sub-pixel resolution)
014        // plot extrema : the center of the lines defining the axes (in image units)
015    
016        public static final double DEFAULT_MINX = 0.0d;
017        public static final double DEFAULT_MINY = 0.0d;
018        public static final double DEFAULT_MAXX = 1.0d;
019        public static final double DEFAULT_MAXY = 1.0d;
020    
021        public static final double DEFAULT_UNITX = 1.0d;
022        public static final double DEFAULT_UNITY = 1.0d;
023    
024        // plot extrema in data units (should this be an instance of rectangle class ?)
025        protected double minX = DEFAULT_MINX;
026        protected double minY = DEFAULT_MINY;
027        protected double maxX = DEFAULT_MAXX;
028        protected double maxY = DEFAULT_MAXY;
029    
030        protected double unitX = DEFAULT_UNITX;
031        protected double unitY = DEFAULT_UNITY;
032    
033        //This constructor is redundant because it is 'inherited' from Rectangle class ?
034        public Calibration() {
035            super(new Rectangle());
036        }
037    
038        //This constructor is redundant because it is 'inherited' from Rectangle class ?
039        public Calibration(Rectangle aBorder) {
040            this(aBorder, DEFAULT_MINX, DEFAULT_MINY, DEFAULT_MAXX, DEFAULT_MAXY);
041        }
042    
043        // rectangle representing the plot window
044        public Calibration(Rectangle aBorder, double aMinX, double aMinY, double aMaxX, double aMaxY) {
045            this(aBorder, aMinX, aMinY, aMaxX, aMaxY, DEFAULT_UNITX, DEFAULT_UNITY);
046    
047        }
048    
049        // rectangle representing the plot window
050        public Calibration(Rectangle aBorder, double aMinX, double aMinY, double aMaxX, double aMaxY, double aUnitX, double aUnitY) {
051            super(aBorder);
052            minX = aMinX;
053            minY = aMinY;
054            maxX = aMaxX;
055            maxY = aMaxY;
056            unitX = aUnitX;
057            unitY = aUnitY;
058        }
059    
060        /** Convert an image coordinate into a data coordinate.
061         * @param anImageCoordinate a coordinate in image format
062         * @return a data coordinate mapped from the image coordinate
063         */
064        public DataCoordinate map(ImageCoordinate anImageCoordinate) {
065            double x = (double) anImageCoordinate.getX();
066            double y = (double) anImageCoordinate.getY();
067            double mapx = getMinX() + (x - getX()) / getWidth()  * (getMaxX() - getMinX());
068            double mapy = getMinY() + (y - getY()) / getHeight() * (getMaxY() - getMinY());
069            // TODO: some mapping function which uses the current calibration state
070            return new DataCoordinate(mapx, mapy);
071        }
072    
073        /** Convert data coordinate into an image coordinate in the native unit of the data.
074         * @param aDataCoordinate a coordinate in data format
075         * @return a coordinate in image format mapped from the data coordinate
076         */
077        public ImageCoordinate mapInDataUnits(DataCoordinate aDataCoordinate) {
078            double x = aDataCoordinate.getX() / getUnitX();
079            double y = aDataCoordinate.getY() / getUnitY();
080            return map(new DataCoordinate(x, y));
081        }
082    
083        /** Convert data coordinate into an image coordinate.
084         * @param aDataCoordinate a coordinate in data format
085         * @return a coordinate in image format mapped from the data coordinate
086         */
087        public ImageCoordinate map(DataCoordinate aDataCoordinate) {
088            double x = aDataCoordinate.getX();
089            double y = aDataCoordinate.getY();
090    
091            double relativeX = (x - getMinX()) / (getMaxX() - getMinX());
092            double relativeY = (y - getMinY()) / (getMaxY() - getMinY());
093    
094            int imageX = (int) (relativeX * getWidth()  + getX());
095            int imageY = (int) (relativeY * getHeight() + getY());
096            return new ImageCoordinate(imageX, imageY);
097        }
098    
099        /** Get the unit of the X-axis. Multiply getX() by this number to obtain the scaled x unit.
100         */
101        public double getUnitX() {
102            return unitX;
103        }
104    
105        public void setUnitX(double aUnitX) {
106            unitX = aUnitX;
107        }
108    
109        /** Get the unit of the Y-axis. Multiply getY() by this number to obtain the scaled y unit.
110         */
111        public double getUnitY() {
112            return unitY;
113        }
114    
115        public void setUnitY(double aUnitY) {
116            unitY = aUnitY;
117        }
118    
119        /** Get the minimum x value of the calibration zone.
120         *
121         * @return the minimum x value in calibration zone in double precision
122         * @see     #setMinX
123         */
124        public double getMinX() {
125            return minX;
126        }
127    
128        /** Set the minimum x value of the calibration zone.
129         *
130         * @param aMinX the minimum x value in the calibration zone in double precision
131         * @see     #getMinX
132         */
133        public void setMinX(double aMinX) {
134            minX = aMinX;
135        }
136    
137        /** Get the minimum y value of the calibration zone.
138         *
139         * @return the minimum intensity in the calibration zone in double precision
140         */
141        public double getMinY() {
142            return minY;
143        }
144    
145        /** Set the minimum y value of the calibration zone.
146         *
147         * @param aMinY the minimum intensity in the calibration zone in double precision
148         */
149        public void setMinY(double aMinY) {
150            minY = aMinY;
151        }
152    
153        /** Get the maximum x value of the calibration zone.
154         *
155         * @return the maximum x value in the calibration zone in double precision
156         * @see     #setMaxX
157         */
158        public double getMaxX() {
159            return maxX;
160        }
161    
162        /** Set the maximum x value of the calibration zone.
163         *
164         * @param aMaxX the maximum wavelength in the calibration zone in double precision
165         */
166        public void setMaxX(double aMaxX) {
167            maxX = aMaxX;
168        }
169    
170        /** Get the maximum y value of the calibration zone.
171         *
172         * @return the maximum intensity in the calibration zone in double precision
173         */
174        public double getMaxY() {
175            return maxY;
176        }
177    
178        /** Set the maximum y value of the calibration zone.
179         *
180         * @param aMaxY the maximum intensity in the calibration zone in double precision
181         */
182        public void setMaxY(double aMaxY) {
183            maxY = aMaxY;
184        }
185    
186    }
187