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__ */