View Javadoc

1   /*
2    * Copyright (c) 2003-2008 by Cosylab d. d.
3    *
4    * This file is part of CosyBeans-Common.
5    *
6    * CosyBeans-Common is free software: you can redistribute it and/or modify
7    * it under the terms of the GNU General Public License as published by
8    * the Free Software Foundation, either version 3 of the License, or
9    * (at your option) any later version.
10   *
11   * CosyBeans-Common is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   * GNU General Public License for more details.
15   *
16   * You should have received a copy of the GNU General Public License
17   * along with CosyBeans-Common.  If not, see <http://www.gnu.org/licenses/>.
18   */
19  
20  package com.cosylab.gui.components.gauger;
21  
22  import java.awt.Graphics;
23  import java.awt.Point;
24  import java.awt.Rectangle;
25  import java.awt.geom.Point2D;
26  
27  import java.util.ArrayList;
28  
29  
30  /**
31   * Abstract utility class that provides the mathematic foundation for drawing
32   * the Gauger scales. Scale is defined in its own coordinate system with the
33   * axis (u, v). In this system the extents of the scale are defined to be  (0,
34   * 0) and (1, 1), meaning that any point on this scale can be specified  with
35   * the (u, v) parameter value between 0 and 1. This class is the
36   * implementation of this transformation and the component cartesian
37   * coordinate system.
38   *
39   * @author <a href="mailto:ales.pucelj@cosylab.com">Ales Pucelj</a>
40   * @version $id$
41   */
42  public abstract class ScaleTransform
43  {
44  	private Point2D tempPoint = new Point2D.Double();
45  	private Point labelPosition = new Point();
46  	private boolean polar = false;
47  
48  	/**
49  	 * Abstract base class for scale segments.
50  	 *
51  	 * @author $Author: jbobnar $
52  	 * @version $Revision: 1.4 $
53  	 */
54  	public class ScaleSegment
55  	{
56  	}
57  
58  	/**
59  	 * Class defining linear scale segment.
60  	 *
61  	 * @author $Author: jbobnar $
62  	 * @version $Revision: 1.4 $
63  	 */
64  	public class LineSegment extends ScaleSegment
65  	{
66  		/** Starting point of line */
67  		public Point2D lineStart;
68  
69  		/** Ending point of line */
70  		public Point2D lineEnd;
71  
72  		/**
73  		 * Creates a new LineSegment object.
74  		 *
75  		 * @param xs X coordinate of starting point.
76  		 * @param ys Y coordinate of starting point.
77  		 * @param xe X coordinate of ending point.
78  		 * @param ye Y coordinate of ending point.
79  		 */
80  		public LineSegment(double xs, double ys, double xe, double ye)
81  		{
82  			lineStart = new Point2D.Double(xs, ys);
83  			lineEnd = new Point2D.Double(xe, ye);
84  		}
85  	}
86  
87  	/**
88  	 * Definition of arc scale segment.
89  	 *
90  	 * @author $Author: jbobnar $
91  	 * @version $Revision: 1.4 $
92  	 */
93  	public class ArcSegment extends ScaleSegment
94  	{
95  		/** Center point of arc */
96  		public Point2D center;
97  
98  		/** Outer radius of arc */
99  		public double rOuter;
100 
101 		/** Inner radius of arc */
102 		public double rInner;
103 
104 		/** Starting angle of arc */
105 		public double startAngle;
106 
107 		/** Included angle of arc */
108 		public double arcAngle;
109 
110 		/**
111 		 * Creates a new ArcSegment object.
112 		 *
113 		 * @param c Center point
114 		 * @param r inner radius
115 		 * @param R Outer radius
116 		 * @param start Starting angle
117 		 * @param angle Included angle
118 		 */
119 		public ArcSegment(Point2D c, double r, double R, double start,
120 		    double angle)
121 		{
122 			center = c;
123 			rOuter = R;
124 			rInner = r;
125 			startAngle = start;
126 			arcAngle = angle;
127 		}
128 	}
129 
130 	/**
131 	 * Defines rectangular scale segment.
132 	 *
133 	 * @author $Author: jbobnar $
134 	 * @version $Revision: 1.4 $
135 	 */
136 	public class RectangleSegment extends ScaleSegment
137 	{
138 		/** Coordinates of rectangle */
139 		public Rectangle rect;
140 
141 		/**
142 		 * Creates a new RectangleSegment object.
143 		 *
144 		 * @param rect Coordinates of rectangle.
145 		 */
146 		public RectangleSegment(Rectangle rect)
147 		{
148 			this.rect = rect;
149 		}
150 	}
151 
152 	/** Segments comprising this scale. */
153 	private ArrayList<ScaleSegment> segments = null;
154 
155 	/**
156 	 * Creates a new ScaleTransform object.
157 	 */
158 	public ScaleTransform()
159 	{
160 		super();
161 		segments = new ArrayList<ScaleSegment>();
162 	}
163 
164 	/**
165 	 * Sets whether this transform is polar. A polar scale will be rendered in
166 	 * polar coordinates rather then cartesian. Lines will be rendered as arcs
167 	 * and text will be rotated.
168 	 *
169 	 * @param value True if polar.
170 	 */
171 	public void setPolar(boolean value)
172 	{
173 		polar = value;
174 	}
175 
176 	/**
177 	 * Returns whether this scale is polar.
178 	 *
179 	 * @return True if polar.
180 	 *
181 	 * @see setPolar(boolean)
182 	 */
183 	public boolean isPolar()
184 	{
185 		return polar;
186 	}
187 
188 	/**
189 	 * Sets the component parameters for this transformation.
190 	 *
191 	 * @param w width of the component that will display this transformation
192 	 * @param h height of the component that will display this transformation
193 	 * @param marginX not used
194 	 * @param marginY not used
195 	 * @param tickOffset space between the edge of the scale and the first tick
196 	 */
197 	public abstract void setParameters(int w, int h, int marginX, int marginY,
198 	    int tickOffset);
199 
200 	/**
201 	 * Maps the point specified with (u, v) coordinates in the scale space to
202 	 * cartesian space with coordinates (x, y). (u, v) values must be in
203 	 * [0..1]  range, the (x, y) points will be in (0..w-1, 0..h-1) range.
204 	 *
205 	 * @param scaleSpace point in scale space
206 	 * @param cartesianSpace point in cartesian space
207 	 */
208 	public abstract void mapUVtoXY(Point2D scaleSpace, Point2D cartesianSpace);
209 
210 	/**
211 	 * Maps the point specified with (u, v) coordinates in the scale space to
212 	 * cartesian space with coordinates (x, y). (u, v) values must be in
213 	 * [0..1] range, the (x, y) points will be in (0..w-1, 0..h-1) range.
214 	 *
215 	 * @param u coordinate in scale space
216 	 * @param v coordinate in scale space
217 	 * @param cartesianSpace point in cartesian space
218 	 */
219 	public void mapUVtoXY(double u, double v, Point2D cartesianSpace)
220 	{
221 		tempPoint.setLocation(u, v);
222 		mapUVtoXY(tempPoint, cartesianSpace);
223 	}
224 
225 	/**
226 	 * Maps point specified with (u, v) coordinates in scale space to
227 	 * cartesian space with coordinates (x, y)
228 	 *
229 	 * @param u coordinate in scale space.
230 	 * @param v coordinate in scale space.
231 	 *
232 	 * @return Point2D cartesianSpace point.
233 	 *
234 	 * @see mapUVtoXY(u, v, Point2D)
235 	 */
236 	public Point2D mapUVtoXY(double u, double v)
237 	{
238 		Point2D point = new Point2D.Double();
239 		mapUVtoXY(u, v, point);
240 
241 		return point;
242 	}
243 
244 	/**
245 	 * Returns angle between horizontal and specified relative position in
246 	 * scale space. This angle is defined as angle between X axis and line
247 	 * from point (x, 0.0) to point (x, 100.0). This is the angle at which
248 	 * vertical straight line in polar mode is rotated in cartesian space.
249 	 *
250 	 * @param x Relative point in scale space in range 0.0 to 1.0.
251 	 *
252 	 * @return double angle in radians
253 	 */
254 	public final double getAngle(double x)
255 	{
256 		final Point2D p1 = mapUVtoXY(x, 0);
257 		final Point2D p2 = mapUVtoXY(x, 100000.0);
258 
259 		final double dx = (p2.getX() - p1.getX());
260 		final double dy = (p2.getY() - p1.getY());
261 
262 		double phi = (dx == 0.0) ? 0 : -Math.atan(dy / dx) - Math.PI * 0.5;
263 
264 		if(dx < 0) {
265 			phi += Math.PI;
266 		}
267 
268 		return phi;
269 	}
270 
271 	/**
272 	 * Returns the width of scale in pixels at the specified location v in the
273 	 * scale space. Although the scale for v is only defined in the range
274 	 * [0..1], this value can generaly return even values outside this range,
275 	 * although this is not guaranteed.
276 	 *
277 	 * @return Width of scale in pixels.
278 	 */
279 	public abstract double scaleWidth(double v);
280 
281 	/**
282 	 * Returns the height of scale in pixels at the specified location u in the
283 	 * scale space. Although the scale for u is only defined in the range
284 	 * [0..1], this value can generaly return even values outside this range,
285 	 * although this is not guaranteed.
286 	 *
287 	 * @return Height of scale in pixels.
288 	 */
289 	public abstract double scaleHeight(double u);
290 
291 	/**
292 	 * Returns the point where the label should be positioned. This point
293 	 * represents geometric center of the text. There are no limits to the
294 	 * size  of the text written around this position.
295 	 *
296 	 * @return Center point for label.
297 	 */
298 	public Point getLabelPosition()
299 	{
300 		return labelPosition;
301 	}
302 
303 	/**
304 	 * Returns the number of segments describing this scale. Even if the value
305 	 * is zero, this transform may still provide space transformation
306 	 * functionality.
307 	 *
308 	 * @return Number of segments.
309 	 */
310 	public int getSegmentCount()
311 	{
312 		return segments.size();
313 	}
314 
315 	/**
316 	 * Adds segment to this transform.
317 	 * 
318 	 * @param segment to add.
319 	 */
320 	protected void addSegment(ScaleSegment segment)
321 	{
322 		segments.add(segment);
323 	}
324 
325 	/**
326 	 * Returns scale segment at specified index.
327 	 *
328 	 * @param i Index of segment.
329 	 *
330 	 * @return Scale segment.
331 	 */
332 	public ScaleSegment getSegment(int i)
333 	{
334 		return (ScaleSegment)(segments.get(i));
335 	}
336 
337 	/**
338 	 * Sets position of value label. The position is center point of label.
339 	 * 
340 	 * @param x coordinate of label center.
341 	 * @param y coordinate of label center.
342 	 */
343 	protected void setLabelPosition(int x, int y)
344 	{
345 		labelPosition.x = x;
346 		labelPosition.y = y;
347 	}
348 
349 	/**
350 	 * Measues the width of tick label.
351 	 *
352 	 * @param g Graphic context.
353 	 * @param x Relative position of tick.
354 	 * @param text Tick label.
355 	 *
356 	 * @return Width of label in pixels.
357 	 */
358 	public abstract int measureTick(Graphics g, double x, String text);
359 }
360 
361 /* __oOo__ */